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³²).
If a float smaller than one in absolute value is written without a
leading zero in the mod file, for instance as `.5`, we really need to
prefix the number with a zero. The simplest approach is to convert
the strings representing the numerical constants into floats.
The “diff” operator was incorrectly replaced by its argument in the static
model, leading to an incorrect result for the steady state.
This is because the information contained in the “expr_node” field of the
auxiliary variables storage was not consistent across all types of auxiliary
variables: for a “diff()” operator, it would contain the argument of the
operator, instead of the full node. Hence it would not simplify to zero at the
steady state.
A similar inconsistency was also present for the “expectation()” operator,
though it was not leading to an incorrect static model.
In the absence of braces, the last “else” clause is always associated with the
closest “if”, which is not what was intended here. The indentation was
misleading.
Allows for the inclusion/exclusion of a set of equations, specified either on the command line or in a text file.
If the equation has a single endogenous variable on the LHS, then the equation is moved. If not, if the equation has an `endogenous` tag then that variable is removed along with this equation. If not, then an error is thrown.
As a command line argument, `exclude_eqs` can take the form (same syntax for `include_eqs`):
* `exclude_eqs=eq1 to remove all equations declared as `[name=eq1]`
* `exclude_eqs=[eq 1, eq 2]` to remove all equations declared as `[name=eq 1]` or `[name=eq 2]`
* `exclude_eqs=[tagname=X]` to remove all equations declared as `[tagname=X]`
* `exclude_eqs=[tagname=(X, Y)]` to remove all equations declared as `[tagname=X]` or `[tagname=Y]`
When declared in a file, the file should be of the form:
```
eq 1
eq 2
```
to remove all equations declared as `[name=eq 1]` or `[name=eq 2]`.
It should be of the form:
```
tagname=
X
Y
```
to remove all equations declared as `[tagname=X]` or `[tagname=Y]`.
In many cases, they can be replaced by the curly braces syntax.
Otherwise, we can now use the pair() and tuple() constructors, without the need
to specify template parameters, thanks to class template argument
deduction (new in C++17).
This is made possible by the getLagEquivalenceClass() method introduced in the
previous commit.
Previously, the static version of the LHS expressions was used.
As a consequence, drop ModFile::diff_static_model, now useless.
Previously, for testing whether two diff() expressions or two unary ops were
the lead/lag of each other, the preprocessor would test whether they have the
same static representation. This is ok for simple expressions (e.g.
diff(x(-1))), but not for more complex ones (e.g. diff(x-y) and diff(x(-1)-y)
should not be given the same auxiliary variable).
This commit fixes this by properly constructing the equivalence relationship
and choosing a representative within each equivalence class. See the comments
above lag_equivalence_table_t in ExprNode.hh for more details.
Closes#27
Those methods can return a negative value in some cases. For example,
maxLead(x₋₁) = −1.
But constants were always returning a value of zero, which means that we had
inconsistent behaviour like maxLead(x₋₁ + 2) = 0.
This commits fixes the behaviour by making these methods return the smallest
possible integer when called on constants.
The transformation would be incorrect because of the expectation operator.
There was already a safety check, but it was not entirely correct. For example,
if “exp(y)” was appearing before “exp(y(+1))”, the check would not catch the
problem, because it happened after the substitution table had been filled. So
we now do the check before filling that table.