From b4c3d004ad6c8c19aa56a477677d1c6c89f8f23e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org> Date: Thu, 13 Mar 2014 11:22:00 +0100 Subject: [PATCH] Introduce a new abstract class for external function nodes. This fixes the following bugs: - 1st and 2nd ext fcn deriv nodes were incorrectly added to DataTree::external_function_node_map, because of the chaining of constructors. - the following methods of FirstDerivExternalFunctionNode were not overloaded: toStatic(), buildSimilarExternalFunctionNode() - the following methods of SecondDerivExternalFunctionNode were not overloaded: toStatic(), buildSimilarExternalFunctionNode(), compile(), compileExternalFunctionOutput() --- preprocessor/DataTree.hh | 1 + preprocessor/DynamicModel.cc | 4 +- preprocessor/ExprNode.cc | 154 ++++++++++++++++++++++++----------- preprocessor/ExprNode.hh | 76 +++++++++++++---- preprocessor/ModelTree.cc | 4 +- preprocessor/StaticModel.cc | 8 +- 6 files changed, 175 insertions(+), 72 deletions(-) diff --git a/preprocessor/DataTree.hh b/preprocessor/DataTree.hh index 859556c5c4..19712e9bfd 100644 --- a/preprocessor/DataTree.hh +++ b/preprocessor/DataTree.hh @@ -44,6 +44,7 @@ class DataTree friend class UnaryOpNode; friend class BinaryOpNode; friend class TrinaryOpNode; + friend class AbstractExternalFunctionNode; friend class ExternalFunctionNode; friend class FirstDerivExternalFunctionNode; friend class SecondDerivExternalFunctionNode; diff --git a/preprocessor/DynamicModel.cc b/preprocessor/DynamicModel.cc index 1a5de8b9b0..bd2adaede7 100644 --- a/preprocessor/DynamicModel.cc +++ b/preprocessor/DynamicModel.cc @@ -460,7 +460,7 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const for (temporary_terms_t::const_iterator it = v_temporary_terms[block][i].begin(); it != v_temporary_terms[block][i].end(); it++) { - if (dynamic_cast<ExternalFunctionNode *>(*it) != NULL) + if (dynamic_cast<AbstractExternalFunctionNode *>(*it) != NULL) (*it)->writeExternalFunctionOutput(output, local_output_type, tt2, tef_terms); output << " " << sps; @@ -1181,7 +1181,7 @@ DynamicModel::writeModelEquationsCode_Block(string &file_name, const string &bin for (temporary_terms_t::const_iterator it = v_temporary_terms[block][i].begin(); it != v_temporary_terms[block][i].end(); it++) { - if (dynamic_cast<ExternalFunctionNode *>(*it) != NULL) + if (dynamic_cast<AbstractExternalFunctionNode *>(*it) != NULL) (*it)->compileExternalFunctionOutput(code_file, instruction_number, false, tt2, map_idx, true, false, tef_terms); FNUMEXPR_ fnumexpr(TemporaryTerm, (int) (map_idx.find((*it)->idx)->second)); diff --git a/preprocessor/ExprNode.cc b/preprocessor/ExprNode.cc index d6df84960d..f435107a3e 100644 --- a/preprocessor/ExprNode.cc +++ b/preprocessor/ExprNode.cc @@ -4274,19 +4274,26 @@ TrinaryOpNode::isInStaticForm() const return arg1->isInStaticForm() && arg2->isInStaticForm() && arg3->isInStaticForm(); } -ExternalFunctionNode::ExternalFunctionNode(DataTree &datatree_arg, - int symb_id_arg, - const vector<expr_t> &arguments_arg) : +AbstractExternalFunctionNode::AbstractExternalFunctionNode(DataTree &datatree_arg, + int symb_id_arg, + const vector<expr_t> &arguments_arg) : ExprNode(datatree_arg), symb_id(symb_id_arg), arguments(arguments_arg) +{ +} + +ExternalFunctionNode::ExternalFunctionNode(DataTree &datatree_arg, + int symb_id_arg, + const vector<expr_t> &arguments_arg) : + AbstractExternalFunctionNode(datatree_arg, symb_id_arg, arguments_arg) { // Add myself to the external function map datatree.external_function_node_map[make_pair(arguments, symb_id)] = this; } void -ExternalFunctionNode::prepareForDerivation() +AbstractExternalFunctionNode::prepareForDerivation() { if (preparedForDerivation) return; @@ -4306,7 +4313,7 @@ ExternalFunctionNode::prepareForDerivation() } expr_t -ExternalFunctionNode::computeDerivative(int deriv_id) +AbstractExternalFunctionNode::computeDerivative(int deriv_id) { assert(datatree.external_functions_table.getNargs(symb_id) > 0); vector<expr_t> dargs; @@ -4330,7 +4337,7 @@ ExternalFunctionNode::composeDerivatives(const vector<expr_t> &dargs) } expr_t -ExternalFunctionNode::getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recursive_variables) +AbstractExternalFunctionNode::getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recursive_variables) { assert(datatree.external_functions_table.getNargs(symb_id) > 0); vector<expr_t> dargs; @@ -4349,9 +4356,9 @@ ExternalFunctionNode::computeTemporaryTerms(map<expr_t, int> &reference_count, } void -ExternalFunctionNode::writeExternalFunctionArguments(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const +AbstractExternalFunctionNode::writeExternalFunctionArguments(ostream &output, ExprNodeOutputType output_type, + const temporary_terms_t &temporary_terms, + deriv_node_temp_terms_t &tef_terms) const { for (vector<expr_t>::const_iterator it = arguments.begin(); it != arguments.end(); it++) @@ -4364,9 +4371,9 @@ ExternalFunctionNode::writeExternalFunctionArguments(ostream &output, ExprNodeOu } void -ExternalFunctionNode::writePrhs(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, const string &ending) const +AbstractExternalFunctionNode::writePrhs(ostream &output, ExprNodeOutputType output_type, + const temporary_terms_t &temporary_terms, + deriv_node_temp_terms_t &tef_terms, const string &ending) const { output << "mxArray *prhs"<< ending << "[nrhs"<< ending << "];" << endl; int i = 0; @@ -4411,10 +4418,10 @@ ExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType output_typ } unsigned int -ExternalFunctionNode::compileExternalFunctionArguments(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const +AbstractExternalFunctionNode::compileExternalFunctionArguments(ostream &CompileCode, unsigned int &instruction_number, + bool lhs_rhs, const temporary_terms_t &temporary_terms, + const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, + deriv_node_temp_terms_t &tef_terms) const { for (vector<expr_t>::const_iterator it = arguments.begin(); it != arguments.end(); it++) @@ -4602,7 +4609,7 @@ ExternalFunctionNode::computeTemporaryTerms(map<expr_t, int> &reference_count, } void -ExternalFunctionNode::collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const +AbstractExternalFunctionNode::collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const { for (vector<expr_t>::const_iterator it = arguments.begin(); it != arguments.end(); it++) @@ -4610,9 +4617,9 @@ ExternalFunctionNode::collectDynamicVariables(SymbolType type_arg, set<pair<int, } void -ExternalFunctionNode::collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const +AbstractExternalFunctionNode::collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const { - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast<ExternalFunctionNode *>(this)); + temporary_terms_t::const_iterator it = temporary_terms.find(const_cast<AbstractExternalFunctionNode *>(this)); if (it != temporary_terms.end()) temporary_terms_inuse.insert(idx); else @@ -4624,13 +4631,13 @@ ExternalFunctionNode::collectTemporary_terms(const temporary_terms_t &temporary_ } double -ExternalFunctionNode::eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException) +AbstractExternalFunctionNode::eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException) { throw EvalExternalFunctionException(); } pair<int, expr_t> -ExternalFunctionNode::normalizeEquation(int var_endo, vector<pair<int, pair<expr_t, expr_t> > > &List_of_Op_RHS) const +AbstractExternalFunctionNode::normalizeEquation(int var_endo, vector<pair<int, pair<expr_t, expr_t> > > &List_of_Op_RHS) const { vector<pair<bool, expr_t> > V_arguments; vector<expr_t> V_expr_t; @@ -4669,7 +4676,7 @@ ExternalFunctionNode::cloneDynamic(DataTree &dynamic_datatree) const } int -ExternalFunctionNode::maxEndoLead() const +AbstractExternalFunctionNode::maxEndoLead() const { int val = 0; for (vector<expr_t>::const_iterator it = arguments.begin(); @@ -4679,7 +4686,7 @@ ExternalFunctionNode::maxEndoLead() const } int -ExternalFunctionNode::maxExoLead() const +AbstractExternalFunctionNode::maxExoLead() const { int val = 0; for (vector<expr_t>::const_iterator it = arguments.begin(); @@ -4689,7 +4696,7 @@ ExternalFunctionNode::maxExoLead() const } int -ExternalFunctionNode::maxEndoLag() const +AbstractExternalFunctionNode::maxEndoLag() const { int val = 0; for (vector<expr_t>::const_iterator it = arguments.begin(); @@ -4699,7 +4706,7 @@ ExternalFunctionNode::maxEndoLag() const } int -ExternalFunctionNode::maxExoLag() const +AbstractExternalFunctionNode::maxExoLag() const { int val = 0; for (vector<expr_t>::const_iterator it = arguments.begin(); @@ -4709,7 +4716,7 @@ ExternalFunctionNode::maxExoLag() const } int -ExternalFunctionNode::maxLead() const +AbstractExternalFunctionNode::maxLead() const { int val = 0; for (vector<expr_t>::const_iterator it = arguments.begin(); @@ -4719,7 +4726,7 @@ ExternalFunctionNode::maxLead() const } expr_t -ExternalFunctionNode::decreaseLeadsLags(int n) const +AbstractExternalFunctionNode::decreaseLeadsLags(int n) const { vector<expr_t> arguments_subst; for (vector<expr_t>::const_iterator it = arguments.begin(); it != arguments.end(); it++) @@ -4728,7 +4735,7 @@ ExternalFunctionNode::decreaseLeadsLags(int n) const } expr_t -ExternalFunctionNode::decreaseLeadsLagsPredeterminedVariables() const +AbstractExternalFunctionNode::decreaseLeadsLagsPredeterminedVariables() const { vector<expr_t> arguments_subst; for (vector<expr_t>::const_iterator it = arguments.begin(); it != arguments.end(); it++) @@ -4737,7 +4744,7 @@ ExternalFunctionNode::decreaseLeadsLagsPredeterminedVariables() const } expr_t -ExternalFunctionNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const +AbstractExternalFunctionNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const { vector<expr_t> arguments_subst; for (vector<expr_t>::const_iterator it = arguments.begin(); it != arguments.end(); it++) @@ -4746,7 +4753,7 @@ ExternalFunctionNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_tabl } expr_t -ExternalFunctionNode::substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const +AbstractExternalFunctionNode::substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const { vector<expr_t> arguments_subst; for (vector<expr_t>::const_iterator it = arguments.begin(); it != arguments.end(); it++) @@ -4755,7 +4762,7 @@ ExternalFunctionNode::substituteEndoLagGreaterThanTwo(subst_table_t &subst_table } expr_t -ExternalFunctionNode::substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const +AbstractExternalFunctionNode::substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const { vector<expr_t> arguments_subst; for (vector<expr_t>::const_iterator it = arguments.begin(); it != arguments.end(); it++) @@ -4764,7 +4771,7 @@ ExternalFunctionNode::substituteExoLead(subst_table_t &subst_table, vector<Binar } expr_t -ExternalFunctionNode::substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const +AbstractExternalFunctionNode::substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const { vector<expr_t> arguments_subst; for (vector<expr_t>::const_iterator it = arguments.begin(); it != arguments.end(); it++) @@ -4773,7 +4780,7 @@ ExternalFunctionNode::substituteExoLag(subst_table_t &subst_table, vector<Binary } expr_t -ExternalFunctionNode::substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const +AbstractExternalFunctionNode::substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const { vector<expr_t> arguments_subst; for (vector<expr_t>::const_iterator it = arguments.begin(); it != arguments.end(); it++) @@ -4782,7 +4789,7 @@ ExternalFunctionNode::substituteExpectation(subst_table_t &subst_table, vector<B } expr_t -ExternalFunctionNode::differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const +AbstractExternalFunctionNode::differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const { vector<expr_t> arguments_subst; for (vector<expr_t>::const_iterator it = arguments.begin(); it != arguments.end(); it++) @@ -4797,7 +4804,7 @@ ExternalFunctionNode::buildSimilarExternalFunctionNode(vector<expr_t> &alt_args, } bool -ExternalFunctionNode::alreadyWrittenAsTefTerm(int the_symb_id, deriv_node_temp_terms_t &tef_terms) const +AbstractExternalFunctionNode::alreadyWrittenAsTefTerm(int the_symb_id, deriv_node_temp_terms_t &tef_terms) const { deriv_node_temp_terms_t::const_iterator it = tef_terms.find(make_pair(the_symb_id, arguments)); if (it != tef_terms.end()) @@ -4806,7 +4813,7 @@ ExternalFunctionNode::alreadyWrittenAsTefTerm(int the_symb_id, deriv_node_temp_t } int -ExternalFunctionNode::getIndxInTefTerms(int the_symb_id, deriv_node_temp_terms_t &tef_terms) const throw (UnknownFunctionNameAndArgs) +AbstractExternalFunctionNode::getIndxInTefTerms(int the_symb_id, deriv_node_temp_terms_t &tef_terms) const throw (UnknownFunctionNameAndArgs) { deriv_node_temp_terms_t::const_iterator it = tef_terms.find(make_pair(the_symb_id, arguments)); if (it != tef_terms.end()) @@ -4815,19 +4822,19 @@ ExternalFunctionNode::getIndxInTefTerms(int the_symb_id, deriv_node_temp_terms_t } bool -ExternalFunctionNode::isNumConstNodeEqualTo(double value) const +AbstractExternalFunctionNode::isNumConstNodeEqualTo(double value) const { return false; } bool -ExternalFunctionNode::isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const +AbstractExternalFunctionNode::isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const { return false; } bool -ExternalFunctionNode::containsEndogenous(void) const +AbstractExternalFunctionNode::containsEndogenous(void) const { bool result = false; for (vector<expr_t>::const_iterator it = arguments.begin(); it != arguments.end(); it++) @@ -4836,7 +4843,7 @@ ExternalFunctionNode::containsEndogenous(void) const } expr_t -ExternalFunctionNode::replaceTrendVar() const +AbstractExternalFunctionNode::replaceTrendVar() const { vector<expr_t> arguments_subst; for (vector<expr_t>::const_iterator it = arguments.begin(); it != arguments.end(); it++) @@ -4845,7 +4852,7 @@ ExternalFunctionNode::replaceTrendVar() const } expr_t -ExternalFunctionNode::detrend(int symb_id, bool log_trend, expr_t trend) const +AbstractExternalFunctionNode::detrend(int symb_id, bool log_trend, expr_t trend) const { vector<expr_t> arguments_subst; for (vector<expr_t>::const_iterator it = arguments.begin(); it != arguments.end(); it++) @@ -4854,7 +4861,7 @@ ExternalFunctionNode::detrend(int symb_id, bool log_trend, expr_t trend) const } expr_t -ExternalFunctionNode::removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const +AbstractExternalFunctionNode::removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const { vector<expr_t> arguments_subst; for (vector<expr_t>::const_iterator it = arguments.begin(); it != arguments.end(); it++) @@ -4863,7 +4870,7 @@ ExternalFunctionNode::removeTrendLeadLag(map<int, expr_t> trend_symbols_map) con } bool -ExternalFunctionNode::isInStaticForm() const +AbstractExternalFunctionNode::isInStaticForm() const { for (vector<expr_t>::const_iterator it = arguments.begin(); it != arguments.end(); ++it) if (!(*it)->isInStaticForm()) @@ -4876,7 +4883,7 @@ FirstDerivExternalFunctionNode::FirstDerivExternalFunctionNode(DataTree &datatre int top_level_symb_id_arg, const vector<expr_t> &arguments_arg, int inputIndex_arg) : - ExternalFunctionNode(datatree_arg, top_level_symb_id_arg, arguments_arg), + AbstractExternalFunctionNode(datatree_arg, top_level_symb_id_arg, arguments_arg), inputIndex(inputIndex_arg) { // Add myself to the first derivative external function map @@ -5151,12 +5158,29 @@ FirstDerivExternalFunctionNode::cloneDynamic(DataTree &dynamic_datatree) const inputIndex); } +expr_t +FirstDerivExternalFunctionNode::buildSimilarExternalFunctionNode(vector<expr_t> &alt_args, DataTree &alt_datatree) const +{ + return alt_datatree.AddFirstDerivExternalFunction(symb_id, alt_args, inputIndex); +} + +expr_t +FirstDerivExternalFunctionNode::toStatic(DataTree &static_datatree) const +{ + vector<expr_t> static_arguments; + for (vector<expr_t>::const_iterator it = arguments.begin(); + it != arguments.end(); it++) + static_arguments.push_back((*it)->toStatic(static_datatree)); + return static_datatree.AddFirstDerivExternalFunction(symb_id, static_arguments, + inputIndex); +} + SecondDerivExternalFunctionNode::SecondDerivExternalFunctionNode(DataTree &datatree_arg, int top_level_symb_id_arg, const vector<expr_t> &arguments_arg, int inputIndex1_arg, int inputIndex2_arg) : - ExternalFunctionNode(datatree_arg, top_level_symb_id_arg, arguments_arg), + AbstractExternalFunctionNode(datatree_arg, top_level_symb_id_arg, arguments_arg), inputIndex1(inputIndex1_arg), inputIndex2(inputIndex2_arg) { @@ -5187,7 +5211,8 @@ SecondDerivExternalFunctionNode::computeTemporaryTerms(map<expr_t, int> &referen } expr_t -SecondDerivExternalFunctionNode::computeDerivative(int deriv_id) +SecondDerivExternalFunctionNode::composeDerivatives(const vector<expr_t> &dargs) + { cerr << "ERROR: third order derivatives of external functions are not implemented" << endl; exit(EXIT_FAILURE); @@ -5358,3 +5383,40 @@ SecondDerivExternalFunctionNode::cloneDynamic(DataTree &dynamic_datatree) const return dynamic_datatree.AddSecondDerivExternalFunction(symb_id, dynamic_arguments, inputIndex1, inputIndex2); } + +expr_t +SecondDerivExternalFunctionNode::buildSimilarExternalFunctionNode(vector<expr_t> &alt_args, DataTree &alt_datatree) const +{ + return alt_datatree.AddSecondDerivExternalFunction(symb_id, alt_args, inputIndex1, inputIndex2); +} + +expr_t +SecondDerivExternalFunctionNode::toStatic(DataTree &static_datatree) const +{ + vector<expr_t> static_arguments; + for (vector<expr_t>::const_iterator it = arguments.begin(); + it != arguments.end(); it++) + static_arguments.push_back((*it)->toStatic(static_datatree)); + return static_datatree.AddSecondDerivExternalFunction(symb_id, static_arguments, + inputIndex1, inputIndex2); +} + +void +SecondDerivExternalFunctionNode::compile(ostream &CompileCode, unsigned int &instruction_number, + bool lhs_rhs, const temporary_terms_t &temporary_terms, + const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, + deriv_node_temp_terms_t &tef_terms) const +{ + cerr << "SecondDerivExternalFunctionNode::compile: not implemented." << endl; + exit(EXIT_FAILURE); +} + +void +SecondDerivExternalFunctionNode::compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number, + bool lhs_rhs, const temporary_terms_t &temporary_terms, + const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, + deriv_node_temp_terms_t &tef_terms) const +{ + cerr << "SecondDerivExternalFunctionNode::compileExternalFunctionOutput: not implemented." << endl; + exit(EXIT_FAILURE); +} diff --git a/preprocessor/ExprNode.hh b/preprocessor/ExprNode.hh index c0de01b82e..b008333cdf 100644 --- a/preprocessor/ExprNode.hh +++ b/preprocessor/ExprNode.hh @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2013 Dynare Team + * Copyright (C) 2007-2014 Dynare Team * * This file is part of Dynare. * @@ -125,7 +125,7 @@ class ExprNode friend class UnaryOpNode; friend class BinaryOpNode; friend class TrinaryOpNode; - friend class ExternalFunctionNode; + friend class AbstractExternalFunctionNode; private: //! Computes derivative w.r. to a derivation ID (but doesn't store it in derivatives map) /*! You shoud use getDerivative() to get the benefit of symbolic a priori and of caching */ @@ -771,11 +771,11 @@ public: }; //! External function node -class ExternalFunctionNode : public ExprNode +class AbstractExternalFunctionNode : public ExprNode { private: virtual expr_t computeDerivative(int deriv_id); - virtual expr_t composeDerivatives(const vector<expr_t> &dargs); + virtual expr_t composeDerivatives(const vector<expr_t> &dargs) = 0; protected: //! Thrown when trying to access an unknown entry in external_function_node_map class UnknownFunctionNameAndArgs @@ -790,24 +790,24 @@ protected: //! Helper function to write output arguments of any given external function void writeExternalFunctionArguments(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; public: - ExternalFunctionNode(DataTree &datatree_arg, int symb_id_arg, - const vector<expr_t> &arguments_arg); + AbstractExternalFunctionNode(DataTree &datatree_arg, int symb_id_arg, + const vector<expr_t> &arguments_arg); virtual void prepareForDerivation(); - virtual void computeTemporaryTerms(map<expr_t, int> &reference_count, temporary_terms_t &temporary_terms, bool is_matlab) const; - virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; + virtual void computeTemporaryTerms(map<expr_t, int> &reference_count, temporary_terms_t &temporary_terms, bool is_matlab) const = 0; + virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const = 0; virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const; + deriv_node_temp_terms_t &tef_terms) const = 0; virtual void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const; + deriv_node_temp_terms_t &tef_terms) const = 0; virtual void computeTemporaryTerms(map<expr_t, int> &reference_count, temporary_terms_t &temporary_terms, map<expr_t, pair<int, int> > &first_occurence, int Curr_block, vector< vector<temporary_terms_t> > &v_temporary_terms, - int equation) const; + int equation) const = 0; virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const; virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const; virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException); @@ -816,8 +816,8 @@ public: const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const; - virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const; - virtual expr_t toStatic(DataTree &static_datatree) const; + virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const = 0; + virtual expr_t toStatic(DataTree &static_datatree) const = 0; virtual pair<int, expr_t> normalizeEquation(int symb_id_endo, vector<pair<int, pair<expr_t, expr_t> > > &List_of_Op_RHS) const; virtual expr_t getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recursive_variables); virtual int maxEndoLead() const; @@ -831,7 +831,7 @@ public: virtual expr_t substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const; virtual expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const; virtual expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const; - virtual expr_t buildSimilarExternalFunctionNode(vector<expr_t> &alt_args, DataTree &alt_datatree) const; + virtual expr_t buildSimilarExternalFunctionNode(vector<expr_t> &alt_args, DataTree &alt_datatree) const = 0; virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; @@ -840,12 +840,40 @@ public: virtual void writePrhs(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms, const string &ending) const; virtual expr_t replaceTrendVar() const; virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const; - virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const; + virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const = 0; virtual expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const; virtual bool isInStaticForm() const; }; -class FirstDerivExternalFunctionNode : public ExternalFunctionNode +class ExternalFunctionNode : public AbstractExternalFunctionNode +{ +private: + virtual expr_t composeDerivatives(const vector<expr_t> &dargs); +public: + ExternalFunctionNode(DataTree &datatree_arg, int symb_id_arg, + const vector<expr_t> &arguments_arg); + virtual void computeTemporaryTerms(map<expr_t, int> &reference_count, temporary_terms_t &temporary_terms, bool is_matlab) const; + virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; + virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, + const temporary_terms_t &temporary_terms, + deriv_node_temp_terms_t &tef_terms) const; + virtual void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number, + bool lhs_rhs, const temporary_terms_t &temporary_terms, + const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, + deriv_node_temp_terms_t &tef_terms) const; + virtual void computeTemporaryTerms(map<expr_t, int> &reference_count, + temporary_terms_t &temporary_terms, + map<expr_t, pair<int, int> > &first_occurence, + int Curr_block, + vector< vector<temporary_terms_t> > &v_temporary_terms, + int equation) const; + virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const; + virtual expr_t toStatic(DataTree &static_datatree) const; + virtual expr_t buildSimilarExternalFunctionNode(vector<expr_t> &alt_args, DataTree &alt_datatree) const; + virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const; +}; + +class FirstDerivExternalFunctionNode : public AbstractExternalFunctionNode { private: const int inputIndex; @@ -874,15 +902,17 @@ public: bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const; + virtual expr_t toStatic(DataTree &static_datatree) const; + virtual expr_t buildSimilarExternalFunctionNode(vector<expr_t> &alt_args, DataTree &alt_datatree) const; virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const; }; -class SecondDerivExternalFunctionNode : public ExternalFunctionNode +class SecondDerivExternalFunctionNode : public AbstractExternalFunctionNode { private: const int inputIndex1; const int inputIndex2; - virtual expr_t computeDerivative(int deriv_id); + virtual expr_t composeDerivatives(const vector<expr_t> &dargs); public: SecondDerivExternalFunctionNode(DataTree &datatree_arg, int top_level_symb_id_arg, @@ -897,9 +927,19 @@ public: vector< vector<temporary_terms_t> > &v_temporary_terms, int equation) const; virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; + virtual void compile(ostream &CompileCode, unsigned int &instruction_number, + bool lhs_rhs, const temporary_terms_t &temporary_terms, + const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, + deriv_node_temp_terms_t &tef_terms) const; virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; + virtual void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number, + bool lhs_rhs, const temporary_terms_t &temporary_terms, + const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, + deriv_node_temp_terms_t &tef_terms) const; + virtual expr_t toStatic(DataTree &static_datatree) const; + virtual expr_t buildSimilarExternalFunctionNode(vector<expr_t> &alt_args, DataTree &alt_datatree) const; virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const; }; diff --git a/preprocessor/ModelTree.cc b/preprocessor/ModelTree.cc index 5daf09df08..a83ea06f90 100644 --- a/preprocessor/ModelTree.cc +++ b/preprocessor/ModelTree.cc @@ -1113,7 +1113,7 @@ ModelTree::writeTemporaryTerms(const temporary_terms_t &tt, ostream &output, for (temporary_terms_t::const_iterator it = tt.begin(); it != tt.end(); it++) { - if (dynamic_cast<ExternalFunctionNode *>(*it) != NULL) + if (dynamic_cast<AbstractExternalFunctionNode *>(*it) != NULL) (*it)->writeExternalFunctionOutput(output, output_type, tt2, tef_terms); if (IS_C(output_type)) @@ -1144,7 +1144,7 @@ ModelTree::compileTemporaryTerms(ostream &code_file, unsigned int &instruction_n for (temporary_terms_t::const_iterator it = tt.begin(); it != tt.end(); it++) { - if (dynamic_cast<ExternalFunctionNode *>(*it) != NULL) + if (dynamic_cast<AbstractExternalFunctionNode *>(*it) != NULL) { (*it)->compileExternalFunctionOutput(code_file, instruction_number, false, tt2, map_idx, dynamic, steady_dynamic, tef_terms); } diff --git a/preprocessor/StaticModel.cc b/preprocessor/StaticModel.cc index d82efaeda7..ab11ca9aae 100644 --- a/preprocessor/StaticModel.cc +++ b/preprocessor/StaticModel.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2012 Dynare Team + * Copyright (C) 2003-2014 Dynare Team * * This file is part of Dynare. * @@ -286,7 +286,7 @@ StaticModel::writeModelEquationsOrdered_M(const string &static_basename) const for (temporary_terms_t::const_iterator it = v_temporary_terms[block][i].begin(); it != v_temporary_terms[block][i].end(); it++) { - if (dynamic_cast<ExternalFunctionNode *>(*it) != NULL) + if (dynamic_cast<AbstractExternalFunctionNode *>(*it) != NULL) (*it)->writeExternalFunctionOutput(output, local_output_type, tt2, tef_terms); output << " " << sps; @@ -658,7 +658,7 @@ StaticModel::writeModelEquationsCode_Block(const string file_name, const string for (temporary_terms_t::const_iterator it = v_temporary_terms[block][i].begin(); it != v_temporary_terms[block][i].end(); it++) { - if (dynamic_cast<ExternalFunctionNode *>(*it) != NULL) + if (dynamic_cast<AbstractExternalFunctionNode *>(*it) != NULL) (*it)->compileExternalFunctionOutput(code_file, instruction_number, false, tt2, map_idx, false, false, tef_terms); FNUMEXPR_ fnumexpr(TemporaryTerm, (int) (map_idx.find((*it)->idx)->second)); @@ -851,7 +851,7 @@ StaticModel::writeModelEquationsCode_Block(const string file_name, const string for (temporary_terms_t::const_iterator it = v_temporary_terms_local[block][i].begin(); it != v_temporary_terms_local[block][i].end(); it++) { - if (dynamic_cast<ExternalFunctionNode *>(*it) != NULL) + if (dynamic_cast<AbstractExternalFunctionNode *>(*it) != NULL) (*it)->compileExternalFunctionOutput(code_file, instruction_number, false, tt3, map_idx2[block], false, false, tef_terms2); FNUMEXPR_ fnumexpr(TemporaryTerm, (int) (map_idx2[block].find((*it)->idx)->second)); -- GitLab