diff --git a/BlockTriangular.cc b/BlockTriangular.cc index 3260e546959ed08a60f0f440d1efbe68d1c18d0a..14c8063e275682d2a7cac176ade4a6aae20421b0 100644 --- a/BlockTriangular.cc +++ b/BlockTriangular.cc @@ -20,7 +20,6 @@ #include <iostream> #include <sstream> #include <fstream> -#include <ctime> #include <cstdlib> #include <cstring> #include <cmath> @@ -46,6 +45,7 @@ BlockTriangular::BlockTriangular(SymbolTable &symbol_table_arg, NumericalConstan bt_verbose = 0; ModelBlock = NULL; periods = 0; + prologue = epilogue = 0; Normalized_Equation = new DataTree(symbol_table, num_const); } @@ -114,7 +114,7 @@ BlockTriangular::Prologue_Epilogue(bool *IM, int &prologue, int &epilogue, int n //------------------------------------------------------------------------------ // Find a matching between equations and endogenous variables bool -BlockTriangular::Compute_Normalization(bool *IM, int equation_number, int prologue, int epilogue, bool verbose, bool *IM0, vector<int> &Index_Equ_IM) const +BlockTriangular::Compute_Normalization(bool *IM, int equation_number, int prologue, int epilogue, int verbose, bool *IM0, vector<int> &Index_Equ_IM) const { int n = equation_number - prologue - epilogue; @@ -143,9 +143,17 @@ BlockTriangular::Compute_Normalization(bool *IM, int equation_number, int prolog mate_map_t::const_iterator it = find(mate_map.begin(), mate_map.begin() + n, graph_traits<BipartiteGraph>::null_vertex()); if (it != mate_map.begin() + n) { - if (verbose) + if (verbose == 1) { - cerr << "ERROR: Could not normalize dynamic model. Variable " + cerr << "WARNING: Could not normalize dynamic model. Variable " + << symbol_table.getName(symbol_table.getID(eEndogenous, it - mate_map.begin())) + << " is not in the maximum cardinality matching. Trying to find a singular normalization." << endl; + //exit(EXIT_FAILURE); + return false; + } + else if (verbose == 2) + { + cerr << "ERROR: Could not normalize dynamic model (even with a singularity). Variable " << symbol_table.getName(symbol_table.getID(eEndogenous, it - mate_map.begin())) << " is not in the maximum cardinality matching." << endl; exit(EXIT_FAILURE); @@ -183,7 +191,7 @@ BlockTriangular::Get_Variable_LeadLag_By_Block(vector<int > &components_set, int variable_blck[Index_Var_IM[i]] = i; equation_blck[Index_Equ_IM[i]] = i; } - else if (i < components_set.size() + prologue) + else if (i < (int)components_set.size() + prologue) { variable_blck[Index_Var_IM[i]] = components_set[i-prologue] + prologue; equation_blck[Index_Equ_IM[i]] = components_set[i-prologue] + prologue; @@ -226,7 +234,7 @@ BlockTriangular::Get_Variable_LeadLag_By_Block(vector<int > &components_set, int } void -BlockTriangular::Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Block(bool *IM, int nb_var, int prologue, int epilogue, vector<int> &Index_Equ_IM, vector<int> &Index_Var_IM, vector<pair<int, int> > &blocks, t_etype &Equation_Type, bool verbose_) const +BlockTriangular::Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Block(bool *IM, int nb_var, int prologue, int epilogue, vector<int> &Index_Equ_IM, vector<int> &Index_Var_IM, vector<pair<int, int> > &blocks, t_etype &Equation_Type, bool verbose_, bool select_feedback_variable, int mfs) const { t_vtype V_Variable_Type; int n = nb_var - prologue - epilogue; @@ -272,11 +280,16 @@ BlockTriangular::Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Blo memcpy(SIM, IM, nb_var*nb_var*sizeof(bool)); //Add a loop on vertices which could not be normalized or vertices related to lead variables => force those vertices to belong to the feedback set - for (int i = 0; i < n; i++) - if (Equation_Type[Index_Equ_IM[i+prologue]].first == E_SOLVE or V_Variable_Type[Index_Var_IM[i+prologue]].second > 0 or V_Variable_Type[Index_Var_IM[i+prologue]].first > 0 - or equation_lead_lag[Index_Equ_IM[i+prologue]].second > 0 or equation_lead_lag[Index_Equ_IM[i+prologue]].first > 0) - add_edge(i, i, G2); - + if(select_feedback_variable) + for (int i = 0; i < n; i++) + if (Equation_Type[Index_Equ_IM[i+prologue]].first == E_SOLVE or V_Variable_Type[Index_Var_IM[i+prologue]].second > 0 or V_Variable_Type[Index_Var_IM[i+prologue]].first > 0 + or equation_lead_lag[Index_Equ_IM[i+prologue]].second > 0 or equation_lead_lag[Index_Equ_IM[i+prologue]].first > 0 + or mfs == 0) + add_edge(i, i, G2); + else + for (int i = 0; i < n; i++) + if (Equation_Type[Index_Equ_IM[i+prologue]].first == E_SOLVE or mfs == 0) + add_edge(i, i, G2); //For each block, the minimum set of feedback variable is computed // and the non-feedback variables are reordered to get // a sub-recursive block without feedback variables @@ -686,7 +699,7 @@ BlockTriangular::Free_Block(Model_Block *ModelBlock) const } t_etype -BlockTriangular::Equation_Type_determination(vector<BinaryOpNode *> &equations, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM) +BlockTriangular::Equation_Type_determination(vector<BinaryOpNode *> &equations, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM, int mfs) { NodeID lhs, rhs; ostringstream tmp_output; @@ -709,44 +722,40 @@ BlockTriangular::Equation_Type_determination(vector<BinaryOpNode *> &equations, lhs->writeOutput(tmp_output, oMatlabDynamicModelSparse, temporary_terms); tmp_s << "y(it_, " << Index_Var_IM[i]+1 << ")"; map<pair<int, pair<int, int> >, NodeID>::iterator derivative = first_order_endo_derivatives.find(make_pair(eq, make_pair(var, 0))); - /*cout << "eq=" << eq << " var=" << var << "="; - first_cur_endo_derivatives[make_pair(eq, var)]->writeOutput(cout, oMatlabDynamicModelSparse, temporary_terms); - cout << "\n"; - cout << "equation : "; - eq_node->writeOutput(cout, oMatlabDynamicModelSparse, temporary_terms); - cout << "\n";*/ set<pair<int, int> > result; pair<bool, NodeID> res; derivative->second->collectEndogenous(result); - /*for(set<pair<int, int> >::const_iterator iitt = result.begin(); iitt!=result.end(); iitt++) - cout << "result = " << iitt->first << ", " << iitt->second << "\n";*/ set<pair<int, int> >::const_iterator d_endo_variable = result.find(make_pair(var, 0)); //Determine whether the equation could be evaluated rather than to be solved - if (tmp_output.str() == tmp_s.str() and d_endo_variable == result.end()) + ostringstream tt(""); + derivative->second->writeOutput(tt, oMatlabDynamicModelSparse, temporary_terms); + //cout << tt.str().c_str() << " tmp_output.str()=" << tmp_output.str() << " tmp_s.str()=" << tmp_s.str(); + if (tmp_output.str() == tmp_s.str() and tt.str()=="1") { Equation_Simulation_Type = E_EVALUATE; + //cout << " E_EVALUATE "; } else { - //vector<pair<int, NodeID> > List_of_Op_RHS; - //the equation could be normalized by a permutation of the rhs and the lhs - if (d_endo_variable == result.end()) //the equation is linear in the endogenous and could be normalized using the derivative + vector<pair<int, pair<NodeID, NodeID> > > List_of_Op_RHS; + res = equations[eq]->normalizeEquation(var, List_of_Op_RHS); + if(mfs==2) { - Equation_Simulation_Type = E_EVALUATE_S; - //cout << " gone normalized : "; - res = equations[eq]->normalizeLinearInEndoEquation(var, derivative->second/*, List_of_Op_RHS*/); - /*res.second->writeOutput(cout, oMatlabDynamicModelSparse, temporary_terms); - cout << " done\n";*/ + if(d_endo_variable == result.end() && res.second) + Equation_Simulation_Type = E_EVALUATE_S; + } + else if(mfs==3) + { + if(res.second) // The equation could be solved analytically + Equation_Simulation_Type = E_EVALUATE_S; } } + //cout << " " << c_Equation_Type(Equation_Simulation_Type) << endl; V_Equation_Simulation_Type[eq] = make_pair(Equation_Simulation_Type, dynamic_cast<BinaryOpNode *>(res.second)); } return (V_Equation_Simulation_Type); } -/*void -BlockTriangular::Recompute_Deriavtives_Respect_to_Feedback_Variables( -*/ t_type BlockTriangular::Reduce_Blocks_and_type_determination(int prologue, int epilogue, vector<pair<int, int> > &blocks, vector<BinaryOpNode *> &equations, t_etype &Equation_Type, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM) { @@ -859,15 +868,15 @@ BlockTriangular::Reduce_Blocks_and_type_determination(int prologue, int epilogue map<pair<pair<int, pair<int, int> >, pair<int, int> >, int> BlockTriangular::get_Derivatives(Model_Block *ModelBlock, int blck) { - map<pair<pair<int, pair<int, int> >, pair<int, int> >, int> Derivatives; - Derivatives.clear(); - int nb_endo = symbol_table.endo_nbr(); - /*ModelBlock.Block_List[Blck].first_order_determinstic_simulation_derivatives = new*/ + map<pair<pair<int, pair<int, int> >, pair<int, int> >, int> Derivatives; + Derivatives.clear(); + int nb_endo = symbol_table.endo_nbr(); + /*ModelBlock.Block_List[Blck].first_order_determinstic_simulation_derivatives = new*/ for(int lag = -ModelBlock->Block_List[blck].Max_Lag; lag <= ModelBlock->Block_List[blck].Max_Lead; lag++) { - bool *IM=incidencematrix.Get_IM(lag, eEndogenous); - if(IM) - { + bool *IM=incidencematrix.Get_IM(lag, eEndogenous); + if(IM) + { for(int eq = 0; eq < ModelBlock->Block_List[blck].Size; eq++) { int eqr = ModelBlock->Block_List[blck].Equation[eq]; @@ -886,26 +895,26 @@ BlockTriangular::get_Derivatives(Model_Block *ModelBlock, int blck) OK=false; } - if(OK) - { - if (ModelBlock->Block_List[blck].Equation_Type[eq] == E_EVALUATE_S and eq<ModelBlock->Block_List[blck].Nb_Recursives) - //It's a normalized equation, we have to recompute the derivative using chain rule derivative function*/ + if(OK) + { + if (ModelBlock->Block_List[blck].Equation_Type[eq] == E_EVALUATE_S and eq<ModelBlock->Block_List[blck].Nb_Recursives) + //It's a normalized equation, we have to recompute the derivative using chain rule derivative function*/ Derivatives[make_pair(make_pair(lag, make_pair(eq, var)), make_pair(eqr, varr))] = 1; - else - //It's a feedback equation we can use the derivatives - Derivatives[make_pair(make_pair(lag, make_pair(eq, var)), make_pair(eqr, varr))] = 0; - } - if(var<ModelBlock->Block_List[blck].Nb_Recursives) - { - int eqs = ModelBlock->Block_List[blck].Equation[var]; - for(int vars=ModelBlock->Block_List[blck].Nb_Recursives; vars<ModelBlock->Block_List[blck].Size; vars++) - { - int varrs = ModelBlock->Block_List[blck].Variable[vars]; - //A new derivative need to be computed using the chain rule derivative function (a feedback variable appear in a recursive equation) - if(Derivatives.find(make_pair(make_pair(lag, make_pair(var, vars)), make_pair(eqs, varrs)))!=Derivatives.end()) - Derivatives[make_pair(make_pair(lag, make_pair(eq, vars)), make_pair(eqr, varrs))] = 2; - } - } + else + //It's a feedback equation we can use the derivatives + Derivatives[make_pair(make_pair(lag, make_pair(eq, var)), make_pair(eqr, varr))] = 0; + } + if(var<ModelBlock->Block_List[blck].Nb_Recursives) + { + int eqs = ModelBlock->Block_List[blck].Equation[var]; + for(int vars=ModelBlock->Block_List[blck].Nb_Recursives; vars<ModelBlock->Block_List[blck].Size; vars++) + { + int varrs = ModelBlock->Block_List[blck].Variable[vars]; + //A new derivative need to be computed using the chain rule derivative function (a feedback variable appear in a recursive equation) + if(Derivatives.find(make_pair(make_pair(lag, make_pair(var, vars)), make_pair(eqs, varrs)))!=Derivatives.end()) + Derivatives[make_pair(make_pair(lag, make_pair(eq, vars)), make_pair(eqr, varrs))] = 2; + } + } } } } @@ -915,18 +924,18 @@ BlockTriangular::get_Derivatives(Model_Block *ModelBlock, int blck) } void -BlockTriangular::Normalize_and_BlockDecompose(bool *IM, Model_Block *ModelBlock, int n, int &prologue, int &epilogue, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM, bool *IM_0, jacob_map &j_m, vector<BinaryOpNode *> &equations, t_etype &V_Equation_Type, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives) +BlockTriangular::Normalize_and_BlockDecompose(bool *IM, Model_Block *ModelBlock, int n, int &prologue, int &epilogue, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM, bool *IM_0, jacob_map &j_m, vector<BinaryOpNode *> &equations, t_etype &V_Equation_Type, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives, bool dynamic, int mfs, double cutoff) { int i, j, Nb_TotalBlocks, Nb_RecursBlocks, Nb_SimulBlocks; BlockType Btype; int count_Block, count_Equ; bool *SIM0, *SIM00; - - SIM0 = (bool *) malloc(n * n * sizeof(bool)); + SIM0 = (bool *) malloc(n * n * sizeof(bool)); memcpy(SIM0, IM_0, n*n*sizeof(bool)); Prologue_Epilogue(IM, prologue, epilogue, n, Index_Var_IM, Index_Equ_IM, SIM0); free(SIM0); + int counted = 0; if (prologue+epilogue < n) { @@ -956,7 +965,7 @@ BlockTriangular::Normalize_and_BlockDecompose(bool *IM, Model_Block *ModelBlock, memset(SIM00, 0, n*n*sizeof(bool)); for (map< pair< int, int >, double >::iterator iter = j_m.begin(); iter != j_m.end(); iter++) { - if (fabs(iter->second) > bi) + if (fabs(iter->second) > max(bi, cutoff)) { SIM0[iter->first.first*n+iter->first.second] = 1; if (!IM_0[iter->first.first*n+iter->first.second]) @@ -974,7 +983,7 @@ BlockTriangular::Normalize_and_BlockDecompose(bool *IM, Model_Block *ModelBlock, } free(SIM0); if (suppress != suppressed) - OK = Compute_Normalization(IM, n, prologue, epilogue, false, SIM00, Index_Equ_IM); + OK = Compute_Normalization(IM, n, prologue, epilogue, 0, SIM00, Index_Equ_IM); suppressed = suppress; if (!OK) //bi/=1.07; @@ -984,15 +993,23 @@ BlockTriangular::Normalize_and_BlockDecompose(bool *IM, Model_Block *ModelBlock, free(SIM00); } if (!OK) - Compute_Normalization(IM, n, prologue, epilogue, true, SIM00, Index_Equ_IM); + { + Compute_Normalization(IM, n, prologue, epilogue, 1, SIM00, Index_Equ_IM); + Compute_Normalization(IM, n, prologue, epilogue, 2, IM_0, Index_Equ_IM); + } } - V_Equation_Type = Equation_Type_determination(equations, first_order_endo_derivatives, Index_Var_IM, Index_Equ_IM); + V_Equation_Type = Equation_Type_determination(equations, first_order_endo_derivatives, Index_Var_IM, Index_Equ_IM, mfs); cout << "Finding the optimal block decomposition of the model ...\n"; vector<pair<int, int> > blocks; if (prologue+epilogue < n) - Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Block(IM, n, prologue, epilogue, Index_Equ_IM, Index_Var_IM, blocks, V_Equation_Type, false); + { + if(dynamic) + Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Block(IM, n, prologue, epilogue, Index_Equ_IM, Index_Var_IM, blocks, V_Equation_Type, false, true, mfs); + else + Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Block(IM, n, prologue, epilogue, Index_Equ_IM, Index_Var_IM, blocks, V_Equation_Type, false, false, mfs); + } t_type Type = Reduce_Blocks_and_type_determination(prologue, epilogue, blocks, equations, V_Equation_Type, Index_Var_IM, Index_Equ_IM); @@ -1049,7 +1066,7 @@ BlockTriangular::Normalize_and_BlockDecompose(bool *IM, Model_Block *ModelBlock, // normalize each equation of the dynamic model // and find the optimal block triangular decomposition of the static model void -BlockTriangular::Normalize_and_BlockDecompose_Static_0_Model(jacob_map &j_m, vector<BinaryOpNode *> &equations, t_etype &equation_simulation_type, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives) +BlockTriangular::Normalize_and_BlockDecompose_Static_0_Model(jacob_map &j_m, vector<BinaryOpNode *> &equations, t_etype &equation_simulation_type, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives, int mfs, double cutoff) { bool *SIM, *SIM_0; bool *Cur_IM; @@ -1091,7 +1108,7 @@ BlockTriangular::Normalize_and_BlockDecompose_Static_0_Model(jacob_map &j_m, vec SIM_0 = (bool *) malloc(symbol_table.endo_nbr() * symbol_table.endo_nbr() * sizeof(*SIM_0)); for (i = 0; i < symbol_table.endo_nbr()*symbol_table.endo_nbr(); i++) SIM_0[i] = Cur_IM[i]; - Normalize_and_BlockDecompose(SIM, ModelBlock, symbol_table.endo_nbr(), prologue, epilogue, Index_Var_IM, Index_Equ_IM, SIM_0, j_m, equations, equation_simulation_type, first_order_endo_derivatives); + Normalize_and_BlockDecompose(SIM, ModelBlock, symbol_table.endo_nbr(), prologue, epilogue, Index_Var_IM, Index_Equ_IM, SIM_0, j_m, equations, equation_simulation_type, first_order_endo_derivatives, true, mfs, cutoff); free(SIM_0); free(SIM); } diff --git a/BlockTriangular.hh b/BlockTriangular.hh index 3d6e6dabf1b2165de81c577d46b20d1e7384d8af..c0ebfb4bb2cb96126c81ba6e7b9513a5ea633e31 100644 --- a/BlockTriangular.hh +++ b/BlockTriangular.hh @@ -97,11 +97,11 @@ private: //! Allocates and fills the Model structure describing the content of each block void Allocate_Block(int size, int *count_Equ, int count_Block, BlockType type, BlockSimulationType SimType, Model_Block *ModelBlock, t_etype &Equation_Type, int recurs_Size, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM); //! Finds a matching between equations and endogenous variables - bool Compute_Normalization(bool *IM, int equation_number, int prologue, int epilogue, bool verbose, bool *IM0, vector<int> &Index_Var_IM) const; + bool Compute_Normalization(bool *IM, int equation_number, int prologue, int epilogue, int verbose, bool *IM0, vector<int> &Index_Var_IM) const; //! Decomposes into recurive blocks the non purely recursive equations and determines for each block the minimum feedback variables - void Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Block(bool *IM, int nb_var, int prologue, int epilogue, vector<int> &Index_Equ_IM, vector<int> &Index_Var_IM, vector<pair<int, int> > &blocks, t_etype &Equation_Type, bool verbose_) const; + void Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Block(bool *IM, int nb_var, int prologue, int epilogue, vector<int> &Index_Equ_IM, vector<int> &Index_Var_IM, vector<pair<int, int> > &blocks, t_etype &Equation_Type, bool verbose_, bool select_feedback_variable, int mfs) const; //! determines the type of each equation of the model (could be evaluated or need to be solved) - t_etype Equation_Type_determination(vector<BinaryOpNode *> &equations, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM); + t_etype Equation_Type_determination(vector<BinaryOpNode *> &equations, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM, int mfs); //! Tries to merge the consecutive blocks in a single block and determine the type of each block: recursive, simultaneous, ... t_type Reduce_Blocks_and_type_determination(int prologue, int epilogue, vector<pair<int, int> > &blocks, vector<BinaryOpNode *> &equations, t_etype &Equation_Type, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM); //! Compute for each variable its maximum lead and lag in its block @@ -121,8 +121,8 @@ public: map<pair<pair<int, pair<int, int> >, pair<int, int> >, int> get_Derivatives(Model_Block *ModelBlock, int Blck); - void Normalize_and_BlockDecompose_Static_0_Model(jacob_map &j_m, vector<BinaryOpNode *> &equations, t_etype &V_Equation_Type, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives); - void Normalize_and_BlockDecompose(bool* IM, Model_Block* ModelBlock, int n, int &prologue, int &epilogue, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM, bool* IM_0 , jacob_map &j_m, vector<BinaryOpNode *> &equations, t_etype &equation_simulation_type, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives); + void Normalize_and_BlockDecompose_Static_0_Model(jacob_map &j_m, vector<BinaryOpNode *> &equations, t_etype &V_Equation_Type, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives, int mfs, double cutoff); + void Normalize_and_BlockDecompose(bool* IM, Model_Block* ModelBlock, int n, int &prologue, int &epilogue, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM, bool* IM_0 , jacob_map &j_m, vector<BinaryOpNode *> &equations, t_etype &equation_simulation_type, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives, bool dynamic, int mfs, double cutoff); vector<int> Index_Equ_IM; vector<int> Index_Var_IM; int prologue, epilogue; @@ -187,11 +187,10 @@ public: }; inline static std::string c_Equation_Type(int type) { - char c_Equation_Type[5][13]= + char c_Equation_Type[4][13]= { "E_UNKNOWN ", "E_EVALUATE ", - //"E_EVALUATE_R", "E_EVALUATE_S", "E_SOLVE " }; diff --git a/CodeInterpreter.hh b/CodeInterpreter.hh index cb495131eff5d239aac0103b20fae99a57160a42..a33301f5486287d8dfa2ec864eb72ea8e710db28 100644 --- a/CodeInterpreter.hh +++ b/CodeInterpreter.hh @@ -40,6 +40,15 @@ const char FDIMT=16; const char FEND=17; const char FOK=18; const char FENDEQU=19; +const char FLDSV=20; +const char FSTPSV=21; +const char FLDSU=22; +const char FSTPSU=23; +const char FLDST=24; +const char FSTPST=25; +const char FDIMST=26; + + enum BlockType { @@ -53,7 +62,6 @@ enum EquationType { E_UNKNOWN, //!< Unknown equation type E_EVALUATE, //!< Simple evaluation, normalized variable on left-hand side - //E_EVALUATE_R, //!< Simple evaluation, normalized variable on right-hand side E_EVALUATE_S, //!< Simple evaluation, normalize using the first order derivative E_SOLVE //!< No simple evaluation of the equation, it has to be solved }; diff --git a/ComputingTasks.cc b/ComputingTasks.cc index 533f280676028c354a3e8c0e199275841b0e14fe..22ba5950ad6be4c2fac22614154cfce0d3639139 100644 --- a/ComputingTasks.cc +++ b/ComputingTasks.cc @@ -27,8 +27,8 @@ using namespace std; #include "ComputingTasks.hh" #include "Statement.hh" -SteadyStatement::SteadyStatement(const OptionsList &options_list_arg) : - options_list(options_list_arg) +SteadyStatement::SteadyStatement(const OptionsList &options_list_arg, StaticDllModel::mode_t mode_arg) : + options_list(options_list_arg), mode(mode_arg) { } @@ -37,12 +37,17 @@ SteadyStatement::checkPass(ModFileStructure &mod_file_struct) { if (options_list.num_options.find("block_mfs") != options_list.num_options.end()) mod_file_struct.steady_block_mfs_option = true; + else if (options_list.num_options.find("block_mfs_dll") != options_list.num_options.end()) + mod_file_struct.steady_block_mfs_dll_option = true; } void SteadyStatement::writeOutput(ostream &output, const string &basename) const { options_list.writeOutput(output); + /*if (mode == StaticDllModel::eSparseDLLMode) + output << "oo_.steady_state=simulate('steady');" << endl; + else*/ output << "steady;\n"; } diff --git a/ComputingTasks.hh b/ComputingTasks.hh index fad2123a949c63be3816d08596a4d63a9da4270d..37f7ebc329ddd71e2ffa33b28f506e6412120ce9 100644 --- a/ComputingTasks.hh +++ b/ComputingTasks.hh @@ -32,8 +32,9 @@ class SteadyStatement : public Statement { private: const OptionsList options_list; + const StaticDllModel::mode_t mode; public: - SteadyStatement(const OptionsList &options_list_arg); + SteadyStatement(const OptionsList &options_list_arg, StaticDllModel::mode_t mode_arg); virtual void checkPass(ModFileStructure &mod_file_struct); virtual void writeOutput(ostream &output, const string &basename) const; }; diff --git a/DynamicModel.cc b/DynamicModel.cc index 27471170ff861368ee237aac7f38dd9da4d49bca..89afb45582f2c5f5c38a5972766ad2309a95bf75 100644 --- a/DynamicModel.cc +++ b/DynamicModel.cc @@ -23,7 +23,6 @@ #include <cassert> #include <cstdio> #include <cerrno> - #include "DynamicModel.hh" // For mkdir() and chdir() @@ -46,6 +45,7 @@ DynamicModel::DynamicModel(SymbolTable &symbol_table_arg, mode(eStandardMode), cutoff(1e-15), markowitz(0.7), + mfs(0), block_triangular(symbol_table_arg, num_constants_arg) { } @@ -62,7 +62,7 @@ DynamicModel::compileDerivative(ofstream &code_file, int eq, int symb_id, int la //first_derivatives_type::const_iterator it = first_derivatives.find(make_pair(eq, getDerivID(symb_id, lag))); first_derivatives_type::const_iterator it = first_derivatives.find(make_pair(eq, getDerivID(symbol_table.getID(eEndogenous, symb_id), lag))); if (it != first_derivatives.end()) - (it->second)->compile(code_file, false, temporary_terms, map_idx); + (it->second)->compile(code_file, false, temporary_terms, map_idx, true); else code_file.write(&FLDZ, sizeof(FLDZ)); } @@ -73,7 +73,7 @@ DynamicModel::compileChainRuleDerivative(ofstream &code_file, int eqr, int varr, { map<pair<int, pair<int, int> >, NodeID>::const_iterator it = first_chain_rule_derivatives.find(make_pair(eqr, make_pair(varr, lag))); if (it != first_chain_rule_derivatives.end()) - (it->second)->compile(code_file, false, temporary_terms, map_idx); + (it->second)->compile(code_file, false, temporary_terms, map_idx, true); else code_file.write(&FLDZ, sizeof(FLDZ)); } @@ -112,7 +112,7 @@ DynamicModel::computeTemporaryTermsOrdered(Model_Block *ModelBlock) { map<NodeID, pair<int, int> > first_occurence; map<NodeID, int> reference_count; - int i, j, m, eq, var, lag; + int i, j, m, eq, var, eqr, varr, lag; temporary_terms_type vect; ostringstream tmp_output; BinaryOpNode *eq_node; @@ -127,12 +127,24 @@ DynamicModel::computeTemporaryTermsOrdered(Model_Block *ModelBlock) // Compute the temporary terms reordered for (i = 0;i < ModelBlock->Block_List[j].Size;i++) { - eq_node = equations[ModelBlock->Block_List[j].Equation[i]]; - eq_node->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, j, ModelBlock, i, map_idx); - if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE_S) - if(ModelBlock->Block_List[j].Equation_Normalized[i]) + if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE_S && i<ModelBlock->Block_List[j].Nb_Recursives && ModelBlock->Block_List[j].Equation_Normalized[i]) ModelBlock->Block_List[j].Equation_Normalized[i]->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, j, ModelBlock, i, map_idx); + else + { + eq_node = equations[ModelBlock->Block_List[j].Equation[i]]; + eq_node->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, j, ModelBlock, i, map_idx); + } } + for(i=0; i<(int)ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++) + { + pair< pair<int, pair<int, int> >, pair<int, int> > it = ModelBlock->Block_List[j].Chain_Rule_Derivatives->at(i); + lag=it.first.first; + int eqr=it.second.first; + int varr=it.second.second; + it_chr=first_chain_rule_derivatives.find(make_pair(eqr, make_pair( varr, lag))); + it_chr->second->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, j, ModelBlock, ModelBlock->Block_List[j].Size-1, map_idx); + } + for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++) { lag=m-ModelBlock->Block_List[j].Max_Lag; @@ -141,21 +153,18 @@ DynamicModel::computeTemporaryTermsOrdered(Model_Block *ModelBlock) eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index[i]; var=ModelBlock->Block_List[j].IM_lead_lag[m].Var_Index[i]; it=first_derivatives.find(make_pair(eq,getDerivID(symbol_table.getID(eEndogenous, var), lag))); - //printf("it=%d eq=%d var=%s (%d)\n",it!=first_derivatives.end(), eq, symbol_table.getName(symbol_table.getID(eEndogenous, var)).c_str(), var); - //if(it!=first_derivatives.end()) it->second->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, j, ModelBlock, ModelBlock->Block_List[j].Size-1, map_idx); } } - for(i=0; i<ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++) + /*for(i=0; i<(int)ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++) { pair< pair<int, pair<int, int> >, pair<int, int> > it = ModelBlock->Block_List[j].Chain_Rule_Derivatives->at(i); lag=it.first.first; - eq=it.first.second.first; - var=it.first.second.second; - it_chr=first_chain_rule_derivatives.find(make_pair(eq, make_pair( var, lag))); - //it_chr->second->writeChainRuleDerivative(output, eq, var, k, oMatlabDynamicModelSparse, temporary_terms); + eqr=it.second.first; + varr=it.second.second; + it_chr=first_chain_rule_derivatives.find(make_pair(eqr, make_pair( varr, lag))); it_chr->second->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, j, ModelBlock, ModelBlock->Block_List[j].Size-1, map_idx); - } + }*/ /*for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++) { lag=m-ModelBlock->Block_List[j].Max_Lag; @@ -178,8 +187,6 @@ DynamicModel::computeTemporaryTermsOrdered(Model_Block *ModelBlock) eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index_other_endo[i]; var=ModelBlock->Block_List[j].IM_lead_lag[m].Var_Index_other_endo[i]; it=first_derivatives.find(make_pair(eq,getDerivID(symbol_table.getID(eEndogenous, var), lag))); - //it=first_derivatives.find(make_pair(eq,variable_table.getID(var, lag))); - //if(it!=first_derivatives.end()) it->second->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, j, ModelBlock, ModelBlock->Block_List[j].Size-1, map_idx); } } @@ -190,13 +197,21 @@ DynamicModel::computeTemporaryTermsOrdered(Model_Block *ModelBlock) // Collecte the temporary terms reordered for (i = 0;i < ModelBlock->Block_List[j].Size;i++) { - eq_node = equations[ModelBlock->Block_List[j].Equation[i]]; + if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE_S && i<ModelBlock->Block_List[j].Nb_Recursives && ModelBlock->Block_List[j].Equation_Normalized[i]) + ModelBlock->Block_List[j].Equation_Normalized[i]->collectTemporary_terms(temporary_terms, ModelBlock, j); + else + { + eq_node = equations[ModelBlock->Block_List[j].Equation[i]]; + eq_node->collectTemporary_terms(temporary_terms, ModelBlock, j); + } + + /*eq_node = equations[ModelBlock->Block_List[j].Equation[i]]; eq_node->collectTemporary_terms(temporary_terms, ModelBlock, j); if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE_S) if(ModelBlock->Block_List[j].Equation_Normalized[i]) ModelBlock->Block_List[j].Equation_Normalized[i]->collectTemporary_terms(temporary_terms, ModelBlock, j); for(temporary_terms_type::const_iterator it = ModelBlock->Block_List[j].Temporary_Terms_in_Equation[i]->begin(); it!= ModelBlock->Block_List[j].Temporary_Terms_in_Equation[i]->end(); it++) - (*it)->collectTemporary_terms(temporary_terms, ModelBlock, j); + (*it)->collectTemporary_terms(temporary_terms, ModelBlock, j);*/ } for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++) { @@ -211,14 +226,13 @@ DynamicModel::computeTemporaryTermsOrdered(Model_Block *ModelBlock) it->second->collectTemporary_terms(temporary_terms, ModelBlock, j); } } - for(i=0; i<ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++) + for(i=0; i<(int)ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++) { pair< pair<int, pair<int, int> >, pair<int, int> > it = ModelBlock->Block_List[j].Chain_Rule_Derivatives->at(i); lag=it.first.first; - eq=it.first.second.first; - var=it.first.second.second; - it_chr=first_chain_rule_derivatives.find(make_pair(eq, make_pair( var, lag))); - //it_chr->second->writeChainRuleDerivative(output, eq, var, k, oMatlabDynamicModelSparse, temporary_terms); + eqr=it.second.first; + varr=it.second.second; + it_chr=first_chain_rule_derivatives.find(make_pair(eqr, make_pair( varr, lag))); it_chr->second->collectTemporary_terms(temporary_terms, ModelBlock, j); } /*for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++) @@ -268,7 +282,7 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin BinaryOpNode *eq_node; ostringstream Uf[symbol_table.endo_nbr()]; map<NodeID, int> reference_count; - int prev_Simulation_Type=-1, count_derivates=0; + //int prev_Simulation_Type=-1, count_derivates=0; int jacobian_max_endo_col; ofstream output; //temporary_terms_type::const_iterator it_temp=temporary_terms.begin(); @@ -324,10 +338,9 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin << BlockTriangular::BlockSim(ModelBlock->Block_List[j].Simulation_Type) << " //" << endl << " % ////////////////////////////////////////////////////////////////////////" << endl; //The Temporary terms + //output << " relax = 1;\n"; if (ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD - ||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD - /*||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD_R - ||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD_R*/) + ||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD) { output << " if(jacobian_eval)\n"; output << " g1 = spalloc(" << ModelBlock->Block_List[j].Size-ModelBlock->Block_List[j].Nb_Recursives @@ -437,15 +450,18 @@ evaluation: if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDAR { output << tmp_output.str(); output << " = "; + /*if(!(ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD or ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD)) + { + lhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms); + output << "-relax*("; + lhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms); + output << "-("; + rhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms); + output << "))"; + } + else*/ rhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms); } - /*else if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE_R) - { - rhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms); - output << " = "; - output << tmp_output.str(); - output << "; %reversed " << ModelBlock->Block_List[j].Equation_Type[i] << " \n"; - }*/ else if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE_S) { output << "%" << tmp_output.str(); @@ -454,19 +470,23 @@ evaluation: if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDAR { rhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms); output << "\n "; - /*temporary_terms_type tt2; - tt2.clear();*/ tmp_output.str(""); eq_node = (BinaryOpNode *)ModelBlock->Block_List[j].Equation_Normalized[i]; lhs = eq_node->get_arg1(); rhs = eq_node->get_arg2(); - if(ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD or ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD) - lhs->writeOutput(tmp_output, oMatlabDynamicModelSparse, temporary_terms); - else - lhs->writeOutput(tmp_output, oMatlabDynamicModelSparse, temporary_terms); - output << tmp_output.str(); + lhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms); output << " = "; - rhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms); + /*if(!(ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD or ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD)) + { + lhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms); + output << "-relax*("; + lhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms); + output << "-("; + rhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms); + output << "))"; + } + else*/ + rhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms); } } else @@ -535,9 +555,6 @@ end: { case EVALUATE_BACKWARD: case EVALUATE_FORWARD: - /*case EVALUATE_BACKWARD_R: - case EVALUATE_FORWARD_R:*/ - count_derivates++; for (m=0;m<ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag+1;m++) { k=m-ModelBlock->Block_List[j].Max_Lag; @@ -604,7 +621,6 @@ end: case SOLVE_FORWARD_SIMPLE: case SOLVE_BACKWARD_COMPLETE: case SOLVE_FORWARD_COMPLETE: - count_derivates++; for (m=0;m<ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag+1;m++) { k=m-ModelBlock->Block_List[j].Max_Lag; @@ -649,7 +665,7 @@ end: int var=ModelBlock->Block_List[j].IM_lead_lag[m].Var_Index_other_endo[i]; int eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_other_endo[i]; int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Var_other_endo[i]; - output << " g1_o(" << eqr+1-ModelBlock->Block_List[j].Nb_Recursives << ", " + output << " g1_o(" << eqr+1/*-ModelBlock->Block_List[j].Nb_Recursives*/ << ", " << varr+1+(m+max_endo_lag-ModelBlock->Block_List[j].Max_Lag)*symbol_table.endo_nbr() << ") = "; writeDerivative(output, eq, symbol_table.getID(eEndogenous, var), k, oMatlabDynamicModelSparse, temporary_terms); output << "; % variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, var)) @@ -662,130 +678,76 @@ end: output << " varargout{2}=g1_o;\n"; output << " else" << endl; - m=ModelBlock->Block_List[j].Max_Lag; - //cout << "\nDerivatives in Block " << j << "\n"; - for(i=0; i<ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++) - { - //Chain_Rule_Derivatives.insert(make_pair( make_pair(eq, eqr), make_pair(var, make_pair(varr, lag)))); - pair< pair<int, pair<int, int> >, pair<int, int> > it = ModelBlock->Block_List[j].Chain_Rule_Derivatives->at(i); - k=it.first.first; - int eq=it.first.second.first; - int var=it.first.second.second; - int eqr=it.second.first; - int varr=it.second.second; - - /*for (i=0;i<ModelBlock->Block_List[j].IM_lead_lag[m].size;i++) + for(i=0; i<(int)ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++) { - int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index[i]; - int var=ModelBlock->Block_List[j].IM_lead_lag[m].Var_Index[i]; - int eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ[i]; - int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Var[i]; - ostringstream tmp_output; - if (eqr<ModelBlock->Block_List[j].Nb_Recursives) - { - if (varr>=ModelBlock->Block_List[j].Nb_Recursives) - {*/ - output << " g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives << ", " - << var+1-ModelBlock->Block_List[j].Nb_Recursives << ") = "; - writeChainRuleDerivative(output, eqr, varr, k, oMatlabDynamicModelSparse, temporary_terms); - output << ";"; - output << " %2 variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, varr)) - << "(" << k - << ") " << varr+1 - << ", equation=" << eqr+1 << endl; - } - /*} - } - }*/ + pair< pair<int, pair<int, int> >, pair<int, int> > it = ModelBlock->Block_List[j].Chain_Rule_Derivatives->at(i); + k=it.first.first; + int eq=it.first.second.first; + int var=it.first.second.second; + int eqr=it.second.first; + int varr=it.second.second; + output << " g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives << ", " + << var+1-ModelBlock->Block_List[j].Nb_Recursives << ") = "; + writeChainRuleDerivative(output, eqr, varr, k, oMatlabDynamicModelSparse, temporary_terms); + output << "; %2 variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, varr)) + << "(" << k << ") " << varr+1 << ", equation=" << eqr+1 << endl; + } output << " end;\n"; break; case SOLVE_TWO_BOUNDARIES_SIMPLE: case SOLVE_TWO_BOUNDARIES_COMPLETE: output << " if ~jacobian_eval" << endl; - /*for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++) + for(i=0; i<(int)ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++) { - k=m-ModelBlock->Block_List[j].Max_Lag; - for (i=0;i<ModelBlock->Block_List[j].IM_lead_lag[m].size;i++) + pair< pair<int, pair<int, int> >, pair<int, int> > it = ModelBlock->Block_List[j].Chain_Rule_Derivatives->at(i); + k=it.first.first; + int eq=it.first.second.first; + int var=it.first.second.second; + int eqr=it.second.first; + int varr=it.second.second; + ostringstream tmp_output; + if(eq>=ModelBlock->Block_List[j].Nb_Recursives and var>=ModelBlock->Block_List[j].Nb_Recursives) { - int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index[i]; - int var=ModelBlock->Block_List[j].IM_lead_lag[m].Var_Index[i]; - int eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ[i]; - int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Var[i];*/ - for(i=0; i<ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++) - { - //Chain_Rule_Derivatives.insert(make_pair( make_pair(eq, eqr), make_pair(var, make_pair(varr, lag)))); - pair< pair<int, pair<int, int> >, pair<int, int> > it = ModelBlock->Block_List[j].Chain_Rule_Derivatives->at(i); - k=it.first.first; - int eq=it.first.second.first; - int var=it.first.second.second; - int eqr=it.second.first; - int varr=it.second.second; - - //bool derivative_exist; - ostringstream tmp_output; - /*if (eqr>=ModelBlock->Block_List[j].Nb_Recursives) - { - if (varr>=ModelBlock->Block_List[j].Nb_Recursives) - {*/ - /*for(int equation = ModelBlock->Block_List[j].Nb_Recursives; equation<ModelBlock->Block_List[j].Size; equation++) - { - int eq = ModelBlock->Block_List[j].Equation[equation]; - int eqr = equation - ModelBlock->Block_List[j].Nb_Recursives; - for(int variable = ModelBlock->Block_List[j].Nb_Recursives; variable<ModelBlock->Block_List[j].Size; variable++) - { - int var = ModelBlock->Block_List[j].Variable[variable]; - int varr = variable - ModelBlock->Block_List[j].Nb_Recursives;*/ - //cout << "eqr=" << eqr << " varr=" << varr; - //cout << "k=" << k << " eq=" << eq << " var=" << var << " eqr=" << eqr << " varr=" << varr << " ModelBlock->Block_List[j].Equation[eq]=" << ModelBlock->Block_List[j].Equation[eq] << "\n"; - if(eq>=ModelBlock->Block_List[j].Nb_Recursives and var>=ModelBlock->Block_List[j].Nb_Recursives) - { - - if (k==0) - Uf[ModelBlock->Block_List[j].Equation[eq]] << "+g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives - << "+Per_J_, " << var+1-ModelBlock->Block_List[j].Nb_Recursives - << "+Per_K_)*y(it_, " << varr+1 << ")"; - else if (k==1) - Uf[ModelBlock->Block_List[j].Equation[eq]] << "+g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives - << "+Per_J_, " << var+1-ModelBlock->Block_List[j].Nb_Recursives - << "+Per_y_)*y(it_+1, " << varr+1 << ")"; - else if (k>0) - Uf[ModelBlock->Block_List[j].Equation[eq]] << "+g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives - << "+Per_J_, " << var+1-ModelBlock->Block_List[j].Nb_Recursives - << "+y_size*(it_+" << k-1 << "))*y(it_+" << k << ", " << varr+1 << ")"; - else if (k<0) - Uf[ModelBlock->Block_List[j].Equation[eq]] << "+g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives - << "+Per_J_, " << var+1-ModelBlock->Block_List[j].Nb_Recursives - << "+y_size*(it_" << k-1 << "))*y(it_" << k << ", " << varr+1 << ")"; - if (k==0) - tmp_output << " g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_J_, " - << var+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_K_) = "; - else if (k==1) - tmp_output << " g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_J_, " - << var+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_y_) = "; - else if (k>0) - tmp_output << " g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_J_, " - << var+1-ModelBlock->Block_List[j].Nb_Recursives << "+y_size*(it_+" << k-1 << ")) = "; - else if (k<0) - tmp_output << " g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_J_, " - << var+1-ModelBlock->Block_List[j].Nb_Recursives << "+y_size*(it_" << k-1 << ")) = "; - - - output << " " << tmp_output.str(); - - writeChainRuleDerivative(output, eqr, varr, k, oMatlabDynamicModelSparse, temporary_terms); - - output << ";"; - output << " %2 variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, varr)) - << "(" << k << ") " << varr+1 - << ", equation=" << eqr+1 << " (" << eq+1 << ")" << endl; - } - //cout << " done\n"; - /* } - }*/ - + if (k==0) + Uf[ModelBlock->Block_List[j].Equation[eq]] << "+g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives + << "+Per_J_, " << var+1-ModelBlock->Block_List[j].Nb_Recursives + << "+Per_K_)*y(it_, " << varr+1 << ")"; + else if (k==1) + Uf[ModelBlock->Block_List[j].Equation[eq]] << "+g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives + << "+Per_J_, " << var+1-ModelBlock->Block_List[j].Nb_Recursives + << "+Per_y_)*y(it_+1, " << varr+1 << ")"; + else if (k>0) + Uf[ModelBlock->Block_List[j].Equation[eq]] << "+g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives + << "+Per_J_, " << var+1-ModelBlock->Block_List[j].Nb_Recursives + << "+y_size*(it_+" << k-1 << "))*y(it_+" << k << ", " << varr+1 << ")"; + else if (k<0) + Uf[ModelBlock->Block_List[j].Equation[eq]] << "+g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives + << "+Per_J_, " << var+1-ModelBlock->Block_List[j].Nb_Recursives + << "+y_size*(it_" << k-1 << "))*y(it_" << k << ", " << varr+1 << ")"; + if (k==0) + tmp_output << " g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_J_, " + << var+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_K_) = "; + else if (k==1) + tmp_output << " g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_J_, " + << var+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_y_) = "; + else if (k>0) + tmp_output << " g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_J_, " + << var+1-ModelBlock->Block_List[j].Nb_Recursives << "+y_size*(it_+" << k-1 << ")) = "; + else if (k<0) + tmp_output << " g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_J_, " + << var+1-ModelBlock->Block_List[j].Nb_Recursives << "+y_size*(it_" << k-1 << ")) = "; + output << " " << tmp_output.str(); + + writeChainRuleDerivative(output, eqr, varr, k, oMatlabDynamicModelSparse, temporary_terms); + + output << ";"; + output << " %2 variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, varr)) + << "(" << k << ") " << varr+1 + << ", equation=" << eqr+1 << " (" << eq+1 << ")" << endl; + } #ifdef CONDITION - output << " if (fabs(condition[" << eqr << "])<fabs(u[" << u << "+Per_u_]))\n"; - output << " condition(" << eqr << ")=u(" << u << "+Per_u_);\n"; + output << " if (fabs(condition[" << eqr << "])<fabs(u[" << u << "+Per_u_]))\n"; + output << " condition(" << eqr << ")=u(" << u << "+Per_u_);\n"; #endif //} } @@ -879,7 +841,6 @@ end: default: break; } - prev_Simulation_Type=ModelBlock->Block_List[j].Simulation_Type; output.close(); } } @@ -896,16 +857,14 @@ DynamicModel::writeModelEquationsCodeOrdered(const string file_name, const Model struct Uff { Uff_l *Ufl, *Ufl_First; - int eqr; }; - int i,j,k,m, v; + int i,j,k,v; string tmp_s; ostringstream tmp_output; ofstream code_file; NodeID lhs=NULL, rhs=NULL; BinaryOpNode *eq_node; - bool lhs_rhs_done; Uff Uf[symbol_table.endo_nbr()]; map<NodeID, int> reference_count; vector<int> feedback_variables; @@ -948,7 +907,7 @@ DynamicModel::writeModelEquationsCodeOrdered(const string file_name, const Model //cout << "ModelBlock->Block_List[j].Nb_Recursives = " << ModelBlock->Block_List[j].Nb_Recursives << "\n"; Write_Inf_To_Bin_File(file_name, bin_basename, j, u_count_int,file_open, ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_SIMPLE); - //cout << "u_count_int=" << u_count_int << "\n"; + //cout << "u_count_int=" << u_count_int << "\n"; code_file.write(reinterpret_cast<char *>(&ModelBlock->Block_List[j].is_linear),sizeof(ModelBlock->Block_List[j].is_linear)); //v=block_triangular.ModelBlock->Block_List[j].IM_lead_lag[block_triangular.ModelBlock->Block_List[j].Max_Lag + block_triangular.ModelBlock->Block_List[j].Max_Lead].u_finish + 1; v = u_count_int ; @@ -964,30 +923,19 @@ DynamicModel::writeModelEquationsCodeOrdered(const string file_name, const Model code_file.write(reinterpret_cast<char *>(&v),sizeof(v)); file_open=true; } - /*if (ModelBlock->Block_List[j].Size==1) - { - lhs_rhs_done=true; - eq_node = equations[ModelBlock->Block_List[j].Equation[0]]; - lhs = eq_node->get_arg1(); - rhs = eq_node->get_arg2(); - } - else - lhs_rhs_done=false;*/ // The equations for (i = 0;i < ModelBlock->Block_List[j].Size;i++) { //The Temporary terms temporary_terms_type tt2; tt2.clear(); - /*if (ModelBlock->Block_List[j].Temporary_Terms_in_Equation[i]->size()) - output << " " << sps << "% //Temporary variables" << endl;*/ #ifdef DEBUGC k=0; #endif for (temporary_terms_type::const_iterator it = ModelBlock->Block_List[j].Temporary_Terms_in_Equation[i]->begin(); it != ModelBlock->Block_List[j].Temporary_Terms_in_Equation[i]->end(); it++) { - (*it)->compile(code_file, false, tt2, map_idx); + (*it)->compile(code_file, false, tt2, map_idx, true); code_file.write(&FSTPT, sizeof(FSTPT)); map_idx_type::const_iterator ii=map_idx.find((*it)->idx); v=(int)ii->second; @@ -1010,12 +958,6 @@ DynamicModel::writeModelEquationsCodeOrdered(const string file_name, const Model cout << "map_idx[" << (*it)->idx <<"]=" << ii->second << "\n"; } #endif - /*if (!lhs_rhs_done) - {*/ - eq_node = equations[ModelBlock->Block_List[j].Equation[i]]; - lhs = eq_node->get_arg1(); - rhs = eq_node->get_arg2(); - /*}*/ switch (ModelBlock->Block_List[j].Simulation_Type) { evaluation: @@ -1023,17 +965,19 @@ evaluation: case EVALUATE_FORWARD: if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE) { - rhs->compile(code_file, false, temporary_terms, map_idx); - lhs->compile(code_file, true, temporary_terms, map_idx); + eq_node = equations[ModelBlock->Block_List[j].Equation[i]]; + lhs = eq_node->get_arg1(); + rhs = eq_node->get_arg2(); + rhs->compile(code_file, false, temporary_terms, map_idx, true); + lhs->compile(code_file, true, temporary_terms, map_idx, true); } else if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE_S) { eq_node = (BinaryOpNode*)ModelBlock->Block_List[j].Equation_Normalized[i]; - //cout << "EVALUATE_S var " << ModelBlock->Block_List[j].Variable[i] << "\n"; lhs = eq_node->get_arg1(); rhs = eq_node->get_arg2(); - rhs->compile(code_file, false, temporary_terms, map_idx); - lhs->compile(code_file, true, temporary_terms, map_idx); + rhs->compile(code_file, false, temporary_terms, map_idx, true); + lhs->compile(code_file, true, temporary_terms, map_idx, true); } break; case SOLVE_BACKWARD_COMPLETE: @@ -1044,29 +988,27 @@ evaluation: goto evaluation; feedback_variables.push_back(ModelBlock->Block_List[j].Variable[i]); v=ModelBlock->Block_List[j].Equation[i]; - Uf[v].eqr=i; Uf[v].Ufl=NULL; goto end; default: end: - lhs->compile(code_file, false, temporary_terms, map_idx); - rhs->compile(code_file, false, temporary_terms, map_idx); + eq_node = equations[ModelBlock->Block_List[j].Equation[i]]; + lhs = eq_node->get_arg1(); + rhs = eq_node->get_arg2(); + lhs->compile(code_file, false, temporary_terms, map_idx, true); + rhs->compile(code_file, false, temporary_terms, map_idx, true); code_file.write(&FBINARY, sizeof(FBINARY)); int v=oMinus; code_file.write(reinterpret_cast<char *>(&v),sizeof(v)); code_file.write(&FSTPR, sizeof(FSTPR)); v = i - ModelBlock->Block_List[j].Nb_Recursives; - //cout << "residual[" << v << "]\n"; code_file.write(reinterpret_cast<char *>(&v), sizeof(v)); } } code_file.write(&FENDEQU, sizeof(FENDEQU)); // The Jacobian if we have to solve the block - bool feedback_variable = (feedback_variables.size()>0); if (ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_BACKWARD - && ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_FORWARD - /*&& ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_BACKWARD_R - && ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_FORWARD_R*/) + && ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_FORWARD) { switch (ModelBlock->Block_List[j].Simulation_Type) { @@ -1077,87 +1019,15 @@ end: v=0; code_file.write(reinterpret_cast<char *>(&v), sizeof(v)); break; + case SOLVE_BACKWARD_COMPLETE: case SOLVE_FORWARD_COMPLETE: - count_u = feedback_variables.size(); - //cout << "todo SOLVE_COMPLETE\n"; - for(i=0; i<ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++) - { - //Chain_Rule_Derivatives.insert(make_pair( make_pair(eq, eqr), make_pair(var, make_pair(varr, lag)))); - pair< pair<int, pair<int, int> >, pair<int, int> > it = ModelBlock->Block_List[j].Chain_Rule_Derivatives->at(i); - k=it.first.first; - int eq=it.first.second.first;; - int var=it.first.second.second; - int eqr=it.second.first; - int varr=it.second.second; - int v=ModelBlock->Block_List[j].Equation[eq]; - if (!Uf[v].Ufl) - { - Uf[v].Ufl=(Uff_l*)malloc(sizeof(Uff_l)); - Uf[v].Ufl_First=Uf[v].Ufl; - } - else - { - Uf[v].Ufl->pNext=(Uff_l*)malloc(sizeof(Uff_l)); - Uf[v].Ufl=Uf[v].Ufl->pNext; - } - Uf[v].Ufl->pNext=NULL; - Uf[v].Ufl->u=count_u; - Uf[v].Ufl->var=varr; - compileChainRuleDerivative(code_file, eqr, varr, 0, map_idx); - code_file.write(&FSTPU, sizeof(FSTPU)); - code_file.write(reinterpret_cast<char *>(&count_u), sizeof(count_u)); - count_u++; - } - //cout << "done SOLVE_COMPLETE\n"; - for (i = 0;i < ModelBlock->Block_List[j].Size;i++) - { - if(i>=ModelBlock->Block_List[j].Nb_Recursives) - { - code_file.write(&FLDR, sizeof(FLDR)); - v = i-ModelBlock->Block_List[j].Nb_Recursives; - code_file.write(reinterpret_cast<char *>(&v), sizeof(v)); - code_file.write(&FLDZ, sizeof(FLDZ)); - int v=ModelBlock->Block_List[j].Equation[i]; - for (Uf[v].Ufl=Uf[v].Ufl_First;Uf[v].Ufl;Uf[v].Ufl=Uf[v].Ufl->pNext) - { - code_file.write(&FLDU, sizeof(FLDU)); - code_file.write(reinterpret_cast<char *>(&Uf[v].Ufl->u), sizeof(Uf[v].Ufl->u)); - code_file.write(&FLDV, sizeof(FLDV)); - char vc=eEndogenous; - code_file.write(reinterpret_cast<char *>(&vc), sizeof(vc)); - code_file.write(reinterpret_cast<char *>(&Uf[v].Ufl->var), sizeof(Uf[v].Ufl->var)); - int v1=0; - code_file.write(reinterpret_cast<char *>(&v1), sizeof(v1)); - code_file.write(&FBINARY, sizeof(FBINARY)); - v1=oTimes; - code_file.write(reinterpret_cast<char *>(&v1), sizeof(v1)); - code_file.write(&FCUML, sizeof(FCUML)); - } - Uf[v].Ufl=Uf[v].Ufl_First; - while (Uf[v].Ufl) - { - Uf[v].Ufl_First=Uf[v].Ufl->pNext; - free(Uf[v].Ufl); - Uf[v].Ufl=Uf[v].Ufl_First; - } - code_file.write(&FBINARY, sizeof(FBINARY)); - v=oMinus; - code_file.write(reinterpret_cast<char *>(&v), sizeof(v)); - code_file.write(&FSTPU, sizeof(FSTPU)); - v = i - ModelBlock->Block_List[j].Nb_Recursives; - code_file.write(reinterpret_cast<char *>(&v), sizeof(v)); - } - } - break; case SOLVE_TWO_BOUNDARIES_COMPLETE: case SOLVE_TWO_BOUNDARIES_SIMPLE: - count_u=ModelBlock->Block_List[j].Size - ModelBlock->Block_List[j].Nb_Recursives; - //cout << "todo SOLVE_TWO_BOUNDARIES\n"; - //cout << "ModelBlock->Block_List[j].Nb_Recursives=" << ModelBlock->Block_List[j].Nb_Recursives << "\n"; - for(i=0; i<ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++) - { - //Chain_Rule_Derivatives.insert(make_pair( make_pair(eq, eqr), make_pair(var, make_pair(varr, lag)))); + //count_u=ModelBlock->Block_List[j].Size - ModelBlock->Block_List[j].Nb_Recursives; + count_u = feedback_variables.size(); + for(i=0; i<(int)ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++) + { pair< pair<int, pair<int, int> >, pair<int, int> > it = ModelBlock->Block_List[j].Chain_Rule_Derivatives->at(i); k=it.first.first; int eq=it.first.second.first; @@ -1166,11 +1036,11 @@ end: int varr=it.second.second; //cout << "k=" << k << " eq=" << eq << " (" << eq-ModelBlock->Block_List[j].Nb_Recursives << ") var=" << var << " (" << var-ModelBlock->Block_List[j].Nb_Recursives << ") eqr=" << eqr << " varr=" << varr << " count_u=" << count_u << "\n"; int v=ModelBlock->Block_List[j].Equation[eq]; - /*m = ModelBlock->Block_List[j].Max_Lag + k; + /*m = ModelBlock->Block_List[j].Max_Lag + k; int u=ModelBlock->Block_List[j].IM_lead_lag[m].u[i];*/ if(eq>=ModelBlock->Block_List[j].Nb_Recursives and var>=ModelBlock->Block_List[j].Nb_Recursives) - { - if (!Uf[v].Ufl) + { + if (!Uf[v].Ufl) { Uf[v].Ufl=(Uff_l*)malloc(sizeof(Uff_l)); Uf[v].Ufl_First=Uf[v].Ufl; @@ -1184,53 +1054,21 @@ end: Uf[v].Ufl->u=count_u; Uf[v].Ufl->var=varr; Uf[v].Ufl->lag=k; - //writeChainRuleDerivative(cout, eqr, varr, k, oMatlabDynamicModelSparse, /*map_idx*/temporary_terms); - //cout <<"\n"; compileChainRuleDerivative(code_file, eqr, varr, k, map_idx); code_file.write(&FSTPU, sizeof(FSTPU)); code_file.write(reinterpret_cast<char *>(&count_u), sizeof(count_u)); count_u++; } } - //cout << "done it SOLVE_TWO_BOUNDARIES\n"; - /*for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++) - { - k=m-ModelBlock->Block_List[j].Max_Lag; - for (i=0;i<ModelBlock->Block_List[j].IM_lead_lag[m].size;i++) - { - int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index[i]; - int var=ModelBlock->Block_List[j].IM_lead_lag[m].Var_Index[i]; - int u=ModelBlock->Block_List[j].IM_lead_lag[m].u[i]; - int eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ[i]; - int v=ModelBlock->Block_List[j].Equation[eqr]; - if (!Uf[v].Ufl) - { - Uf[v].Ufl=(Uff_l*)malloc(sizeof(Uff_l)); - Uf[v].Ufl_First=Uf[v].Ufl; - } - else - { - Uf[v].Ufl->pNext=(Uff_l*)malloc(sizeof(Uff_l)); - Uf[v].Ufl=Uf[v].Ufl->pNext; - } - Uf[v].Ufl->pNext=NULL; - Uf[v].Ufl->u=u; - Uf[v].Ufl->var=var; - Uf[v].Ufl->lag=k; - compileDerivative(code_file, eq, var, k, map_idx); - code_file.write(&FSTPU, sizeof(FSTPU)); - code_file.write(reinterpret_cast<char *>(&u), sizeof(u)); - } - }*/ for (i = 0;i < ModelBlock->Block_List[j].Size;i++) { - if(i>=ModelBlock->Block_List[j].Nb_Recursives) - { + if(i>=ModelBlock->Block_List[j].Nb_Recursives) + { code_file.write(&FLDR, sizeof(FLDR)); v = i-ModelBlock->Block_List[j].Nb_Recursives; code_file.write(reinterpret_cast<char *>(&v), sizeof(v)); code_file.write(&FLDZ, sizeof(FLDZ)); - int v=ModelBlock->Block_List[j].Equation[i]; + v=ModelBlock->Block_List[j].Equation[i]; for (Uf[v].Ufl=Uf[v].Ufl_First; Uf[v].Ufl; Uf[v].Ufl=Uf[v].Ufl->pNext) { code_file.write(&FLDU, sizeof(FLDU)); @@ -1260,24 +1098,8 @@ end: code_file.write(&FSTPU, sizeof(FSTPU)); v = i - ModelBlock->Block_List[j].Nb_Recursives; code_file.write(reinterpret_cast<char *>(&v), sizeof(v)); - } - } -#ifdef CONDITION - for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++) - { - k=m-ModelBlock->Block_List[j].Max_Lag; - for (i=0;i<ModelBlock->Block_List[j].IM_lead_lag[m].size;i++) - { - int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index[i]; - int var=ModelBlock->Block_List[j].IM_lead_lag[m].Var_Index[i]; - int u=ModelBlock->Block_List[j].IM_lead_lag[m].u[i]; - int eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ[i]; - output << " u[" << u << "+Per_u_] /= condition[" << eqr << "];\n"; } } - for (i = 0;i < ModelBlock->Block_List[j].Size;i++) - output << " u[" << i << "+Per_u_] /= condition[" << i << "];\n"; -#endif break; default: break; @@ -1421,17 +1243,17 @@ DynamicModel::Write_Inf_To_Bin_File(const string &dynamic_basename, const string int j; std::ofstream SaveCode; if (file_open) - SaveCode.open((bin_basename + ".bin").c_str(), ios::out | ios::in | ios::binary | ios ::ate ); + SaveCode.open((bin_basename + "_dynamic.bin").c_str(), ios::out | ios::in | ios::binary | ios ::ate ); else - SaveCode.open((bin_basename + ".bin").c_str(), ios::out | ios::binary); + SaveCode.open((bin_basename + "_dynamic.bin").c_str(), ios::out | ios::binary); if (!SaveCode.is_open()) { - cout << "Error : Can't open file \"" << bin_basename << ".bin\" for writing\n"; + cout << "Error : Can't open file \"" << bin_basename << "_dynamic.bin\" for writing\n"; exit(EXIT_FAILURE); } u_count_int=0; int Size = block_triangular.ModelBlock->Block_List[num].Size - block_triangular.ModelBlock->Block_List[num].Nb_Recursives; - for(int i=0; i<block_triangular.ModelBlock->Block_List[num].Chain_Rule_Derivatives->size();i++) + for(int i=0; i<(int)block_triangular.ModelBlock->Block_List[num].Chain_Rule_Derivatives->size();i++) { //Chain_Rule_Derivatives.insert(make_pair( make_pair(eq, eqr), make_pair(var, make_pair(varr, lag)))); pair< pair<int, pair<int, int> >, pair<int, int> > it = block_triangular.ModelBlock->Block_List[num].Chain_Rule_Derivatives->at(i); @@ -1578,70 +1400,50 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri tmp_eq.str(""); for (int count_call=1, i = 0;i < block_triangular.ModelBlock->Size;i++, count_call++) { + mDynamicModelFile << " %block_triangular.ModelBlock->Block_List[i].Nb_Recursives=" << block_triangular.ModelBlock->Block_List[i].Nb_Recursives << " block_triangular.ModelBlock->Block_List[i].Size=" << block_triangular.ModelBlock->Block_List[i].Size << "\n"; k=block_triangular.ModelBlock->Block_List[i].Simulation_Type; - if ((BlockTriangular::BlockSim(prev_Simulation_Type)!=BlockTriangular::BlockSim(k)) && - ((prev_Simulation_Type==EVALUATE_FORWARD || prev_Simulation_Type==EVALUATE_BACKWARD /*|| prev_Simulation_Type==EVALUATE_FORWARD_R || prev_Simulation_Type==EVALUATE_BACKWARD_R*/) - || (k==EVALUATE_FORWARD || k==EVALUATE_BACKWARD /*|| k==EVALUATE_FORWARD_R || k==EVALUATE_BACKWARD_R*/))) - { - mDynamicModelFile << " y_index_eq=[" << tmp_eq.str() << "];\n"; - tmp_eq.str(""); - mDynamicModelFile << " y_index=[" << tmp.str() << "];\n"; - tmp.str(""); - mDynamicModelFile << tmp1.str(); - tmp1.str(""); - } - for (int ik=block_triangular.ModelBlock->Block_List[i].Nb_Recursives ;ik<block_triangular.ModelBlock->Block_List[i].Size;ik++) + if(k==EVALUATE_FORWARD || k==EVALUATE_BACKWARD) { - tmp << " " << block_triangular.ModelBlock->Block_List[i].Variable[ik]+1; - tmp_eq << " " << block_triangular.ModelBlock->Block_List[i].Equation[ik]+1; + for (int ik=0 ;ik<block_triangular.ModelBlock->Block_List[i].Size;ik++) + { + tmp << " " << block_triangular.ModelBlock->Block_List[i].Variable[ik]+1; + tmp_eq << " " << block_triangular.ModelBlock->Block_List[i].Equation[ik]+1; + } } - if (k==EVALUATE_FORWARD || k==EVALUATE_BACKWARD /*|| k==EVALUATE_FORWARD_R || k==EVALUATE_BACKWARD_R*/) + else { - if (i==block_triangular.ModelBlock->Size-1) + for (int ik=block_triangular.ModelBlock->Block_List[i].Nb_Recursives ;ik<block_triangular.ModelBlock->Block_List[i].Size;ik++) { - mDynamicModelFile << " y_index_eq=[" << tmp_eq.str() << "];\n"; - tmp_eq.str(""); - mDynamicModelFile << " y_index=[" << tmp.str() << "];\n"; - tmp.str(""); - mDynamicModelFile << tmp1.str(); - tmp1.str(""); + tmp << " " << block_triangular.ModelBlock->Block_List[i].Variable[ik]+1; + tmp_eq << " " << block_triangular.ModelBlock->Block_List[i].Equation[ik]+1; } } - if (BlockTriangular::BlockSim(prev_Simulation_Type)==BlockTriangular::BlockSim(k) && - (k==EVALUATE_FORWARD || k==EVALUATE_BACKWARD /*|| k==EVALUATE_FORWARD_R || k==EVALUATE_BACKWARD_R*/)) - skip_head=true; - else - skip_head=false; + mDynamicModelFile << " y_index_eq=[" << tmp_eq.str() << "];\n"; + mDynamicModelFile << " y_index=[" << tmp.str() << "];\n"; + switch (k) { case EVALUATE_FORWARD: case EVALUATE_BACKWARD: - /*case EVALUATE_FORWARD_R: - case EVALUATE_BACKWARD_R:*/ - if (!skip_head) - { - tmp1 << " [y, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_o]=" << dynamic_basename << "_" << i + 1 << "(y, x, params, 1, it_-1, 1);\n"; - tmp1 << " residual(y_index_eq)=ys(y_index)-y(it_, y_index);\n"; - } - break; + mDynamicModelFile << " [y, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_o]=" << dynamic_basename << "_" << i + 1 << "(y, x, params, 1, it_-1, 1);\n"; + mDynamicModelFile << " residual(y_index_eq)=ys(y_index)-y(it_, y_index);\n"; + break; case SOLVE_FORWARD_SIMPLE: case SOLVE_BACKWARD_SIMPLE: - mDynamicModelFile << " y_index_eq = " << block_triangular.ModelBlock->Block_List[i].Equation[0]+1 << ";\n"; + //mDynamicModelFile << " y_index_eq = " << block_triangular.ModelBlock->Block_List[i].Equation[0]+1 << ";\n"; mDynamicModelFile << " [r, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_o]=" << dynamic_basename << "_" << i + 1 << "(y, x, params, it_, 1);\n"; mDynamicModelFile << " residual(y_index_eq)=r;\n"; - tmp_eq.str(""); - tmp.str(""); break; case SOLVE_FORWARD_COMPLETE: case SOLVE_BACKWARD_COMPLETE: - mDynamicModelFile << " y_index_eq = [" << tmp_eq.str() << "];\n"; + //mDynamicModelFile << " y_index_eq = [" << tmp_eq.str() << "];\n"; mDynamicModelFile << " [r, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_o]=" << dynamic_basename << "_" << i + 1 << "(y, x, params, it_, 1);\n"; mDynamicModelFile << " residual(y_index_eq)=r;\n"; break; case SOLVE_TWO_BOUNDARIES_COMPLETE: case SOLVE_TWO_BOUNDARIES_SIMPLE: int j; - mDynamicModelFile << " y_index_eq = [" << tmp_eq.str() << "];\n"; + /*mDynamicModelFile << " y_index_eq = [" << tmp_eq.str() << "];\n"; tmp_i=block_triangular.ModelBlock->Block_List[i].Max_Lag_Endo+block_triangular.ModelBlock->Block_List[i].Max_Lead_Endo+1; mDynamicModelFile << " y_index = ["; for (j=0;j<tmp_i;j++) @@ -1653,9 +1455,7 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri for (j=0;j<tmp_ix;j++) for (int ik=0;ik<block_triangular.ModelBlock->Block_List[i].nb_exo;ik++) mDynamicModelFile << " " << block_triangular.ModelBlock->Block_List[i].Exogenous[ik]+1+j*symbol_table.exo_nbr()+symbol_table.endo_nbr()*tmp_i; - mDynamicModelFile << " ];\n"; - tmp.str(""); - tmp_eq.str(""); + mDynamicModelFile << " ];\n";*/ //mDynamicModelFile << " ga = [];\n"; j = block_triangular.ModelBlock->Block_List[i].Size*(block_triangular.ModelBlock->Block_List[i].Max_Lag_Endo+block_triangular.ModelBlock->Block_List[i].Max_Lead_Endo+1) + block_triangular.ModelBlock->Block_List[i].nb_exo*(block_triangular.ModelBlock->Block_List[i].Max_Lag_Exo+block_triangular.ModelBlock->Block_List[i].Max_Lead_Exo+1); @@ -1670,7 +1470,8 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri mDynamicModelFile << " residual(y_index_eq)=r(:,M_.maximum_lag+1);\n"; break; } - prev_Simulation_Type=k; + tmp_eq.str(""); + tmp.str(""); } if (tmp1.str().length()) { @@ -2343,7 +2144,7 @@ DynamicModel::writeOutputPostComputing(ostream &output, const string &basename) } void -DynamicModel::evaluateJacobian(const eval_context_type &eval_context, jacob_map *j_m) +DynamicModel::evaluateJacobian(const eval_context_type &eval_context, jacob_map *j_m, bool dynamic) { int i=0; int j=0; @@ -2376,10 +2177,10 @@ DynamicModel::evaluateJacobian(const eval_context_type &eval_context, jacob_map IM=block_triangular.incidencematrix.Get_IM(k1, eEndogenous); a_variable_lag=k1; } - if (k1==0) + if (k1==0 or !dynamic) { j++; - (*j_m)[make_pair(eq,var)]=val; + (*j_m)[make_pair(eq,var)]+=val; } if (IM[eq*symbol_table.endo_nbr()+var] && (fabs(val) < cutoff)) { @@ -2547,8 +2348,7 @@ DynamicModel::computingPass(bool jacobianExo, bool hessian, bool thirdDerivative BuildIncidenceMatrix(); jacob_map j_m; - - evaluateJacobian(eval_context, &j_m); + evaluateJacobian(eval_context, &j_m, true); if (block_triangular.bt_verbose) @@ -2559,12 +2359,15 @@ DynamicModel::computingPass(bool jacobianExo, bool hessian, bool thirdDerivative t_etype equation_simulation_type; map<pair<int, pair<int, int> >, NodeID> first_order_endo_derivatives = collect_first_order_derivatives_endogenous(); - block_triangular.Normalize_and_BlockDecompose_Static_0_Model(j_m, equations, equation_simulation_type, first_order_endo_derivatives); + block_triangular.Normalize_and_BlockDecompose_Static_0_Model(j_m, equations, equation_simulation_type, first_order_endo_derivatives, mfs, cutoff); + BlockLinear(block_triangular.ModelBlock); + + computeChainRuleJacobian(block_triangular.ModelBlock); + if (!no_tmp_terms) computeTemporaryTermsOrdered(block_triangular.ModelBlock); - computeChainRuleJacobian(block_triangular.ModelBlock); } else if (!no_tmp_terms) @@ -2633,6 +2436,20 @@ DynamicModel::toStatic(StaticModel &static_model) const static_model.addEquation((*it)->toStatic(static_model)); } +void +DynamicModel::toStaticDll(StaticDllModel &static_model) const + { + // Convert model local variables (need to be done first) + for (map<int, NodeID>::const_iterator it = local_variables_table.begin(); + it != local_variables_table.end(); it++) + static_model.AddLocalVariable(symbol_table.getName(it->first), it->second->toStatic(static_model)); + + // Convert equations + for (vector<BinaryOpNode *>::const_iterator it = equations.begin(); + it != equations.end(); it++) + static_model.addEquation((*it)->toStatic(static_model)); + } + int DynamicModel::computeDerivID(int symb_id, int lag) { @@ -2789,17 +2606,13 @@ DynamicModel::getDynJacobianCol(int deriv_id) const throw (UnknownDerivIDExcepti void DynamicModel::computeChainRuleJacobian(Model_Block *ModelBlock) { - //cout << "computeChainRuleJacobian\n"; - //clock_t t1 = clock(); map<int, NodeID> recursive_variables; first_chain_rule_derivatives.clear(); for(int blck = 0; blck<ModelBlock->Size; blck++) { - //cout << "blck=" << blck << "\n"; recursive_variables.clear(); if (ModelBlock->Block_List[blck].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE or ModelBlock->Block_List[blck].Simulation_Type==SOLVE_TWO_BOUNDARIES_SIMPLE) { - //cout << "SOLVE_TWO_BOUNDARIES_COMPLETE \n"; ModelBlock->Block_List[blck].Chain_Rule_Derivatives->clear(); for(int i = 0; i < ModelBlock->Block_List[blck].Nb_Recursives; i++) { @@ -2808,56 +2621,41 @@ DynamicModel::computeChainRuleJacobian(Model_Block *ModelBlock) else recursive_variables[getDerivID(symbol_table.getID(eEndogenous, ModelBlock->Block_List[blck].Variable[i]), 0)] = equations[ModelBlock->Block_List[blck].Equation[i]]; } - //cout << "After recursive_alloc\n"; map<pair<pair<int, pair<int, int> >, pair<int, int> >, int> Derivatives = block_triangular.get_Derivatives(ModelBlock, blck); - for(map<pair<pair<int, pair<int, int> >, pair<int, int> >, int>::const_iterator it = Derivatives.begin(); it != Derivatives.end(); it++) - { - int lag = it->first.first.first; - int eq = it->first.first.second.first; - int var = it->first.first.second.second; - int eqr = it->first.second.first; - int varr = it->first.second.second; - int Deriv_type = it->second; - if(Deriv_type == 0) - first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = first_derivatives[make_pair(eqr, getDerivID(symbol_table.getID(eEndogenous, varr), lag))]; - else if (Deriv_type == 1) - first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = ModelBlock->Block_List[blck].Equation_Normalized[eq]->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), lag), recursive_variables); - else if (Deriv_type == 2) - { - if(ModelBlock->Block_List[blck].Equation_Type[eq] == E_EVALUATE_S and eq<ModelBlock->Block_List[blck].Nb_Recursives) - first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = ModelBlock->Block_List[blck].Equation_Normalized[eq]->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), lag), recursive_variables); - else - first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = equations[eqr]->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), lag), recursive_variables); - } - ModelBlock->Block_List[blck].Chain_Rule_Derivatives->push_back(make_pair( make_pair(lag, make_pair(eq, var)), make_pair(eqr, varr))); - } - - - /*for(int lag = -ModelBlock->Block_List[blck].Max_Lag; lag <= ModelBlock->Block_List[blck].Max_Lead; lag++) + map<pair<pair<int, pair<int, int> >, pair<int, int> >, int>::const_iterator it = Derivatives.begin(); + //#pragma omp parallel for shared(it, blck) + for(int i=0; i<(int)Derivatives.size(); i++) { - - for(int eq = 0; eq < ModelBlock->Block_List[blck].Size; eq++) + int Deriv_type = it->second; + pair<pair<int, pair<int, int> >, pair<int, int> > it_l(it->first); + it++; + int lag = it_l.first.first; + int eq = it_l.first.second.first; + int var = it_l.first.second.second; + int eqr = it_l.second.first; + int varr = it_l.second.second; + if(Deriv_type == 0) { - int eqr = ModelBlock->Block_List[blck].Equation[eq]; - for(int var = ModelBlock->Block_List[blck].Nb_Recursives; var < ModelBlock->Block_List[blck].Size; var++) - { - int varr = ModelBlock->Block_List[blck].Variable[var]; - NodeID d1 = equations[eqr]->getChainRuleDerivative(recursive_variables, varr, lag); - if (d1 == Zero) - continue; - first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = d1; - ModelBlock->Block_List[blck].Chain_Rule_Derivatives->push_back(make_pair( make_pair(eqr, eq), make_pair(varr, make_pair(var, lag)))); - } + first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = first_derivatives[make_pair(eqr, getDerivID(symbol_table.getID(eEndogenous, varr), lag))]; } - }*/ - - + else if (Deriv_type == 1) + { + first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = ModelBlock->Block_List[blck].Equation_Normalized[eq]->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), lag), recursive_variables); + } + else if (Deriv_type == 2) + { + if(ModelBlock->Block_List[blck].Equation_Type[eq] == E_EVALUATE_S && eq<ModelBlock->Block_List[blck].Nb_Recursives) + first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = ModelBlock->Block_List[blck].Equation_Normalized[eq]->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), lag), recursive_variables); + else + first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = equations[eqr]->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), lag), recursive_variables); + } + ModelBlock->Block_List[blck].Chain_Rule_Derivatives->push_back(make_pair( make_pair(lag, make_pair(eq, var)), make_pair(eqr, varr))); + } } else if( ModelBlock->Block_List[blck].Simulation_Type==SOLVE_BACKWARD_SIMPLE or ModelBlock->Block_List[blck].Simulation_Type==SOLVE_FORWARD_SIMPLE or ModelBlock->Block_List[blck].Simulation_Type==SOLVE_BACKWARD_COMPLETE or ModelBlock->Block_List[blck].Simulation_Type==SOLVE_FORWARD_COMPLETE) { - //cout << "SOLVE_FORWARD_SIMPLE \n"; ModelBlock->Block_List[blck].Chain_Rule_Derivatives->clear(); for(int i = 0; i < ModelBlock->Block_List[blck].Nb_Recursives; i++) { @@ -2881,7 +2679,6 @@ DynamicModel::computeChainRuleJacobian(Model_Block *ModelBlock) } } } - //cout << "elapsed time in milliseconds = " << 1000.0*(double(clock()) - double(t1))/double(CLOCKS_PER_SEC) << "\n"; } diff --git a/DynamicModel.hh b/DynamicModel.hh index 54263fbecc22841922dcecb1305ea7b45e705429..ee05ea9546316b56694b12dce96eaaf59aea6bd6 100644 --- a/DynamicModel.hh +++ b/DynamicModel.hh @@ -25,6 +25,7 @@ using namespace std; #include <fstream> #include "StaticModel.hh" +#include "StaticDllModel.hh" #include "BlockTriangular.hh" //! Stores a dynamic model @@ -100,7 +101,7 @@ private: - computes the jacobian for the model w.r. to contemporaneous variables - removes edges of the incidence matrix when derivative w.r. to the corresponding variable is too close to zero (below the cutoff) */ - void evaluateJacobian(const eval_context_type &eval_context, jacob_map *j_m); + void evaluateJacobian(const eval_context_type &eval_context, jacob_map *j_m, bool dynamic); void BlockLinear(Model_Block *ModelBlock); string reform(string name) const; map_idx_type map_idx; @@ -152,8 +153,15 @@ public: virtual NodeID AddVariable(const string &name, int lag = 0); //! Absolute value under which a number is considered to be zero double cutoff; - //! The weight of the Markowitz criteria to determine the pivot in the linear solver (simul_NG1 from simulate.cc) + //! The weight of the Markowitz criteria to determine the pivot in the linear solver (simul_NG1 and simul_NG from simulate.cc) double markowitz; + //! Compute the minimum feedback set in the dynamic model: + /*! 0 : all endogenous variables are considered as feedback variables + 1 : the variables belonging to non normalized equation are considered as feedback variables + 2 : the variables belonging to a non linear equation are considered as feedback variables + 3 : the variables belonging to a non normalizable non linear equation are considered as feedback variables + default value = 0 */ + int mfs; //! the file containing the model and the derivatives code ofstream code_file; //! Execute computations (variable sorting + derivation) @@ -184,6 +192,8 @@ public: /*! It assumes that the static model given in argument has just been allocated */ void toStatic(StaticModel &static_model) const; + void toStaticDll(StaticDllModel &static_model) const; + //! Writes LaTeX file with the equations of the dynamic model void writeLatexFile(const string &basename) const; diff --git a/DynareBison.yy b/DynareBison.yy index d7423e8288c4702c5395dc4b49cda9f81dcfe255..439c7532e706b37f9bbd450469803a6bf1b21c2e 100644 --- a/DynareBison.yy +++ b/DynareBison.yy @@ -87,7 +87,7 @@ class ParsingDriver; %} %token AR AUTOCORR -%token BAYESIAN_IRF BETA_PDF BICGSTAB BLOCK_MFS +%token BAYESIAN_IRF BETA_PDF BICGSTAB BLOCK_MFS BLOCK_MFS_DLL %token BVAR_DENSITY BVAR_FORECAST %token BVAR_PRIOR_DECAY BVAR_PRIOR_FLAT BVAR_PRIOR_LAMBDA %token BVAR_PRIOR_MU BVAR_PRIOR_OMEGA BVAR_PRIOR_TAU BVAR_PRIOR_TRAIN @@ -106,7 +106,7 @@ class ParsingDriver; %token KALMAN_ALGO KALMAN_TOL %token LAPLACE LIK_ALGO LIK_INIT LINEAR LOAD_MH_FILE LOAD_PARAMS_AND_STEADY_STATE LOGLINEAR LU %token MARKOWITZ MARGINAL_DENSITY MAX -%token METHOD MH_DROP MH_INIT_SCALE MH_JSCALE MH_MODE MH_NBLOCKS MH_REPLIC MH_RECOVER MIN +%token METHOD MFS MH_DROP MH_INIT_SCALE MH_JSCALE MH_MODE MH_NBLOCKS MH_REPLIC MH_RECOVER MIN %token MODE_CHECK MODE_COMPUTE MODE_FILE MODEL MODEL_COMPARISON MODEL_INFO MSHOCKS %token MODIFIEDHARMONICMEAN MOMENTS_VARENDO DIFFUSE_FILTER %token <string_val> NAME @@ -449,6 +449,7 @@ model_sparse_options_list : model_sparse_options_list COMMA model_sparse_options model_sparse_options : o_cutoff | o_markowitz + | o_mfs ; model : MODEL ';' { driver.begin_model(); } @@ -641,6 +642,10 @@ steady_options : o_solve_algo | o_homotopy_mode | o_homotopy_steps | o_block_mfs + | o_block_mfs_dll + | o_cutoff + | o_markowitz + | o_mfs ; check : CHECK ';' @@ -1496,6 +1501,7 @@ o_method : METHOD EQUAL INT_NUMBER { driver.option_num("simulation_method",$3);} | METHOD EQUAL GMRES { driver.option_num("simulation_method", "2"); } | METHOD EQUAL BICGSTAB { driver.option_num("simulation_method", "3"); }; o_markowitz : MARKOWITZ EQUAL number { driver.option_num("markowitz", $3); }; +o_mfs : MFS EQUAL number { driver.option_num("mfs", $3); }; o_simul : SIMUL { driver.option_num("simul", "1"); }; o_simul_seed : SIMUL_SEED EQUAL INT_NUMBER { driver.option_num("simul_seed", $3); } ; o_qz_criterium : QZ_CRITERIUM EQUAL number { driver.option_num("qz_criterium", $3); }; @@ -1602,6 +1608,8 @@ o_gsa_trans_ident : TRANS_IDENT EQUAL INT_NUMBER { driver.option_num("trans_iden o_homotopy_mode : HOMOTOPY_MODE EQUAL INT_NUMBER {driver.option_num("homotopy_mode",$3); }; o_homotopy_steps : HOMOTOPY_STEPS EQUAL INT_NUMBER {driver.option_num("homotopy_steps",$3); }; o_block_mfs : BLOCK_MFS { driver.option_num("block_mfs", "1"); } +o_block_mfs_dll : BLOCK_MFS_DLL { driver.option_num("block_mfs_dll", "1"); } + o_parameters : PARAMETERS EQUAL symbol {driver.option_str("parameters",$3);}; o_shocks : SHOCKS EQUAL '(' list_of_symbol_lists ')' { driver.option_symbol_list("shocks"); }; o_labels : LABELS EQUAL '(' symbol_list ')' { driver.option_symbol_list("labels"); }; diff --git a/DynareFlex.ll b/DynareFlex.ll index 0180d384f1f22e518794d729197f42d054782c53..395050c03e5871efbde0ccb3103ae381c34d5026 100644 --- a/DynareFlex.ll +++ b/DynareFlex.ll @@ -210,6 +210,7 @@ int sigma_e = 0; <DYNARE_STATEMENT>periods {return token::PERIODS;} <DYNARE_STATEMENT>cutoff {return token::CUTOFF;} <DYNARE_STATEMENT>markowitz {return token::MARKOWITZ;} +<DYNARE_STATEMENT>mfs {return token::MFS;} <DYNARE_STATEMENT>marginal_density {return token::MARGINAL_DENSITY;} <DYNARE_STATEMENT>laplace {return token::LAPLACE;} <DYNARE_STATEMENT>modifiedharmonicmean {return token::MODIFIEDHARMONICMEAN;} @@ -220,6 +221,8 @@ int sigma_e = 0; <DYNARE_STATEMENT>diffuse_filter {return token::DIFFUSE_FILTER;} <DYNARE_STATEMENT>plot_priors {return token::PLOT_PRIORS;} <DYNARE_STATEMENT>block_mfs {return token::BLOCK_MFS;} +<DYNARE_STATEMENT>block_mfs_dll {return token::BLOCK_MFS_DLL;} + <DYNARE_STATEMENT>freq {return token::FREQ;} <DYNARE_STATEMENT>initial_year {return token::INITIAL_YEAR;} <DYNARE_STATEMENT>initial_subperiod {return token::INITIAL_SUBPERIOD;} @@ -302,6 +305,7 @@ int sigma_e = 0; <DYNARE_BLOCK>periods {return token::PERIODS;} <DYNARE_BLOCK>cutoff {return token::CUTOFF;} <DYNARE_BLOCK>markowitz {return token::MARKOWITZ;} +<DYNARE_BLOCK>mfs {return token::MFS;} <DYNARE_BLOCK>gamma_pdf {return token::GAMMA_PDF;} <DYNARE_BLOCK>beta_pdf {return token::BETA_PDF;} <DYNARE_BLOCK>normal_pdf {return token::NORMAL_PDF;} diff --git a/ExprNode.cc b/ExprNode.cc index 5c799fcc0ac50475a2f68988e2f85e3a7fe065dd..6acccd01ba96c261ff6cc3f9ed4ef9e3158d87ca 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -131,6 +131,13 @@ ExprNode::computeTemporaryTerms(map<NodeID, int> &reference_count, } +pair<int, NodeID > +ExprNode::normalizeEquation(int var_endo, vector<pair<int, pair<NodeID, NodeID> > > &List_of_Op_RHS) const + { + return(make_pair(0, (NodeID)NULL)); + } + + void ExprNode::writeOutput(ostream &output) { @@ -184,13 +191,10 @@ NumConstNode::eval(const eval_context_type &eval_context) const throw (EvalExcep } void -NumConstNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const +NumConstNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic) const { CompileCode.write(&FLDC, sizeof(FLDC)); double vard = datatree.num_constants.getDouble(id); -#ifdef DEBUGC - cout << "FLDC " << vard << "\n"; -#endif CompileCode.write(reinterpret_cast<char *>(&vard),sizeof(vard)); } @@ -199,10 +203,10 @@ NumConstNode::collectVariables(SymbolType type_arg, set<pair<int, int> > &result { } -pair<bool, NodeID> -NumConstNode::normalizeLinearInEndoEquation(int var_endo, NodeID Derivative) const +pair<int, NodeID > +NumConstNode::normalizeEquation(int var_endo, vector<pair<int, pair<NodeID, NodeID> > > &List_of_Op_RHS) const { - return(make_pair(false, datatree.AddNumConstant(datatree.num_constants.get(id)))); + return(make_pair(0, datatree.AddNumConstant(datatree.num_constants.get(id)))); } NodeID @@ -295,9 +299,6 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const { // If node is a temporary term -#ifdef DEBUGC - cout << "write_ouput Variable output_type=" << output_type << "\n"; -#endif temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<VariableNode *>(this)); if (it != temporary_terms.end()) { @@ -464,19 +465,22 @@ VariableNode::eval(const eval_context_type &eval_context) const throw (EvalExcep } void -VariableNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const +VariableNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic) const { int i, lagl; -#ifdef DEBUGC - cout << "output_type=" << output_type << "\n"; -#endif if (!lhs_rhs) { - CompileCode.write(&FLDV, sizeof(FLDV)); + if(dynamic) + CompileCode.write(&FLDV, sizeof(FLDV)); + else + CompileCode.write(&FLDSV, sizeof(FLDSV)); } else { - CompileCode.write(&FSTPV, sizeof(FSTPV)); + if(dynamic) + CompileCode.write(&FSTPV, sizeof(FSTPV)); + else + CompileCode.write(&FSTPSV, sizeof(FSTPSV)); } char typel=(char)type; CompileCode.write(&typel, sizeof(typel)); @@ -487,35 +491,41 @@ VariableNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_ //cout << "Parameter=" << tsid << "\n"; i = tsid; CompileCode.write(reinterpret_cast<char *>(&i), sizeof(i)); -#ifdef DEBUGC - cout << "FLD Param[ " << i << ", symb_id=" << symb_id << "]\n"; -#endif break; case eEndogenous : //cout << "Endogenous=" << symb_id << "\n"; i = tsid;//symb_id; CompileCode.write(reinterpret_cast<char *>(&i), sizeof(i)); - lagl=lag; - CompileCode.write(reinterpret_cast<char *>(&lagl), sizeof(lagl)); + if(dynamic) + { + lagl=lag; + CompileCode.write(reinterpret_cast<char *>(&lagl), sizeof(lagl)); + } break; case eExogenous : //cout << "Exogenous=" << tsid << "\n"; i = tsid; CompileCode.write(reinterpret_cast<char *>(&i), sizeof(i)); - lagl=lag; - CompileCode.write(reinterpret_cast<char *>(&lagl), sizeof(lagl)); + if(dynamic) + { + lagl=lag; + CompileCode.write(reinterpret_cast<char *>(&lagl), sizeof(lagl)); + } break; case eExogenousDet: i = tsid + datatree.symbol_table.exo_nbr(); //cout << "ExogenousDet=" << i << "\n"; CompileCode.write(reinterpret_cast<char *>(&i), sizeof(i)); - lagl=lag; - CompileCode.write(reinterpret_cast<char *>(&lagl), sizeof(lagl)); + if(dynamic) + { + lagl=lag; + CompileCode.write(reinterpret_cast<char *>(&lagl), sizeof(lagl)); + } break; case eModelLocalVariable: case eModFileLocalVariable: //cout << "eModelLocalVariable=" << symb_id << "\n"; - datatree.local_variables_table[symb_id]->compile(CompileCode, lhs_rhs, temporary_terms, map_idx); + datatree.local_variables_table[symb_id]->compile(CompileCode, lhs_rhs, temporary_terms, map_idx, dynamic); break; case eUnknownFunction: cerr << "Impossible case: eUnknownFuncion" << endl; @@ -545,22 +555,22 @@ VariableNode::collectVariables(SymbolType type_arg, set<pair<int, int> > &result datatree.local_variables_table[symb_id]->collectVariables(type_arg, result); } -pair<bool, NodeID> -VariableNode::normalizeLinearInEndoEquation(int var_endo, NodeID Derivative) const +pair<int, NodeID> +VariableNode::normalizeEquation(int var_endo, vector<pair<int, pair<NodeID, NodeID> > > &List_of_Op_RHS) const { if (type ==eEndogenous) { if (datatree.symbol_table.getTypeSpecificID(symb_id)==var_endo && lag==0) - return(make_pair(true, (NodeID)NULL)); + return(make_pair(1, (NodeID)NULL )); else - return(make_pair(false, datatree.AddVariableInternal(datatree.symbol_table.getName(symb_id), lag))); + return(make_pair(0, datatree.AddVariableInternal(datatree.symbol_table.getName(symb_id), lag) )); } else { if (type == eParameter) - return(make_pair(false, datatree.AddVariableInternal(datatree.symbol_table.getName(symb_id), 0))); + return(make_pair(0, datatree.AddVariableInternal(datatree.symbol_table.getName(symb_id), 0) )); else - return(make_pair(false, datatree.AddVariableInternal(datatree.symbol_table.getName(symb_id), lag))); + return(make_pair(0, datatree.AddVariableInternal(datatree.symbol_table.getName(symb_id), lag) )); } } @@ -581,9 +591,19 @@ VariableNode::getChainRuleDerivative(int deriv_id_arg, const map<int, NodeID> &r map<int, NodeID>::const_iterator it = recursive_variables.find(deriv_id); if (it != recursive_variables.end()) { - map<int, NodeID> recursive_vars2(recursive_variables); - recursive_vars2.erase(it->first); - return datatree.AddUMinus(it->second->getChainRuleDerivative(deriv_id_arg, recursive_vars2)); + map<int, NodeID>::const_iterator it2 = derivatives.find(deriv_id_arg); + if (it2 != derivatives.end()) + return it2->second; + else + { + map<int, NodeID> recursive_vars2(recursive_variables); + recursive_vars2.erase(it->first); + //NodeID c = datatree.AddNumConstant("1"); + NodeID d = datatree.AddUMinus(it->second->getChainRuleDerivative(deriv_id_arg, recursive_vars2)); + //d = datatree.AddTimes(c, d); + derivatives[deriv_id_arg] = d; + return d; + } } else return datatree.Zero; @@ -997,17 +1017,20 @@ UnaryOpNode::eval(const eval_context_type &eval_context) const throw (EvalExcept } void -UnaryOpNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const +UnaryOpNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic) const { temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<UnaryOpNode *>(this)); if (it != temporary_terms.end()) { - CompileCode.write(&FLDT, sizeof(FLDT)); + if(dynamic) + CompileCode.write(&FLDT, sizeof(FLDT)); + else + CompileCode.write(&FLDST, sizeof(FLDST)); int var=map_idx[idx]; CompileCode.write(reinterpret_cast<char *>(&var), sizeof(var)); return; } - arg->compile(CompileCode, lhs_rhs, temporary_terms, map_idx); + arg->compile(CompileCode, lhs_rhs, temporary_terms, map_idx, dynamic); CompileCode.write(&FUNARY, sizeof(FUNARY)); UnaryOpcode op_codel=op_code; CompileCode.write(reinterpret_cast<char *>(&op_codel), sizeof(op_codel)); @@ -1019,53 +1042,101 @@ UnaryOpNode::collectVariables(SymbolType type_arg, set<pair<int, int> > &result) arg->collectVariables(type_arg, result); } -pair<bool, NodeID> -UnaryOpNode::normalizeLinearInEndoEquation(int var_endo, NodeID Derivative) const +pair<int, NodeID> +UnaryOpNode::normalizeEquation(int var_endo, vector<pair<int, pair<NodeID, NodeID> > > &List_of_Op_RHS) const { - pair<bool, NodeID> res = arg->normalizeLinearInEndoEquation(var_endo, Derivative); - bool is_endogenous_present = res.first; + pair<bool, NodeID > res = arg->normalizeEquation(var_endo, List_of_Op_RHS); + int is_endogenous_present = res.first; NodeID New_NodeID = res.second; - if (!is_endogenous_present) + /*if(res.second.second)*/ + if(is_endogenous_present==2) + return(make_pair(2, (NodeID)NULL)); + else if (is_endogenous_present) + { + switch (op_code) + { + case oUminus: + List_of_Op_RHS.push_back(make_pair(oUminus, make_pair((NodeID)NULL, (NodeID)NULL))); + return(make_pair(1, (NodeID)NULL)); + case oExp: + List_of_Op_RHS.push_back(make_pair(oLog, make_pair((NodeID)NULL, (NodeID)NULL))); + return(make_pair(1, (NodeID)NULL)); + case oLog: + List_of_Op_RHS.push_back(make_pair(oExp, make_pair((NodeID)NULL, (NodeID)NULL))); + return(make_pair(1, (NodeID)NULL)); + case oLog10: + List_of_Op_RHS.push_back(make_pair(oPower, make_pair((NodeID)NULL, datatree.AddNumConstant("10")))); + return(make_pair(1, (NodeID)NULL)); + case oCos: + return(make_pair(1, (NodeID)NULL)); + case oSin: + return(make_pair(1, (NodeID)NULL)); + case oTan: + return(make_pair(1, (NodeID)NULL)); + case oAcos: + return(make_pair(1, (NodeID)NULL)); + case oAsin: + return(make_pair(1, (NodeID)NULL)); + case oAtan: + return(make_pair(1, (NodeID)NULL)); + case oCosh: + return(make_pair(1, (NodeID)NULL)); + case oSinh: + return(make_pair(1, (NodeID)NULL)); + case oTanh: + return(make_pair(1, (NodeID)NULL)); + case oAcosh: + return(make_pair(1, (NodeID)NULL)); + case oAsinh: + return(make_pair(1, (NodeID)NULL)); + case oAtanh: + return(make_pair(1, (NodeID)NULL)); + case oSqrt: + List_of_Op_RHS.push_back(make_pair(oPower, make_pair((NodeID)NULL, datatree.AddNumConstant("2")))); + return(make_pair(1, (NodeID)NULL)); + } + } + else { switch (op_code) { case oUminus: - return(make_pair(false, /*tmp_*/datatree.AddUMinus(New_NodeID))); + return(make_pair(0, datatree.AddUMinus(New_NodeID))); case oExp: - return(make_pair(false, /*tmp_*/datatree.AddExp(New_NodeID))); + return(make_pair(0, datatree.AddExp(New_NodeID))); case oLog: - return(make_pair(false, /*tmp_*/datatree.AddLog(New_NodeID))); + return(make_pair(0, datatree.AddLog(New_NodeID))); case oLog10: - return(make_pair(false, /*tmp_*/datatree.AddLog10(New_NodeID))); + return(make_pair(0, datatree.AddLog10(New_NodeID))); case oCos: - return(make_pair(false, /*tmp_*/datatree.AddCos(New_NodeID))); + return(make_pair(0, datatree.AddCos(New_NodeID))); case oSin: - return(make_pair(false, /*tmp_*/datatree.AddSin(New_NodeID))); + return(make_pair(0, datatree.AddSin(New_NodeID))); case oTan: - return(make_pair(false, /*tmp_*/datatree.AddTan(New_NodeID))); + return(make_pair(0, datatree.AddTan(New_NodeID))); case oAcos: - return(make_pair(false, /*tmp_*/datatree.AddAcos(New_NodeID))); + return(make_pair(0, datatree.AddAcos(New_NodeID))); case oAsin: - return(make_pair(false, /*tmp_*/datatree.AddAsin(New_NodeID))); + return(make_pair(0, datatree.AddAsin(New_NodeID))); case oAtan: - return(make_pair(false, /*tmp_*/datatree.AddAtan(New_NodeID))); + return(make_pair(0, datatree.AddAtan(New_NodeID))); case oCosh: - return(make_pair(false, /*tmp_*/datatree.AddCosh(New_NodeID))); + return(make_pair(0, datatree.AddCosh(New_NodeID))); case oSinh: - return(make_pair(false, /*tmp_*/datatree.AddSinh(New_NodeID))); + return(make_pair(0, datatree.AddSinh(New_NodeID))); case oTanh: - return(make_pair(false, /*tmp_*/datatree.AddTanh(New_NodeID))); + return(make_pair(0, datatree.AddTanh(New_NodeID))); case oAcosh: - return(make_pair(false, /*tmp_*/datatree.AddAcosh(New_NodeID))); + return(make_pair(0, datatree.AddAcosh(New_NodeID))); case oAsinh: - return(make_pair(false, /*tmp_*/datatree.AddAsinh(New_NodeID))); + return(make_pair(0, datatree.AddAsinh(New_NodeID))); case oAtanh: - return(make_pair(false, /*tmp_*/datatree.AddAtanh(New_NodeID))); + return(make_pair(0, datatree.AddAtanh(New_NodeID))); case oSqrt: - return(make_pair(false, /*tmp_*/datatree.AddSqrt(New_NodeID))); + return(make_pair(0, datatree.AddSqrt(New_NodeID))); } } - return(make_pair(true, (NodeID)NULL)); + return(make_pair(1, (NodeID)NULL)); } @@ -1435,19 +1506,22 @@ BinaryOpNode::eval(const eval_context_type &eval_context) const throw (EvalExcep } void -BinaryOpNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const +BinaryOpNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic) const { // If current node is a temporary term temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<BinaryOpNode *>(this)); if (it != temporary_terms.end()) { - CompileCode.write(&FLDT, sizeof(FLDT)); + if(dynamic) + CompileCode.write(&FLDT, sizeof(FLDT)); + else + CompileCode.write(&FLDST, sizeof(FLDST)); int var=map_idx[idx]; CompileCode.write(reinterpret_cast<char *>(&var), sizeof(var)); return; } - arg1->compile(CompileCode, lhs_rhs, temporary_terms, map_idx); - arg2->compile(CompileCode, lhs_rhs, temporary_terms, map_idx); + arg1->compile(CompileCode, lhs_rhs, temporary_terms, map_idx, dynamic); + arg2->compile(CompileCode, lhs_rhs, temporary_terms, map_idx, dynamic); CompileCode.write(&FBINARY, sizeof(FBINARY)); BinaryOpcode op_codel=op_code; CompileCode.write(reinterpret_cast<char *>(&op_codel),sizeof(op_codel)); @@ -1636,129 +1710,272 @@ BinaryOpNode::collectVariables(SymbolType type_arg, set<pair<int, int> > &result arg2->collectVariables(type_arg, result); } -pair<bool, NodeID> -BinaryOpNode::normalizeLinearInEndoEquation(int var_endo, NodeID Derivative) const +NodeID +BinaryOpNode::Compute_RHS(NodeID arg1, NodeID arg2, int op, int op_type) const +{ + temporary_terms_type temp; + switch(op_type) + { + case 0: /*Unary Operator*/ + switch(op) + { + case oUminus: + return(datatree.AddUMinus(arg1)); + break; + case oExp: + return(datatree.AddExp(arg1)); + break; + case oLog: + return(datatree.AddLog(arg1)); + break; + case oLog10: + return(datatree.AddLog10(arg1)); + break; + } + break; + case 1: /*Binary Operator*/ + switch(op) + { + case oPlus: + return(datatree.AddPlus(arg1, arg2)); + break; + case oMinus: + return(datatree.AddMinus(arg1, arg2)); + break; + case oTimes: + return(datatree.AddTimes(arg1, arg2)); + break; + case oDivide: + return(datatree.AddDivide(arg1, arg2)); + break; + case oPower: + return(datatree.AddPower(arg1, arg2)); + break; + } + break; + } + return((NodeID)NULL); +} + +pair<int, NodeID> +BinaryOpNode::normalizeEquation(int var_endo, vector<pair<int, pair<NodeID, NodeID> > > &List_of_Op_RHS) const { - pair<bool, NodeID> res = arg1->normalizeLinearInEndoEquation(var_endo, Derivative); - bool is_endogenous_present_1 = res.first; - NodeID NodeID_1 = res.second; - res = arg2->normalizeLinearInEndoEquation(var_endo, Derivative); - bool is_endogenous_present_2 = res.first; - NodeID NodeID_2 = res.second; + vector<pair<int, pair<NodeID, NodeID> > > List_of_Op_RHS1, List_of_Op_RHS2; + int is_endogenous_present_1, is_endogenous_present_2; + pair<int, NodeID> res; + NodeID NodeID_1, NodeID_2; + res = arg1->normalizeEquation(var_endo, List_of_Op_RHS1); + is_endogenous_present_1 = res.first; + NodeID_1 = res.second; + + res = arg2->normalizeEquation(var_endo, List_of_Op_RHS2); + is_endogenous_present_2 = res.first; + NodeID_2 = res.second; + if(is_endogenous_present_1==2 || is_endogenous_present_2==2) + return(make_pair(2,(NodeID)NULL)); + else if(is_endogenous_present_1 && is_endogenous_present_2) + return(make_pair(2,(NodeID)NULL)); + else if(is_endogenous_present_1) + { + if(op_code==oEqual) + { + pair<int, pair<NodeID, NodeID> > it; + int oo=List_of_Op_RHS1.size(); + for(int i=0;i<oo;i++) + { + it = List_of_Op_RHS1.back(); + List_of_Op_RHS1.pop_back(); + if(it.second.first && !it.second.second) /*Binary operator*/ + NodeID_2 = Compute_RHS(NodeID_2, (BinaryOpNode*)it.second.first, it.first, 1); + else if(it.second.second && !it.second.first) /*Binary operator*/ + NodeID_2 = Compute_RHS(it.second.second, NodeID_2, it.first, 1); + else if(it.second.second && it.second.first) /*Binary operator*/ + NodeID_2 = Compute_RHS(it.second.first, it.second.second, it.first, 1); + else /*Unary operator*/ + NodeID_2 = Compute_RHS((UnaryOpNode*)NodeID_2, (UnaryOpNode*)it.second.first, it.first, 0); + } + } + else + List_of_Op_RHS = List_of_Op_RHS1; + } + else if(is_endogenous_present_2) + { + if(op_code==oEqual) + { + int oo=List_of_Op_RHS2.size(); + for(int i=0;i<oo;i++) + { + pair<int, pair<NodeID, NodeID> > it; + it = List_of_Op_RHS2.back(); + List_of_Op_RHS2.pop_back(); + if(it.second.first && !it.second.second) /*Binary operator*/ + NodeID_1 = Compute_RHS((BinaryOpNode*)NodeID_1, (BinaryOpNode*)it.second.first, it.first, 1); + else if(it.second.second && !it.second.first) /*Binary operator*/ + NodeID_1 = Compute_RHS((BinaryOpNode*)it.second.second, (BinaryOpNode*)NodeID_1, it.first, 1); + else if(it.second.second && it.second.first) /*Binary operator*/ + NodeID_1 = Compute_RHS(it.second.first, it.second.second, it.first, 1); + else + NodeID_1 = Compute_RHS((UnaryOpNode*)NodeID_1, (UnaryOpNode*)it.second.first, it.first, 0); + } + } + else + List_of_Op_RHS =List_of_Op_RHS2; + } switch (op_code) { case oPlus: if (!is_endogenous_present_1 && !is_endogenous_present_2) - return(make_pair(false, /*tmp_*/datatree.AddPlus(NodeID_1, NodeID_2))); + { + List_of_Op_RHS.push_back(make_pair(oMinus, make_pair(datatree.AddPlus(NodeID_1, NodeID_2), (NodeID)NULL))); + return(make_pair(0, datatree.AddPlus(NodeID_1, NodeID_2))); + } else if (is_endogenous_present_1 && is_endogenous_present_2) - return(make_pair(true, (NodeID)NULL)); + return(make_pair(1, (NodeID)NULL)); else if (!is_endogenous_present_1 && is_endogenous_present_2) - return(make_pair(false, NodeID_1)); + { + List_of_Op_RHS.push_back(make_pair(oMinus, make_pair(NodeID_1, (NodeID)NULL))); + return(make_pair(1, NodeID_1)); + } else if (is_endogenous_present_1 && !is_endogenous_present_2) - return(make_pair(false, NodeID_2)); + { + List_of_Op_RHS.push_back(make_pair(oMinus, make_pair(NodeID_2, (NodeID)NULL) )); + return(make_pair(1, NodeID_2)); + } break; case oMinus: if (!is_endogenous_present_1 && !is_endogenous_present_2) - return(make_pair(false, /*tmp_*/datatree.AddMinus(NodeID_1, NodeID_2))); + { + List_of_Op_RHS.push_back(make_pair(oMinus, make_pair(datatree.AddMinus(NodeID_1, NodeID_2), (NodeID)NULL) )); + return(make_pair(0, datatree.AddMinus(NodeID_1, NodeID_2))); + } else if (is_endogenous_present_1 && is_endogenous_present_2) - return(make_pair(true, (NodeID)NULL)); + return(make_pair(1, (NodeID)NULL)); else if (!is_endogenous_present_1 && is_endogenous_present_2) - return(make_pair(false, NodeID_1)); + { + List_of_Op_RHS.push_back(make_pair(oUminus, make_pair((NodeID)NULL, (NodeID)NULL))); + List_of_Op_RHS.push_back(make_pair(oMinus, make_pair(NodeID_1, (NodeID)NULL) )); + return(make_pair(1, NodeID_1)); + } else if (is_endogenous_present_1 && !is_endogenous_present_2) - return(make_pair(false, /*tmp_*/datatree.AddUMinus(NodeID_2))); + { + List_of_Op_RHS.push_back(make_pair(oPlus, make_pair(NodeID_2, (NodeID) NULL) )); + return(make_pair(1, datatree.AddUMinus(NodeID_2))); + } break; case oTimes: if (!is_endogenous_present_1 && !is_endogenous_present_2) - return(make_pair(false, /*tmp_*/datatree.AddTimes(NodeID_1, NodeID_2))); + return(make_pair(0, datatree.AddTimes(NodeID_1, NodeID_2))); + else if(!is_endogenous_present_1 && is_endogenous_present_2) + { + List_of_Op_RHS.push_back(make_pair(oDivide, make_pair(NodeID_1, (NodeID)NULL) )); + return(make_pair(1, NodeID_1)); + } + else if(is_endogenous_present_1 && !is_endogenous_present_2) + { + List_of_Op_RHS.push_back(make_pair(oDivide, make_pair(NodeID_2, (NodeID)NULL) )); + return(make_pair(1, NodeID_2)); + } else - return(make_pair(true, (NodeID)NULL)); + return(make_pair(1, (NodeID)NULL)); break; case oDivide: if (!is_endogenous_present_1 && !is_endogenous_present_2) - return(make_pair(false, datatree.AddDivide(NodeID_1, NodeID_2))); + return(make_pair(0, datatree.AddDivide(NodeID_1, NodeID_2))); + else if(!is_endogenous_present_1 && is_endogenous_present_2) + { + List_of_Op_RHS.push_back(make_pair(oDivide, make_pair((NodeID)NULL, NodeID_1) )); + return(make_pair(1, NodeID_1)); + } + else if(is_endogenous_present_1 && !is_endogenous_present_2) + { + List_of_Op_RHS.push_back(make_pair(oTimes, make_pair(NodeID_2, (NodeID)NULL) )); + return(make_pair(1, NodeID_2)); + } else - return(make_pair(true, (NodeID)NULL)); + return(make_pair(1, (NodeID)NULL)); break; case oPower: if (!is_endogenous_present_1 && !is_endogenous_present_2) - return(make_pair(false, datatree.AddPower(NodeID_1, NodeID_2))); - else - return(make_pair(true, (NodeID)NULL)); + return(make_pair(0, datatree.AddPower(NodeID_1, NodeID_2))); + else if(is_endogenous_present_1 && !is_endogenous_present_2) + { + List_of_Op_RHS.push_back(make_pair(oPower, make_pair(datatree.AddDivide( datatree.AddNumConstant("1"), NodeID_2), (NodeID)NULL) )); + return(make_pair(1, (NodeID)NULL)); + } break; case oEqual: if (!is_endogenous_present_1 && !is_endogenous_present_2) { - if (Derivative!=datatree.One) - return( make_pair(false, datatree.AddEqual(datatree.AddVariable(datatree.symbol_table.getName(datatree.symbol_table.getID(eEndogenous, var_endo)), 0), datatree.AddDivide(datatree.AddMinus(NodeID_2, NodeID_1), Derivative))) ); - else - return( make_pair(false, datatree.AddEqual(datatree.AddVariable(datatree.symbol_table.getName(datatree.symbol_table.getID(eEndogenous, var_endo)), 0), datatree.AddMinus(NodeID_2, NodeID_1))) ); + return( make_pair(0, + datatree.AddEqual(datatree.AddVariable(datatree.symbol_table.getName(datatree.symbol_table.getID(eEndogenous, var_endo)), 0), datatree.AddMinus(NodeID_2, NodeID_1)) + )); } else if (is_endogenous_present_1 && is_endogenous_present_2) { - return(make_pair(false, datatree.AddEqual(datatree.AddVariable(datatree.symbol_table.getName(datatree.symbol_table.getID(eEndogenous, var_endo)), 0), datatree.Zero))); + return(make_pair(0, + datatree.AddEqual(datatree.AddVariable(datatree.symbol_table.getName(datatree.symbol_table.getID(eEndogenous, var_endo)), 0), datatree.Zero) + )); } else if (!is_endogenous_present_1 && is_endogenous_present_2) { - if (Derivative!=datatree.One) - return(make_pair(false, datatree.AddEqual(datatree.AddVariable(datatree.symbol_table.getName(datatree.symbol_table.getID(eEndogenous, var_endo)), 0), datatree.AddDivide(datatree.AddUMinus(NodeID_1), Derivative)))); - else - return(make_pair(false, datatree.AddEqual(datatree.AddVariable(datatree.symbol_table.getName(datatree.symbol_table.getID(eEndogenous, var_endo)), 0), datatree.AddUMinus(NodeID_1)))); + return(make_pair(0, + datatree.AddEqual(datatree.AddVariable(datatree.symbol_table.getName(datatree.symbol_table.getID(eEndogenous, var_endo)), 0), /*datatree.AddUMinus(NodeID_1)*/NodeID_1) + )); } else if (is_endogenous_present_1 && !is_endogenous_present_2) { - if (Derivative!=datatree.One) - return(make_pair(false, datatree.AddEqual(datatree.AddVariable(datatree.symbol_table.getName(datatree.symbol_table.getID(eEndogenous, var_endo)), 0), datatree.AddDivide(NodeID_2, Derivative)))); - else - return(make_pair(false, datatree.AddEqual(datatree.AddVariable(datatree.symbol_table.getName(datatree.symbol_table.getID(eEndogenous, var_endo)), 0), NodeID_2))); + return(make_pair(0, + datatree.AddEqual(datatree.AddVariable(datatree.symbol_table.getName(datatree.symbol_table.getID(eEndogenous, var_endo)), 0), NodeID_2) + )); } break; case oMax: if (!is_endogenous_present_1 && !is_endogenous_present_2) - return(make_pair(false, datatree.AddMax(NodeID_1, NodeID_2))); + return(make_pair(0, datatree.AddMax(NodeID_1, NodeID_2) )); else - return(make_pair(true, (NodeID)NULL)); + return(make_pair(1, (NodeID)NULL )); break; case oMin: if (!is_endogenous_present_1 && !is_endogenous_present_2) - return(make_pair(false, datatree.AddMin(NodeID_1, NodeID_2))); + return(make_pair(0, datatree.AddMin(NodeID_1, NodeID_2) )); else - return(make_pair(true, (NodeID)NULL)); + return(make_pair(1, (NodeID)NULL )); break; case oLess: if (!is_endogenous_present_1 && !is_endogenous_present_2) - return(make_pair(false, /*tmp_*/datatree.AddLess(NodeID_1, NodeID_2))); + return(make_pair(0, datatree.AddLess(NodeID_1, NodeID_2) )); else - return(make_pair(true, (NodeID)NULL)); + return(make_pair(1, (NodeID)NULL )); break; case oGreater: if (!is_endogenous_present_1 && !is_endogenous_present_2) - return(make_pair(false, /*tmp_*/datatree.AddGreater(NodeID_1, NodeID_2))); + return(make_pair(0, datatree.AddGreater(NodeID_1, NodeID_2) )); else - return(make_pair(true, (NodeID)NULL)); + return(make_pair(1, (NodeID)NULL )); break; case oLessEqual: if (!is_endogenous_present_1 && !is_endogenous_present_2) - return(make_pair(false, /*tmp_*/datatree.AddLessEqual(NodeID_1, NodeID_2))); + return(make_pair(0, datatree.AddLessEqual(NodeID_1, NodeID_2) )); else - return(make_pair(true, (NodeID)NULL)); + return(make_pair(1, (NodeID)NULL )); break; case oGreaterEqual: if (!is_endogenous_present_1 && !is_endogenous_present_2) - return(make_pair(false, /*tmp_*/datatree.AddGreaterEqual(NodeID_1, NodeID_2))); + return(make_pair(0, datatree.AddGreaterEqual(NodeID_1, NodeID_2) )); else - return(make_pair(true, (NodeID)NULL)); + return(make_pair(1, (NodeID)NULL )); break; case oEqualEqual: if (!is_endogenous_present_1 && !is_endogenous_present_2) - return(make_pair(false, /*tmp_*/datatree.AddEqualEqual(NodeID_1, NodeID_2))); + return(make_pair(0, datatree.AddEqualEqual(NodeID_1, NodeID_2) )); else - return(make_pair(true, (NodeID)NULL)); + return(make_pair(1, (NodeID)NULL )); break; case oDifferent: if (!is_endogenous_present_1 && !is_endogenous_present_2) - return(make_pair(false, /*tmp_*/datatree.AddDifferent(NodeID_1, NodeID_2))); + return(make_pair(0, datatree.AddDifferent(NodeID_1, NodeID_2) )); else - return(make_pair(true, (NodeID)NULL)); + return(make_pair(1, (NodeID)NULL )); break; } // Suppress GCC warning @@ -2023,20 +2240,23 @@ TrinaryOpNode::eval(const eval_context_type &eval_context) const throw (EvalExce } void -TrinaryOpNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const +TrinaryOpNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic) const { // If current node is a temporary term temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<TrinaryOpNode *>(this)); if (it != temporary_terms.end()) { - CompileCode.write(&FLDT, sizeof(FLDT)); + if(dynamic) + CompileCode.write(&FLDT, sizeof(FLDT)); + else + CompileCode.write(&FLDST, sizeof(FLDST)); int var=map_idx[idx]; CompileCode.write(reinterpret_cast<char *>(&var), sizeof(var)); return; } - arg1->compile(CompileCode, lhs_rhs, temporary_terms, map_idx); - arg2->compile(CompileCode, lhs_rhs, temporary_terms, map_idx); - arg3->compile(CompileCode, lhs_rhs, temporary_terms, map_idx); + arg1->compile(CompileCode, lhs_rhs, temporary_terms, map_idx, dynamic); + arg2->compile(CompileCode, lhs_rhs, temporary_terms, map_idx, dynamic); + arg3->compile(CompileCode, lhs_rhs, temporary_terms, map_idx, dynamic); CompileCode.write(&FBINARY, sizeof(FBINARY)); TrinaryOpcode op_codel=op_code; CompileCode.write(reinterpret_cast<char *>(&op_codel),sizeof(op_codel)); @@ -2094,22 +2314,22 @@ TrinaryOpNode::collectVariables(SymbolType type_arg, set<pair<int, int> > &resul arg3->collectVariables(type_arg, result); } -pair<bool, NodeID> -TrinaryOpNode::normalizeLinearInEndoEquation(int var_endo, NodeID Derivative) const +pair<int, NodeID> +TrinaryOpNode::normalizeEquation(int var_endo, vector<pair<int, pair<NodeID, NodeID> > > &List_of_Op_RHS) const { - pair<bool, NodeID> res = arg1->normalizeLinearInEndoEquation(var_endo, Derivative); + pair<int, NodeID> res = arg1->normalizeEquation(var_endo, List_of_Op_RHS); bool is_endogenous_present_1 = res.first; NodeID NodeID_1 = res.second; - res = arg2->normalizeLinearInEndoEquation(var_endo, Derivative); + res = arg2->normalizeEquation(var_endo, List_of_Op_RHS); bool is_endogenous_present_2 = res.first; NodeID NodeID_2 = res.second; - res = arg3->normalizeLinearInEndoEquation(var_endo, Derivative); + res = arg3->normalizeEquation(var_endo, List_of_Op_RHS); bool is_endogenous_present_3 = res.first; NodeID NodeID_3 = res.second; if (!is_endogenous_present_1 && !is_endogenous_present_2 && !is_endogenous_present_3) - return(make_pair(false, /*tmp_*/datatree.AddNormcdf(NodeID_1, NodeID_2, NodeID_3))); + return(make_pair(0, datatree.AddNormcdf(NodeID_1, NodeID_2, NodeID_3) )); else - return(make_pair(true, (NodeID)NULL)); + return(make_pair(1, (NodeID)NULL )); } NodeID @@ -2226,14 +2446,14 @@ UnknownFunctionNode::eval(const eval_context_type &eval_context) const throw (Ev } void -UnknownFunctionNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const +UnknownFunctionNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic) const { cerr << "UnknownFunctionNode::compile: operation impossible!" << endl; exit(EXIT_FAILURE); } -pair<bool, NodeID> -UnknownFunctionNode::normalizeLinearInEndoEquation(int var_endo, NodeID Derivative) const +pair<int, NodeID> +UnknownFunctionNode::normalizeEquation(int var_endo, vector<pair<int, pair<NodeID, NodeID> > > &List_of_Op_RHS) const { vector<pair<bool, NodeID> > V_arguments; vector<NodeID> V_NodeID; @@ -2241,14 +2461,14 @@ UnknownFunctionNode::normalizeLinearInEndoEquation(int var_endo, NodeID Derivati for (vector<NodeID>::const_iterator it = arguments.begin(); it != arguments.end(); it++) { - V_arguments.push_back((*it)->normalizeLinearInEndoEquation(var_endo, Derivative)); + V_arguments.push_back((*it)->normalizeEquation(var_endo, List_of_Op_RHS)); present = present || V_arguments[V_arguments.size()-1].first; V_NodeID.push_back(V_arguments[V_arguments.size()-1].second); } if (!present) - return(make_pair(false, datatree.AddUnknownFunction(datatree.symbol_table.getName(symb_id), V_NodeID))); + return(make_pair(0, datatree.AddUnknownFunction(datatree.symbol_table.getName(symb_id), V_NodeID))); else - return(make_pair(true, (NodeID)NULL)); + return(make_pair(1, (NodeID)NULL )); } NodeID diff --git a/ExprNode.hh b/ExprNode.hh index cb2c751a386cef3de76c14ca8f21cbfb6dae39a3..b4d0b0505785c2c384b435146705e1fd06c7194a 100644 --- a/ExprNode.hh +++ b/ExprNode.hh @@ -94,6 +94,7 @@ class ExprNode { friend class DataTree; friend class DynamicModel; + friend class StaticDllModel; friend class ExprNodeLess; friend class NumConstNode; friend class VariableNode; @@ -200,7 +201,7 @@ public: }; virtual double eval(const eval_context_type &eval_context) const throw (EvalException) = 0; - virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const = 0; + virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic) const = 0; //! 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, @@ -208,7 +209,7 @@ public: */ virtual NodeID toStatic(DataTree &static_datatree) const = 0; //! Try to normalize an equation linear in its endogenous variable - virtual pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const = 0; + virtual pair<int, NodeID> normalizeEquation(int symb_id_endo, vector<pair<int, pair<NodeID, NodeID> > > &List_of_Op_RHS) const = 0; }; //! Object used to compare two nodes (using their indexes) @@ -234,9 +235,9 @@ public: virtual void collectVariables(SymbolType type_arg, set<pair<int, int> > &result) const; virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const; virtual double eval(const eval_context_type &eval_context) const throw (EvalException); - virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const; + virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic) const; virtual NodeID toStatic(DataTree &static_datatree) const; - virtual pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const; + virtual pair<int, NodeID> normalizeEquation(int symb_id_endo, vector<pair<int, pair<NodeID, NodeID> > > &List_of_Op_RHS) const; virtual NodeID getChainRuleDerivative(int deriv_id, const map<int, NodeID> &recursive_variables); }; @@ -264,10 +265,10 @@ public: map_idx_type &map_idx) const; virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const; virtual double eval(const eval_context_type &eval_context) const throw (EvalException); - virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const; + virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic) const; virtual NodeID toStatic(DataTree &static_datatree) const; int get_symb_id() const { return symb_id; }; - virtual pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const; + virtual pair<int, NodeID> normalizeEquation(int symb_id_endo, vector<pair<int, pair<NodeID, NodeID> > > &List_of_Op_RHS) const; virtual NodeID getChainRuleDerivative(int deriv_id, const map<int, NodeID> &recursive_variables); }; @@ -296,13 +297,13 @@ public: virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const; static double eval_opcode(UnaryOpcode op_code, double v) throw (EvalException); virtual double eval(const eval_context_type &eval_context) const throw (EvalException); - virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const; + virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic) const; //! Returns operand NodeID get_arg() const { return(arg); }; //! Returns op code UnaryOpcode get_op_code() const { return(op_code); }; virtual NodeID toStatic(DataTree &static_datatree) const; - virtual pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const; + virtual pair<int, NodeID> normalizeEquation(int symb_id_endo, vector<pair<int, pair<NodeID, NodeID> > > &List_of_Op_RHS) const; virtual NodeID getChainRuleDerivative(int deriv_id, const map<int, NodeID> &recursive_variables); }; @@ -333,7 +334,8 @@ public: virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const; static double eval_opcode(double v1, BinaryOpcode op_code, double v2) throw (EvalException); virtual double eval(const eval_context_type &eval_context) const throw (EvalException); - virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const; + virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic) const; + virtual NodeID Compute_RHS(NodeID arg1, NodeID arg2, int op, int op_type) const; //! Returns first operand NodeID get_arg1() const { return(arg1); }; //! Returns second operand @@ -341,7 +343,7 @@ public: //! Returns op code BinaryOpcode get_op_code() const { return(op_code); }; virtual NodeID toStatic(DataTree &static_datatree) const; - pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const; + virtual pair<int, NodeID> normalizeEquation(int symb_id_endo, vector<pair<int, pair<NodeID, NodeID> > > &List_of_Op_RHS) const; virtual NodeID getChainRuleDerivative(int deriv_id, const map<int, NodeID> &recursive_variables); }; @@ -373,9 +375,9 @@ public: virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const; static double eval_opcode(double v1, TrinaryOpcode op_code, double v2, double v3) throw (EvalException); virtual double eval(const eval_context_type &eval_context) const throw (EvalException); - virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const; + virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic) const; virtual NodeID toStatic(DataTree &static_datatree) const; - virtual pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const; + virtual pair<int, NodeID> normalizeEquation(int symb_id_endo, vector<pair<int, pair<NodeID, NodeID> > > &List_of_Op_RHS) const; virtual NodeID getChainRuleDerivative(int deriv_id, const map<int, NodeID> &recursive_variables); }; @@ -401,9 +403,9 @@ public: virtual void collectVariables(SymbolType type_arg, set<pair<int, int> > &result) const; virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const; virtual double eval(const eval_context_type &eval_context) const throw (EvalException); - virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const; + virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic) const; virtual NodeID toStatic(DataTree &static_datatree) const; - virtual pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const; + virtual pair<int, NodeID> normalizeEquation(int symb_id_endo, vector<pair<int, pair<NodeID, NodeID> > > &List_of_Op_RHS) const; virtual NodeID getChainRuleDerivative(int deriv_id, const map<int, NodeID> &recursive_variables); }; diff --git a/Makefile.in b/Makefile.in index a8d2af7c9cbef075de40ad50f6dea22c21d39810..6dc04bddf198c19e034955fd8002ccade599ca0c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -14,6 +14,7 @@ MAIN_OBJS = \ ComputingTasks.o \ ModelTree.o \ StaticModel.o \ + StaticDllModel.o \ DynamicModel.o \ NumericalConstants.o \ NumericalInitialization.o \ diff --git a/MinimumFeedbackSet.cc b/MinimumFeedbackSet.cc index 0be2e17a9bcf0fab4994203aef3e1cc92d41a1d8..d9d50ee20542afd05306198f7588c0b929667d0e 100644 --- a/MinimumFeedbackSet.cc +++ b/MinimumFeedbackSet.cc @@ -382,6 +382,7 @@ namespace MFS { bool something_has_been_done = true; int cut_ = 0; + feed_back_vertices.clear(); AdjacencyList_type G(G1); while (num_vertices(G) > 0) { diff --git a/ModFile.cc b/ModFile.cc index 138f3b1b665946b37c19046fd0eb5d4879a01e54..c5bb7914828ae47430f6ce92bfa9c5e385ed460f 100644 --- a/ModFile.cc +++ b/ModFile.cc @@ -25,6 +25,7 @@ ModFile::ModFile() : expressions_tree(symbol_table, num_constants), static_model(symbol_table, num_constants), + static_dll_model(symbol_table, num_constants), dynamic_model(symbol_table, num_constants), linear(false) { @@ -143,9 +144,16 @@ ModFile::computingPass(bool no_tmp_terms) if (dynamic_model.equation_number() > 0) { // Compute static model and its derivatives - dynamic_model.toStatic(static_model); - static_model.computingPass(mod_file_struct.steady_block_mfs_option, false, no_tmp_terms); - + if(mod_file_struct.steady_block_mfs_dll_option) + { + dynamic_model.toStaticDll(static_dll_model); + static_dll_model.computingPass(global_eval_context, no_tmp_terms); + } + else + { + dynamic_model.toStatic(static_model); + static_model.computingPass(mod_file_struct.steady_block_mfs_option, false, no_tmp_terms); + } // Set things to compute for dynamic model if (mod_file_struct.simul_present) @@ -228,7 +236,10 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all) const if (dynamic_model.equation_number() > 0) { dynamic_model.writeOutput(mOutputFile, basename); - static_model.writeOutput(mOutputFile); + if(mod_file_struct.steady_block_mfs_dll_option) + static_dll_model.writeOutput(mOutputFile, basename); + else + static_model.writeOutput(mOutputFile); } // Print statements @@ -248,7 +259,10 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all) const // Create static and dynamic files if (dynamic_model.equation_number() > 0) { - static_model.writeStaticFile(basename); + if(mod_file_struct.steady_block_mfs_dll_option) + static_dll_model.writeStaticFile(basename); + else + static_model.writeStaticFile(basename); dynamic_model.writeDynamicFile(basename); dynamic_model.writeParamsDerivativesFile(basename); } diff --git a/ModFile.hh b/ModFile.hh index b43f408fbb36fe5064c30fc7eca30300d6282ed1..c7f4647eca871e2bcd0da161710b82176e4db2f4 100644 --- a/ModFile.hh +++ b/ModFile.hh @@ -29,6 +29,7 @@ using namespace std; #include "NumericalConstants.hh" #include "NumericalInitialization.hh" #include "StaticModel.hh" +#include "StaticDllModel.hh" #include "DynamicModel.hh" #include "Statement.hh" @@ -46,6 +47,8 @@ public: DataTree expressions_tree; //! Static model StaticModel static_model; + //! Static Dll model + StaticDllModel static_dll_model; //! Dynamic model DynamicModel dynamic_model; //! Option linear diff --git a/ParsingDriver.cc b/ParsingDriver.cc index c3641a3308b166c5ef2135d70573b2af900c735b..fd8a2258351b24afd2fca0a51dd7e992777e3842 100644 --- a/ParsingDriver.cc +++ b/ParsingDriver.cc @@ -586,7 +586,7 @@ ParsingDriver::add_to_row(NodeID v) void ParsingDriver::steady() { - mod_file->addStatement(new SteadyStatement(options_list)); + mod_file->addStatement(new SteadyStatement(options_list, mod_file->static_dll_model.mode)); options_list.clear(); } @@ -620,7 +620,17 @@ ParsingDriver::option_num(const string &name_option, const string &opt) if ((name_option == "periods") && (mod_file->dynamic_model.mode == DynamicModel::eSparseDLLMode || mod_file->dynamic_model.mode == DynamicModel::eSparseMode)) mod_file->dynamic_model.block_triangular.periods = atoi(opt.c_str()); else if (name_option == "cutoff") - mod_file->dynamic_model.cutoff = atof(opt.c_str()); + { + mod_file->dynamic_model.cutoff = atof(opt.c_str()); + mod_file->static_dll_model.cutoff = atof(opt.c_str()); + } + else if (name_option == "mfs") + { + mod_file->dynamic_model.mfs = atoi(opt.c_str()); + mod_file->static_dll_model.mfs = atoi(opt.c_str()); + } + else if (name_option == "block_mfs_dll") + mod_file->static_dll_model.mode = (StaticDllModel::mode_t)DynamicModel::eSparseDLLMode; options_list.num_options[name_option] = opt; } diff --git a/Statement.cc b/Statement.cc index 4350af575e931385a51ece1f1d12cb4cd6add0f3..527b9af3f502009f4779d3743653155973949ed0 100644 --- a/Statement.cc +++ b/Statement.cc @@ -31,7 +31,8 @@ ModFileStructure::ModFileStructure() : bvar_density_present(false), bvar_forecast_present(false), identification_present(false), - steady_block_mfs_option(false) + steady_block_mfs_option(false), + steady_block_mfs_dll_option(false) { } diff --git a/Statement.hh b/Statement.hh index 85f7686e9b8ad6e9859b32d27c175e382b8759ea..fd519c52cf125e5d343fb4a6c8cf9ca8e97b538f 100644 --- a/Statement.hh +++ b/Statement.hh @@ -62,6 +62,8 @@ public: bool identification_present; //! Whether the option "block_mfs" is used on steady statement bool steady_block_mfs_option; + //! Whether the option "block_mfs_dll" is used on steady statement + bool steady_block_mfs_dll_option; }; class Statement