Commit Graph

3370 Commits (e22d9049ee79e0dfbdd7552aba277eaa5fd15f20)

Author SHA1 Message Date
Sébastien Villemot e22d9049ee
Optimization: use std::unordered_map instead of std::map for caching chain rule derivation
Improves performance on very very large models (tens of thousands of equations).
2023-04-05 19:49:16 +02:00
Sébastien Villemot b9bfcaad5d
Block+bytecode: minor simplification 2023-04-03 18:29:57 +02:00
Sébastien Villemot a87f536799
ramsey_policy: implement fully at the preprocessor level
The implementation no longer relies on ramsey_policy.m at the MATLAB/Octave
level.

By the way, drop ModFileStructure::ramsey_model_present, which is now
redundant.
2023-03-29 16:14:59 +02:00
Sébastien Villemot e9babf0242
🐛 ramsey_policy: lift restriction that order must be ⩽ 2
This restriction no longer exists, and is actually not applied to stoch_simul
when following ramsey_model.
2023-03-29 16:05:38 +02:00
Sébastien Villemot 419c684929
🐛 Extend incompatibility with deterministic exogenous to ramsey_model command
The check was only done with ramsey_policy.
2023-03-29 15:33:15 +02:00
Sébastien Villemot d0bc8128c7
ramsey_model: remove useless checks
Options “order”, “partial_information” and “k_order_solver” are not accepted by
the command (this code is probably a remnant of the deprecated “ramsey_policy”
command).
2023-03-29 15:27:57 +02:00
Sébastien Villemot 4282c98527
New field: M_.discretionary_orig_eq_nbr
It indicates the number of equations written in the model block by the user in
the discretionary policy case.
2023-03-28 18:47:02 +02:00
Sébastien Villemot cecc9aad69
New fields: M_.ramsey_orig_{eq,endo}_nbr
– M_.ramsey_orig_endo_nbr is the number of endogenous variables in the model
  present just before adding the Lagrange multipliers and computing the Ramsey
  FOC; it is by construction equal to the number of equations that will be added
  by the process of computing the FOCs
– M_.ramsey_orig_eq_nbr is the number of equations in the model present just
  before adding the Lagrange multipliers and computing the Ramsey FOC; it is by
  construction equal to the number of Lagrange multipliers that will be added by
  the process of computing the FOCs

Note that both may be greater than the number of endogenous/equations written
by the user, because some auxiliary variables may have already been added.

Also note that the number of policy instruments in M_.ramsey_orig_endo_nbr −
M_.ramsey_orig_eq_nbr

As a consequence, drop M_.ramsey_eq_nbr (which was actually equal to
M_.ramsey_orig_endo_nbr) and M_.orig_eq_nbr (which was actually equal to
M_.ramsey_orig_eq_nbr, but would also be set in the non-Ramsey case). The new
names are clearer.
2023-03-28 18:46:42 +02:00
Sébastien Villemot 70192aec71
Always set options_.{ramsey,discretionary}_policy at the preprocessor level
And set them before any computation is done.

These fields should rather be in M_.
2023-03-28 18:29:42 +02:00
Sébastien Villemot 2f353a3c62
Remove useless casts 2023-03-28 16:39:13 +02:00
Sébastien Villemot 1ef5feec15
Factorize methods for writing set auxiliary variables/series files 2023-03-28 16:37:05 +02:00
Sébastien Villemot 0d41e0ce3d
Make ModFileStructure a struct 2023-03-28 15:07:45 +02:00
Sébastien Villemot 0169240f76
Ramsey: write derivatives of static model w.r.t. Lagrange multipliers in a new file
The computing of the Ramsey steady state relies on the fact that Lagrange
multipliers appear linearly in the system to be solved. Instead of directly
solving for the Lagrange multipliers along with the other variables,
dyn_ramsey_static.m reduces the size of the problem by always computing the
value of the multipliers that minimizes the residuals, given the other
variables (using a minimum norm solution, easy to compute because of the
linearity property). That function thus needs the derivatives of the optimality
FOCs with respect to the multipliers. The problem is that, when multipliers
appear in an auxiliary variable related to a lead/lag, then those derivatives
need to be retrieved by a chain rule derivation, which cannot be easily done
with the regular static file.

This commit implements the creation of a new file,
ramsey_multipliers_static_g1.{m,mex}, that provides exactly the needed
derivatives w.r.t. Lagrange multipliers through chain rule derivation.

Ref. dynare#633, dynare#1119, dynare#1133
2023-03-28 14:27:51 +02:00
Sébastien Villemot fe3f18947e
No longer replace all auxiliary variables by their definition in the static model
This is effectively a revert of commits 1b4f68f934,
32fb90d5f3 and f6f4ea70fb.

This transformation had been introduced in order to fix the computation of the
Ramsey steady state in the case where Lagrange multipliers appeared with a lead
or lag ⩾ 2 (and where thus part of the definition of an auxiliary variable).

But this transformation had introduced bugs in the handling of external
functions which were difficult to tackle.

Moreover, it seems preferable to keep the strict correspondence between the
dynamic and static model, in order to make reasoning about the preprocessor
internals easier (in particular, for this reason this transformation was not
implemented in ModFile::transformPass() but in ModFile::computingPass(), which
was a bit confusing).

A better solution for the Ramsey steady state issue will is implemented in the
descendent of the present commit.

Ref. dynare#633, dynare#1119, dynare#1133
2023-03-28 14:10:13 +02:00
Sébastien Villemot f48a698458
🐛 Suboptimal temporary terms for external functions
If a given external function was called two times with different arguments,
then the second call would always be computed in the same temporary terms
chunk (derivation order or block) as the first call, even if this was not
necessary (technically, the second call would be promoted in the temporary
terms computation in the same category as the first call).

This could possibly lead to an inefficiency.
2023-03-28 14:00:06 +02:00
Sébastien Villemot 712b11a045
🐛 Incorrect stochastic transformation with endo lead ⩾ 2 or exo lead ⩾ 1 in external functions
If an endogenous with a lead ⩾ 2 or an exogenous with a lead ⩾ 1 appeared in
the argument(s) of a call to an external function, the auxiliary variable
transformation was incorrect (the variable was replaced inside the function
call, while it is the whole function call that has to be replaced).

This could lead to incorrect results in stochastic contexts, when the external
function is nonlinear.
2023-03-28 13:56:13 +02:00
Sébastien Villemot 3b20f835db
ModelTree: fix call to ExprNode::computeTemporaryTerms()
The first argument to ExprNode::computeTemporaryTerms() is supposed to be a
pair (endo derivation order, param derivation order). The two elements were
interverted in the call. This would not affect the result, because parameter
derivatives are not computed there and what matters is the lexical ordering
which remains the same. But fixing the order is better, for consistency with
the method description.
2023-03-28 13:54:10 +02:00
Sébastien Villemot 34c37cfd01
🐛 Crash when writing the (static) set_auxiliary_variables file in the presence of external functions 2023-03-28 13:49:34 +02:00
Sébastien Villemot acdfc1ad62
🐛 Julia: auxiliary variables of static model were incorrect in set_auxiliary_variables!
The output was in MATLAB syntax instead of Julia syntax.
2023-03-28 13:47:18 +02:00
Sébastien Villemot a8fc8e7afc
🐛 Incorrect cost table used when computing temporary terms in static model with “use_dll”
It was erroneously using MATLAB costs, leading to possible
inefficiencies (though those cost tables are probably not very accurate and
should be revised).
2023-03-28 13:43:31 +02:00
Sébastien Villemot 42ea2aac34
Fix typo 2023-03-24 19:02:33 +01:00
Sébastien Villemot 89a1a4d27f
Remove unused function 2023-03-24 19:02:33 +01:00
Sébastien Villemot 5ff503a964
Use map::try_emplace() instead of map::emplace() to simplify some calls
By the way, remove a redundant Cluster{} constructor call.
2023-03-23 16:10:42 +01:00
Sébastien Villemot 7c6402cc34
DataTree: optimize the filling of node maps
Use map::{try,}emplace() instead of operator[], which should in theory be
slightly faster.
2023-03-23 16:10:40 +01:00
Sébastien Villemot 69a394a115
ExprNode: factorization of code that recurisively applies a transformation on a node 2023-03-23 12:39:35 +01:00
Sébastien Villemot 661f116af1
Rename the argument to ExprNode::clone() for clarity
The argument had the same name as the data member “datatree”, so this could
lead to confusion (though there was no bug, since the argument was masking
the data member).
2023-03-23 12:39:35 +01:00
Sébastien Villemot 2f111f5055
ExprNode: simplification of external function nodes clone() and toStatic() methods 2023-03-23 12:39:11 +01:00
Sébastien Villemot bff80c0eaf
use_dll: under Windows, append MinGW location to the PATH variable only once
Previously, the MinGW location was appended multiple times to the PATH
variable, which in some cases would make the variable too long and thus
dysfunctional.

The variable is now initialized once when the worker threads are created.

By the way, move the macOS+Octave environment variable initializations to the
same place, for consistency.
2023-03-20 18:27:33 +01:00
Sébastien Villemot a219c68543
Macroprocessor: drop useless Expression::clone() method 2023-03-16 11:36:41 +01:00
Sébastien Villemot 96e7a764b2
Macroprocessor: make method Expression::eval() const 2023-03-16 11:32:50 +01:00
Sébastien Villemot df7144525d
CI: remove useless quotes 2023-03-13 17:36:20 +01:00
Sébastien Villemot ba78d0c813
CI: adapt for new macOS runner
- enforce x86-64 architecture
- use “sysctl -n hw.ncpu” instead of “nproc” (which has not been installed in
  the new runner)
2023-03-13 17:33:05 +01:00
Sébastien Villemot 715ec9e4bc
Fix bytecode for block+mfs>0 in static model
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.
2023-03-03 17:45:08 +01:00
Sébastien Villemot 7acf278370
Performance improvement of chain rule derivation
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”).
2023-03-02 17:52:36 +01:00
Sébastien Villemot f8edce01ec
Minor simplification 2023-03-02 17:28:03 +01:00
Sébastien Villemot bf8ca27a47
Make ExprNode::prepareForDerivation() a protected member (was public) 2023-03-02 16:08:55 +01:00
Sébastien Villemot fe83933b1d
Bugfix: undefined behaviour in AbstractExternalFunctionNode::prepareForDerivation()
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.
2023-03-02 15:55:51 +01:00
Sébastien Villemot 41052ccb74
Optimization for derivation of STEADY_STATE(…) operator in a dynamic context
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.
2023-03-02 15:11:49 +01:00
Sébastien Villemot d64317a64f
Minor simplification 2023-03-02 15:11:47 +01:00
Sébastien Villemot 13e51fba6b
CI: various cleanups
- 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
2023-03-01 13:04:02 +01:00
Sébastien Villemot ae83974e0e
Minor simplification using if with initialization 2023-02-28 16:27:31 +01:00
Sébastien Villemot 62c455ff56
Misc simplifications using STL algorithms 2023-02-28 16:27:29 +01:00
Sébastien Villemot 008a80910e
Bytecode: move CodeLoad class out of the preprocessor 2023-02-21 16:01:27 -05:00
Sébastien Villemot a88b921991
Bytecode: improve deserialization routines for FCALL and FBEGINBLOCK 2023-02-17 16:20:40 -05:00
Sébastien Villemot cf3ab36ac8
Bytecode: simplify specialized serialization methods 2023-02-17 15:31:22 -05:00
Sébastien Villemot 114d8eadfb
New “homotopy_alt_starting_point” option to “perfect_foresight_solver” command 2023-02-07 14:44:59 -05:00
Sébastien Villemot 389a2647d3
Block decomposition: make mfs=1 the default
NB: mfs=3 is nevertheless used when “block” option has not been used, and the
model is purely backward/forward or static, for solve_algo={12,14}.
2023-01-25 18:38:58 +01:00
Sébastien Villemot dc966014a3
Remove some incorrect normalization rules for the case mfs=3
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.
2023-01-25 17:14:01 +01:00
Sébastien Villemot 0ddcf81ac0
Fix typo 2023-01-25 16:50:56 +01:00
Sébastien Villemot 1c813a1cf9
Run detrending engine if trend variables are present, even if unused in a var(deflator=…) statement
Closes: #113
2023-01-24 14:14:40 +01:00