Add new “log” option to “var” statement
When an endogenous is declared with “var(log)”, say “y”: – creates an auxiliary named “LOG_y” – replaces “y(±l)” everywhere by “exp(LOG_y(±l))” – adds a new auxiliary equation “y=exp(LOG_y)” – adds a new definition “LOG_y=log(y)” in set_auxiliary_variables.m and dynamic_set_auxiliary_series.m files This option also works in conjunction with “deflator=…”, such as “var(log, deflator=…)” (the “log” must appear befor “deflator”). There are no provisions for combining “log” with “log_deflator”, because that would not make much sense from an economic point of view (amounts to taking the log two times). Ref. dynare#349fix-tolerance-parameters
parent
ee14027e1b
commit
71edfd05e4
|
@ -5768,6 +5768,65 @@ DynamicModel::transformPredeterminedVariables()
|
|||
// No need to handle static_only_equations, since there are no leads/lags there
|
||||
}
|
||||
|
||||
void
|
||||
DynamicModel::substituteLogTransform()
|
||||
{
|
||||
for (int symb_id : symbol_table.getVariablesWithLogTransform())
|
||||
{
|
||||
expr_t aux_def = AddLog(AddVariable(symb_id));
|
||||
int aux_symb_id = symbol_table.addLogTransformAuxiliaryVar(symb_id, 0, aux_def);
|
||||
|
||||
for (auto &[id, definition] : local_variables_table)
|
||||
definition = definition->substituteLogTransform(symb_id, aux_symb_id);
|
||||
|
||||
for (auto &equation : equations)
|
||||
equation = dynamic_cast<BinaryOpNode *>(equation->substituteLogTransform(symb_id, aux_symb_id));
|
||||
|
||||
for (auto &equation : static_only_equations)
|
||||
equation = dynamic_cast<BinaryOpNode *>(equation->substituteLogTransform(symb_id, aux_symb_id));
|
||||
|
||||
/*
|
||||
We add the following new equations:
|
||||
+ X=exp(log_X) to the model
|
||||
+ log_X=log(X) to the list of auxiliary equations
|
||||
|
||||
In this way:
|
||||
+ statements like X=1 in initval/endval blocks will be correctly
|
||||
handled (i.e. log_X will be initialized to 0 in this case), through
|
||||
the set_auxiliary_variables.m and dynamic_set_auxiliary_series.m files
|
||||
+ computation of X in perfect foresight simulations will be done by
|
||||
simple evaluation when using block decomposition (X will belong to an
|
||||
block of type “evaluate”, or maybe even the epilogue)
|
||||
*/
|
||||
addAuxEquation(AddEqual(AddVariable(aux_symb_id), aux_def));
|
||||
addEquation(AddEqual(AddVariable(symb_id), AddExp(AddVariable(aux_symb_id))),
|
||||
-1, {});
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DynamicModel::checkNoWithLogTransform(const set<int> &eqnumbers)
|
||||
{
|
||||
set<int> endos;
|
||||
for (int eq : eqnumbers)
|
||||
equations[eq]->collectVariables(SymbolType::endogenous, endos);
|
||||
|
||||
const set<int> &with_log_transform = symbol_table.getVariablesWithLogTransform();
|
||||
|
||||
vector<int> intersect;
|
||||
set_intersection(endos.begin(), endos.end(),
|
||||
with_log_transform.begin(), with_log_transform.end(),
|
||||
back_inserter(intersect));
|
||||
if (!intersect.empty())
|
||||
{
|
||||
cerr << "ERROR: the following variables are declared with var(log) and therefore cannot appear in a VAR/TCM/PAC equation: ";
|
||||
for (int symb_id : intersect)
|
||||
cerr << symbol_table.getName(symb_id) << " ";
|
||||
cerr << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DynamicModel::detrendEquations()
|
||||
{
|
||||
|
|
|
@ -499,6 +499,12 @@ public:
|
|||
//! Transforms the model by decreasing the lead/lag of predetermined variables in model equations by one
|
||||
void transformPredeterminedVariables();
|
||||
|
||||
// Performs the transformations associated to variables declared with “var(log)”
|
||||
void substituteLogTransform();
|
||||
|
||||
// Check that no variable was declared with “var(log)” in the given equations
|
||||
void checkNoWithLogTransform(const set<int> &eqnumbers);
|
||||
|
||||
//! Transforms the model by removing trends specified by the user
|
||||
void detrendEquations();
|
||||
|
||||
|
|
|
@ -491,11 +491,17 @@ log_trend_var : LOG_TREND_VAR '(' LOG_GROWTH_FACTOR EQUAL { driver.begin_model()
|
|||
;
|
||||
|
||||
var : VAR symbol_list_with_tex_and_partition ';'
|
||||
{ driver.var($2); }
|
||||
{ driver.var($2, false); }
|
||||
| VAR '(' LOG ')' symbol_list_with_tex_and_partition ';'
|
||||
{ driver.var($5, true); }
|
||||
| VAR '(' DEFLATOR EQUAL { driver.begin_model(); } hand_side ')' symbol_list_with_tex_and_partition ';'
|
||||
{ driver.end_nonstationary_var(false, $6, $8); }
|
||||
{ driver.end_nonstationary_var(false, $6, $8, false); }
|
||||
| VAR '(' LOG COMMA DEFLATOR EQUAL { driver.begin_model(); } hand_side ')' symbol_list_with_tex_and_partition ';'
|
||||
{ driver.end_nonstationary_var(false, $8, $10, true); }
|
||||
| VAR '(' LOG_DEFLATOR EQUAL { driver.begin_model(); } hand_side ')' symbol_list_with_tex_and_partition ';'
|
||||
{ driver.end_nonstationary_var(true, $6, $8); }
|
||||
{ driver.end_nonstationary_var(true, $6, $8, false); }
|
||||
/* The case LOG + LOG_DEFLATOR is omitted, because it does not make much sense
|
||||
from an economic point of view (amounts to taking the log two times) */
|
||||
;
|
||||
|
||||
var_remove : VAR_REMOVE symbol_list ';' { driver.var_remove($2); };
|
||||
|
|
|
@ -748,6 +748,12 @@ NumConstNode::replaceVarsInEquation(map<VariableNode *, NumConstNode *> &table)
|
|||
return const_cast<NumConstNode *>(this);
|
||||
}
|
||||
|
||||
expr_t
|
||||
NumConstNode::substituteLogTransform(int orig_symb_id, int aux_symb_id) const
|
||||
{
|
||||
return const_cast<NumConstNode *>(this);
|
||||
}
|
||||
|
||||
VariableNode::VariableNode(DataTree &datatree_arg, int idx_arg, int symb_id_arg, int lag_arg) :
|
||||
ExprNode{datatree_arg, idx_arg},
|
||||
symb_id{symb_id_arg},
|
||||
|
@ -1990,6 +1996,18 @@ VariableNode::matchMatchedMoment(vector<int> &symb_ids, vector<int> &lags, vecto
|
|||
powers.push_back(1);
|
||||
}
|
||||
|
||||
expr_t
|
||||
VariableNode::substituteLogTransform(int orig_symb_id, int aux_symb_id) const
|
||||
{
|
||||
if (get_type() == SymbolType::modelLocalVariable)
|
||||
return datatree.getLocalVariable(symb_id)->substituteLogTransform(orig_symb_id, aux_symb_id);
|
||||
|
||||
if (symb_id == orig_symb_id)
|
||||
return datatree.AddExp(datatree.AddVariable(aux_symb_id, lag));
|
||||
else
|
||||
return const_cast<VariableNode *>(this);
|
||||
}
|
||||
|
||||
UnaryOpNode::UnaryOpNode(DataTree &datatree_arg, int idx_arg, UnaryOpcode op_code_arg, const expr_t arg_arg, int expectation_information_set_arg, int param1_symb_id_arg, int param2_symb_id_arg, string adl_param_name_arg, vector<int> adl_lags_arg) :
|
||||
ExprNode{datatree_arg, idx_arg},
|
||||
arg{arg_arg},
|
||||
|
@ -3768,6 +3786,13 @@ UnaryOpNode::replaceVarsInEquation(map<VariableNode *, NumConstNode *> &table) c
|
|||
return buildSimilarUnaryOpNode(argsubst, datatree);
|
||||
}
|
||||
|
||||
expr_t
|
||||
UnaryOpNode::substituteLogTransform(int orig_symb_id, int aux_symb_id) const
|
||||
{
|
||||
expr_t argsubst = arg->substituteLogTransform(orig_symb_id, aux_symb_id);
|
||||
return buildSimilarUnaryOpNode(argsubst, datatree);
|
||||
}
|
||||
|
||||
BinaryOpNode::BinaryOpNode(DataTree &datatree_arg, int idx_arg, const expr_t arg1_arg,
|
||||
BinaryOpcode op_code_arg, const expr_t arg2_arg, int powerDerivOrder_arg) :
|
||||
ExprNode{datatree_arg, idx_arg},
|
||||
|
@ -5620,6 +5645,13 @@ BinaryOpNode::matchMatchedMoment(vector<int> &symb_ids, vector<int> &lags, vecto
|
|||
throw MatchFailureException("Unsupported binary operator");
|
||||
}
|
||||
|
||||
expr_t
|
||||
BinaryOpNode::substituteLogTransform(int orig_symb_id, int aux_symb_id) const
|
||||
{
|
||||
expr_t arg1subst = arg1->substituteLogTransform(orig_symb_id, aux_symb_id);
|
||||
expr_t arg2subst = arg2->substituteLogTransform(orig_symb_id, aux_symb_id);
|
||||
return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree);
|
||||
}
|
||||
|
||||
TrinaryOpNode::TrinaryOpNode(DataTree &datatree_arg, int idx_arg, const expr_t arg1_arg,
|
||||
TrinaryOpcode op_code_arg, const expr_t arg2_arg, const expr_t arg3_arg) :
|
||||
|
@ -6499,6 +6531,15 @@ TrinaryOpNode::replaceVarsInEquation(map<VariableNode *, NumConstNode *> &table)
|
|||
return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree);
|
||||
}
|
||||
|
||||
expr_t
|
||||
TrinaryOpNode::substituteLogTransform(int orig_symb_id, int aux_symb_id) const
|
||||
{
|
||||
expr_t arg1subst = arg1->substituteLogTransform(orig_symb_id, aux_symb_id);
|
||||
expr_t arg2subst = arg2->substituteLogTransform(orig_symb_id, aux_symb_id);
|
||||
expr_t arg3subst = arg3->substituteLogTransform(orig_symb_id, aux_symb_id);
|
||||
return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree);
|
||||
}
|
||||
|
||||
AbstractExternalFunctionNode::AbstractExternalFunctionNode(DataTree &datatree_arg,
|
||||
int idx_arg,
|
||||
int symb_id_arg,
|
||||
|
@ -7079,6 +7120,15 @@ ExternalFunctionNode::ExternalFunctionNode(DataTree &datatree_arg,
|
|||
{
|
||||
}
|
||||
|
||||
expr_t
|
||||
AbstractExternalFunctionNode::substituteLogTransform(int orig_symb_id, int aux_symb_id) const
|
||||
{
|
||||
vector<expr_t> arguments_subst;
|
||||
for (auto argument : arguments)
|
||||
arguments_subst.push_back(argument->substituteLogTransform(orig_symb_id, aux_symb_id));
|
||||
return buildSimilarExternalFunctionNode(arguments_subst, datatree);
|
||||
}
|
||||
|
||||
expr_t
|
||||
ExternalFunctionNode::composeDerivatives(const vector<expr_t> &dargs)
|
||||
{
|
||||
|
@ -8371,6 +8421,12 @@ SubModelNode::removeTrendLeadLag(const map<int, expr_t> &trend_symbols_map) cons
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
expr_t
|
||||
SubModelNode::substituteLogTransform(int orig_symb_id, int aux_symb_id) const
|
||||
{
|
||||
return const_cast<SubModelNode *>(this);
|
||||
}
|
||||
|
||||
VarExpectationNode::VarExpectationNode(DataTree &datatree_arg,
|
||||
int idx_arg,
|
||||
string model_name_arg) :
|
||||
|
|
|
@ -744,6 +744,9 @@ public:
|
|||
|
||||
// Returns true if the expression contains an exogenous or an exogenous deterministic
|
||||
bool hasExogenous() const;
|
||||
|
||||
// Substitutes orig_symb_id(±l) with exp(aux_symb_id(±l)) (used for “var(log)”)
|
||||
virtual expr_t substituteLogTransform(int orig_symb_id, int aux_symb_id) const = 0;
|
||||
};
|
||||
|
||||
//! Object used to compare two nodes (using their indexes)
|
||||
|
@ -826,6 +829,7 @@ public:
|
|||
bool containsPacTargetNonstationary(const string &pac_model_name = "") const override;
|
||||
bool isParamTimesEndogExpr() const override;
|
||||
expr_t substituteStaticAuxiliaryVariable() const override;
|
||||
expr_t substituteLogTransform(int orig_symb_id, int aux_symb_id) const override;
|
||||
};
|
||||
|
||||
//! Symbol or variable node
|
||||
|
@ -901,6 +905,7 @@ public:
|
|||
expr_t substituteStaticAuxiliaryVariable() const override;
|
||||
void matchMatchedMoment(vector<int> &symb_ids, vector<int> &lags, vector<int> &powers) const override;
|
||||
pair<int, expr_t> matchEndogenousTimesConstant() const override;
|
||||
expr_t substituteLogTransform(int orig_symb_id, int aux_symb_id) const override;
|
||||
};
|
||||
|
||||
//! Unary operator node
|
||||
|
@ -1004,6 +1009,7 @@ public:
|
|||
//! Substitute auxiliary variables by their expression in static model
|
||||
expr_t substituteStaticAuxiliaryVariable() const override;
|
||||
void decomposeAdditiveTerms(vector<pair<expr_t, int>> &terms, int current_sign) const override;
|
||||
expr_t substituteLogTransform(int orig_symb_id, int aux_symb_id) const override;
|
||||
};
|
||||
|
||||
//! Binary operator node
|
||||
|
@ -1148,6 +1154,7 @@ public:
|
|||
void decomposeMultiplicativeFactors(vector<pair<expr_t, int>> &factors, int current_exponent = 1) const override;
|
||||
void matchMatchedMoment(vector<int> &symb_ids, vector<int> &lags, vector<int> &powers) const override;
|
||||
pair<int, expr_t> matchEndogenousTimesConstant() const override;
|
||||
expr_t substituteLogTransform(int orig_symb_id, int aux_symb_id) const override;
|
||||
};
|
||||
|
||||
//! Trinary operator node
|
||||
|
@ -1244,6 +1251,7 @@ public:
|
|||
bool isParamTimesEndogExpr() const override;
|
||||
//! Substitute auxiliary variables by their expression in static model
|
||||
expr_t substituteStaticAuxiliaryVariable() const override;
|
||||
expr_t substituteLogTransform(int orig_symb_id, int aux_symb_id) const override;
|
||||
};
|
||||
|
||||
//! External function node
|
||||
|
@ -1355,6 +1363,7 @@ public:
|
|||
bool isParamTimesEndogExpr() const override;
|
||||
//! Substitute auxiliary variables by their expression in static model
|
||||
expr_t substituteStaticAuxiliaryVariable() const override;
|
||||
expr_t substituteLogTransform(int orig_symb_id, int aux_symb_id) const override;
|
||||
};
|
||||
|
||||
class ExternalFunctionNode : public AbstractExternalFunctionNode
|
||||
|
@ -1531,6 +1540,7 @@ public:
|
|||
expr_t replaceTrendVar() const override;
|
||||
expr_t detrend(int symb_id, bool log_trend, expr_t trend) const override;
|
||||
expr_t removeTrendLeadLag(const map<int, expr_t> &trend_symbols_map) const override;
|
||||
expr_t substituteLogTransform(int orig_symb_id, int aux_symb_id) const override;
|
||||
};
|
||||
|
||||
class VarExpectationNode : public SubModelNode
|
||||
|
|
|
@ -428,6 +428,9 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, bool
|
|||
set<int> unary_ops_eqs = dynamic_model.getEquationNumbersFromTags(var_tcm_eqtags);
|
||||
unary_ops_eqs.merge(dynamic_model.findPacExpectationEquationNumbers());
|
||||
|
||||
// Check that no variable in VAR/TCM/PAC equations was declared with “var(log)”
|
||||
dynamic_model.checkNoWithLogTransform(unary_ops_eqs);
|
||||
|
||||
// Create auxiliary variables and equations for unary ops
|
||||
lag_equivalence_table_t unary_ops_nodes;
|
||||
ExprNode::subst_table_t unary_ops_subst_table;
|
||||
|
@ -502,6 +505,9 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, bool
|
|||
|
||||
dynamic_model.createVariableMapping();
|
||||
|
||||
// Must come after detrending of variables and Ramsey policy transformation
|
||||
dynamic_model.substituteLogTransform();
|
||||
|
||||
/* Create auxiliary vars for leads and lags greater than 2, on both endos and
|
||||
exos. The transformation is not exactly the same on stochastic and
|
||||
deterministic models, because there is no need to take into account the
|
||||
|
|
|
@ -205,10 +205,15 @@ ParsingDriver::declare_endogenous(const string &name, const string &tex_name, co
|
|||
}
|
||||
|
||||
void
|
||||
ParsingDriver::var(const vector<tuple<string, string, vector<pair<string, string>>>> &symbol_list)
|
||||
ParsingDriver::var(const vector<tuple<string, string, vector<pair<string, string>>>> &symbol_list,
|
||||
bool log_option)
|
||||
{
|
||||
for (auto &[name, tex_name, partition] : symbol_list)
|
||||
declare_endogenous(name, tex_name, partition);
|
||||
{
|
||||
int symb_id = declare_endogenous(name, tex_name, partition);
|
||||
if (log_option)
|
||||
mod_file->symbol_table.markWithLogTransform(symb_id);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -469,7 +474,7 @@ ParsingDriver::add_expression_variable(const string &name)
|
|||
}
|
||||
|
||||
void
|
||||
ParsingDriver::end_nonstationary_var(bool log_deflator, expr_t deflator, const vector<tuple<string, string, vector<pair<string, string>>>> &symbol_list)
|
||||
ParsingDriver::end_nonstationary_var(bool log_deflator, expr_t deflator, const vector<tuple<string, string, vector<pair<string, string>>>> &symbol_list, bool log_option)
|
||||
{
|
||||
mod_file->nonstationary_variables = true;
|
||||
|
||||
|
@ -478,6 +483,8 @@ ParsingDriver::end_nonstationary_var(bool log_deflator, expr_t deflator, const v
|
|||
{
|
||||
int symb_id = declare_endogenous(name, tex_name, partition);
|
||||
declared_nonstationary_vars.push_back(symb_id);
|
||||
if (log_option)
|
||||
mod_file->symbol_table.markWithLogTransform(symb_id);
|
||||
}
|
||||
|
||||
try
|
||||
|
|
|
@ -354,8 +354,8 @@ public:
|
|||
void initval_file();
|
||||
//! Declares an endogenous variable (and returns its symbol ID)
|
||||
int declare_endogenous(const string &name, const string &tex_name = "", const vector<pair<string, string>> &partition_value = {});
|
||||
// Handles a “var” statement (without “deflator” or “log_deflator” options)
|
||||
void var(const vector<tuple<string, string, vector<pair<string, string>>>> &symbol_list);
|
||||
// Handles a “var” or “var(log)” statement (without “deflator” or “log_deflator” options)
|
||||
void var(const vector<tuple<string, string, vector<pair<string, string>>>> &symbol_list, bool log_option);
|
||||
//! Declares an exogenous variable (and returns its symbol ID)
|
||||
int declare_exogenous(const string &name, const string &tex_name = "", const vector<pair<string, string>> &partition_value = {});
|
||||
// Handles a “varexo” statement
|
||||
|
@ -844,8 +844,8 @@ public:
|
|||
void add_steady_state_model_equal_multiple(const vector<string> &symbol_list, expr_t expr);
|
||||
//! Ends declaration of trend variable
|
||||
void end_trend_var(bool log_trend, expr_t growth_factor, const vector<pair<string, string>> &symbol_list);
|
||||
//! Ends declaration of nonstationary variable
|
||||
void end_nonstationary_var(bool log_deflator, expr_t deflator, const vector<tuple<string, string, vector<pair<string, string>>>> &symbol_list);
|
||||
//! Handles a “var(deflator=…)”, “var(log, deflator=…)” or “var(log_deflator=…)” statement
|
||||
void end_nonstationary_var(bool log_deflator, expr_t deflator, const vector<tuple<string, string, vector<pair<string, string>>>> &symbol_list, bool log_option);
|
||||
//! Add a graph format to the list of formats requested
|
||||
void add_graph_format(string name);
|
||||
//! Add the graph_format option to the OptionsList structure
|
||||
|
|
|
@ -363,6 +363,7 @@ SymbolTable::writeOutput(ostream &output) const noexcept(false)
|
|||
break;
|
||||
case AuxVarType::endoLag:
|
||||
case AuxVarType::exoLag:
|
||||
case AuxVarType::logTransform:
|
||||
case AuxVarType::diffLag:
|
||||
case AuxVarType::diffLead:
|
||||
case AuxVarType::diffForward:
|
||||
|
@ -525,6 +526,26 @@ SymbolTable::addExpectationAuxiliaryVar(int information_set, int index, expr_t e
|
|||
return symb_id;
|
||||
}
|
||||
|
||||
int
|
||||
SymbolTable::addLogTransformAuxiliaryVar(int orig_symb_id, int orig_lead_lag, expr_t expr_arg) noexcept(false)
|
||||
{
|
||||
string varname = "LOG_" + getName(orig_symb_id);
|
||||
int symb_id;
|
||||
try
|
||||
{
|
||||
symb_id = addSymbol(varname, SymbolType::endogenous);
|
||||
}
|
||||
catch (AlreadyDeclaredException &e)
|
||||
{
|
||||
cerr << "ERROR: you should rename your variable called " << varname << ", it conflicts with the auxiliary variable created for representing the log of " << getName(orig_symb_id) << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
aux_vars.emplace_back(symb_id, AuxVarType::logTransform, orig_symb_id, orig_lead_lag, 0, 0, expr_arg, "");
|
||||
|
||||
return symb_id;
|
||||
}
|
||||
|
||||
int
|
||||
SymbolTable::addDiffLagAuxiliaryVar(int index, expr_t expr_arg, int orig_symb_id, int orig_lag) noexcept(false)
|
||||
{
|
||||
|
@ -763,6 +784,19 @@ SymbolTable::markPredetermined(int symb_id) noexcept(false)
|
|||
predetermined_variables.insert(symb_id);
|
||||
}
|
||||
|
||||
void
|
||||
SymbolTable::markWithLogTransform(int symb_id) noexcept(false)
|
||||
{
|
||||
validateSymbID(symb_id);
|
||||
|
||||
if (frozen)
|
||||
throw FrozenException();
|
||||
|
||||
assert(getType(symb_id) == SymbolType::endogenous);
|
||||
|
||||
with_log_transform.insert(symb_id);
|
||||
}
|
||||
|
||||
bool
|
||||
SymbolTable::isPredetermined(int symb_id) const noexcept(false)
|
||||
{
|
||||
|
@ -992,6 +1026,7 @@ SymbolTable::writeJsonOutput(ostream &output) const
|
|||
break;
|
||||
case AuxVarType::endoLag:
|
||||
case AuxVarType::exoLag:
|
||||
case AuxVarType::logTransform:
|
||||
case AuxVarType::diffLag:
|
||||
case AuxVarType::diffLead:
|
||||
case AuxVarType::diffForward:
|
||||
|
@ -1064,3 +1099,9 @@ SymbolTable::getEquationNumberForMultiplier(int symb_id) const
|
|||
return aux_var.get_equation_number_for_multiplier();
|
||||
return -1;
|
||||
}
|
||||
|
||||
const set<int> &
|
||||
SymbolTable::getVariablesWithLogTransform() const
|
||||
{
|
||||
return with_log_transform;
|
||||
}
|
||||
|
|
|
@ -46,9 +46,7 @@ enum class AuxVarType
|
|||
for the differentiate_forward_vars option.
|
||||
N.B.: nothing to do with the diff() operator! */
|
||||
multiplier = 6, //!< Multipliers for FOC of Ramsey Problem
|
||||
|
||||
// Value 7 is unused for the time being (but could be reused)
|
||||
|
||||
logTransform = 7, //!< Log-transformation of a variable declared with “var(log)”
|
||||
diff = 8, //!< Variable for Diff operator
|
||||
diffLag = 9, //!< Variable for timing between Diff operators (lag)
|
||||
unaryOp = 10, //!< Variable for allowing the undiff operator to work when diff was taken of unary op, eg diff(log(x))
|
||||
|
@ -65,7 +63,7 @@ private:
|
|||
AuxVarType type; //!< Its type
|
||||
int orig_symb_id; /* Symbol ID of the (only) endo that appears on the RHS of
|
||||
the definition of this auxvar.
|
||||
Used by endoLag, exoLag, diffForward, diff, diffLag,
|
||||
Used by endoLag, exoLag, diffForward, logTransform, diff, diffLag,
|
||||
diffLead and unaryOp.
|
||||
For diff and unaryOp, if the argument expression is more complex
|
||||
than than a simple variable, this value is equal to -1. */
|
||||
|
@ -182,6 +180,9 @@ private:
|
|||
//! Stores the list of observed exogenous variables
|
||||
vector<int> varexobs;
|
||||
|
||||
//! Stores the endogenous variables declared with “var(log)”
|
||||
set<int> with_log_transform;
|
||||
|
||||
public:
|
||||
//! Thrown when trying to access an unknown symbol (by name)
|
||||
class UnknownSymbolNameException
|
||||
|
@ -308,6 +309,13 @@ public:
|
|||
\return the symbol ID of the new symbol
|
||||
*/
|
||||
int addMultiplierAuxiliaryVar(int index) noexcept(false);
|
||||
/* Adds an auxiliary variable associated to an endogenous declared with
|
||||
“var(log)”.
|
||||
– orig_symb_id is the symbol ID of the original variable
|
||||
– orig_lead_lag is typically 0
|
||||
– expr_arg is typically log(orig_symb_id)
|
||||
*/
|
||||
int addLogTransformAuxiliaryVar(int orig_symb_id, int orig_lead_lag, expr_t expr_arg) noexcept(false);
|
||||
//! Adds an auxiliary variable for the (time) differentiate of a forward var
|
||||
/*!
|
||||
\param[in] orig_symb_id The symb_id of the forward variable
|
||||
|
@ -409,6 +417,8 @@ public:
|
|||
void writeJsonOutput(ostream &output) const;
|
||||
//! Mark a symbol as predetermined variable
|
||||
void markPredetermined(int symb_id) noexcept(false);
|
||||
//! Mark an endogenous as having been declared with “var(log)”
|
||||
void markWithLogTransform(int symb_id) noexcept(false);
|
||||
//! Test if a given symbol is a predetermined variable
|
||||
bool isPredetermined(int symb_id) const noexcept(false);
|
||||
//! Return the number of predetermined variables
|
||||
|
@ -456,6 +466,8 @@ public:
|
|||
/* Return all the information about a given auxiliary variable. Throws
|
||||
UnknownSymbolIDException if it is not an aux var */
|
||||
const AuxVarInfo &getAuxVarInfo(int symb_id) const;
|
||||
// Returns the set of all endogenous declared with “var(log)”
|
||||
const set<int> &getVariablesWithLogTransform() const;
|
||||
};
|
||||
|
||||
inline void
|
||||
|
|
Loading…
Reference in New Issue