Fix bytecode compilation of external function nodes
parent
591b5e5f9e
commit
171cd65566
|
@ -168,11 +168,11 @@ DynamicModel::operator=(const DynamicModel &m)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DynamicModel::compileDerivative(ofstream &code_file, unsigned int &instruction_number, int eq, int symb_id, int lag, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs) const
|
DynamicModel::compileDerivative(ofstream &code_file, unsigned int &instruction_number, int eq, int symb_id, int lag, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const
|
||||||
{
|
{
|
||||||
if (auto it = derivatives[1].find({ eq, getDerivID(symbol_table.getID(SymbolType::endogenous, symb_id), lag) });
|
if (auto it = derivatives[1].find({ eq, getDerivID(symbol_table.getID(SymbolType::endogenous, symb_id), lag) });
|
||||||
it != derivatives[1].end())
|
it != derivatives[1].end())
|
||||||
it->second->compile(code_file, instruction_number, false, temporary_terms, temporary_terms_idxs, true, false);
|
it->second->compile(code_file, instruction_number, false, temporary_terms, temporary_terms_idxs, true, false, tef_terms);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FLDZ_ fldz;
|
FLDZ_ fldz;
|
||||||
|
@ -181,11 +181,11 @@ DynamicModel::compileDerivative(ofstream &code_file, unsigned int &instruction_n
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DynamicModel::compileChainRuleDerivative(ofstream &code_file, unsigned int &instruction_number, int blk, int eq, int var, int lag, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs) const
|
DynamicModel::compileChainRuleDerivative(ofstream &code_file, unsigned int &instruction_number, int blk, int eq, int var, int lag, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const
|
||||||
{
|
{
|
||||||
if (auto it = blocks_derivatives[blk].find({ eq, var, lag });
|
if (auto it = blocks_derivatives[blk].find({ eq, var, lag });
|
||||||
it != blocks_derivatives[blk].end())
|
it != blocks_derivatives[blk].end())
|
||||||
it->second->compile(code_file, instruction_number, false, temporary_terms, temporary_terms_idxs, true, false);
|
it->second->compile(code_file, instruction_number, false, temporary_terms, temporary_terms_idxs, true, false, tef_terms);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FLDZ_ fldz;
|
FLDZ_ fldz;
|
||||||
|
@ -886,9 +886,11 @@ DynamicModel::writeDynamicBytecode(const string &basename) const
|
||||||
fbeginblock.write(code_file, instruction_number);
|
fbeginblock.write(code_file, instruction_number);
|
||||||
|
|
||||||
temporary_terms_t temporary_terms_union;
|
temporary_terms_t temporary_terms_union;
|
||||||
compileTemporaryTerms(code_file, instruction_number, true, false, temporary_terms_union, temporary_terms_idxs);
|
deriv_node_temp_terms_t tef_terms;
|
||||||
|
|
||||||
compileModelEquations(code_file, instruction_number, true, false, temporary_terms_union, temporary_terms_idxs);
|
compileTemporaryTerms(code_file, instruction_number, true, false, temporary_terms_union, temporary_terms_idxs, tef_terms);
|
||||||
|
|
||||||
|
compileModelEquations(code_file, instruction_number, true, false, temporary_terms_union, temporary_terms_idxs, tef_terms);
|
||||||
|
|
||||||
FENDEQU_ fendequ;
|
FENDEQU_ fendequ;
|
||||||
fendequ.write(code_file, instruction_number);
|
fendequ.write(code_file, instruction_number);
|
||||||
|
@ -915,7 +917,7 @@ DynamicModel::writeDynamicBytecode(const string &basename) const
|
||||||
if (!my_derivatives[eq].size())
|
if (!my_derivatives[eq].size())
|
||||||
my_derivatives[eq].clear();
|
my_derivatives[eq].clear();
|
||||||
my_derivatives[eq].emplace_back(var, lag, count_u);
|
my_derivatives[eq].emplace_back(var, lag, count_u);
|
||||||
d1->compile(code_file, instruction_number, false, temporary_terms_union, temporary_terms_idxs, true, false);
|
d1->compile(code_file, instruction_number, false, temporary_terms_union, temporary_terms_idxs, true, false, tef_terms);
|
||||||
|
|
||||||
FSTPU_ fstpu(count_u);
|
FSTPU_ fstpu(count_u);
|
||||||
fstpu.write(code_file, instruction_number);
|
fstpu.write(code_file, instruction_number);
|
||||||
|
@ -977,7 +979,7 @@ DynamicModel::writeDynamicBytecode(const string &basename) const
|
||||||
prev_lag = lag;
|
prev_lag = lag;
|
||||||
count_col_endo++;
|
count_col_endo++;
|
||||||
}
|
}
|
||||||
d1->compile(code_file, instruction_number, false, temporary_terms_union, temporary_terms_idxs, true, false);
|
d1->compile(code_file, instruction_number, false, temporary_terms_union, temporary_terms_idxs, true, false, tef_terms);
|
||||||
FSTPG3_ fstpg3(eq, var, lag, count_col_endo-1);
|
FSTPG3_ fstpg3(eq, var, lag, count_col_endo-1);
|
||||||
fstpg3.write(code_file, instruction_number);
|
fstpg3.write(code_file, instruction_number);
|
||||||
}
|
}
|
||||||
|
@ -996,7 +998,7 @@ DynamicModel::writeDynamicBytecode(const string &basename) const
|
||||||
prev_lag = lag;
|
prev_lag = lag;
|
||||||
count_col_exo++;
|
count_col_exo++;
|
||||||
}
|
}
|
||||||
d1->compile(code_file, instruction_number, false, temporary_terms_union, temporary_terms_idxs, true, false);
|
d1->compile(code_file, instruction_number, false, temporary_terms_union, temporary_terms_idxs, true, false, tef_terms);
|
||||||
FSTPG3_ fstpg3(eq, var, lag, count_col_exo-1);
|
FSTPG3_ fstpg3(eq, var, lag, count_col_exo-1);
|
||||||
fstpg3.write(code_file, instruction_number);
|
fstpg3.write(code_file, instruction_number);
|
||||||
}
|
}
|
||||||
|
@ -1152,16 +1154,16 @@ DynamicModel::writeDynamicBlockBytecode(const string &basename) const
|
||||||
eq_node = getBlockEquationExpr(block, i);
|
eq_node = getBlockEquationExpr(block, i);
|
||||||
lhs = eq_node->arg1;
|
lhs = eq_node->arg1;
|
||||||
rhs = eq_node->arg2;
|
rhs = eq_node->arg2;
|
||||||
rhs->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, true, false);
|
rhs->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, true, false, tef_terms);
|
||||||
lhs->compile(code_file, instruction_number, true, temporary_terms_union, blocks_temporary_terms_idxs, true, false);
|
lhs->compile(code_file, instruction_number, true, temporary_terms_union, blocks_temporary_terms_idxs, true, false, tef_terms);
|
||||||
}
|
}
|
||||||
else if (equ_type == EquationType::evaluateRenormalized)
|
else if (equ_type == EquationType::evaluateRenormalized)
|
||||||
{
|
{
|
||||||
eq_node = getBlockEquationRenormalizedExpr(block, i);
|
eq_node = getBlockEquationRenormalizedExpr(block, i);
|
||||||
lhs = eq_node->arg1;
|
lhs = eq_node->arg1;
|
||||||
rhs = eq_node->arg2;
|
rhs = eq_node->arg2;
|
||||||
rhs->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, true, false);
|
rhs->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, true, false, tef_terms);
|
||||||
lhs->compile(code_file, instruction_number, true, temporary_terms_union, blocks_temporary_terms_idxs, true, false);
|
lhs->compile(code_file, instruction_number, true, temporary_terms_union, blocks_temporary_terms_idxs, true, false, tef_terms);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BlockSimulationType::solveBackwardComplete:
|
case BlockSimulationType::solveBackwardComplete:
|
||||||
|
@ -1182,8 +1184,8 @@ DynamicModel::writeDynamicBlockBytecode(const string &basename) const
|
||||||
eq_node = getBlockEquationExpr(block, i);
|
eq_node = getBlockEquationExpr(block, i);
|
||||||
lhs = eq_node->arg1;
|
lhs = eq_node->arg1;
|
||||||
rhs = eq_node->arg2;
|
rhs = eq_node->arg2;
|
||||||
lhs->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, true, false);
|
lhs->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, true, false, tef_terms);
|
||||||
rhs->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, true, false);
|
rhs->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, true, false, tef_terms);
|
||||||
|
|
||||||
FBINARY_ fbinary{static_cast<int>(BinaryOpcode::minus)};
|
FBINARY_ fbinary{static_cast<int>(BinaryOpcode::minus)};
|
||||||
fbinary.write(code_file, instruction_number);
|
fbinary.write(code_file, instruction_number);
|
||||||
|
@ -1221,7 +1223,7 @@ DynamicModel::writeDynamicBlockBytecode(const string &basename) const
|
||||||
FNUMEXPR_ fnumexpr(ExpressionType::FirstEndoDerivative, getBlockEquationID(block, 0), getBlockVariableID(block, 0), 0);
|
FNUMEXPR_ fnumexpr(ExpressionType::FirstEndoDerivative, getBlockEquationID(block, 0), getBlockVariableID(block, 0), 0);
|
||||||
fnumexpr.write(code_file, instruction_number);
|
fnumexpr.write(code_file, instruction_number);
|
||||||
}
|
}
|
||||||
compileDerivative(code_file, instruction_number, getBlockEquationID(block, 0), getBlockVariableID(block, 0), 0, temporary_terms_union, blocks_temporary_terms_idxs);
|
compileDerivative(code_file, instruction_number, getBlockEquationID(block, 0), getBlockVariableID(block, 0), 0, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms);
|
||||||
{
|
{
|
||||||
FSTPG_ fstpg(0);
|
FSTPG_ fstpg(0);
|
||||||
fstpg.write(code_file, instruction_number);
|
fstpg.write(code_file, instruction_number);
|
||||||
|
@ -1260,7 +1262,7 @@ DynamicModel::writeDynamicBlockBytecode(const string &basename) const
|
||||||
Uf[eqr].Ufl->lag = lag;
|
Uf[eqr].Ufl->lag = lag;
|
||||||
FNUMEXPR_ fnumexpr(ExpressionType::FirstEndoDerivative, eqr, varr, lag);
|
FNUMEXPR_ fnumexpr(ExpressionType::FirstEndoDerivative, eqr, varr, lag);
|
||||||
fnumexpr.write(code_file, instruction_number);
|
fnumexpr.write(code_file, instruction_number);
|
||||||
compileChainRuleDerivative(code_file, instruction_number, block, eq, var, lag, temporary_terms_union, blocks_temporary_terms_idxs);
|
compileChainRuleDerivative(code_file, instruction_number, block, eq, var, lag, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms);
|
||||||
FSTPU_ fstpu(count_u);
|
FSTPU_ fstpu(count_u);
|
||||||
fstpu.write(code_file, instruction_number);
|
fstpu.write(code_file, instruction_number);
|
||||||
count_u++;
|
count_u++;
|
||||||
|
@ -1337,7 +1339,7 @@ DynamicModel::writeDynamicBlockBytecode(const string &basename) const
|
||||||
int varr = getBlockVariableID(block, var);
|
int varr = getBlockVariableID(block, var);
|
||||||
FNUMEXPR_ fnumexpr(ExpressionType::FirstEndoDerivative, eqr, varr, lag);
|
FNUMEXPR_ fnumexpr(ExpressionType::FirstEndoDerivative, eqr, varr, lag);
|
||||||
fnumexpr.write(code_file, instruction_number);
|
fnumexpr.write(code_file, instruction_number);
|
||||||
compileDerivative(code_file, instruction_number, eqr, varr, lag, temporary_terms_union, blocks_temporary_terms_idxs);
|
compileDerivative(code_file, instruction_number, eqr, varr, lag, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms);
|
||||||
FSTPG3_ fstpg3(eq, var, lag, blocks_jacob_cols_endo[block].at({ var, lag }));
|
FSTPG3_ fstpg3(eq, var, lag, blocks_jacob_cols_endo[block].at({ var, lag }));
|
||||||
fstpg3.write(code_file, instruction_number);
|
fstpg3.write(code_file, instruction_number);
|
||||||
}
|
}
|
||||||
|
@ -1348,7 +1350,7 @@ DynamicModel::writeDynamicBlockBytecode(const string &basename) const
|
||||||
int varr = 0; // Dummy value, actually unused by the bytecode MEX
|
int varr = 0; // Dummy value, actually unused by the bytecode MEX
|
||||||
FNUMEXPR_ fnumexpr(ExpressionType::FirstExoDerivative, eqr, varr, lag);
|
FNUMEXPR_ fnumexpr(ExpressionType::FirstExoDerivative, eqr, varr, lag);
|
||||||
fnumexpr.write(code_file, instruction_number);
|
fnumexpr.write(code_file, instruction_number);
|
||||||
d->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, true, false);
|
d->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, true, false, tef_terms);
|
||||||
FSTPG3_ fstpg3(eq, var, lag, blocks_jacob_cols_exo[block].at({ var, lag }));
|
FSTPG3_ fstpg3(eq, var, lag, blocks_jacob_cols_exo[block].at({ var, lag }));
|
||||||
fstpg3.write(code_file, instruction_number);
|
fstpg3.write(code_file, instruction_number);
|
||||||
}
|
}
|
||||||
|
@ -1359,7 +1361,7 @@ DynamicModel::writeDynamicBlockBytecode(const string &basename) const
|
||||||
int varr = 0; // Dummy value, actually unused by the bytecode MEX
|
int varr = 0; // Dummy value, actually unused by the bytecode MEX
|
||||||
FNUMEXPR_ fnumexpr(ExpressionType::FirstExodetDerivative, eqr, varr, lag);
|
FNUMEXPR_ fnumexpr(ExpressionType::FirstExodetDerivative, eqr, varr, lag);
|
||||||
fnumexpr.write(code_file, instruction_number);
|
fnumexpr.write(code_file, instruction_number);
|
||||||
d->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, true, false);
|
d->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, true, false, tef_terms);
|
||||||
FSTPG3_ fstpg3(eq, var, lag, blocks_jacob_cols_exo_det[block].at({ var, lag }));
|
FSTPG3_ fstpg3(eq, var, lag, blocks_jacob_cols_exo_det[block].at({ var, lag }));
|
||||||
fstpg3.write(code_file, instruction_number);
|
fstpg3.write(code_file, instruction_number);
|
||||||
}
|
}
|
||||||
|
@ -1370,7 +1372,7 @@ DynamicModel::writeDynamicBlockBytecode(const string &basename) const
|
||||||
int varr = 0; // Dummy value, actually unused by the bytecode MEX
|
int varr = 0; // Dummy value, actually unused by the bytecode MEX
|
||||||
FNUMEXPR_ fnumexpr(ExpressionType::FirstOtherEndoDerivative, eqr, varr, lag);
|
FNUMEXPR_ fnumexpr(ExpressionType::FirstOtherEndoDerivative, eqr, varr, lag);
|
||||||
fnumexpr.write(code_file, instruction_number);
|
fnumexpr.write(code_file, instruction_number);
|
||||||
d->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, true, false);
|
d->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, true, false, tef_terms);
|
||||||
FSTPG3_ fstpg3(eq, var, lag, blocks_jacob_cols_other_endo[block].at({ var, lag }));
|
FSTPG3_ fstpg3(eq, var, lag, blocks_jacob_cols_other_endo[block].at({ var, lag }));
|
||||||
fstpg3.write(code_file, instruction_number);
|
fstpg3.write(code_file, instruction_number);
|
||||||
}
|
}
|
||||||
|
|
|
@ -185,9 +185,9 @@ private:
|
||||||
map<expr_t, tuple<int, int, int>> &reference_count) const override;
|
map<expr_t, tuple<int, int, int>> &reference_count) const override;
|
||||||
|
|
||||||
//! Write derivative code of an equation w.r. to a variable
|
//! Write derivative code of an equation w.r. to a variable
|
||||||
void compileDerivative(ofstream &code_file, unsigned int &instruction_number, int eq, int symb_id, int lag, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs) const;
|
void compileDerivative(ofstream &code_file, unsigned int &instruction_number, int eq, int symb_id, int lag, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const;
|
||||||
//! Write chain rule derivative code of an equation w.r. to a variable
|
//! Write chain rule derivative code of an equation w.r. to a variable
|
||||||
void compileChainRuleDerivative(ofstream &code_file, unsigned int &instruction_number, int blk, int eq, int var, int lag, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs) const;
|
void compileChainRuleDerivative(ofstream &code_file, unsigned int &instruction_number, int blk, int eq, int var, int lag, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const;
|
||||||
|
|
||||||
//! Get the type corresponding to a derivation ID
|
//! Get the type corresponding to a derivation ID
|
||||||
SymbolType getTypeByDerivID(int deriv_id) const noexcept(false) override;
|
SymbolType getTypeByDerivID(int deriv_id) const noexcept(false) override;
|
||||||
|
|
|
@ -169,14 +169,6 @@ ExprNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const tem
|
||||||
writeOutput(output, output_type, temporary_terms, temporary_terms_idxs, {});
|
writeOutput(output, output_type, temporary_terms, temporary_terms_idxs, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
ExprNode::compile(ostream &CompileCode, unsigned int &instruction_number,
|
|
||||||
bool lhs_rhs, const temporary_terms_t &temporary_terms,
|
|
||||||
const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic) const
|
|
||||||
{
|
|
||||||
compile(CompileCode, instruction_number, lhs_rhs, temporary_terms, temporary_terms_idxs, dynamic, steady_dynamic, {});
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ExprNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
|
ExprNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
|
||||||
const temporary_terms_t &temporary_terms,
|
const temporary_terms_t &temporary_terms,
|
||||||
|
|
|
@ -410,7 +410,7 @@ public:
|
||||||
|
|
||||||
virtual double eval(const eval_context_t &eval_context) const noexcept(false) = 0;
|
virtual double eval(const eval_context_t &eval_context) const noexcept(false) = 0;
|
||||||
virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, const deriv_node_temp_terms_t &tef_terms) const = 0;
|
virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, const deriv_node_temp_terms_t &tef_terms) const = 0;
|
||||||
void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic) const;
|
|
||||||
//! Creates a static version of this node
|
//! Creates a static version of this node
|
||||||
/*!
|
/*!
|
||||||
This method duplicates the current node by creating a similar node from which all leads/lags have been stripped,
|
This method duplicates the current node by creating a similar node from which all leads/lags have been stripped,
|
||||||
|
|
|
@ -1260,10 +1260,9 @@ ModelTree::testNestedParenthesis(const string &str) const
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ModelTree::compileTemporaryTerms(ostream &code_file, unsigned int &instruction_number, bool dynamic, bool steady_dynamic, temporary_terms_t &temporary_terms_union, const temporary_terms_idxs_t &temporary_terms_idxs) const
|
ModelTree::compileTemporaryTerms(ostream &code_file, unsigned int &instruction_number, bool dynamic, bool steady_dynamic, temporary_terms_t &temporary_terms_union, const temporary_terms_idxs_t &temporary_terms_idxs, deriv_node_temp_terms_t &tef_terms) const
|
||||||
{
|
{
|
||||||
// To store the functions that have already been written in the form TEF* = ext_fun();
|
// To store the functions that have already been written in the form TEF* = ext_fun();
|
||||||
deriv_node_temp_terms_t tef_terms;
|
|
||||||
for (auto [tt, idx] : temporary_terms_idxs)
|
for (auto [tt, idx] : temporary_terms_idxs)
|
||||||
{
|
{
|
||||||
if (dynamic_cast<AbstractExternalFunctionNode *>(tt))
|
if (dynamic_cast<AbstractExternalFunctionNode *>(tt))
|
||||||
|
@ -1398,7 +1397,7 @@ ModelTree::writeModelEquations(ostream &output, ExprNodeOutputType output_type,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ModelTree::compileModelEquations(ostream &code_file, unsigned int &instruction_number, bool dynamic, bool steady_dynamic, const temporary_terms_t &temporary_terms_union, const temporary_terms_idxs_t &temporary_terms_idxs) const
|
ModelTree::compileModelEquations(ostream &code_file, unsigned int &instruction_number, bool dynamic, bool steady_dynamic, const temporary_terms_t &temporary_terms_union, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const
|
||||||
{
|
{
|
||||||
for (int eq = 0; eq < static_cast<int>(equations.size()); eq++)
|
for (int eq = 0; eq < static_cast<int>(equations.size()); eq++)
|
||||||
{
|
{
|
||||||
|
@ -1419,8 +1418,8 @@ ModelTree::compileModelEquations(ostream &code_file, unsigned int &instruction_n
|
||||||
|
|
||||||
if (vrhs != 0) // The right hand side of the equation is not empty ==> residual=lhs-rhs;
|
if (vrhs != 0) // The right hand side of the equation is not empty ==> residual=lhs-rhs;
|
||||||
{
|
{
|
||||||
lhs->compile(code_file, instruction_number, false, temporary_terms_union, temporary_terms_idxs, dynamic, steady_dynamic);
|
lhs->compile(code_file, instruction_number, false, temporary_terms_union, temporary_terms_idxs, dynamic, steady_dynamic, tef_terms);
|
||||||
rhs->compile(code_file, instruction_number, false, temporary_terms_union, temporary_terms_idxs, dynamic, steady_dynamic);
|
rhs->compile(code_file, instruction_number, false, temporary_terms_union, temporary_terms_idxs, dynamic, steady_dynamic, tef_terms);
|
||||||
|
|
||||||
FBINARY_ fbinary{static_cast<int>(BinaryOpcode::minus)};
|
FBINARY_ fbinary{static_cast<int>(BinaryOpcode::minus)};
|
||||||
fbinary.write(code_file, instruction_number);
|
fbinary.write(code_file, instruction_number);
|
||||||
|
@ -1430,7 +1429,7 @@ ModelTree::compileModelEquations(ostream &code_file, unsigned int &instruction_n
|
||||||
}
|
}
|
||||||
else // The right hand side of the equation is empty ==> residual=lhs;
|
else // The right hand side of the equation is empty ==> residual=lhs;
|
||||||
{
|
{
|
||||||
lhs->compile(code_file, instruction_number, false, temporary_terms_union, temporary_terms_idxs, dynamic, steady_dynamic);
|
lhs->compile(code_file, instruction_number, false, temporary_terms_union, temporary_terms_idxs, dynamic, steady_dynamic, tef_terms);
|
||||||
FSTPR_ fstpr(eq);
|
FSTPR_ fstpr(eq);
|
||||||
fstpr.write(code_file, instruction_number);
|
fstpr.write(code_file, instruction_number);
|
||||||
}
|
}
|
||||||
|
|
|
@ -237,7 +237,7 @@ protected:
|
||||||
void writeTemporaryTerms(const temporary_terms_t &tt, temporary_terms_t &temp_term_union, const temporary_terms_idxs_t &tt_idxs, ostream &output, ExprNodeOutputType output_type, deriv_node_temp_terms_t &tef_terms) const;
|
void writeTemporaryTerms(const temporary_terms_t &tt, temporary_terms_t &temp_term_union, const temporary_terms_idxs_t &tt_idxs, ostream &output, ExprNodeOutputType output_type, deriv_node_temp_terms_t &tef_terms) const;
|
||||||
void writeJsonTemporaryTerms(const temporary_terms_t &tt, temporary_terms_t &temp_term_union, ostream &output, deriv_node_temp_terms_t &tef_terms, const string &concat) const;
|
void writeJsonTemporaryTerms(const temporary_terms_t &tt, temporary_terms_t &temp_term_union, ostream &output, deriv_node_temp_terms_t &tef_terms, const string &concat) const;
|
||||||
//! Compiles temporary terms
|
//! Compiles temporary terms
|
||||||
void compileTemporaryTerms(ostream &code_file, unsigned int &instruction_number, bool dynamic, bool steady_dynamic, temporary_terms_t &temporary_terms_union, const temporary_terms_idxs_t &temporary_terms_idxs) const;
|
void compileTemporaryTerms(ostream &code_file, unsigned int &instruction_number, bool dynamic, bool steady_dynamic, temporary_terms_t &temporary_terms_union, const temporary_terms_idxs_t &temporary_terms_idxs, deriv_node_temp_terms_t &tef_terms) const;
|
||||||
//! Adds information for (non-block) bytecode simulation in a separate .bin file
|
//! Adds information for (non-block) bytecode simulation in a separate .bin file
|
||||||
void writeBytecodeBinFile(const string &filename, int &u_count_int, bool &file_open, bool is_two_boundaries) const;
|
void writeBytecodeBinFile(const string &filename, int &u_count_int, bool &file_open, bool is_two_boundaries) const;
|
||||||
//! Fixes output when there are more than 32 nested parens, Issue #1201
|
//! Fixes output when there are more than 32 nested parens, Issue #1201
|
||||||
|
@ -260,7 +260,7 @@ protected:
|
||||||
Optionally put the external function variable calls into TEF terms */
|
Optionally put the external function variable calls into TEF terms */
|
||||||
void writeJsonModelLocalVariables(ostream &output, bool write_tef_terms, deriv_node_temp_terms_t &tef_terms) const;
|
void writeJsonModelLocalVariables(ostream &output, bool write_tef_terms, deriv_node_temp_terms_t &tef_terms) const;
|
||||||
//! Compiles model equations
|
//! Compiles model equations
|
||||||
void compileModelEquations(ostream &code_file, unsigned int &instruction_number, bool dynamic, bool steady_dynamic, const temporary_terms_t &temporary_terms_union, const temporary_terms_idxs_t &temporary_terms_idxs) const;
|
void compileModelEquations(ostream &code_file, unsigned int &instruction_number, bool dynamic, bool steady_dynamic, const temporary_terms_t &temporary_terms_union, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const;
|
||||||
|
|
||||||
//! Writes LaTeX model file
|
//! Writes LaTeX model file
|
||||||
void writeLatexModelFile(const string &mod_basename, const string &latex_basename, ExprNodeOutputType output_type, bool write_equation_tags) const;
|
void writeLatexModelFile(const string &mod_basename, const string &latex_basename, ExprNodeOutputType output_type, bool write_equation_tags) const;
|
||||||
|
|
|
@ -103,11 +103,11 @@ StaticModel::StaticModel(const DynamicModel &m) :
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
StaticModel::compileDerivative(ofstream &code_file, unsigned int &instruction_number, int eq, int symb_id, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs) const
|
StaticModel::compileDerivative(ofstream &code_file, unsigned int &instruction_number, int eq, int symb_id, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const
|
||||||
{
|
{
|
||||||
if (auto it = derivatives[1].find({ eq, getDerivID(symbol_table.getID(SymbolType::endogenous, symb_id), 0) });
|
if (auto it = derivatives[1].find({ eq, getDerivID(symbol_table.getID(SymbolType::endogenous, symb_id), 0) });
|
||||||
it != derivatives[1].end())
|
it != derivatives[1].end())
|
||||||
it->second->compile(code_file, instruction_number, false, temporary_terms, temporary_terms_idxs, false, false);
|
it->second->compile(code_file, instruction_number, false, temporary_terms, temporary_terms_idxs, false, false, tef_terms);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FLDZ_ fldz;
|
FLDZ_ fldz;
|
||||||
|
@ -116,11 +116,11 @@ StaticModel::compileDerivative(ofstream &code_file, unsigned int &instruction_nu
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
StaticModel::compileChainRuleDerivative(ofstream &code_file, unsigned int &instruction_number, int blk, int eq, int var, int lag, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs) const
|
StaticModel::compileChainRuleDerivative(ofstream &code_file, unsigned int &instruction_number, int blk, int eq, int var, int lag, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const
|
||||||
{
|
{
|
||||||
if (auto it = blocks_derivatives[blk].find({ eq, var, lag });
|
if (auto it = blocks_derivatives[blk].find({ eq, var, lag });
|
||||||
it != blocks_derivatives[blk].end())
|
it != blocks_derivatives[blk].end())
|
||||||
it->second->compile(code_file, instruction_number, false, temporary_terms, temporary_terms_idxs, false, false);
|
it->second->compile(code_file, instruction_number, false, temporary_terms, temporary_terms_idxs, false, false, tef_terms);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FLDZ_ fldz;
|
FLDZ_ fldz;
|
||||||
|
@ -420,9 +420,11 @@ StaticModel::writeStaticBytecode(const string &basename) const
|
||||||
fbeginblock.write(code_file, instruction_number);
|
fbeginblock.write(code_file, instruction_number);
|
||||||
|
|
||||||
temporary_terms_t temporary_terms_union;
|
temporary_terms_t temporary_terms_union;
|
||||||
compileTemporaryTerms(code_file, instruction_number, false, false, temporary_terms_union, temporary_terms_idxs);
|
deriv_node_temp_terms_t tef_terms;
|
||||||
|
|
||||||
compileModelEquations(code_file, instruction_number, false, false, temporary_terms_union, temporary_terms_idxs);
|
compileTemporaryTerms(code_file, instruction_number, false, false, temporary_terms_union, temporary_terms_idxs, tef_terms);
|
||||||
|
|
||||||
|
compileModelEquations(code_file, instruction_number, false, false, temporary_terms_union, temporary_terms_idxs, tef_terms);
|
||||||
|
|
||||||
FENDEQU_ fendequ;
|
FENDEQU_ fendequ;
|
||||||
fendequ.write(code_file, instruction_number);
|
fendequ.write(code_file, instruction_number);
|
||||||
|
@ -449,7 +451,7 @@ StaticModel::writeStaticBytecode(const string &basename) const
|
||||||
my_derivatives[eq].clear();
|
my_derivatives[eq].clear();
|
||||||
my_derivatives[eq].emplace_back(var, count_u);
|
my_derivatives[eq].emplace_back(var, count_u);
|
||||||
|
|
||||||
d1->compile(code_file, instruction_number, false, temporary_terms_union, temporary_terms_idxs, false, false);
|
d1->compile(code_file, instruction_number, false, temporary_terms_union, temporary_terms_idxs, false, false, tef_terms);
|
||||||
|
|
||||||
FSTPSU_ fstpsu(count_u);
|
FSTPSU_ fstpsu(count_u);
|
||||||
fstpsu.write(code_file, instruction_number);
|
fstpsu.write(code_file, instruction_number);
|
||||||
|
@ -511,7 +513,7 @@ StaticModel::writeStaticBytecode(const string &basename) const
|
||||||
my_derivatives[eq].clear();
|
my_derivatives[eq].clear();
|
||||||
my_derivatives[eq].emplace_back(var, count_u);
|
my_derivatives[eq].emplace_back(var, count_u);
|
||||||
|
|
||||||
d1->compile(code_file, instruction_number, false, temporary_terms_union, temporary_terms_idxs, false, false);
|
d1->compile(code_file, instruction_number, false, temporary_terms_union, temporary_terms_idxs, false, false, tef_terms);
|
||||||
FSTPG2_ fstpg2(eq, var);
|
FSTPG2_ fstpg2(eq, var);
|
||||||
fstpg2.write(code_file, instruction_number);
|
fstpg2.write(code_file, instruction_number);
|
||||||
}
|
}
|
||||||
|
@ -660,16 +662,16 @@ StaticModel::writeStaticBlockBytecode(const string &basename) const
|
||||||
eq_node = getBlockEquationExpr(block, i);
|
eq_node = getBlockEquationExpr(block, i);
|
||||||
lhs = eq_node->arg1;
|
lhs = eq_node->arg1;
|
||||||
rhs = eq_node->arg2;
|
rhs = eq_node->arg2;
|
||||||
rhs->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, false, false);
|
rhs->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, false, false, tef_terms);
|
||||||
lhs->compile(code_file, instruction_number, true, temporary_terms_union, blocks_temporary_terms_idxs, false, false);
|
lhs->compile(code_file, instruction_number, true, temporary_terms_union, blocks_temporary_terms_idxs, false, false, tef_terms);
|
||||||
}
|
}
|
||||||
else if (equ_type == EquationType::evaluateRenormalized)
|
else if (equ_type == EquationType::evaluateRenormalized)
|
||||||
{
|
{
|
||||||
eq_node = getBlockEquationRenormalizedExpr(block, i);
|
eq_node = getBlockEquationRenormalizedExpr(block, i);
|
||||||
lhs = eq_node->arg1;
|
lhs = eq_node->arg1;
|
||||||
rhs = eq_node->arg2;
|
rhs = eq_node->arg2;
|
||||||
rhs->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, false, false);
|
rhs->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, false, false, tef_terms);
|
||||||
lhs->compile(code_file, instruction_number, true, temporary_terms_union, blocks_temporary_terms_idxs, false, false);
|
lhs->compile(code_file, instruction_number, true, temporary_terms_union, blocks_temporary_terms_idxs, false, false, tef_terms);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BlockSimulationType::solveBackwardComplete:
|
case BlockSimulationType::solveBackwardComplete:
|
||||||
|
@ -688,8 +690,8 @@ StaticModel::writeStaticBlockBytecode(const string &basename) const
|
||||||
eq_node = getBlockEquationExpr(block, i);
|
eq_node = getBlockEquationExpr(block, i);
|
||||||
lhs = eq_node->arg1;
|
lhs = eq_node->arg1;
|
||||||
rhs = eq_node->arg2;
|
rhs = eq_node->arg2;
|
||||||
lhs->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, false, false);
|
lhs->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, false, false, tef_terms);
|
||||||
rhs->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, false, false);
|
rhs->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, false, false, tef_terms);
|
||||||
|
|
||||||
FBINARY_ fbinary{static_cast<int>(BinaryOpcode::minus)};
|
FBINARY_ fbinary{static_cast<int>(BinaryOpcode::minus)};
|
||||||
fbinary.write(code_file, instruction_number);
|
fbinary.write(code_file, instruction_number);
|
||||||
|
@ -716,7 +718,7 @@ StaticModel::writeStaticBlockBytecode(const string &basename) const
|
||||||
FNUMEXPR_ fnumexpr(ExpressionType::FirstEndoDerivative, 0, 0);
|
FNUMEXPR_ fnumexpr(ExpressionType::FirstEndoDerivative, 0, 0);
|
||||||
fnumexpr.write(code_file, instruction_number);
|
fnumexpr.write(code_file, instruction_number);
|
||||||
}
|
}
|
||||||
compileDerivative(code_file, instruction_number, getBlockEquationID(block, 0), getBlockVariableID(block, 0), temporary_terms_union, blocks_temporary_terms_idxs);
|
compileDerivative(code_file, instruction_number, getBlockEquationID(block, 0), getBlockVariableID(block, 0), temporary_terms_union, blocks_temporary_terms_idxs, tef_terms);
|
||||||
{
|
{
|
||||||
FSTPG_ fstpg(0);
|
FSTPG_ fstpg(0);
|
||||||
fstpg.write(code_file, instruction_number);
|
fstpg.write(code_file, instruction_number);
|
||||||
|
@ -748,7 +750,7 @@ StaticModel::writeStaticBlockBytecode(const string &basename) const
|
||||||
Uf[eqr].Ufl->var = varr;
|
Uf[eqr].Ufl->var = varr;
|
||||||
FNUMEXPR_ fnumexpr(ExpressionType::FirstEndoDerivative, eqr, varr);
|
FNUMEXPR_ fnumexpr(ExpressionType::FirstEndoDerivative, eqr, varr);
|
||||||
fnumexpr.write(code_file, instruction_number);
|
fnumexpr.write(code_file, instruction_number);
|
||||||
compileChainRuleDerivative(code_file, instruction_number, block, eq, var, 0, temporary_terms_union, blocks_temporary_terms_idxs);
|
compileChainRuleDerivative(code_file, instruction_number, block, eq, var, 0, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms);
|
||||||
FSTPSU_ fstpsu(count_u);
|
FSTPSU_ fstpsu(count_u);
|
||||||
fstpsu.write(code_file, instruction_number);
|
fstpsu.write(code_file, instruction_number);
|
||||||
count_u++;
|
count_u++;
|
||||||
|
@ -836,16 +838,16 @@ StaticModel::writeStaticBlockBytecode(const string &basename) const
|
||||||
eq_node = getBlockEquationExpr(block, i);
|
eq_node = getBlockEquationExpr(block, i);
|
||||||
lhs = eq_node->arg1;
|
lhs = eq_node->arg1;
|
||||||
rhs = eq_node->arg2;
|
rhs = eq_node->arg2;
|
||||||
rhs->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, false, false);
|
rhs->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, false, false, tef_terms);
|
||||||
lhs->compile(code_file, instruction_number, true, temporary_terms_union, blocks_temporary_terms_idxs, false, false);
|
lhs->compile(code_file, instruction_number, true, temporary_terms_union, blocks_temporary_terms_idxs, false, false, tef_terms);
|
||||||
}
|
}
|
||||||
else if (equ_type == EquationType::evaluateRenormalized)
|
else if (equ_type == EquationType::evaluateRenormalized)
|
||||||
{
|
{
|
||||||
eq_node = getBlockEquationRenormalizedExpr(block, i);
|
eq_node = getBlockEquationRenormalizedExpr(block, i);
|
||||||
lhs = eq_node->arg1;
|
lhs = eq_node->arg1;
|
||||||
rhs = eq_node->arg2;
|
rhs = eq_node->arg2;
|
||||||
rhs->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, false, false);
|
rhs->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, false, false, tef_terms);
|
||||||
lhs->compile(code_file, instruction_number, true, temporary_terms_union, blocks_temporary_terms_idxs, false, false);
|
lhs->compile(code_file, instruction_number, true, temporary_terms_union, blocks_temporary_terms_idxs, false, false, tef_terms);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BlockSimulationType::solveBackwardComplete:
|
case BlockSimulationType::solveBackwardComplete:
|
||||||
|
@ -864,8 +866,8 @@ StaticModel::writeStaticBlockBytecode(const string &basename) const
|
||||||
eq_node = getBlockEquationExpr(block, i);
|
eq_node = getBlockEquationExpr(block, i);
|
||||||
lhs = eq_node->arg1;
|
lhs = eq_node->arg1;
|
||||||
rhs = eq_node->arg2;
|
rhs = eq_node->arg2;
|
||||||
lhs->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, false, false);
|
lhs->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, false, false, tef_terms);
|
||||||
rhs->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, false, false);
|
rhs->compile(code_file, instruction_number, false, temporary_terms_union, blocks_temporary_terms_idxs, false, false, tef_terms);
|
||||||
|
|
||||||
FBINARY_ fbinary{static_cast<int>(BinaryOpcode::minus)};
|
FBINARY_ fbinary{static_cast<int>(BinaryOpcode::minus)};
|
||||||
fbinary.write(code_file, instruction_number);
|
fbinary.write(code_file, instruction_number);
|
||||||
|
@ -890,7 +892,7 @@ StaticModel::writeStaticBlockBytecode(const string &basename) const
|
||||||
FNUMEXPR_ fnumexpr(ExpressionType::FirstEndoDerivative, 0, 0);
|
FNUMEXPR_ fnumexpr(ExpressionType::FirstEndoDerivative, 0, 0);
|
||||||
fnumexpr.write(code_file, instruction_number);
|
fnumexpr.write(code_file, instruction_number);
|
||||||
}
|
}
|
||||||
compileDerivative(code_file, instruction_number, getBlockEquationID(block, 0), getBlockVariableID(block, 0), temporary_terms_union, blocks_temporary_terms_idxs);
|
compileDerivative(code_file, instruction_number, getBlockEquationID(block, 0), getBlockVariableID(block, 0), temporary_terms_union, blocks_temporary_terms_idxs, tef_terms);
|
||||||
{
|
{
|
||||||
FSTPG2_ fstpg2(0, 0);
|
FSTPG2_ fstpg2(0, 0);
|
||||||
fstpg2.write(code_file, instruction_number);
|
fstpg2.write(code_file, instruction_number);
|
||||||
|
@ -909,7 +911,7 @@ StaticModel::writeStaticBlockBytecode(const string &basename) const
|
||||||
FNUMEXPR_ fnumexpr(ExpressionType::FirstEndoDerivative, eqr, varr, 0);
|
FNUMEXPR_ fnumexpr(ExpressionType::FirstEndoDerivative, eqr, varr, 0);
|
||||||
fnumexpr.write(code_file, instruction_number);
|
fnumexpr.write(code_file, instruction_number);
|
||||||
|
|
||||||
compileChainRuleDerivative(code_file, instruction_number, block, eq, var, 0, temporary_terms_union, blocks_temporary_terms_idxs);
|
compileChainRuleDerivative(code_file, instruction_number, block, eq, var, 0, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms);
|
||||||
|
|
||||||
FSTPG2_ fstpg2(eq, var);
|
FSTPG2_ fstpg2(eq, var);
|
||||||
fstpg2.write(code_file, instruction_number);
|
fstpg2.write(code_file, instruction_number);
|
||||||
|
|
|
@ -78,9 +78,9 @@ private:
|
||||||
void evaluateJacobian(const eval_context_t &eval_context, jacob_map_t *j_m, bool dynamic);
|
void evaluateJacobian(const eval_context_t &eval_context, jacob_map_t *j_m, bool dynamic);
|
||||||
|
|
||||||
//! Write derivative code of an equation w.r. to a variable
|
//! Write derivative code of an equation w.r. to a variable
|
||||||
void compileDerivative(ofstream &code_file, unsigned int &instruction_number, int eq, int symb_id, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs) const;
|
void compileDerivative(ofstream &code_file, unsigned int &instruction_number, int eq, int symb_id, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const;
|
||||||
//! Write chain rule derivative code of an equation w.r. to a variable
|
//! Write chain rule derivative code of an equation w.r. to a variable
|
||||||
void compileChainRuleDerivative(ofstream &code_file, unsigned int &instruction_number, int blk, int eq, int var, int lag, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs) const;
|
void compileChainRuleDerivative(ofstream &code_file, unsigned int &instruction_number, int blk, int eq, int var, int lag, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const;
|
||||||
|
|
||||||
//! Get the type corresponding to a derivation ID
|
//! Get the type corresponding to a derivation ID
|
||||||
SymbolType getTypeByDerivID(int deriv_id) const noexcept(false) override;
|
SymbolType getTypeByDerivID(int deriv_id) const noexcept(false) override;
|
||||||
|
|
Loading…
Reference in New Issue