Variable indices would be incorrect in the evaluated Jacobian if recursive
variables were present. This would lead to incorrect results and/or crashes in
bytecode MEX. This bug has been exposed by commit
f45a99fc68, which actually enabled mfs>0 for
static models.
Commit 23b0c12d8e introduced caching in chain
rule derivation (used by block decomposition), which increased speed for mfs >
0, but actually decreased it for mfs=0.
This patch introduces the pre-computation of derivatives which are known to be
zero using symbolic a priori (similarly to what is done in the non-chain rule
context). The algorithms are now identical between the two contexts (both
symbolic a priori + caching), the difference being that in the chain rule
context, the symbolic a priori and the cache are not stored within the ExprNode
class, since they depend on the list of recursive variables.
This patch brings a significant performant improvement for all values of the
“mfs” option (the improvement is greater for small values of “mfs”).
Input and output ranges should not overlap when calling std::set_union(),
otherwise the behaviour is undefined.
It seems that in this precise case the computation would still be
correct (though inefficient), because of the properties of std::set or because
of the specific implementation in libstdc++. But it’s better to be on the safe
side.
In a dynamic context, the only potentially non-null derivatives of
STEADY_STATE(…) are the parameters. We know that the derivatives w.r.t. other
variables are zero, so store that information in non_null_derivatives.
- drop the Julia stuff, since it is no longer used
In particular, no longer use static linking, since builds are now only
for testing purposes and are not shipped
- drop the Windows i686 build, since we no longer support that configuration
- bump Boost version used for Windows x86-64 build
- rename build_linux_aarch64 into build_linux_arm64 for clarity
More precisely, incorrect equation normalization could occur in the presence of
cos, sin, tan, cosh and x^n (where n is an even integer).
Also add some comments explaining why some other rules are (hopefully) correct.
Note that DynamicModel::determineBlockDerivativesType(), it’s legitimate to
replace max_{lead,lag} by max_endo_{lead,lag}, because for exogenous
lag=lead=0, and we no longer compute derivatives w.r.t. to endogenous that do
not belong to the block (so-called “other” endogenous).
As a consequence, and as a temporary measure, always output the
non-block-decomposed legacy representation.
Also drop the block kalman filter output, and drop now useless variables in
M_.block_structure.