Decomposition

<< Click to Display Table of Contents >>

Navigation:  Details >

Decomposition

Previous pageReturn to chapter overviewNext page

DECOMP performs decomposition of expressions or model equations. For a non-linear model, decomposition traces effects from equation to equation, so that a given impulse (a change in an exogenous variable) can be traced, as it propagates through equations and endogenous variables. There are many details in such decomposition, and it is quite complicated math-wise. There is also the concept of "precedents" -- how to determine exactly which variables enter a given equation or statement? This is easier said than done.

Gekko contains "old" and "new" decomposition code (the new code is located in Decomp.cs, and the old code will be deprecated soon and is therefore not described here). The new code is pretty complicated, because decomposition is inherently complicated, but also because the new code takes a pivot table approach to the reporting of decomposed values. So in that sense, it becomes doubly complicated. On the positive side, DECOMP is a stand-alone component and not a deep part of Gekko.

The concept of precedents is a bit difficult, if it should be able to decompose any statement/expression, and not just the relatively simple model equations. In a statement like = x1 + x2;, the precedents are simply x1 and x2, because these independendt variables are the only variables that determine the dependent variable y. Finding out that x1 and x1 are determining y is just a matter of looking at the equation as a string, using for instance a tokenizer. But other expressions are less obvious, for instance = movsum(x, 3);, which is in reality = x + x[-1] + x[-2];, or even worse = sum(#i, x[#i]);, where #= a, b, c. For this #i, the statement is equal to = x[a] + x[b] + x[c];, so x[a], x[b], and x[c] are precedents here. Gekko also allows name substitution like %= 'a'; y = x{%i} + y{%i};, which is equal to = xa + xb;. All this is difficult to extract just from looking at a statement like = sum(#i, x[#i]); or = x{%i} + y{%i}; as a text string, analyzing it with a tokenizer.

So the approach in the "new" DECOMP is to try to evaluate a statement like = x{%i} + y{%i}; and record which Gekko variables get queried during evaluation (this is done in the lookup code where all variable querying takes place). So when doing an evaluation of = x{%i} + y{%i};  at some point the timeseries xa gets queried, and later on ya. These names are stored as precedents. One of the benefits of this is that even a function like = manynames(); can be decomposed, where manynames() is a function that depends upon a number of Gekko variables that are only specificed in the function proper.