When computing the derivatives or block decomposition of the planner objective,
the epilogue or the original Ramsey model, the preprocessor would talk about
dynamic/static model, which was confusing. It now uses the right terminology.
If block decomposition fails, error out if “block” option was passed, but not
otherwise.
This commit does not modify the generated files.
This is a preliminary step for dynare#1859.
– factorize common code between the static and the dynamic version
– reorganise language-specific code into dedicated functions
– use a function template in the main helper to do some computations
at compile-time (using constexpr features)
– a generic one: CommonEnums.hh
– and a bytecode-specific one: Bytecode.hh
By the way, rename global constant “near_zero” into “power_deriv_near_zero”,
for clarity.
In particular, use this feature in many loops which feature a special treatment
for the first iteration, using a boolean variable (replacing iterator
manipulation). By the way, also use std::exchange() to simultaneously test the
value of this variable and update it.
And, symmetrically, when the “bytecode” option is requested by the user, always
create the .m static/dynamic files.
The “bytecode” option therefore no longer modifies the preprocessor output.
– Indicate whether we are trying to normalize the static or dynamic model
– If failed to normalize the static model, suggest to use the “no_static”
option
– Remove a superfluous error message
— rename the files with camel case
— encapsulate the functions with modules
— change the signature of function <MODFILE>_dynamic_set_series!, by removing
the output argument and appending the exclamation mark, since this function
modifies one of its arguments, and for symmetry with the static version
Ref. DynareJulia/Dynare.jl#1
Use 3-column format before calling sparse().
Ensure that the 3-column matrix is constructed in column-major order: data
locality will greatly improve performance once we implement use_dll.
Rather use a single vector as in non-block mode.
By the way, change the order of output arguments in static functions, to be
closer to the dynamic ones.
Temporary terms need to be computed per equation (as was done previously), and
not simply per block.
It’s necessary to track temporary terms per equation, because some equations
are evaluated instead of solved, and an equation E1 may depend on the value of
an endogenous Y computed by a previously evaluated equation E2; in this case,
if some temporary term TT of equation E2 contains Y, then TT needs to be
computed after E1, but before E2.
In particular, in dynamic models, temporary terms are now computed for
derivatives w.r.t. exogenous, and also w.r.t. endogenous variables that do not
belong to the block.
Also remove a message about elements below the cutoff that was no longer
correct (elements below the cutoff have no impact on the incidence matrix
outside of normalization).
By the way, this probably fixes a bug in the presence of external
functions (so-called TEF terms were not properly repeated in each per-block
static file).
Also remove debugging output in the M-file.
By the way, remove the BlockType stuff which was purely informative (and it’s
not worth carrying over prologue and epilogue information just for that).
Previously, the cutoff option would also impact the block decomposition itself,
since it would had an influence on the incidence matrix used for computing the
blocks and their derivatives.
The problem is that, in the general case, it’s quite possible that an element
of the numerical Jacobian be zero at the evaluation point, while being quite
different from zero along the simulation path. A typical example is an
expression of the type x*y, where y is an endogenous and x is an exogenous not
present in the initval block (and hence initialized to zero).
It has been superseded by ModelTree::blocks_derivatives.
By the way, fix the initial number of non-zero elements in sparse Jacobian.
Also avoid computing suboptimal temporary terms.
— use a std::map for storing block derivatives
— remove redundant ModelTree::first_chain_rule_derivatives structure
— remove unused codepaths in StaticModel
— DynamicModel: simplify code that determines the type of derivatives in a
block. We now use a slightly different categorization.
— by the way, fix the max lead/lag information for blocks that are obtained via
merging. A workaround was previously implemented in
DynamicModel::get_Derivative(), but it is no longer needed with this fix.
This was only adding unneeded complexity, for no clear reason (we’re very far
from reaching 2³¹ equations, and if we wanted to support models that large, it
would be better to use long integers to avoid being limited to 2³²).
— return output arguments on the left-hand side
— do not pass class members as input/output arguments
By the way, fix a (benign) vector allocation bug in
{Static,Dynamic}Model::computeChainRuleJacobian().