diff --git a/BlockTriangular.cc b/BlockTriangular.cc index 63fc314c..d7119571 100644 --- a/BlockTriangular.cc +++ b/BlockTriangular.cc @@ -17,7 +17,6 @@ * along with Dynare. If not, see . */ - #include #include #include @@ -38,25 +37,27 @@ using namespace std; using namespace boost; using namespace MFS; - - - -BlockTriangular::BlockTriangular(const SymbolTable &symbol_table_arg) : - symbol_table(symbol_table_arg), - normalization(symbol_table_arg), - incidencematrix(symbol_table_arg) +BlockTriangular::BlockTriangular(SymbolTable &symbol_table_arg, NumericalConstants &num_const_arg) + : symbol_table(symbol_table_arg), + //normalization(symbol_table_arg), + incidencematrix(symbol_table_arg), + num_const(num_const_arg) { bt_verbose = 0; ModelBlock = NULL; periods = 0; + Normalized_Equation = new DataTree(symbol_table, num_const); } - +BlockTriangular::~BlockTriangular() +{ + delete Normalized_Equation; +} //------------------------------------------------------------------------------ // Find the prologue and the epilogue of the model void -BlockTriangular::Prologue_Epilogue(bool* IM, int &prologue, int &epilogue, int n, vector &Index_Var_IM, vector &Index_Equ_IM, bool* IM0) +BlockTriangular::Prologue_Epilogue(bool *IM, int &prologue, int &epilogue, int n, vector &Index_Var_IM, vector &Index_Equ_IM, bool *IM0) { bool modifie = 1; int i, j, k, l = 0; @@ -65,10 +66,10 @@ BlockTriangular::Prologue_Epilogue(bool* IM, int &prologue, int &epilogue, int n while (modifie) { modifie = 0; - for (i = prologue;i < n;i++) + for (i = prologue; i < n; i++) { k = 0; - for (j = prologue;j < n;j++) + for (j = prologue; j < n; j++) { if (IM[i*n + j]) { @@ -89,10 +90,10 @@ BlockTriangular::Prologue_Epilogue(bool* IM, int &prologue, int &epilogue, int n while (modifie) { modifie = 0; - for (i = prologue;i < n - epilogue;i++) + for (i = prologue; i < n - epilogue; i++) { k = 0; - for (j = prologue;j < n - epilogue;j++) + for (j = prologue; j < n - epilogue; j++) { if (IM[j*n + i]) { @@ -110,148 +111,199 @@ 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 &Index_Equ_IM) const - { - int n = equation_number - prologue - epilogue; +{ + int n = equation_number - prologue - epilogue; + typedef adjacency_list BipartiteGraph; - typedef adjacency_list BipartiteGraph; + /* + Vertices 0 to n-1 are for endogenous (using type specific ID) + Vertices n to 2*n-1 are for equations (using equation no.) + */ + BipartiteGraph g(2 * n); + // Fill in the graph + for (int i = 0; i < n; i++) + for (int j = 0; j < n; j++) + if (IM0[(i+prologue) * equation_number+j+prologue]) + add_edge(i + n, j, g); - /* - Vertices 0 to n-1 are for endogenous (using type specific ID) - Vertices n to 2*n-1 are for equations (using equation no.) - */ - BipartiteGraph g(2 * n); - // Fill in the graph - for (int i = 0; i < n; i++) - for (int j = 0; j < n; j++) - if (IM0[(i+prologue) * equation_number+j+prologue]) - add_edge(i + n, j, g); + // Compute maximum cardinality matching + typedef vector::vertex_descriptor> mate_map_t; + mate_map_t mate_map(2*n); + bool check = checked_edmonds_maximum_cardinality_matching(g, &mate_map[0]); + //cout << "check = " << check << "\n"; + if (check) + { + // Check if all variables are normalized + mate_map_t::const_iterator it = find(mate_map.begin(), mate_map.begin() + n, graph_traits::null_vertex()); + if (it != mate_map.begin() + n) + { + if (verbose) + { + cerr << "ERROR: Could not normalize dynamic model. Variable " + << symbol_table.getName(symbol_table.getID(eEndogenous, it - mate_map.begin())) + << " is not in the maximum cardinality matching." << endl; + exit(EXIT_FAILURE); + } + return false; + } + vector Index_Equ_IM_tmp(Index_Equ_IM); + bool *SIM; + SIM = (bool *) malloc(equation_number*equation_number*sizeof(bool)); + memcpy(SIM, IM, equation_number*equation_number*sizeof(bool)); + for (int i = 0; i < n; i++) + { + Index_Equ_IM[i + prologue] = Index_Equ_IM_tmp[mate_map[i] - n + prologue]; + for (int k = 0; k < n; k++) + IM[(i+prologue)*equation_number+k +prologue] = SIM[(mate_map[i]-n+prologue)*equation_number+k +prologue]; + } + free(SIM); + } + return check; +} - // Compute maximum cardinality matching - typedef vector::vertex_descriptor> mate_map_t; - mate_map_t mate_map(2*n); - - bool check = checked_edmonds_maximum_cardinality_matching(g, &mate_map[0]); - //cout << "check = " << check << "\n"; - if (check) - { - // Check if all variables are normalized - mate_map_t::const_iterator it = find(mate_map.begin(), mate_map.begin() + n, graph_traits::null_vertex()); - if (it != mate_map.begin() + n) - { - if (verbose) - { - cerr << "ERROR: Could not normalize dynamic model. Variable " - << symbol_table.getName(symbol_table.getID(eEndogenous, it - mate_map.begin())) - << " is not in the maximum cardinality matching." << endl; - exit(EXIT_FAILURE); - } - return false; - } - vector Index_Equ_IM_tmp(Index_Equ_IM); - bool *SIM; - SIM = (bool*)malloc(equation_number*equation_number*sizeof(bool)); - memcpy(SIM, IM, equation_number*equation_number*sizeof(bool)); - for (int i = 0; i < n; i++) - { - Index_Equ_IM[i + prologue] = Index_Equ_IM_tmp[mate_map[i] - n + prologue]; - for (int k=0; k &components_set, int nb_blck_sim, int prologue, int epilogue) const +{ + int nb_endo = symbol_table.endo_nbr(); + vector variable_blck(nb_endo), equation_blck(nb_endo); + t_vtype Variable_Type(nb_endo); + for (int i = 0; i < nb_endo; i++) + { + if (i < prologue) + { + variable_blck[Index_Var_IM[i]] = i; + equation_blck[Index_Equ_IM[i]] = i; + } + else if (i < 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; + } + else + { + variable_blck[Index_Var_IM[i]] = i- (nb_endo - nb_blck_sim - prologue - epilogue); + equation_blck[Index_Equ_IM[i]] = i- (nb_endo - nb_blck_sim - prologue - epilogue); + } + //cout << "equation_blck[" << Index_Equ_IM[i] << "]=" << equation_blck[Index_Equ_IM[i]] << " variable_blck[" << Index_Var_IM[i] << "] = " << variable_blck[Index_Var_IM[i]] << "\n"; + Variable_Type[i] = make_pair(0, 0); + } + for (int k = -incidencematrix.Model_Max_Lag_Endo; k <= incidencematrix.Model_Max_Lead_Endo; k++) + { + bool *Cur_IM = incidencematrix.Get_IM(k, eEndogenous); + if (Cur_IM) + { + for (int i = 0; i < nb_endo; i++) + { + int i_1 = Index_Var_IM[i]; + for (int j = 0; j < nb_endo; j++) + { + if (Cur_IM[i_1 + Index_Equ_IM[ j] * nb_endo] and variable_blck[i_1] == equation_blck[Index_Equ_IM[ j]]) + { + if (k > Variable_Type[i_1].second) + Variable_Type[i_1] = make_pair(Variable_Type[i_1].first, k); + if (k < -Variable_Type[i_1].first) + Variable_Type[i_1] = make_pair(-k, Variable_Type[i_1].second); + } + } + } + } + } + /*for(int i = 0; i < nb_endo; i++) + cout << "Variable_Type[" << Index_Equ_IM[i] << "].first = " << Variable_Type[Index_Equ_IM[i]].first << " Variable_Type[" << Index_Equ_IM[i] << "].second=" << Variable_Type[Index_Equ_IM[i]].second << "\n";*/ + return (Variable_Type); +} void BlockTriangular::Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Block(bool *IM, int nb_var, int prologue, int epilogue, vector &Index_Equ_IM, vector &Index_Var_IM, vector > &blocks, t_etype &Equation_Type, bool verbose_) const - { - int n = nb_var - prologue - epilogue; - bool *AMp; - AMp = (bool*) malloc(n*n*sizeof(bool)); - //transforms the incidence matrix of the complet model into an adjancent matrix of the non-recursive part of the model - for (int i=prologue; i component(num_vertices(G2)), discover_time(num_vertices(G2)); + //In a first step we compute the strong components of the graph representation of the static model. + // This insures that block are dynamically recursives. + GraphvizDigraph G2 = AM_2_GraphvizDigraph(AMp, n); + vector component(num_vertices(G2)), discover_time(num_vertices(G2)); - int num = strong_components(G2, &component[0]); + int num = strong_components(G2, &component[0]); - blocks = vector >(num , make_pair(0,0)); + blocks = vector >(num, make_pair(0, 0)); - //This vector contains for each block: - // - first set = equations belonging to the block, - // - second set = the feeback variables, - // - third vector = the reordered non-feedback variables. - vector, pair, vector > > > components_set(num); + //This vector contains for each block: + // - first set = equations belonging to the block, + // - second set = the feeback variables, + // - third vector = the reordered non-feedback variables. + vector, pair, vector > > > components_set(num); - for (unsigned int i=0; i tmp_Index_Equ_IM(Index_Equ_IM), tmp_Index_Var_IM(Index_Var_IM); - int order = prologue; - bool *SIM; - SIM = (bool*)malloc(nb_var*nb_var*sizeof(bool)); - memcpy(SIM, IM, nb_var*nb_var*sizeof(bool)); + vector tmp_Index_Equ_IM(Index_Equ_IM), tmp_Index_Var_IM(Index_Var_IM); + int order = prologue; + bool *SIM; + SIM = (bool *) malloc(nb_var*nb_var*sizeof(bool)); + memcpy(SIM, IM, nb_var*nb_var*sizeof(bool)); - //Add a loop on vertices which could not be normalized => force those vvertices to belong to the feedback set - for(int i=0; i 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) + 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 - for (int i=0; i feed_back_vertices; - //Print(G); - AdjacencyList_type G1 = Minimal_set_of_feedback_vertex(feed_back_vertices, G); - property_map::type v_index = get(vertex_index, G); - components_set[i].second.first = feed_back_vertices; - blocks[i].second = feed_back_vertices.size(); - vector Reordered_Vertice; - Reordered_Vertice = Reorder_the_recursive_variables(G, feed_back_vertices); - //First we have the recursive equations conditional on feedback variables - for (vector::iterator its=Reordered_Vertice.begin();its != Reordered_Vertice.end(); its++) - { - Index_Equ_IM[order] = tmp_Index_Equ_IM[*its+prologue]; - Index_Var_IM[order] = tmp_Index_Var_IM[*its+prologue]; - order++; - } - components_set[i].second.second = Reordered_Vertice; - //Second we have the equations related to the feedback variables - for (set::iterator its=feed_back_vertices.begin();its != feed_back_vertices.end(); its++) - { - Index_Equ_IM[order] = tmp_Index_Equ_IM[v_index[vertex(*its, G)]+prologue]; - Index_Var_IM[order] = tmp_Index_Var_IM[v_index[vertex(*its, G)]+prologue]; - order++; - } - } - free(AMp); - free(SIM); - } + //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 + for (int i = 0; i < num; i++) + { + AdjacencyList_type G = GraphvizDigraph_2_AdjacencyList(G2, components_set[i].first); + set feed_back_vertices; + //Print(G); + AdjacencyList_type G1 = Minimal_set_of_feedback_vertex(feed_back_vertices, G); + property_map::type v_index = get(vertex_index, G); + components_set[i].second.first = feed_back_vertices; + blocks[i].second = feed_back_vertices.size(); + vector Reordered_Vertice; + Reordered_Vertice = Reorder_the_recursive_variables(G, feed_back_vertices); + //First we have the recursive equations conditional on feedback variables + for (vector::iterator its = Reordered_Vertice.begin(); its != Reordered_Vertice.end(); its++) + { + Index_Equ_IM[order] = tmp_Index_Equ_IM[*its+prologue]; + Index_Var_IM[order] = tmp_Index_Var_IM[*its+prologue]; + order++; + } + components_set[i].second.second = Reordered_Vertice; + //Second we have the equations related to the feedback variables + for (set::iterator its = feed_back_vertices.begin(); its != feed_back_vertices.end(); its++) + { + Index_Equ_IM[order] = tmp_Index_Equ_IM[v_index[vertex(*its, G)]+prologue]; + Index_Var_IM[order] = tmp_Index_Var_IM[v_index[vertex(*its, G)]+prologue]; + order++; + } + } + free(AMp); + free(SIM); +} void -BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, BlockType type, BlockSimulationType SimType, Model_Block * ModelBlock, t_etype &Equation_Type, int recurs_Size) +BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, BlockType type, BlockSimulationType SimType, Model_Block *ModelBlock, t_etype &Equation_Type, int recurs_Size) { int i, j, k, l, ls, m, i_1, Lead, Lag, first_count_equ, i1, li; int *tmp_size, *tmp_size_other_endo, *tmp_size_exo, *tmp_var, *tmp_endo, *tmp_other_endo, *tmp_exo, tmp_nb_other_endo, tmp_nb_exo, nb_lead_lag_endo; @@ -260,36 +312,28 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block bool *IM, OK; int Lag_Endo, Lead_Endo, Lag_Exo, Lead_Exo, Lag_Other_Endo, Lead_Other_Endo; - - cout << "Allocate Block=" << count_Block << " recurs_Size=" << recurs_Size << "\n"; ModelBlock->Periods = periods; - ModelBlock->Block_List[count_Block].is_linear=true; + ModelBlock->Block_List[count_Block].is_linear = true; ModelBlock->Block_List[count_Block].Size = size; ModelBlock->Block_List[count_Block].Type = type; ModelBlock->Block_List[count_Block].Nb_Recursives = recurs_Size; - ModelBlock->Block_List[count_Block].Temporary_InUse=new temporary_terms_inuse_type (); + ModelBlock->Block_List[count_Block].Temporary_InUse = new temporary_terms_inuse_type(); ModelBlock->Block_List[count_Block].Temporary_InUse->clear(); ModelBlock->Block_List[count_Block].Simulation_Type = SimType; - ModelBlock->Block_List[count_Block].Equation = (int*)malloc(ModelBlock->Block_List[count_Block].Size * sizeof(int)); - ModelBlock->Block_List[count_Block].Equation_Type = (EquationType*)malloc(ModelBlock->Block_List[count_Block].Size * sizeof(EquationType)); - ModelBlock->Block_List[count_Block].Equation_Type_Var = (int*)malloc(ModelBlock->Block_List[count_Block].Size * sizeof(int)); - /*cout << "ModelBlock->Block_List[" << count_Block << "].Size = " << ModelBlock->Block_List[count_Block].Size << " E_UNKNOWN=" << E_UNKNOWN << "\n"; - t_etype eType(size); - cout << "eType[0].first=" << eType[0].first << " eType[0].second=" << eType[0].second << " eType.size()=" << eType.size() << "\n"; - ModelBlock->Block_List[count_Block].Equation_Type(eType); - cout << "after that\n";*/ - ModelBlock->Block_List[count_Block].Variable = (int*)malloc(ModelBlock->Block_List[count_Block].Size * sizeof(int)); - ModelBlock->Block_List[count_Block].Temporary_Terms_in_Equation = (temporary_terms_type**)malloc(ModelBlock->Block_List[count_Block].Size * sizeof(temporary_terms_type)); - ModelBlock->Block_List[count_Block].Own_Derivative = (int*)malloc(ModelBlock->Block_List[count_Block].Size * sizeof(int)); + ModelBlock->Block_List[count_Block].Equation = (int *) malloc(ModelBlock->Block_List[count_Block].Size * sizeof(int)); + ModelBlock->Block_List[count_Block].Equation_Type = (EquationType *) malloc(ModelBlock->Block_List[count_Block].Size * sizeof(EquationType)); + ModelBlock->Block_List[count_Block].Equation_Normalized = (NodeID *) malloc(ModelBlock->Block_List[count_Block].Size * sizeof(NodeID)); + ModelBlock->Block_List[count_Block].Variable = (int *) malloc(ModelBlock->Block_List[count_Block].Size * sizeof(int)); + ModelBlock->Block_List[count_Block].Temporary_Terms_in_Equation = (temporary_terms_type **) malloc(ModelBlock->Block_List[count_Block].Size * sizeof(temporary_terms_type)); + ModelBlock->Block_List[count_Block].Own_Derivative = (int *) malloc(ModelBlock->Block_List[count_Block].Size * sizeof(int)); Lead = Lag = 0; first_count_equ = *count_Equ; - tmp_var = (int*)malloc(size * sizeof(int)); - tmp_endo = (int*)malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1) * sizeof(int)); - tmp_other_endo = (int*)malloc(symbol_table.endo_nbr() * sizeof(int)); - tmp_size = (int*)malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1) * sizeof(int)); - //cout << "tmp_size = (int*)malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1= " << incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1 << ") * sizeof(int))\n"; - tmp_size_other_endo = (int*)malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1) * sizeof(int)); - tmp_size_exo = (int*)malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1) * sizeof(int)); + tmp_var = (int *) malloc(size * sizeof(int)); + tmp_endo = (int *) malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1) * sizeof(int)); + tmp_other_endo = (int *) malloc(symbol_table.endo_nbr() * sizeof(int)); + tmp_size = (int *) malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1) * sizeof(int)); + tmp_size_other_endo = (int *) malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1) * sizeof(int)); + tmp_size_exo = (int *) malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1) * sizeof(int)); memset(tmp_size_exo, 0, (incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1)*sizeof(int)); memset(tmp_size_other_endo, 0, (incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1)*sizeof(int)); memset(tmp_size, 0, (incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1)*sizeof(int)); @@ -299,18 +343,25 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block Lag_Endo = Lead_Endo = Lag_Other_Endo = Lead_Other_Endo = Lag_Exo = Lead_Exo = 0; //Variable by variable looking for all leads and lags its occurence in each equation of the block - tmp_variable_evaluated = (bool*)malloc(symbol_table.endo_nbr()*sizeof(bool)); + tmp_variable_evaluated = (bool *) malloc(symbol_table.endo_nbr()*sizeof(bool)); memset(tmp_variable_evaluated, 0, symbol_table.endo_nbr()*sizeof(bool)); - for (i = 0;i < size;i++) + for (i = 0; i < size; i++) { - ModelBlock->Block_List[count_Block].Temporary_Terms_in_Equation[i]=new temporary_terms_type (); + ModelBlock->Block_List[count_Block].Temporary_Terms_in_Equation[i] = new temporary_terms_type(); ModelBlock->Block_List[count_Block].Temporary_Terms_in_Equation[i]->clear(); ModelBlock->Block_List[count_Block].Equation[i] = Index_Equ_IM[*count_Equ]; ModelBlock->Block_List[count_Block].Variable[i] = Index_Var_IM[*count_Equ]; ModelBlock->Block_List[count_Block].Equation_Type[i] = Equation_Type[Index_Equ_IM[*count_Equ]].first; - ModelBlock->Block_List[count_Block].Equation_Type_Var[i] = Equation_Type[Index_Equ_IM[*count_Equ]].second; + ModelBlock->Block_List[count_Block].Equation_Normalized[i] = Equation_Type[Index_Equ_IM[*count_Equ]].second; + /*if(Equation_Type[Index_Equ_IM[*count_Equ]].second) + { + temporary_terms_type temporary_terms; + cout << "Equation_Type[Index_Equ_IM[*count_Equ]].second->get_op_code()=" << Equation_Type[Index_Equ_IM[*count_Equ]].second->get_op_code() << "\n"; + cout << "ModelBlock->Block_List[" << count_Block << "].Equation_Normalized[" << i << "]->get_op_code()=" << ModelBlock->Block_List[count_Block].Equation_Normalized[i]->get_op_code() << "\n"; + ModelBlock->Block_List[count_Block].Equation_Normalized[i]->writeOutput(cout, oMatlabDynamicModelSparse, temporary_terms); + }*/ i_1 = Index_Var_IM[*count_Equ]; - for (k = -incidencematrix.Model_Max_Lag_Endo; k<=incidencematrix.Model_Max_Lead_Endo; k++) + for (k = -incidencematrix.Model_Max_Lag_Endo; k <= incidencematrix.Model_Max_Lead_Endo; k++) { Cur_IM = incidencematrix.Get_IM(k, eEndogenous); if (Cur_IM) @@ -318,7 +369,7 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block OK = false; if (k >= 0) { - for (j = 0;j < size;j++) + for (j = 0; j < size; j++) { if (Cur_IM[i_1 + Index_Equ_IM[first_count_equ + j]*symbol_table.endo_nbr()]) { @@ -337,7 +388,7 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block } else { - for (j = 0;j < size;j++) + for (j = 0; j < size; j++) { if (Cur_IM[i_1 + Index_Equ_IM[first_count_equ + j]*symbol_table.endo_nbr()]) { @@ -363,15 +414,15 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block Lead_Endo = Lead; tmp_nb_other_endo = 0; - for (i = 0;i < size;i++) + for (i = 0; i < size; i++) { - for (k = -incidencematrix.Model_Max_Lag_Endo; k<=incidencematrix.Model_Max_Lead_Endo; k++) + for (k = -incidencematrix.Model_Max_Lag_Endo; k <= incidencematrix.Model_Max_Lead_Endo; k++) { Cur_IM = incidencematrix.Get_IM(k, eEndogenous); if (Cur_IM) { i_1 = Index_Equ_IM[first_count_equ+i] * symbol_table.endo_nbr(); - for (j = 0;j < symbol_table.endo_nbr();j++) + for (j = 0; j < symbol_table.endo_nbr(); j++) if (Cur_IM[i_1 + j]) { if (!tmp_variable_evaluated[j]) @@ -379,13 +430,13 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block tmp_other_endo[j] = 1; tmp_nb_other_endo++; } - if (k>0 && k>Lead_Other_Endo) + if (k > 0 && k > Lead_Other_Endo) Lead_Other_Endo = k; - else if (k<0 && (-k)>Lag_Other_Endo) + else if (k < 0 && (-k) > Lag_Other_Endo) Lag_Other_Endo = -k; - if (k>0 && k>Lead) + if (k > 0 && k > Lead) Lead = k; - else if (k<0 && (-k)>Lag) + else if (k < 0 && (-k) > Lag) Lag = -k; tmp_size_other_endo[k+incidencematrix.Model_Max_Lag_Endo]++; } @@ -393,21 +444,20 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block } } ModelBlock->Block_List[count_Block].nb_other_endo = tmp_nb_other_endo; - ModelBlock->Block_List[count_Block].Other_Endogenous = (int*)malloc(tmp_nb_other_endo * sizeof(int)); + ModelBlock->Block_List[count_Block].Other_Endogenous = (int *) malloc(tmp_nb_other_endo * sizeof(int)); - - tmp_exo = (int*)malloc(symbol_table.exo_nbr() * sizeof(int)); + tmp_exo = (int *) malloc(symbol_table.exo_nbr() * sizeof(int)); memset(tmp_exo, 0, symbol_table.exo_nbr() * sizeof(int)); tmp_nb_exo = 0; - for (i = 0;i < size;i++) + for (i = 0; i < size; i++) { - for (k = -incidencematrix.Model_Max_Lag_Exo; k<=incidencematrix.Model_Max_Lead_Exo; k++) + for (k = -incidencematrix.Model_Max_Lag_Exo; k <= incidencematrix.Model_Max_Lead_Exo; k++) { Cur_IM = incidencematrix.Get_IM(k, eExogenous); if (Cur_IM) { i_1 = Index_Equ_IM[first_count_equ+i] * symbol_table.exo_nbr(); - for (j=0;j0 && k>Lead_Exo) + if (k > 0 && k > Lead_Exo) Lead_Exo = k; - else if (k<0 && (-k)>Lag_Exo) + else if (k < 0 && (-k) > Lag_Exo) Lag_Exo = -k; - if (k>0 && k>Lead) + if (k > 0 && k > Lead) Lead = k; - else if (k<0 && (-k)>Lag) + else if (k < 0 && (-k) > Lag) Lag = -k; tmp_size_exo[k+incidencematrix.Model_Max_Lag_Exo]++; } @@ -429,11 +479,10 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block } } - ModelBlock->Block_List[count_Block].nb_exo = tmp_nb_exo; - ModelBlock->Block_List[count_Block].Exogenous = (int*)malloc(tmp_nb_exo * sizeof(int)); + ModelBlock->Block_List[count_Block].Exogenous = (int *) malloc(tmp_nb_exo * sizeof(int)); k = 0; - for (j=0;jBlock_List[count_Block].Exogenous[k] = j; @@ -450,52 +499,52 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block ModelBlock->Block_List[count_Block].Max_Lead_Other_Endo = Lead_Other_Endo; ModelBlock->Block_List[count_Block].Max_Lag_Exo = Lag_Exo; ModelBlock->Block_List[count_Block].Max_Lead_Exo = Lead_Exo; - ModelBlock->Block_List[count_Block].IM_lead_lag = (IM_compact*)malloc((Lead + Lag + 1) * sizeof(IM_compact)); + ModelBlock->Block_List[count_Block].IM_lead_lag = (IM_compact *) malloc((Lead + Lag + 1) * sizeof(IM_compact)); ls = l = li = size; i1 = 0; ModelBlock->Block_List[count_Block].Nb_Lead_Lag_Endo = nb_lead_lag_endo; - for (i = 0;i < Lead + Lag + 1;i++) + for (i = 0; i < Lead + Lag + 1; i++) { - if (incidencematrix.Model_Max_Lag_Endo-Lag+i>=0) + if (incidencematrix.Model_Max_Lag_Endo-Lag+i >= 0) { ModelBlock->Block_List[count_Block].IM_lead_lag[i].size = tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i]; ModelBlock->Block_List[count_Block].IM_lead_lag[i].nb_endo = tmp_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i]; - ModelBlock->Block_List[count_Block].IM_lead_lag[i].u = (int*)malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int)); - ModelBlock->Block_List[count_Block].IM_lead_lag[i].us = (int*)malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int)); - ModelBlock->Block_List[count_Block].IM_lead_lag[i].Var = (int*)malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int)); - ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ = (int*)malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int)); - ModelBlock->Block_List[count_Block].IM_lead_lag[i].Var_Index = (int*)malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int)); - ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ_Index = (int*)malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int)); + ModelBlock->Block_List[count_Block].IM_lead_lag[i].u = (int *) malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int)); + ModelBlock->Block_List[count_Block].IM_lead_lag[i].us = (int *) malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int)); + ModelBlock->Block_List[count_Block].IM_lead_lag[i].Var = (int *) malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int)); + ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ = (int *) malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int)); + ModelBlock->Block_List[count_Block].IM_lead_lag[i].Var_Index = (int *) malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int)); + ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ_Index = (int *) malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int)); ModelBlock->Block_List[count_Block].IM_lead_lag[i].size_other_endo = tmp_size_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i]; ModelBlock->Block_List[count_Block].IM_lead_lag[i].nb_other_endo = tmp_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i]; - ModelBlock->Block_List[count_Block].IM_lead_lag[i].u_other_endo = (int*)malloc(tmp_size_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int)); - ModelBlock->Block_List[count_Block].IM_lead_lag[i].Var_other_endo = (int*)malloc(tmp_size_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int)); - ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ_other_endo = (int*)malloc(tmp_size_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int)); - ModelBlock->Block_List[count_Block].IM_lead_lag[i].Var_Index_other_endo = (int*)malloc(tmp_size_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int)); - ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ_Index_other_endo = (int*)malloc(tmp_size_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int)); + ModelBlock->Block_List[count_Block].IM_lead_lag[i].u_other_endo = (int *) malloc(tmp_size_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int)); + ModelBlock->Block_List[count_Block].IM_lead_lag[i].Var_other_endo = (int *) malloc(tmp_size_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int)); + ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ_other_endo = (int *) malloc(tmp_size_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int)); + ModelBlock->Block_List[count_Block].IM_lead_lag[i].Var_Index_other_endo = (int *) malloc(tmp_size_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int)); + ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ_Index_other_endo = (int *) malloc(tmp_size_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int)); } else ModelBlock->Block_List[count_Block].IM_lead_lag[i].size = 0; /*if (incidencematrix.Model_Max_Lag_Exo-Lag+i>=0) - { + { ModelBlock->Block_List[count_Block].IM_lead_lag[i].size_exo = tmp_size_exo[incidencematrix.Model_Max_Lag_Exo - Lag + i]; ModelBlock->Block_List[count_Block].IM_lead_lag[i].Exogenous = (int*)malloc(tmp_size_exo[incidencematrix.Model_Max_Lag_Exo - Lag + i] * sizeof(int)); ModelBlock->Block_List[count_Block].IM_lead_lag[i].Exogenous_Index = (int*)malloc(tmp_size_exo[incidencematrix.Model_Max_Lag_Exo - Lag + i] * sizeof(int)); ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ_X = (int*)malloc(tmp_size_exo[incidencematrix.Model_Max_Lag_Exo - Lag + i] * sizeof(int)); ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ_X_Index = (int*)malloc(tmp_size_exo[incidencematrix.Model_Max_Lag_Exo - Lag + i] * sizeof(int)); - } - else - ModelBlock->Block_List[count_Block].IM_lead_lag[i].size_exo = 0;*/ + } + else + ModelBlock->Block_List[count_Block].IM_lead_lag[i].size_exo = 0;*/ ModelBlock->Block_List[count_Block].IM_lead_lag[i].u_init = l; memset(tmp_variable_evaluated, 0, symbol_table.endo_nbr()*sizeof(bool)); IM = incidencematrix.Get_IM(i - Lag, eEndogenous); if (IM) { - for (j = first_count_equ;j < size + first_count_equ;j++) + for (j = first_count_equ; j < size + first_count_equ; j++) { i_1 = Index_Var_IM[j]; m = 0; - for (k = first_count_equ;k < size + first_count_equ;k++) + for (k = first_count_equ; k < size + first_count_equ; k++) if (IM[i_1 + Index_Equ_IM[k] * symbol_table.endo_nbr()]) m++; if (m > 0) @@ -505,10 +554,10 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block } } m = 0; - for (j = first_count_equ;j < size + first_count_equ;j++) + for (j = first_count_equ; j < size + first_count_equ; j++) { i_1 = Index_Equ_IM[j] * symbol_table.endo_nbr(); - for (k = first_count_equ;k < size + first_count_equ;k++) + for (k = first_count_equ; k < size + first_count_equ; k++) if (IM[Index_Var_IM[k] + i_1]) { if (i == Lag) @@ -529,10 +578,10 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block } ModelBlock->Block_List[count_Block].IM_lead_lag[i].u_finish = li - 1; m = 0; - for (j = first_count_equ;j < size + first_count_equ;j++) + for (j = first_count_equ; j < size + first_count_equ; j++) { i_1 = Index_Equ_IM[j] * symbol_table.endo_nbr(); - for (k = 0;k < symbol_table.endo_nbr();k++) + for (k = 0; k < symbol_table.endo_nbr(); k++) if ((!tmp_variable_evaluated[Index_Var_IM[k]]) && IM[Index_Var_IM[k] + i_1]) { ModelBlock->Block_List[count_Block].IM_lead_lag[i].u_other_endo[m] = l; @@ -547,8 +596,8 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block ModelBlock->Block_List[count_Block].IM_lead_lag[i].size_other_endo = m; } /*IM = incidencematrix.Get_IM(i - Lag, eExogenous); - if (IM) - { + if (IM) + { m = 0; for (j = first_count_equ;j < size + first_count_equ;j++) { @@ -565,7 +614,7 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block } } } - }*/ + }*/ } free(tmp_size); free(tmp_size_other_endo); @@ -577,55 +626,52 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block free(tmp_variable_evaluated); } - void -BlockTriangular::Free_Block(Model_Block* ModelBlock) const - { - int blk, i; - for (blk = 0;blk < ModelBlock->Size;blk++) - { - - - free(ModelBlock->Block_List[blk].Equation); - free(ModelBlock->Block_List[blk].Variable); - free(ModelBlock->Block_List[blk].Exogenous); - free(ModelBlock->Block_List[blk].Own_Derivative); - free(ModelBlock->Block_List[blk].Other_Endogenous); - free(ModelBlock->Block_List[blk].Equation_Type); - free(ModelBlock->Block_List[blk].Equation_Type_Var); - for (i = 0;i < ModelBlock->Block_List[blk].Max_Lag + ModelBlock->Block_List[blk].Max_Lead + 1;i++) - { - if (incidencematrix.Model_Max_Lag_Endo-ModelBlock->Block_List[blk].Max_Lag+i>=0 /*&& ModelBlock->Block_List[blk].IM_lead_lag[i].size*/) - { - free(ModelBlock->Block_List[blk].IM_lead_lag[i].u); - free(ModelBlock->Block_List[blk].IM_lead_lag[i].us); - free(ModelBlock->Block_List[blk].IM_lead_lag[i].Equ); - free(ModelBlock->Block_List[blk].IM_lead_lag[i].Var); - free(ModelBlock->Block_List[blk].IM_lead_lag[i].Equ_Index); - free(ModelBlock->Block_List[blk].IM_lead_lag[i].Var_Index); - free(ModelBlock->Block_List[blk].IM_lead_lag[i].u_other_endo); - free(ModelBlock->Block_List[blk].IM_lead_lag[i].Var_other_endo); - free(ModelBlock->Block_List[blk].IM_lead_lag[i].Equ_other_endo); - free(ModelBlock->Block_List[blk].IM_lead_lag[i].Var_Index_other_endo); - free(ModelBlock->Block_List[blk].IM_lead_lag[i].Equ_Index_other_endo); - } - /*if (incidencematrix.Model_Max_Lag_Exo-ModelBlock->Block_List[blk].Max_Lag+i>=0 ) - { - free(ModelBlock->Block_List[blk].IM_lead_lag[i].Exogenous); - free(ModelBlock->Block_List[blk].IM_lead_lag[i].Exogenous_Index); - free(ModelBlock->Block_List[blk].IM_lead_lag[i].Equ_X_Index); - free(ModelBlock->Block_List[blk].IM_lead_lag[i].Equ_X); - }*/ - } - free(ModelBlock->Block_List[blk].IM_lead_lag); - for (i=0; iBlock_List[blk].Size; i++) - delete ModelBlock->Block_List[blk].Temporary_Terms_in_Equation[i]; - free(ModelBlock->Block_List[blk].Temporary_Terms_in_Equation); - delete(ModelBlock->Block_List[blk].Temporary_InUse); - } - free(ModelBlock->Block_List); - free(ModelBlock); - } +BlockTriangular::Free_Block(Model_Block *ModelBlock) const +{ + int blk, i; + for (blk = 0; blk < ModelBlock->Size; blk++) + { + free(ModelBlock->Block_List[blk].Equation); + free(ModelBlock->Block_List[blk].Variable); + free(ModelBlock->Block_List[blk].Exogenous); + free(ModelBlock->Block_List[blk].Own_Derivative); + free(ModelBlock->Block_List[blk].Other_Endogenous); + free(ModelBlock->Block_List[blk].Equation_Type); + free(ModelBlock->Block_List[blk].Equation_Normalized); + for (i = 0; i < ModelBlock->Block_List[blk].Max_Lag + ModelBlock->Block_List[blk].Max_Lead + 1; i++) + { + if (incidencematrix.Model_Max_Lag_Endo-ModelBlock->Block_List[blk].Max_Lag+i >= 0 /*&& ModelBlock->Block_List[blk].IM_lead_lag[i].size*/) + { + free(ModelBlock->Block_List[blk].IM_lead_lag[i].u); + free(ModelBlock->Block_List[blk].IM_lead_lag[i].us); + free(ModelBlock->Block_List[blk].IM_lead_lag[i].Equ); + free(ModelBlock->Block_List[blk].IM_lead_lag[i].Var); + free(ModelBlock->Block_List[blk].IM_lead_lag[i].Equ_Index); + free(ModelBlock->Block_List[blk].IM_lead_lag[i].Var_Index); + free(ModelBlock->Block_List[blk].IM_lead_lag[i].u_other_endo); + free(ModelBlock->Block_List[blk].IM_lead_lag[i].Var_other_endo); + free(ModelBlock->Block_List[blk].IM_lead_lag[i].Equ_other_endo); + free(ModelBlock->Block_List[blk].IM_lead_lag[i].Var_Index_other_endo); + free(ModelBlock->Block_List[blk].IM_lead_lag[i].Equ_Index_other_endo); + } + /*if (incidencematrix.Model_Max_Lag_Exo-ModelBlock->Block_List[blk].Max_Lag+i>=0 ) + { + free(ModelBlock->Block_List[blk].IM_lead_lag[i].Exogenous); + free(ModelBlock->Block_List[blk].IM_lead_lag[i].Exogenous_Index); + free(ModelBlock->Block_List[blk].IM_lead_lag[i].Equ_X_Index); + free(ModelBlock->Block_List[blk].IM_lead_lag[i].Equ_X); + }*/ + } + free(ModelBlock->Block_List[blk].IM_lead_lag); + for (i = 0; i < ModelBlock->Block_List[blk].Size; i++) + delete ModelBlock->Block_List[blk].Temporary_Terms_in_Equation[i]; + free(ModelBlock->Block_List[blk].Temporary_Terms_in_Equation); + delete (ModelBlock->Block_List[blk].Temporary_InUse); + } + free(ModelBlock->Block_List); + free(ModelBlock); +} t_etype BlockTriangular::Equation_Type_determination(vector &equations, map, NodeID> &first_cur_endo_derivatives, vector &Index_Var_IM, vector &Index_Equ_IM) @@ -637,7 +683,7 @@ BlockTriangular::Equation_Type_determination(vector &equations, temporary_terms_type temporary_terms; EquationType Equation_Simulation_Type; t_etype V_Equation_Simulation_Type(equations.size()); - for(unsigned int i = 0; i < equations.size(); i++) + for (unsigned int i = 0; i < equations.size(); i++) { temporary_terms.clear(); int eq = Index_Equ_IM[i]; @@ -646,59 +692,57 @@ BlockTriangular::Equation_Type_determination(vector &equations, lhs = eq_node->get_arg1(); rhs = eq_node->get_arg2(); Equation_Simulation_Type = E_SOLVE; - int Var_To_Derivate = -1; tmp_s.str(""); tmp_output.str(""); lhs->writeOutput(tmp_output, oMatlabDynamicModelSparse, temporary_terms); tmp_s << "y(it_, " << Index_Var_IM[i]+1 << ")"; map, NodeID>::iterator derivative = first_cur_endo_derivatives.find(make_pair(eq, var)); + /*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 > result; - //result.clear(); + pair res; derivative->second->collectEndogenous(result); + /*for(set >::const_iterator iitt = result.begin(); iitt!=result.end(); iitt++) + cout << "result = " << iitt->first << ", " << iitt->second << "\n";*/ set >::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()) - Equation_Simulation_Type = E_EVALUATE; + { + Equation_Simulation_Type = E_EVALUATE; + } else - { //the equation could be normalized by a permutation of the rhs and the lhs - tmp_output.str(""); - rhs->writeOutput(tmp_output, oMatlabDynamicModelSparse, temporary_terms); - if (tmp_output.str() == tmp_s.str() and d_endo_variable == result.end()) + { + //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 { - Equation_Simulation_Type = E_EVALUATE_R; - //cout << "Equation " << eq << " is reversed\n"; - } - else - { //the equation could be normalized using the derivative independant of the endogenous variable - if (d_endo_variable == result.end()) - { - Equation_Simulation_Type = E_EVALUATE_S; - Var_To_Derivate = var; - } + Equation_Simulation_Type = E_EVALUATE_S; + //cout << " gone normalized : "; + res = equations[eq]->normalizeLinearInEndoEquation(var, derivative->second); + /*res.second->writeOutput(cout, oMatlabDynamicModelSparse, temporary_terms); + cout << " done\n";*/ } } - /*cout << "-----------------------------------------------------------\n"; - lhs->writeOutput(cout, oMatlabDynamicModelSparse, temporary_terms); - cout << " = "; - rhs->writeOutput(cout, oMatlabDynamicModelSparse, temporary_terms); - cout << "% " << c_Equation_Type(Equation_Simulation_Type) << " " << var+1 << "\n";*/ - V_Equation_Simulation_Type[eq] = make_pair(Equation_Simulation_Type, Var_To_Derivate); + V_Equation_Simulation_Type[eq] = make_pair(Equation_Simulation_Type, dynamic_cast(res.second)); } - return(V_Equation_Simulation_Type); + return (V_Equation_Simulation_Type); } t_type BlockTriangular::Reduce_Blocks_and_type_determination(int prologue, int epilogue, vector > &blocks, vector &equations, t_etype &Equation_Type) { - int i=0; - int count_equ = 0, blck_count_simult =0; + int i = 0; + int count_equ = 0, blck_count_simult = 0; int Blck_Size, Recurs_Size; int Lead, Lag; t_type Type; bool *Cur_IM; - BlockSimulationType Simulation_Type , prev_Type=UNKNOWN; + BlockSimulationType Simulation_Type, prev_Type = UNKNOWN; int eq = 0; - for ( i=0; i 0) { if ((prev_Type == EVALUATE_FORWARD and Simulation_Type == EVALUATE_FORWARD) - or (prev_Type == EVALUATE_BACKWARD and Simulation_Type == EVALUATE_BACKWARD)) + or (prev_Type == EVALUATE_BACKWARD and Simulation_Type == EVALUATE_BACKWARD)) { BlockSimulationType c_Type = (Type[Type.size()-1]).first; int c_Size = (Type[Type.size()-1]).second.first; - Type[Type.size()-1]=make_pair(c_Type, make_pair(++c_Size, Type[Type.size()-1].second.second)); + Type[Type.size()-1] = make_pair(c_Type, make_pair(++c_Size, Type[Type.size()-1].second.second)); } else Type.push_back(make_pair(Simulation_Type, make_pair(Blck_Size, Recurs_Size))); @@ -792,53 +836,53 @@ BlockTriangular::Reduce_Blocks_and_type_determination(int prologue, int epilogue prev_Type = Simulation_Type; eq += Blck_Size; } - return(Type); + return (Type); } - void -BlockTriangular::Normalize_and_BlockDecompose(bool* IM, Model_Block* ModelBlock, int n, int &prologue, int &epilogue, vector &Index_Var_IM, vector &Index_Equ_IM, bool* IM_0, jacob_map &j_m, vector &equations, t_etype &V_Equation_Type, map, NodeID> &first_cur_endo_derivatives) +BlockTriangular::Normalize_and_BlockDecompose(bool *IM, Model_Block *ModelBlock, int n, int &prologue, int &epilogue, vector &Index_Var_IM, vector &Index_Equ_IM, bool *IM_0, jacob_map &j_m, vector &equations, t_etype &V_Equation_Type, map, NodeID> &first_cur_endo_derivatives) { int i, j, Nb_TotalBlocks, Nb_RecursBlocks, Nb_SimulBlocks; BlockType Btype; int count_Block, count_Equ; - bool* SIM0, *SIM00; + bool *SIM0, *SIM00; - SIM0 = (bool*)malloc(n * n * sizeof(bool)); - memcpy(SIM0,IM_0,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, double >::iterator iter = j_m.begin(); iter != j_m.end(); iter++ ) + double *max_val = (double *) malloc(n*sizeof(double)); + memset(max_val, 0, n*sizeof(double)); + for (map< pair< int, int >, double >::iterator iter = j_m.begin(); iter != j_m.end(); iter++) { - if (fabs(iter->second)>max_val[iter->first.first]) - max_val[iter->first.first]=fabs(iter->second); + if (fabs(iter->second) > max_val[iter->first.first]) + max_val[iter->first.first] = fabs(iter->second); } - for ( map< pair< int, int >, double >::iterator iter = j_m.begin(); iter != j_m.end(); iter++ ) - iter->second/=max_val[iter->first.first]; + for (map< pair< int, int >, double >::iterator iter = j_m.begin(); iter != j_m.end(); iter++) + iter->second /= max_val[iter->first.first]; free(max_val); - bool OK=false; - double bi=0.99999999; - int suppressed=0; + bool OK = false; + double bi = 0.99999999; + //double bi=1e-13; + int suppressed = 0; vector Index_Equ_IM_save(Index_Equ_IM); - while (!OK && bi>1e-14) + while (!OK && bi > 1e-14) { - int suppress=0; + int suppress = 0; Index_Equ_IM = Index_Equ_IM_save; - SIM0 = (bool*)malloc(n * n * sizeof(bool)); - memset(SIM0,0,n*n*sizeof(bool)); - SIM00 = (bool*)malloc(n * n * sizeof(bool)); - memset(SIM00,0,n*n*sizeof(bool)); - for ( map< pair< int, int >, double >::iterator iter = j_m.begin(); iter != j_m.end(); iter++ ) + SIM0 = (bool *) malloc(n * n * sizeof(bool)); + memset(SIM0, 0, n*n*sizeof(bool)); + SIM00 = (bool *) malloc(n * n * sizeof(bool)); + 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) > bi) { - SIM0[iter->first.first*n+iter->first.second]=1; + SIM0[iter->first.first*n+iter->first.second] = 1; if (!IM_0[iter->first.first*n+iter->first.second]) { cout << "Error nothing at IM_0[" << iter->first.first << ", " << iter->first.second << "]=" << IM_0[iter->first.first*n+iter->first.second] << " " << iter->second << "\n"; @@ -847,32 +891,31 @@ BlockTriangular::Normalize_and_BlockDecompose(bool* IM, Model_Block* ModelBlock, else suppress++; } - for (i = 0;i < n;i++) - for (j = 0;j < n;j++) + for (i = 0; i < n; i++) + for (j = 0; j < n; j++) { SIM00[i*n + j] = SIM0[Index_Equ_IM[i] * n + Index_Var_IM[j]]; } free(SIM0); - if (suppress!=suppressed) + if (suppress != suppressed) OK = Compute_Normalization(IM, n, prologue, epilogue, false, SIM00, Index_Equ_IM); - suppressed=suppress; + suppressed = suppress; if (!OK) //bi/=1.07; - bi/=3; + bi /= 2; counted++; - if (bi>1e-14) + if (bi > 1e-14) free(SIM00); } if (!OK) Compute_Normalization(IM, n, prologue, epilogue, true, SIM00, Index_Equ_IM); - } V_Equation_Type = Equation_Type_determination(equations, first_cur_endo_derivatives, Index_Var_IM, Index_Equ_IM); cout << "Finding the optimal block decomposition of the model ...\n"; vector > blocks; - if (prologue+epiloguefirst==SOLVE_FORWARD_COMPLETE || it->first==SOLVE_BACKWARD_COMPLETE || it->first==SOLVE_TWO_BOUNDARIES_COMPLETE) + if (it->first == SOLVE_FORWARD_COMPLETE || it->first == SOLVE_BACKWARD_COMPLETE || it->first == SOLVE_TWO_BOUNDARIES_COMPLETE) { Nb_SimulBlocks++; - if (it->second.first>j) + if (it->second.first > j) { - j=it->second.first; + j = it->second.first; Nb_fv = blocks[Nb_SimulBlocks-1].second; } } @@ -898,20 +941,21 @@ BlockTriangular::Normalize_and_BlockDecompose(bool* IM, Model_Block* ModelBlock, Nb_RecursBlocks = Nb_TotalBlocks - Nb_SimulBlocks; cout << Nb_TotalBlocks << " block(s) found:\n"; cout << " " << Nb_RecursBlocks << " recursive block(s) and " << blocks.size() << " simultaneous block(s). \n"; - cout << " the largest simultaneous block has " << j << " equation(s)\n" << - " and " << Nb_fv << " feedback variable(s).\n"; + cout << " the largest simultaneous block has " << j << " equation(s)\n" + <<" and " << Nb_fv << " feedback variable(s).\n"; ModelBlock->Size = Nb_TotalBlocks; ModelBlock->Periods = periods; - ModelBlock->Block_List = (Block*)malloc(sizeof(ModelBlock->Block_List[0]) * Nb_TotalBlocks); + ModelBlock->Block_List = (Block *) malloc(sizeof(ModelBlock->Block_List[0]) * Nb_TotalBlocks); count_Equ = count_Block = 0; - for (t_type::const_iterator it = Type.begin(); it!=Type.end(); it++) + + for (t_type::const_iterator it = Type.begin(); it != Type.end(); it++) { - if (count_Equsecond.first==1) + else if (count_Equ < n-epilogue) + if (it->second.first == 1) Btype = PROLOGUE; else Btype = SIMULTANS; @@ -921,26 +965,25 @@ 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 &equations, t_etype &equation_simulation_type, map, NodeID> &first_cur_endo_derivatives) { - bool* SIM, *SIM_0; - bool* Cur_IM; + bool *SIM, *SIM_0; + bool *Cur_IM; int i, k, size; //First create a static model incidence matrix size = symbol_table.endo_nbr() * symbol_table.endo_nbr() * sizeof(*SIM); - SIM = (bool*)malloc(size); - for (i = 0; i< symbol_table.endo_nbr() * symbol_table.endo_nbr(); i++) SIM[i] = 0; - for (k = -incidencematrix.Model_Max_Lag_Endo; k<=incidencematrix.Model_Max_Lead_Endo; k++) + SIM = (bool *) malloc(size); + for (i = 0; i < symbol_table.endo_nbr() * symbol_table.endo_nbr(); i++) SIM[i] = 0; + for (k = -incidencematrix.Model_Max_Lag_Endo; k <= incidencematrix.Model_Max_Lead_Endo; k++) { Cur_IM = incidencematrix.Get_IM(k, eEndogenous); if (Cur_IM) { - for (i = 0;i < symbol_table.endo_nbr()*symbol_table.endo_nbr();i++) + for (i = 0; i < symbol_table.endo_nbr()*symbol_table.endo_nbr(); i++) { SIM[i] = (SIM[i]) || (Cur_IM[i]); } @@ -952,21 +995,21 @@ BlockTriangular::Normalize_and_BlockDecompose_Static_0_Model(jacob_map &j_m, vec incidencematrix.Print_SIM(SIM, eEndogenous); } Index_Equ_IM = vector(symbol_table.endo_nbr()); - for (i = 0;i < symbol_table.endo_nbr();i++) + for (i = 0; i < symbol_table.endo_nbr(); i++) { Index_Equ_IM[i] = i; } Index_Var_IM = vector(symbol_table.endo_nbr()); - for (i = 0;i < symbol_table.endo_nbr();i++) + for (i = 0; i < symbol_table.endo_nbr(); i++) { Index_Var_IM[i] = i; } if (ModelBlock != NULL) Free_Block(ModelBlock); - ModelBlock = (Model_Block*)malloc(sizeof(*ModelBlock)); + ModelBlock = (Model_Block *) malloc(sizeof(*ModelBlock)); Cur_IM = incidencematrix.Get_IM(0, eEndogenous); - 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 = (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_cur_endo_derivatives); free(SIM_0); diff --git a/BlockTriangular.hh b/BlockTriangular.hh index 87761639..009741f5 100644 --- a/BlockTriangular.hh +++ b/BlockTriangular.hh @@ -24,21 +24,23 @@ #include "CodeInterpreter.hh" #include "ExprNode.hh" #include "SymbolTable.hh" -#include "ModelNormalization.hh" -#include "ModelBlocks.hh" +//#include "ModelNormalization.hh" +//#include "ModelBlocks.hh" #include "IncidenceMatrix.hh" #include "ModelTree.hh" - - //! Sparse matrix of double to store the values of the Jacobian typedef map,double> jacob_map; typedef vector > > t_type; -typedef vector > t_etype; +//! Vector describing equations: BlockSimulationType, if BlockSimulationType == EVALUATE_s then a NodeID on the new normalized equation +typedef vector > t_etype; + +//! Vector describing variables: max_lag in the block, max_lead in the block +typedef vector > t_vtype; //! Creates the incidence matrix, computes prologue & epilogue, normalizes the model and computes the block decomposition class BlockTriangular @@ -52,27 +54,32 @@ private: bool Compute_Normalization(bool *IM, int equation_number, int prologue, int epilogue, bool verbose, bool *IM0, vector &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 &Index_Equ_IM, vector &Index_Var_IM, vector > &blocks, t_etype &Equation_Type, bool verbose_) const; - //! determine the type of each equation of the model (couble evaluated or need to be solved) + //! determines the type of each equation of the model (could be evaluated or need to be solved) t_etype Equation_Type_determination(vector &equations, map, NodeID> &first_cur_endo_derivatives, vector &Index_Var_IM, vector &Index_Equ_IM); //! 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 > &blocks, vector &equations, t_etype &Equation_Type); + //! Compute for each variable its maximum lead and lag in its block + t_vtype Get_Variable_LeadLag_By_Block(vector &components_set, int nb_blck_sim, int prologue, int epilogue) const; public: - const SymbolTable &symbol_table; - BlockTriangular(const SymbolTable &symbol_table_arg); + SymbolTable &symbol_table; + /*Blocks blocks; + Normalization normalization;*/ + IncidenceMatrix incidencematrix; + NumericalConstants &num_const; + DataTree *Normalized_Equation; + BlockTriangular(SymbolTable &symbol_table_arg, NumericalConstants &num_const_arg); + ~BlockTriangular(); //! Frees the Model structure describing the content of each block void Free_Block(Model_Block* ModelBlock) const; - //BlockTriangular(const IncidenceMatrix &incidence_matrix_arg); - //const SymbolTable &symbol_table; - Blocks blocks; - Normalization normalization; - IncidenceMatrix incidencematrix; + + + void Normalize_and_BlockDecompose_Static_0_Model(jacob_map &j_m, vector &equations, t_etype &V_Equation_Type, map, NodeID> &first_cur_endo_derivatives); void Normalize_and_BlockDecompose(bool* IM, Model_Block* ModelBlock, int n, int &prologue, int &epilogue, vector &Index_Var_IM, vector &Index_Equ_IM, bool* IM_0 , jacob_map &j_m, vector &equations, t_etype &equation_simulation_type, map, NodeID> &first_cur_endo_derivatives); vector Index_Equ_IM; vector Index_Var_IM; int prologue, epilogue; bool bt_verbose; - //int endo_nbr, exo_nbr; Model_Block* ModelBlock; int periods; inline static std::string BlockType0(int type) @@ -101,11 +108,11 @@ public: switch (type) { case EVALUATE_FORWARD: - case EVALUATE_FORWARD_R: + //case EVALUATE_FORWARD_R: return ("EVALUATE FORWARD "); break; case EVALUATE_BACKWARD: - case EVALUATE_BACKWARD_R: + //case EVALUATE_BACKWARD_R: return ("EVALUATE BACKWARD "); break; case SOLVE_FORWARD_SIMPLE: @@ -137,7 +144,7 @@ public: { "E_UNKNOWN ", "E_EVALUATE ", - "E_EVALUATE_R", + //"E_EVALUATE_R", "E_EVALUATE_S", "E_SOLVE " }; diff --git a/CodeInterpreter.hh b/CodeInterpreter.hh index 1ecc837c..cb495131 100644 --- a/CodeInterpreter.hh +++ b/CodeInterpreter.hh @@ -53,8 +53,8 @@ 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 which does not involve the normalized variable + //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 }; @@ -71,8 +71,8 @@ enum BlockSimulationType SOLVE_FORWARD_COMPLETE, //!< Block of several equations, newton solver needed, forward SOLVE_BACKWARD_COMPLETE, //!< Block of several equations, newton solver needed, backward SOLVE_TWO_BOUNDARIES_COMPLETE, //!< Block of several equations, newton solver needed, forward and backwar - EVALUATE_FORWARD_R, //!< Simple evaluation, normalized variable on right-hand side, forward - EVALUATE_BACKWARD_R //!< Simple evaluation, normalized variable on right-hand side, backward + //EVALUATE_FORWARD_R, //!< Simple evaluation, normalized variable on right-hand side, forward + //EVALUATE_BACKWARD_R //!< Simple evaluation, normalized variable on right-hand side, backward }; //! Enumeration of possible symbol types diff --git a/DynamicModel.cc b/DynamicModel.cc index 5e40bfc3..08ccf074 100644 --- a/DynamicModel.cc +++ b/DynamicModel.cc @@ -35,15 +35,15 @@ DynamicModel::DynamicModel(SymbolTable &symbol_table_arg, NumericalConstants &num_constants_arg) : - ModelTree(symbol_table_arg, num_constants_arg), - max_lag(0), max_lead(0), - max_endo_lag(0), max_endo_lead(0), - max_exo_lag(0), max_exo_lead(0), - max_exo_det_lag(0), max_exo_det_lead(0), - dynJacobianColsNbr(0), - cutoff(1e-15), - markowitz(0.7), - block_triangular(symbol_table_arg) + ModelTree(symbol_table_arg, num_constants_arg), + max_lag(0), max_lead(0), + max_endo_lag(0), max_endo_lead(0), + max_exo_lag(0), max_exo_lead(0), + max_exo_det_lag(0), max_exo_det_lead(0), + dynJacobianColsNbr(0), + cutoff(1e-15), + markowitz(0.7), + block_triangular(symbol_table_arg, num_constants_arg) { } @@ -55,13 +55,14 @@ DynamicModel::AddVariable(const string &name, int lag) void DynamicModel::compileDerivative(ofstream &code_file, int eq, int symb_id, int lag, map_idx_type &map_idx) const -{ - first_derivatives_type::const_iterator it = first_derivatives.find(make_pair(eq, getDerivID(symb_id, lag))); - if (it != first_derivatives.end()) - (it->second)->compile(code_file, false, temporary_terms, map_idx); - else - code_file.write(&FLDZ, sizeof(FLDZ)); -} + { + //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); + else + code_file.write(&FLDZ, sizeof(FLDZ)); + } void DynamicModel::BuildIncidenceMatrix() @@ -77,7 +78,7 @@ DynamicModel::BuildIncidenceMatrix() Id->collectEndogenous(endogenous); for (set >::iterator it_endogenous=endogenous.begin();it_endogenous!=endogenous.end();it_endogenous++) { - block_triangular.incidencematrix.fill_IM(eq, symbol_table.getTypeSpecificID(it_endogenous->first), it_endogenous->second, eEndogenous); + block_triangular.incidencematrix.fill_IM(eq, it_endogenous->first, it_endogenous->second, eEndogenous); } exogenous.clear(); Id = eq_node->get_arg1(); @@ -86,7 +87,7 @@ DynamicModel::BuildIncidenceMatrix() Id->collectExogenous(exogenous); for (set >::iterator it_exogenous=exogenous.begin();it_exogenous!=exogenous.end();it_exogenous++) { - block_triangular.incidencematrix.fill_IM(eq, symbol_table.getTypeSpecificID(it_exogenous->first), it_exogenous->second, eExogenous); + block_triangular.incidencematrix.fill_IM(eq, it_exogenous->first, it_exogenous->second, eExogenous); } } } @@ -107,12 +108,14 @@ DynamicModel::computeTemporaryTermsOrdered(Model_Block *ModelBlock) map_idx.clear(); for (j = 0;j < ModelBlock->Size;j++) { - //cerr << "block=" << j+1 << "\n"; // 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]) + ModelBlock->Block_List[j].Equation_Normalized[i]->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, j, ModelBlock, i, map_idx); } for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++) { @@ -158,11 +161,16 @@ DynamicModel::computeTemporaryTermsOrdered(Model_Block *ModelBlock) } for (j = 0;j < ModelBlock->Size;j++) { - // Compute the temporary terms reordered + // Collecte 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->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); } for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++) { @@ -216,1838 +224,2109 @@ DynamicModel::computeTemporaryTermsOrdered(Model_Block *ModelBlock) void DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const string &dynamic_basename) const -{ - int i,j,k,m; - string tmp_s, sps; - ostringstream tmp_output, tmp1_output, global_output; - NodeID lhs=NULL, rhs=NULL; - BinaryOpNode *eq_node; - ostringstream Uf[symbol_table.endo_nbr()]; - map reference_count; - 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(); - int nze, nze_exo, nze_other_endo; - //---------------------------------------------------------------------- - //For each block - for (j = 0;j < ModelBlock->Size;j++) - { - //For a block composed of a single equation determines wether we have to evaluate or to solve the equation - nze = nze_exo = nze_other_endo =0; - for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++) - nze+=ModelBlock->Block_List[j].IM_lead_lag[m].size; - for (m=0;m<=ModelBlock->Block_List[j].Max_Lead_Exo+ModelBlock->Block_List[j].Max_Lag_Exo;m++) - nze_exo+=ModelBlock->Block_List[j].IM_lead_lag[m].size_exo; - for (m=0;m<=ModelBlock->Block_List[j].Max_Lead_Other_Endo+ModelBlock->Block_List[j].Max_Lag_Other_Endo;m++) - nze_other_endo+=ModelBlock->Block_List[j].IM_lead_lag[m].size_other_endo; - tmp1_output.str(""); - tmp1_output << dynamic_basename << "_" << j+1 << ".m"; - output.open(tmp1_output.str().c_str(), ios::out | ios::binary); - output << "%\n"; - output << "% " << tmp1_output.str() << " : Computes dynamic model for Dynare\n"; - output << "%\n"; - output << "% Warning : this file is generated automatically by Dynare\n"; - output << "% from model file (.mod)\n\n"; - output << "%/\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) - { - output << "function [y, g1, g2, g3, varargout] = " << dynamic_basename << "_" << j+1 << "(y, x, params, jacobian_eval, y_kmin, periods)\n"; - } - else if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_FORWARD_COMPLETE - || ModelBlock->Block_List[j].Simulation_Type==SOLVE_BACKWARD_COMPLETE) - output << "function [residual, g1, g2, g3, varargout] = " << dynamic_basename << "_" << j+1 << "(y, x, params, it_, jacobian_eval)\n"; - else if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_BACKWARD_SIMPLE - || ModelBlock->Block_List[j].Simulation_Type==SOLVE_FORWARD_SIMPLE) - output << "function [residual, g1, g2, g3, varargout] = " << dynamic_basename << "_" << j+1 << "(y, x, params, it_, jacobian_eval)\n"; - else - output << "function [residual, g1, g2, g3, b, varargout] = " << dynamic_basename << "_" << j+1 << "(y, x, params, periods, jacobian_eval, y_kmin, y_size)\n"; - output << " % ////////////////////////////////////////////////////////////////////////" << endl - << " % //" << string(" Block ").substr(int(log10(j + 1))) << j + 1 << " " << BlockTriangular::BlockType0(ModelBlock->Block_List[j].Type) - << " //" << endl - << " % // Simulation type " - << BlockTriangular::BlockSim(ModelBlock->Block_List[j].Simulation_Type) << " //" << endl - << " % ////////////////////////////////////////////////////////////////////////" << endl; - //The Temporary terms - 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) - { - output << " if(jacobian_eval)\n"; - output << " g1 = spalloc(" << ModelBlock->Block_List[j].Size << ", " << ModelBlock->Block_List[j].Size*(1+ModelBlock->Block_List[j].Max_Lag_Endo+ModelBlock->Block_List[j].Max_Lead_Endo) << ", " << nze << ");\n"; - //output << " g1_x=spalloc(" << ModelBlock->Block_List[j].Size << ", " << (ModelBlock->Block_List[j].nb_exo + ModelBlock->Block_List[j].nb_exo_det)*(1+ModelBlock->Block_List[j].Max_Lag_Exo+ModelBlock->Block_List[j].Max_Lead_Exo) << ", " << nze_exo << ");\n"; - //output << " g1_o=spalloc(" << ModelBlock->Block_List[j].Size << ", " << ModelBlock->Block_List[j].nb_other_endo*(1+ModelBlock->Block_List[j].Max_Lag_Other_Endo+ModelBlock->Block_List[j].Max_Lead_Other_Endo) << ", " << nze_other_endo << ");\n"; - output << " end;\n"; - } - else - { - output << " if(jacobian_eval)\n"; - output << " g1 = spalloc(" << ModelBlock->Block_List[j].Size << ", " << ModelBlock->Block_List[j].Size*(1+ModelBlock->Block_List[j].Max_Lag_Endo+ModelBlock->Block_List[j].Max_Lead_Endo) << ", " << nze << ");\n"; - //output << " g1_x=spalloc(" << ModelBlock->Block_List[j].Size << ", " << (ModelBlock->Block_List[j].nb_exo + ModelBlock->Block_List[j].nb_exo_det)*(1+ModelBlock->Block_List[j].Max_Lag_Exo+ModelBlock->Block_List[j].Max_Lead_Exo) << ", " << nze_exo << ");\n"; - output << " g1_o=spalloc(" << ModelBlock->Block_List[j].Size << ", " << ModelBlock->Block_List[j].nb_other_endo*(1+ModelBlock->Block_List[j].Max_Lag_Other_Endo+ModelBlock->Block_List[j].Max_Lead_Other_Endo) << ", " << nze_other_endo << ");\n"; - output << " else\n"; - if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_SIMPLE) - output << " g1 = spalloc(" << ModelBlock->Block_List[j].Size*ModelBlock->Periods << ", " << ModelBlock->Block_List[j].Size*(ModelBlock->Periods+ModelBlock->Block_List[j].Max_Lag+ModelBlock->Block_List[j].Max_Lead) << ", " << nze*ModelBlock->Periods << ");\n"; + { + int i,j,k,m; + string tmp_s, sps; + ostringstream tmp_output, tmp1_output, global_output; + NodeID lhs=NULL, rhs=NULL; + BinaryOpNode *eq_node; + ostringstream Uf[symbol_table.endo_nbr()]; + map reference_count; + 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(); + int nze, nze_exo, nze_other_endo; + map recursive_variables; + vector feedback_variables; + //---------------------------------------------------------------------- + //For each block + for (j = 0;j < ModelBlock->Size;j++) + { + recursive_variables.clear(); + feedback_variables.clear(); + //For a block composed of a single equation determines wether we have to evaluate or to solve the equation + nze = nze_exo = nze_other_endo = 0; + for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++) + nze+=ModelBlock->Block_List[j].IM_lead_lag[m].size; + /*for (m=0;m<=ModelBlock->Block_List[j].Max_Lead_Exo+ModelBlock->Block_List[j].Max_Lag_Exo;m++) + nze_exo+=ModelBlock->Block_List[j].IM_lead_lag[m].size_exo;*/ + 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; + if (block_triangular.incidencematrix.Model_Max_Lag_Endo - ModelBlock->Block_List[j].Max_Lag +m >=0) + nze_other_endo+=ModelBlock->Block_List[j].IM_lead_lag[m].size_other_endo; + } + tmp1_output.str(""); + tmp1_output << dynamic_basename << "_" << j+1 << ".m"; + output.open(tmp1_output.str().c_str(), ios::out | ios::binary); + output << "%\n"; + output << "% " << tmp1_output.str() << " : Computes dynamic model for Dynare\n"; + output << "%\n"; + output << "% Warning : this file is generated automatically by Dynare\n"; + output << "% from model file (.mod)\n\n"; + output << "%/\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*/) + { + output << "function [y, g1, g2, g3, varargout] = " << dynamic_basename << "_" << j+1 << "(y, x, params, jacobian_eval, y_kmin, periods)\n"; + } + else if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_FORWARD_COMPLETE + || ModelBlock->Block_List[j].Simulation_Type==SOLVE_BACKWARD_COMPLETE) + output << "function [residual, y, g1, g2, g3, varargout] = " << dynamic_basename << "_" << j+1 << "(y, x, params, it_, jacobian_eval)\n"; + else if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_BACKWARD_SIMPLE + || ModelBlock->Block_List[j].Simulation_Type==SOLVE_FORWARD_SIMPLE) + output << "function [residual, y, g1, g2, g3, varargout] = " << dynamic_basename << "_" << j+1 << "(y, x, params, it_, jacobian_eval)\n"; + else + output << "function [residual, y, g1, g2, g3, b, varargout] = " << dynamic_basename << "_" << j+1 << "(y, x, params, periods, jacobian_eval, y_kmin, y_size)\n"; + output << " % ////////////////////////////////////////////////////////////////////////" << endl + << " % //" << string(" Block ").substr(int(log10(j + 1))) << j + 1 << " " << BlockTriangular::BlockType0(ModelBlock->Block_List[j].Type) + << " //" << endl + << " % // Simulation type " + << BlockTriangular::BlockSim(ModelBlock->Block_List[j].Simulation_Type) << " //" << endl + << " % ////////////////////////////////////////////////////////////////////////" << endl; + //The Temporary terms + 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*/) + { + output << " if(jacobian_eval)\n"; + output << " g1 = spalloc(" << ModelBlock->Block_List[j].Size-ModelBlock->Block_List[j].Nb_Recursives + << ", " << (ModelBlock->Block_List[j].Size-ModelBlock->Block_List[j].Nb_Recursives)*(1+ModelBlock->Block_List[j].Max_Lag_Endo+ModelBlock->Block_List[j].Max_Lead_Endo) + << ", " << nze << ");\n"; + output << " g1_x=spalloc(" << ModelBlock->Block_List[j].Size << ", " << (ModelBlock->Block_List[j].nb_exo + ModelBlock->Block_List[j].nb_exo_det)*(1+ModelBlock->Block_List[j].Max_Lag_Exo+ModelBlock->Block_List[j].Max_Lead_Exo) << ", " << nze_exo << ");\n"; + output << " g1_o=spalloc(" << ModelBlock->Block_List[j].Size << ", " << ModelBlock->Block_List[j].nb_other_endo*(1+ModelBlock->Block_List[j].Max_Lag_Other_Endo+ModelBlock->Block_List[j].Max_Lead_Other_Endo) << ", " << nze_other_endo << ");\n"; + output << " end;\n"; + } + else + { + output << " if(jacobian_eval)\n"; + output << " g1 = spalloc(" << ModelBlock->Block_List[j].Size << ", " << ModelBlock->Block_List[j].Size*(1+ModelBlock->Block_List[j].Max_Lag_Endo+ModelBlock->Block_List[j].Max_Lead_Endo) << ", " << nze << ");\n"; + output << " g1_x=spalloc(" << ModelBlock->Block_List[j].Size << ", " << (ModelBlock->Block_List[j].nb_exo + ModelBlock->Block_List[j].nb_exo_det)*(1+ModelBlock->Block_List[j].Max_Lag_Exo+ModelBlock->Block_List[j].Max_Lead_Exo) << ", " << nze_exo << ");\n"; + output << " g1_o=spalloc(" << ModelBlock->Block_List[j].Size << ", " << ModelBlock->Block_List[j].nb_other_endo*(1+ModelBlock->Block_List[j].Max_Lag_Other_Endo+ModelBlock->Block_List[j].Max_Lead_Other_Endo) << ", " << nze_other_endo << ");\n"; + output << " else\n"; + if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_SIMPLE) + { + output << " g1 = spalloc(" << (ModelBlock->Block_List[j].Size-ModelBlock->Block_List[j].Nb_Recursives)*ModelBlock->Periods + << ", " << (ModelBlock->Block_List[j].Size-ModelBlock->Block_List[j].Nb_Recursives)*(ModelBlock->Periods+ModelBlock->Block_List[j].Max_Lag+ModelBlock->Block_List[j].Max_Lead+1) + << ", " << nze*ModelBlock->Periods << ");\n"; + output << " g1_tmp_r = spalloc(" << (ModelBlock->Block_List[j].Nb_Recursives) + << ", " << (ModelBlock->Block_List[j].Size)*(ModelBlock->Block_List[j].Max_Lag+ModelBlock->Block_List[j].Max_Lead+1) + << ", " << nze << ");\n"; + output << " g1_tmp_b = spalloc(" << (ModelBlock->Block_List[j].Size-ModelBlock->Block_List[j].Nb_Recursives) + << ", " << (ModelBlock->Block_List[j].Size)*(ModelBlock->Block_List[j].Max_Lag+ModelBlock->Block_List[j].Max_Lead+1) + << ", " << nze << ");\n"; + } + else + { + output << " g1 = spalloc(" << ModelBlock->Block_List[j].Size-ModelBlock->Block_List[j].Nb_Recursives + << ", " << ModelBlock->Block_List[j].Size-ModelBlock->Block_List[j].Nb_Recursives << ", " << nze << ");\n"; + output << " g1_tmp_r = spalloc(" << ModelBlock->Block_List[j].Nb_Recursives + << ", " << ModelBlock->Block_List[j].Size << ", " << nze << ");\n"; + output << " g1_tmp_b = spalloc(" << ModelBlock->Block_List[j].Size-ModelBlock->Block_List[j].Nb_Recursives + << ", " << ModelBlock->Block_List[j].Size << ", " << nze << ");\n"; + } + output << " end;\n"; + } + + output << " g2=0;g3=0;\n"; + if (ModelBlock->Block_List[j].Temporary_InUse->size()) + { + tmp_output.str(""); + for (temporary_terms_inuse_type::const_iterator it = ModelBlock->Block_List[j].Temporary_InUse->begin(); + it != ModelBlock->Block_List[j].Temporary_InUse->end(); it++) + tmp_output << " T" << *it; + output << " global" << tmp_output.str() << ";\n"; + } + if (ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_BACKWARD and ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_FORWARD) + output << " residual=zeros(" << ModelBlock->Block_List[j].Size-ModelBlock->Block_List[j].Nb_Recursives << ",1);\n"; + if (ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD) + output << " for it_ = (y_kmin+periods):y_kmin+1\n"; + if (ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD) + output << " for it_ = y_kmin+1:(y_kmin+periods)\n"; + + if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_SIMPLE) + { + output << " b = zeros(periods*y_size,1);\n"; + output << " for it_ = y_kmin+1:(periods+y_kmin)\n"; + output << " Per_y_=it_*y_size;\n"; + output << " Per_J_=(it_-y_kmin-1)*y_size;\n"; + output << " Per_K_=(it_-1)*y_size;\n"; + sps=" "; + } + else + if (ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD || ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD ) + sps = " "; else - output << " g1 = spalloc(" << ModelBlock->Block_List[j].Size << ", " << ModelBlock->Block_List[j].Size << ", " << nze << ");\n"; - output << " end;\n"; - } - - output << " g2=0;g3=0;\n"; - if(ModelBlock->Block_List[j].Temporary_InUse->size()) - { - tmp_output.str(""); - for (temporary_terms_inuse_type::const_iterator it = ModelBlock->Block_List[j].Temporary_InUse->begin(); - it != ModelBlock->Block_List[j].Temporary_InUse->end(); it++) - tmp_output << " T" << *it; - output << " global" << tmp_output.str() << ";\n"; - } - output << " residual=zeros(" << ModelBlock->Block_List[j].Size << ",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) - output << " for it_ = y_kmin+1:(y_kmin+periods)\n"; - - - if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_SIMPLE) - { - output << " b = [];\n"; - output << " for it_ = y_kmin+1:(periods+y_kmin)\n"; - output << " Per_y_=it_*y_size;\n"; - output << " Per_J_=(it_-y_kmin-1)*y_size;\n"; - output << " Per_K_=(it_-1)*y_size;\n"; - sps=" "; - } - else - 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) - sps = " "; + sps=""; + // The equations + for (i = 0;i < ModelBlock->Block_List[j].Size;i++) + { + temporary_terms_type tt2; + tt2.clear(); + if (ModelBlock->Block_List[j].Temporary_Terms_in_Equation[i]->size()) + output << " " << sps << "% //Temporary variables" << endl; + 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++) + { + output << " " << sps; + (*it)->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms); + output << " = "; + (*it)->writeOutput(output, oMatlabDynamicModelSparse, tt2); + // Insert current node into tt2 + tt2.insert(*it); + output << ";" << endl; + } + string sModel = symbol_table.getName(symbol_table.getID(eEndogenous, ModelBlock->Block_List[j].Variable[i])) ; + eq_node = equations[ModelBlock->Block_List[j].Equation[i]]; + lhs = eq_node->get_arg1(); + rhs = eq_node->get_arg2(); + tmp_output.str(""); + lhs->writeOutput(tmp_output, oMatlabDynamicModelSparse, temporary_terms); + switch (ModelBlock->Block_List[j].Simulation_Type) + { + case EVALUATE_BACKWARD: + case EVALUATE_FORWARD: +evaluation: + output << " % equation " << ModelBlock->Block_List[j].Equation[i]+1 << " variable : " << sModel + << " (" << ModelBlock->Block_List[j].Variable[i]+1 << ") " << block_triangular.c_Equation_Type(ModelBlock->Block_List[j].Equation_Type[i]) << endl; + output << " "; + if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE) + { + output << tmp_output.str(); + output << " = "; + 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(); + output << " = "; + if (ModelBlock->Block_List[j].Equation_Normalized[i]) + { + rhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms); + output << "\n "; + temporary_terms_type tt2; + tt2.clear(); + ModelBlock->Block_List[j].Equation_Normalized[i]->writeOutput(output , oMatlabDynamicModelSparse, temporary_terms/*tt2*/); + } + } + else + { + cerr << "Type missmatch for equation " << ModelBlock->Block_List[j].Equation[i]+1 << "\n"; + exit(EXIT_FAILURE); + } + output << ";\n"; + break; + case SOLVE_BACKWARD_SIMPLE: + case SOLVE_FORWARD_SIMPLE: + case SOLVE_BACKWARD_COMPLETE: + case SOLVE_FORWARD_COMPLETE: + if (iBlock_List[j].Nb_Recursives) + { + if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE_S) + recursive_variables[getDerivID(symbol_table.getID(eEndogenous, ModelBlock->Block_List[j].Variable[i]), 0)] = ModelBlock->Block_List[j].Equation_Normalized[i]; + else + recursive_variables[getDerivID(symbol_table.getID(eEndogenous, ModelBlock->Block_List[j].Variable[i]), 0)] = equations[ModelBlock->Block_List[j].Equation[i]]; + goto evaluation; + } + feedback_variables.push_back(ModelBlock->Block_List[j].Variable[i]); + output << " % equation " << ModelBlock->Block_List[j].Equation[i]+1 << " variable : " << sModel + << " (" << ModelBlock->Block_List[j].Variable[i]+1 << ") " << block_triangular.c_Equation_Type(ModelBlock->Block_List[j].Equation_Type[i]) << endl; + output << " " << "residual(" << i+1-ModelBlock->Block_List[j].Nb_Recursives << ") = ("; + goto end; + case SOLVE_TWO_BOUNDARIES_COMPLETE: + case SOLVE_TWO_BOUNDARIES_SIMPLE: + if (iBlock_List[j].Nb_Recursives) + { + if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE_S) + recursive_variables[getDerivID(symbol_table.getID(eEndogenous, ModelBlock->Block_List[j].Variable[i]), 0)] = ModelBlock->Block_List[j].Equation_Normalized[i]; + else + recursive_variables[getDerivID(symbol_table.getID(eEndogenous, ModelBlock->Block_List[j].Variable[i]), 0)] = equations[ModelBlock->Block_List[j].Equation[i]]; + goto evaluation; + } + feedback_variables.push_back(ModelBlock->Block_List[j].Variable[i]); + output << " % equation " << ModelBlock->Block_List[j].Equation[i]+1 << " variable : " << sModel + << " (" << ModelBlock->Block_List[j].Variable[i]+1 << ") " << block_triangular.c_Equation_Type(ModelBlock->Block_List[j].Equation_Type[i]) << endl; + Uf[ModelBlock->Block_List[j].Equation[i]] << " b(" << i+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_J_) = -residual(" << i+1-ModelBlock->Block_List[j].Nb_Recursives << ", it_)"; + output << " residual(" << i+1-ModelBlock->Block_List[j].Nb_Recursives << ", it_) = ("; + goto end; + default: +end: + output << tmp_output.str(); + output << ") - ("; + rhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms); + output << ");\n"; +#ifdef CONDITION + if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_SIMPLE) + output << " condition(" << i+1 << ")=0;\n"; +#endif + } + } + // The Jacobian if we have to solve the block + if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_SIMPLE + || ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE) + output << " " << sps << "% Jacobian " << endl; else - sps=""; - // The equations - for (i = 0;i < ModelBlock->Block_List[j].Size;i++) - { - temporary_terms_type tt2; - tt2.clear(); - if (ModelBlock->Block_List[j].Temporary_Terms_in_Equation[i]->size()) - output << " " << sps << "% //Temporary variables" << endl; - 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++) - { - output << " " << sps; - (*it)->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms); - output << " = "; - (*it)->writeOutput(output, oMatlabDynamicModelSparse, tt2); - // Insert current node into tt2 - tt2.insert(*it); - output << ";" << endl; - } - string sModel = symbol_table.getName(ModelBlock->Block_List[j].Variable[i]) ; - eq_node = equations[ModelBlock->Block_List[j].Equation[i]]; - lhs = eq_node->get_arg1(); - rhs = eq_node->get_arg2(); - tmp_output.str(""); - lhs->writeOutput(tmp_output, oMatlabDynamicModelSparse, temporary_terms); - switch (ModelBlock->Block_List[j].Simulation_Type) - { - case EVALUATE_BACKWARD: - case EVALUATE_FORWARD: - evaluation: - output << " % equation " << ModelBlock->Block_List[j].Equation[i]+1 << " variable : " << sModel - << " (" << ModelBlock->Block_List[j].Variable[i]+1 << ") " << block_triangular.c_Equation_Type(ModelBlock->Block_List[j].Equation_Type[i]) << endl; - output << " "; - if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE) - { - output << tmp_output.str(); - output << " = "; - 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 - { - cerr << "Type missmatch for equation " << ModelBlock->Block_List[j].Equation[i]+1 << "\n"; - exit(-1); - } - output << ";\n"; - break; /*case EVALUATE_BACKWARD_R: - case EVALUATE_FORWARD_R: - output << " % equation " << ModelBlock->Block_List[j].Equation[i]+1 << " variable : " << sModel - << " (" << ModelBlock->Block_List[j].Variable[i]+1 << ")" << endl; - output << " "; - rhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms); - output << " = "; - lhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms); - output << ";\n"; - break;*/ - case SOLVE_BACKWARD_SIMPLE: - case SOLVE_FORWARD_SIMPLE: - case SOLVE_BACKWARD_COMPLETE: - case SOLVE_FORWARD_COMPLETE: - if(iBlock_List[j].Nb_Recursives) - goto evaluation; - output << " % equation " << ModelBlock->Block_List[j].Equation[i]+1 << " variable : " << sModel - << " (" << ModelBlock->Block_List[j].Variable[i]+1 << ") " << block_triangular.c_Equation_Type(ModelBlock->Block_List[j].Equation_Type[i]) << endl; - output << " " << "residual(" << i+1-ModelBlock->Block_List[j].Nb_Recursives << ") = ("; - goto end; - case SOLVE_TWO_BOUNDARIES_COMPLETE: - case SOLVE_TWO_BOUNDARIES_SIMPLE: - if(iBlock_List[j].Nb_Recursives) - goto evaluation; - output << " % equation " << ModelBlock->Block_List[j].Equation[i]+1 << " variable : " << sModel - << " (" << ModelBlock->Block_List[j].Variable[i]+1 << ") " << block_triangular.c_Equation_Type(ModelBlock->Block_List[j].Equation_Type[i]) << endl; - Uf[ModelBlock->Block_List[j].Equation[i]] << " b(" << i+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_J_) = -residual(" << i+1 << ", it_)"; - output << " residual(" << i+1-ModelBlock->Block_List[j].Nb_Recursives << ", it_) = ("; - goto end; - default: - end: - output << tmp_output.str(); - output << ") - ("; - rhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms); - output << ");\n"; -#ifdef CONDITION - if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_SIMPLE) - output << " condition(" << i+1 << ")=0;\n"; -#endif - } - } - // The Jacobian if we have to solve the block - if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_SIMPLE - || ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE) - output << " " << sps << "% Jacobian " << endl; - else - if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_BACKWARD_SIMPLE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_FORWARD_SIMPLE || - ModelBlock->Block_List[j].Simulation_Type==SOLVE_BACKWARD_COMPLETE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_FORWARD_COMPLETE) - output << " % Jacobian " << endl << " if jacobian_eval" << endl; - else - output << " % Jacobian " << endl << " if jacobian_eval" << endl; - switch (ModelBlock->Block_List[j].Simulation_Type) - { - case EVALUATE_BACKWARD: - case EVALUATE_FORWARD: - case EVALUATE_BACKWARD_R: - case EVALUATE_FORWARD_R: - count_derivates++; - for (m=0;mBlock_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag+1;m++) - { - k=m-ModelBlock->Block_List[j].Max_Lag; - for (i=0;iBlock_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 eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ[i]; - int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Var[i]; - output << " g1(" << eqr+1 << ", " << /*varr+1+(m+variable_table.max_lag-ModelBlock->Block_List[j].Max_Lag)*symbol_table.endo_nbr*/ + if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_BACKWARD_SIMPLE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_FORWARD_SIMPLE || + ModelBlock->Block_List[j].Simulation_Type==SOLVE_BACKWARD_COMPLETE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_FORWARD_COMPLETE) + output << " % Jacobian " << endl << " if jacobian_eval" << endl; + else + output << " % Jacobian " << endl << " if jacobian_eval" << endl; + switch (ModelBlock->Block_List[j].Simulation_Type) + { + case EVALUATE_BACKWARD: + case EVALUATE_FORWARD: + /*case EVALUATE_BACKWARD_R: + case EVALUATE_FORWARD_R:*/ + count_derivates++; + for (m=0;mBlock_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag+1;m++) + { + k=m-ModelBlock->Block_List[j].Max_Lag; + for (i=0;iBlock_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 eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ[i]; + int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Var[i]; + output << " g1(" << eqr+1 << ", " << /*varr+1+(m+variable_table.max_lag-ModelBlock->Block_List[j].Max_Lag)*symbol_table.endo_nbr*/ varr+1+m*ModelBlock->Block_List[j].Size << ") = "; - writeDerivative(output, eq, symbol_table.getID(eEndogenous, var), k, oMatlabDynamicModelSparse, temporary_terms); - output << "; % variable=" << symbol_table.getName(var) - << "(" << k//variable_table.getLag(variable_table.getSymbolID(ModelBlock->Block_List[j].Variable[0])) - << ") " << var+1 - << ", equation=" << eq+1 << endl; - } - } - //jacobian_max_endo_col=(variable_table.max_endo_lag+variable_table.max_endo_lead+1)*symbol_table.endo_nbr; - /*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;iBlock_List[j].IM_lead_lag[m].size_exo;i++) - { - int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_X_Index[i]; - int var=ModelBlock->Block_List[j].IM_lead_lag[m].Exogenous_Index[i]; - int eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_X[i]; - int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Exogenous[i]; - output << " g1_x(" << eqr+1 << ", " - << varr+1+(m+max_exo_lag-ModelBlock->Block_List[j].Max_Lag)*symbol_table.exo_nbr() << ") = "; - writeDerivative(output, eq, symbol_table.getID(eExogenous, var), k, oMatlabDynamicModelSparse, temporary_terms); - output << "; % variable=" << symbol_table.getName(var) - << "(" << k << ") " << var+1 - << ", equation=" << eq+1 << endl; - } - }*/ - 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; - if (block_triangular.incidencematrix.Model_Max_Lag_Endo - ModelBlock->Block_List[j].Max_Lag +m >=0) - { - for (i=0;iBlock_List[j].IM_lead_lag[m].size_other_endo;i++) - { - int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index_other_endo[i]; - 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 << ", " - << 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(var) - << "(" << k << ") " << var+1 - << ", equation=" << eq+1 << endl; - } - } - } - output << " varargout{1}=g1_x;\n"; - output << " varargout{2}=g1_o;\n"; - output << " end;" << endl; - output << " end;" << endl; - break; - case SOLVE_BACKWARD_SIMPLE: - case SOLVE_FORWARD_SIMPLE: - case SOLVE_BACKWARD_COMPLETE: - case SOLVE_FORWARD_COMPLETE: - count_derivates++; - for (m=0;mBlock_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag+1;m++) - { - k=m-ModelBlock->Block_List[j].Max_Lag; - for (i=0;iBlock_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 eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ[i]; - int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Var[i]; - output << " g1(" << eqr+1 << ", " << /*varr+1+(m+variable_table.max_lag-ModelBlock->Block_List[j].Max_Lag)*symbol_table.endo_nbr*/ - varr+1+m*ModelBlock->Block_List[j].Size << ") = "; - writeDerivative(output, eq, symbol_table.getID(eEndogenous, var), k, oMatlabDynamicModelSparse, temporary_terms); - output << "; % variable=" << symbol_table.getName(var) - << "(" << k - << ") " << var+1 - << ", equation=" << eq+1 << endl; - } - } - /*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;iBlock_List[j].IM_lead_lag[m].size_exo;i++) - { - int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_X_Index[i]; - int var=ModelBlock->Block_List[j].IM_lead_lag[m].Exogenous_Index[i]; - int eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_X[i]; - int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Exogenous[i]; - output << " g1_x(" << eqr+1 << ", " << varr+1+(m+max_exo_lag-ModelBlock->Block_List[j].Max_Lag)*ModelBlock->Block_List[j].nb_exo << ") = "; - writeDerivative(output, eq, symbol_table.getID(eExogenous, var), k, oMatlabDynamicModelSparse, temporary_terms); - output << "; % variable=" << symbol_table.getName(var) - << "(" << k << ") " << var+1 - << ", equation=" << eq+1 << endl; - } - }*/ - 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; - if (block_triangular.incidencematrix.Model_Max_Lag_Endo - ModelBlock->Block_List[j].Max_Lag +m >=0) - { - for (i=0;iBlock_List[j].IM_lead_lag[m].size_other_endo;i++) - { - int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index_other_endo[i]; - 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 << ", " - << 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(var) - << "(" << k << ") " << var+1 - << ", equation=" << eq+1 << endl; - } - } - } - output << " varargout{1}=g1_x;\n"; - output << " varargout{2}=g1_o;\n"; - output << " else" << endl; + writeDerivative(output, eq, symbol_table.getID(eEndogenous, var), k, oMatlabDynamicModelSparse, temporary_terms); + output << "; % variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, var)) + << "(" << k//variable_table.getLag(variable_table.getSymbolID(ModelBlock->Block_List[j].Variable[0])) + << ") " << var+1 + << ", equation=" << eq+1 << endl; + } + } + //jacobian_max_endo_col=(variable_table.max_endo_lag+variable_table.max_endo_lead+1)*symbol_table.endo_nbr; + /*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;iBlock_List[j].IM_lead_lag[m].size_exo;i++) + { + int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_X_Index[i]; + int var=ModelBlock->Block_List[j].IM_lead_lag[m].Exogenous_Index[i]; + int eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_X[i]; + int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Exogenous[i]; + output << " g1_x(" << eqr+1 << ", " + << varr+1+(m+max_exo_lag-ModelBlock->Block_List[j].Max_Lag)*symbol_table.exo_nbr() << ") = "; + writeDerivative(output, eq, symbol_table.getID(eExogenous, var), k, oMatlabDynamicModelSparse, temporary_terms); + output << "; % variable=" << symbol_table.getName(var) + << "(" << k << ") " << var+1 + << ", equation=" << eq+1 << endl; + } + }*/ + 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; + if (block_triangular.incidencematrix.Model_Max_Lag_Endo - ModelBlock->Block_List[j].Max_Lag +m >=0) + { + for (i=0;iBlock_List[j].IM_lead_lag[m].size_other_endo;i++) + { + int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index_other_endo[i]; + 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 << ", " + << 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)) + << "(" << k << ") " << var+1 + << ", equation=" << eq+1 << endl; + } + } + } + output << " varargout{1}=g1_x;\n"; + output << " varargout{2}=g1_o;\n"; + output << " end;" << endl; + //output << " ya = y;\n"; + output << " end;" << endl; + break; + case SOLVE_BACKWARD_SIMPLE: + case SOLVE_FORWARD_SIMPLE: + case SOLVE_BACKWARD_COMPLETE: + case SOLVE_FORWARD_COMPLETE: + count_derivates++; + for (m=0;mBlock_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag+1;m++) + { + k=m-ModelBlock->Block_List[j].Max_Lag; + for (i=0;iBlock_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 eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ[i]; + int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Var[i]; + output << " g1(" << eqr+1 << ", " + << varr+1 + m*(ModelBlock->Block_List[j].Size) << ") = "; + writeDerivative(output, eq, symbol_table.getID(eEndogenous, var), k, oMatlabDynamicModelSparse, temporary_terms); + output << "; % variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, var)) + << "(" << k << ") " << var+1 + << ", equation=" << eq+1 << endl; + } + } + /*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;iBlock_List[j].IM_lead_lag[m].size_exo;i++) + { + int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_X_Index[i]; + int var=ModelBlock->Block_List[j].IM_lead_lag[m].Exogenous_Index[i]; + int eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_X[i]; + int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Exogenous[i]; + output << " g1_x(" << eqr+1 << ", " << varr+1+(m+max_exo_lag-ModelBlock->Block_List[j].Max_Lag)*ModelBlock->Block_List[j].nb_exo << ") = "; + writeDerivative(output, eq, symbol_table.getID(eExogenous, var), k, oMatlabDynamicModelSparse, temporary_terms); + output << "; % variable=" << symbol_table.getName(var) + << "(" << k << ") " << var+1 + << ", equation=" << eq+1 << endl; + } + }*/ + 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; + if (block_triangular.incidencematrix.Model_Max_Lag_Endo - ModelBlock->Block_List[j].Max_Lag +m >=0) + { + for (i=0;iBlock_List[j].IM_lead_lag[m].size_other_endo;i++) + { + int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index_other_endo[i]; + 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 << ", " + << 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)) + << "(" << k << ") " << var+1 + << ", equation=" << eq+1 << endl; + } + } + } + output << " varargout{1}=g1_x;\n"; + 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;iBlock_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 eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ[i]; + int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Var[i]; + bool derivative_exist; + ostringstream tmp_output; + if (eqrBlock_List[j].Nb_Recursives) + { + if (varr>=ModelBlock->Block_List[j].Nb_Recursives) + { + /*tmp_output << " g1_tmp_r(" << eqr+1 << ", " + << varr+1-ModelBlock->Block_List[j].Nb_Recursives << ") = "; + NodeID tmp_n; + if (ModelBlock->Block_List[j].Equation_Type[eqr] == E_EVALUATE) + tmp_n = equations[ModelBlock->Block_List[j].Equation[eqr]]; + else + tmp_n = ModelBlock->Block_List[j].Equation_Normalized[eqr]; + int deriv_id = getDerivID(symbol_table.getID(eEndogenous, var),0); + NodeID ChaineRule_Derivative = tmp_n->getChaineRuleDerivative(deriv_id ,recursive_variables); + ChaineRule_Derivative->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms); + output << " %1 variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, var)) + << "(" << k + << ") " << var+1 + << ", equation=" << eq+1 << endl;*/ + } + } + else + { + if (varr>=ModelBlock->Block_List[j].Nb_Recursives) + { + output << " g1(" << eqr+1-ModelBlock->Block_List[j].Nb_Recursives << ", " + << varr+1-ModelBlock->Block_List[j].Nb_Recursives << ") = "; + /*writeDerivative(output, eq, symbol_table.getID(eEndogenous, var), k, oMatlabDynamicModelSparse, temporary_terms);*/ + /*if (ModelBlock->Block_List[j].Equation_Type[eqr] == E_EVALUATE or ModelBlock->Block_List[j].Equation_Type[eqr] == E_SOLVE) + derivative_exist = equations[ModelBlock->Block_List[j].Equation[eqr]]->writeOutputDerivativesRespectToFeedBackVariables(tmp_output, oMatlabDynamicModelSparse, temporary_terms, eq, var, varr, 0, 0, recursive_variables, feedback_variables); + else + derivative_exist = ModelBlock->Block_List[j].Equation_Normalized[eqr]->writeOutputDerivativesRespectToFeedBackVariables(tmp_output, oMatlabDynamicModelSparse, temporary_terms, eq, var, varr, 0, 0, recursive_variables, feedback_variables); + //if (derivative_exist) + output << tmp_output.str() << ";";*/ + NodeID tmp_n; + //if (ModelBlock->Block_List[j].Equation_Type[eqr] == E_EVALUATE or ModelBlock->Block_List[j].Equation_Type[eqr] == E_SOLVE) + tmp_n = equations[ModelBlock->Block_List[j].Equation[eqr]]; + /*else + tmp_n = ModelBlock->Block_List[j].Equation_Normalized[eqr];*/ + //cout << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"; + //cout << "derivaive eq=" << eq << " var=" << var << " k0=" << k << "\n"; + int deriv_id = getDerivID(symbol_table.getID(eEndogenous, var),0); + map recursive_variables_save(recursive_variables); + NodeID ChaineRule_Derivative = tmp_n->getChaineRuleDerivative(deriv_id ,recursive_variables, var, 0); + recursive_variables = recursive_variables_save; + ChaineRule_Derivative->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms); + output << ";"; + output << " %2 variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, var)) + << "(" << k + << ") " << var+1 + << ", equation=" << eq+1 << endl; + } + } + /*if (eqrBlock_List[j].Nb_Recursives or varrBlock_List[j].Nb_Recursives) + output << " g1(" << eqr+1-ModelBlock->Block_List[j].Nb_Recursives << ", " + << varr+1-ModelBlock->Block_List[j].Nb_Recursives << ") = "; + writeDerivative(output, eq, symbol_table.getID(eEndogenous, var), 0, oMatlabDynamicModelSparse, temporary_terms); + output << "; % variable=" << symbol_table.getName(var) + << "(0) " << var+1 + << ", equation=" << eq+1 << endl;*/ + } + output << " end;\n"; + //output << " ya = y;\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++) + { + k=m-ModelBlock->Block_List[j].Max_Lag; + for (i=0;iBlock_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 eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ[i]; + int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Var[i]; + bool derivative_exist; + ostringstream tmp_output; + //cout << "ModelBlock->Block_List[" << j << "].Nb_Recursives=" << ModelBlock->Block_List[j].Nb_Recursives << "\n"; + if (eqrBlock_List[j].Nb_Recursives) + { + /*if (varrBlock_List[j].Nb_Recursives) + { + if (k==0) + Uf[ModelBlock->Block_List[j].Equation[eqr]] << "+g1_tmp_r(" << eqr+1 + << ", " << varr+1 + << "+" << ModelBlock->Block_List[j].Size*ModelBlock->Block_List[j].Max_Lag << ")*y(it_, " << var+1 << ")"; + else if (k>0) + Uf[ModelBlock->Block_List[j].Equation[eqr]] << "+g1_tmp_r(" << eqr+1 + << ", " << varr+1 + << "+" << ModelBlock->Block_List[j].Size << "*" << k+ModelBlock->Block_List[j].Max_Lag << ")*y(it_+" << k << ", " << var+1 << ")"; + else if (k<0) + Uf[ModelBlock->Block_List[j].Equation[eqr]] << "+g1_tmp_r(" << eqr+1 + << ", " << varr+1 + << "+" << ModelBlock->Block_List[j].Size << "*" << k+ModelBlock->Block_List[j].Max_Lag << ")*y(it_" << k << ", " << var+1 << ")"; + if (k==0) + tmp_output << " g1_tmp_r(" << eqr+1 << ", " + << varr+1 << "+" << ModelBlock->Block_List[j].Size << "*" << ModelBlock->Block_List[j].Max_Lag << ") = "; + else if (k>0) + tmp_output << " g1_tmp_r(" << eqr+1 << ", " + << varr+1 << "+" << ModelBlock->Block_List[j].Size << "*" << k+ModelBlock->Block_List[j].Max_Lag << ") = "; + else if (k<0) + tmp_output << " g1_tmp_r(" << eqr+1 << ", " + << varr+1 << "+" << ModelBlock->Block_List[j].Size << "*" << k+ModelBlock->Block_List[j].Max_Lag << ") = "; + if (ModelBlock->Block_List[j].Equation_Type[eqr] == E_EVALUATE) + derivative_exist = equations[ModelBlock->Block_List[j].Equation[eqr]]->get_arg2()->writeOutputDerivativesRespectToFeedBackVariables(tmp_output, oMatlabDynamicModelSparse, temporary_terms, eq, var, varr, k, ModelBlock->Block_List[j].Max_Lag, recursive_variables, feedback_variables); + else + { + BinaryOpNode* tt = (BinaryOpNode*)ModelBlock->Block_List[j].Equation_Normalized[eqr]; + derivative_exist = tt->get_arg2()->writeOutputDerivativesRespectToFeedBackVariables(tmp_output, oMatlabDynamicModelSparse, temporary_terms, eq, var, varr, k, ModelBlock->Block_List[j].Max_Lag, recursive_variables, feedback_variables); + } + if (derivative_exist) + output << tmp_output.str() << ";"; + else + { + //output << "1" << ";"; + if (ModelBlock->Block_List[j].Equation_Type[eqr] != E_EVALUATE) + { + + } + } + //writeDerivative(output, eq, symbol_table.getID(eEndogenous, var), k, oMatlabDynamicModelSparse, temporary_terms); + output << " %1 variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, var)) + << "(" << k << ") " << var+1 + << ", equation=" << eq+1 << " derivative_exist=" << derivative_exist << " varr+1=" << varr+1 << endl; + }*/ + } + else + { + if (varr>=ModelBlock->Block_List[j].Nb_Recursives) + { + if (k==0) + Uf[ModelBlock->Block_List[j].Equation[eqr]] << "+g1(" << eqr+1-ModelBlock->Block_List[j].Nb_Recursives + << "+Per_J_, " << varr+1-ModelBlock->Block_List[j].Nb_Recursives + << "+Per_K_)*y(it_, " << var+1 << ")"; + else if (k==1) + Uf[ModelBlock->Block_List[j].Equation[eqr]] << "+g1(" << eqr+1-ModelBlock->Block_List[j].Nb_Recursives + << "+Per_J_, " << varr+1-ModelBlock->Block_List[j].Nb_Recursives + << "+Per_y_)*y(it_+1, " << var+1 << ")"; + else if (k>0) + Uf[ModelBlock->Block_List[j].Equation[eqr]] << "+g1(" << eqr+1-ModelBlock->Block_List[j].Nb_Recursives + << "+Per_J_, " << varr+1-ModelBlock->Block_List[j].Nb_Recursives + << "+y_size*(it_+" << k-1 << "))*y(it_+" << k << ", " << var+1 << ")"; + else if (k<0) + Uf[ModelBlock->Block_List[j].Equation[eqr]] << "+g1(" << eqr+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_J_, " + << varr+1-ModelBlock->Block_List[j].Nb_Recursives + << "+y_size*(it_" << k-1 << "))*y(it_" << k << ", " << var+1 << ")"; + if (k==0) + tmp_output << " g1(" << eqr+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_J_, " + << varr+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_K_) = "; + else if (k==1) + tmp_output << " g1(" << eqr+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_J_, " + << varr+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_y_) = "; + else if (k>0) + tmp_output << " g1(" << eqr+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_J_, " + << varr+1-ModelBlock->Block_List[j].Nb_Recursives << "+y_size*(it_+" << k-1 << ")) = "; + else if (k<0) + tmp_output << " g1(" << eqr+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_J_, " + << varr+1-ModelBlock->Block_List[j].Nb_Recursives << "+y_size*(it_" << k-1 << ")) = "; + /*NodeID tmp_n; + if (ModelBlock->Block_List[j].Equation_Type[eqr] == E_EVALUATE or ModelBlock->Block_List[j].Equation_Type[eqr] == E_SOLVE) + tmp_n = equations[ModelBlock->Block_List[j].Equation[eqr]]; + else + tmp_n = ModelBlock->Block_List[j].Equation_Normalized[eqr];*/ + /*int deriv_id = getDerivID(symbol_table.getID(eEndogenous, var),k); + //cout << "-------------------------------------------------------------------------------------\n"; + //cout << "derivaive eq=" << eq << " var=" << var << " k=" << k << "\n"; + //output << " " << tmp_output.str(); + map recursive_variables_save(recursive_variables); + NodeID ChaineRule_Derivative = tmp_n->getChaineRuleDerivative(deriv_id ,recursive_variables, var, k); + recursive_variables = recursive_variables_save; + //ChaineRule_Derivative->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms); + */ + /*if (ModelBlock->Block_List[j].Equation_Type[eqr] == E_EVALUATE or ModelBlock->Block_List[j].Equation_Type[eqr] == E_SOLVE) + derivative_exist = equations[ModelBlock->Block_List[j].Equation[eqr]]->writeOutputDerivativesRespectToFeedBackVariables(tmp_output, oMatlabDynamicModelSparse, temporary_terms, eq, var, varr, k, ModelBlock->Block_List[j].Max_Lag, recursive_variables, feedback_variables); + else + derivative_exist = ModelBlock->Block_List[j].Equation_Normalized[eqr]->writeOutputDerivativesRespectToFeedBackVariables(tmp_output, oMatlabDynamicModelSparse, temporary_terms, eq, var, varr, k, ModelBlock->Block_List[j].Max_Lag, recursive_variables, feedback_variables); + if (derivative_exist) + output << tmp_output.str() << ";";*/ + + /*output << tmp_output.str();*/ + //output << ";"; + //output << "\n%"; + output << tmp_output.str(); + writeDerivative(output, eq, symbol_table.getID(eEndogenous, var), k, oMatlabDynamicModelSparse, temporary_terms); + output << ";"; + + output << " %2 variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, var)) + << "(" << k << ") " << var+1 + << ", equation=" << eq+1 << endl; + } + /*else + { + if (k==0) + tmp_output << " g1_tmp_b(" << eqr+1-ModelBlock->Block_List[j].Nb_Recursives << ", " + << varr+1 << "+" << ModelBlock->Block_List[j].Size << "*" << ModelBlock->Block_List[j].Max_Lag << ") = "; + else if (k>0) + tmp_output << " g1_tmp_b(" << eqr+1-ModelBlock->Block_List[j].Nb_Recursives << ", " + << varr+1 << "+" << ModelBlock->Block_List[j].Size << "*" << k+ModelBlock->Block_List[j].Max_Lag << ") = "; + else if (k<0) + tmp_output << " g1_tmp_b(" << eqr+1-ModelBlock->Block_List[j].Nb_Recursives << ", " + << varr+1 << "+" << ModelBlock->Block_List[j].Size << "*" << k+ModelBlock->Block_List[j].Max_Lag << ") = "; + if (ModelBlock->Block_List[j].Equation_Type[eqr] == E_EVALUATE or ModelBlock->Block_List[j].Equation_Type[eqr] == E_SOLVE) + derivative_exist = equations[ModelBlock->Block_List[j].Equation[eqr]]->writeOutputDerivativesRespectToFeedBackVariables(tmp_output, oMatlabDynamicModelSparse, temporary_terms, eq, var, varr, k, ModelBlock->Block_List[j].Max_Lag, recursive_variables, feedback_variables); + else + derivative_exist = ModelBlock->Block_List[j].Equation_Normalized[eqr]->writeOutputDerivativesRespectToFeedBackVariables(tmp_output, oMatlabDynamicModelSparse, temporary_terms, eq, var, varr, k, ModelBlock->Block_List[j].Max_Lag, recursive_variables, feedback_variables); + if (derivative_exist) + output << tmp_output.str() << ";"; + + if (k==0) + Uf[ModelBlock->Block_List[j].Equation[eqr]] << "+g1_tmp_b(" << eqr+1-ModelBlock->Block_List[j].Nb_Recursives + << ", " << varr+1 << "+" << ModelBlock->Block_List[j].Size << "*" << ModelBlock->Block_List[j].Max_Lag + << ")*y(it_, " << var+1 << ")"; + else if (k>0) + Uf[ModelBlock->Block_List[j].Equation[eqr]] << "+g1_tmp_b(" << eqr+1-ModelBlock->Block_List[j].Nb_Recursives + << ", " << varr+1 << "+" << ModelBlock->Block_List[j].Size << "*" << k+ModelBlock->Block_List[j].Max_Lag + << ")*y(it_+" << k << ", " << var+1 << ")"; + else if (k<0) + Uf[ModelBlock->Block_List[j].Equation[eqr]] << "+g1_tmp_b(" << eqr+1-ModelBlock->Block_List[j].Nb_Recursives + << ", " << varr+1 << "+" << ModelBlock->Block_List[j].Size << "*" << k+ModelBlock->Block_List[j].Max_Lag + << ")*y(it_" << k << ", " << var+1 << ")"; + output << " %2 variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, var)) + << "(" << k << ") " << var+1 + << ", equation=" << eq+1 << endl; + }*/ + } - m=ModelBlock->Block_List[j].Max_Lag; - for (i=0;iBlock_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 eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ[i]; - int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Var[i]; - output << " g1(" << eqr+1 << ", " << varr+1 << ") = "; - writeDerivative(output, eq, symbol_table.getID(eEndogenous, var), 0, oMatlabDynamicModelSparse, temporary_terms); - output << "; % variable=" << symbol_table.getName(var) - << "(0) " << var+1 - << ", equation=" << eq+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++) - { - k=m-ModelBlock->Block_List[j].Max_Lag; - for (i=0;iBlock_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 eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ[i]; - int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Var[i]; - if (k==0) - Uf[ModelBlock->Block_List[j].Equation[eqr]] << "+g1(" << eqr+1 << "+Per_J_, " << varr+1 << "+Per_K_)*y(it_, " << var+1 << ")"; - else if (k==1) - Uf[ModelBlock->Block_List[j].Equation[eqr]] << "+g1(" << eqr+1 << "+Per_J_, " << varr+1 << "+Per_y_)*y(it_+1, " << var+1 << ")"; - else if (k>0) - Uf[ModelBlock->Block_List[j].Equation[eqr]] << "+g1(" << eqr+1 << "+Per_J_, " << varr+1 << "+y_size*(it_+" << k-1 << "))*y(it_+" << k << ", " << var+1 << ")"; - else if (k<0) - Uf[ModelBlock->Block_List[j].Equation[eqr]] << "+g1(" << eqr+1 << "+Per_J_, " << varr+1 << "+y_size*(it_" << k-1 << "))*y(it_" << k << ", " << var+1 << ")"; - if (k==0) - output << " g1(" << eqr+1 << "+Per_J_, " << varr+1 << "+Per_K_) = "; - else if (k==1) - output << " g1(" << eqr+1 << "+Per_J_, " << varr+1 << "+Per_y_) = "; - else if (k>0) - output << " g1(" << eqr+1 << "+Per_J_, " << varr+1 << "+y_size*(it_+" << k-1 << ")) = "; - else if (k<0) - output << " g1(" << eqr+1 << "+Per_J_, " << varr+1 << "+y_size*(it_" << k-1 << ")) = "; - writeDerivative(output, eq, symbol_table.getID(eEndogenous, var), k, oMatlabDynamicModelSparse, temporary_terms); - output << "; % variable=" << symbol_table.getName(var) - << "(" << k << ") " << var+1 - << ", equation=" << eq+1 << endl; #ifdef CONDITION - output << " if (fabs(condition[" << eqr << "])Block_List[j].Size;i++) - { - output << " " << Uf[ModelBlock->Block_List[j].Equation[i]].str() << ";\n"; + } + } + for (i = 0;i < ModelBlock->Block_List[j].Size;i++) + { + if (i>=ModelBlock->Block_List[j].Nb_Recursives) + output << " " << Uf[ModelBlock->Block_List[j].Equation[i]].str() << ";\n"; #ifdef CONDITION - output << " if (fabs(condition(" << i+1 << "))Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++) - { - k=m-ModelBlock->Block_List[j].Max_Lag; - for (i=0;iBlock_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+1 << "+Per_u_) = u(" << u+1 << "+Per_u_) / condition(" << eqr+1 << ");\n"; - } - } - for (i = 0;i < ModelBlock->Block_List[j].Size;i++) - output << " u(" << i+1 << "+Per_u_) = u(" << i+1 << "+Per_u_) / condition(" << i+1 << ");\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;iBlock_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+1 << "+Per_u_) = u(" << u+1 << "+Per_u_) / condition(" << eqr+1 << ");\n"; + } + } + for (i = 0;i < ModelBlock->Block_List[j].Size;i++) + output << " u(" << i+1 << "+Per_u_) = u(" << i+1 << "+Per_u_) / condition(" << i+1 << ");\n"; #endif - output << " else" << endl; - 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;iBlock_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 eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ[i]; - int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Var[i]; - output << " g1(" << eqr+1 << ", " << varr+1+(m-ModelBlock->Block_List[j].Max_Lag+ModelBlock->Block_List[j].Max_Lag_Endo)*ModelBlock->Block_List[j].Size << ") = "; - writeDerivative(output, eq, symbol_table.getID(eEndogenous, var), k, oMatlabDynamicModelSparse, temporary_terms); - output << "; % variable=" << symbol_table.getName(var) - << "(" << k << ") " << var+1 - << ", equation=" << eq+1 << endl; - } - } - jacobian_max_endo_col=(ModelBlock->Block_List[j].Max_Lead_Endo+ModelBlock->Block_List[j].Max_Lag_Endo+1)*ModelBlock->Block_List[j].Size; - /*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;iBlock_List[j].IM_lead_lag[m].size_exo;i++) - { - int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_X_Index[i]; - int eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_X[i]; - int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Exogenous[i]; - int var=ModelBlock->Block_List[j].IM_lead_lag[m].Exogenous_Index[i]; - output << " g1_x(" << eqr+1 << ", " - << jacobian_max_endo_col+(m-(ModelBlock->Block_List[j].Max_Lag-ModelBlock->Block_List[j].Max_Lag_Exo))*ModelBlock->Block_List[j].nb_exo+varr+1 << ") = "; - writeDerivative(output, eq, symbol_table.getID(eExogenous, var), k, oMatlabDynamicModelSparse, temporary_terms); - output << "; % variable (exogenous)=" << symbol_table.getName(var) - << "(" << k << ") " << var+1 << " " << varr+1 - << ", equation=" << eq+1 << endl; - } - }*/ - 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; - if (block_triangular.incidencematrix.Model_Max_Lag_Endo - ModelBlock->Block_List[j].Max_Lag +m >=0) - { - for (i=0;iBlock_List[j].IM_lead_lag[m].size_other_endo;i++) - { - int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index_other_endo[i]; - 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 << ", " - << 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(var) - << "(" << k << ") " << var+1 - << ", equation=" << eq+1 << endl; - } - } - } - output << " varargout{1}=g1_x;\n"; - output << " varargout{2}=g1_o;\n"; - output << " end;\n"; - output << " end;\n"; - break; - default: - break; - } - prev_Simulation_Type=ModelBlock->Block_List[j].Simulation_Type; - output.close(); - } -} + output << " else" << endl; + 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;iBlock_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 eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ[i]; + int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Var[i]; + output << " g1(" << eqr+1 << ", " << varr+1+(m-ModelBlock->Block_List[j].Max_Lag+ModelBlock->Block_List[j].Max_Lag_Endo)*ModelBlock->Block_List[j].Size << ") = "; + writeDerivative(output, eq, symbol_table.getID(eEndogenous, var), k, oMatlabDynamicModelSparse, temporary_terms); + output << "; % variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, var)) + << "(" << k << ") " << var+1 + << ", equation=" << eq+1 << endl; + } + } + jacobian_max_endo_col=(ModelBlock->Block_List[j].Max_Lead_Endo+ModelBlock->Block_List[j].Max_Lag_Endo+1)*ModelBlock->Block_List[j].Size; + /*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;iBlock_List[j].IM_lead_lag[m].size_exo;i++) + { + int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_X_Index[i]; + int eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_X[i]; + int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Exogenous[i]; + int var=ModelBlock->Block_List[j].IM_lead_lag[m].Exogenous_Index[i]; + output << " g1_x(" << eqr+1 << ", " + << jacobian_max_endo_col+(m-(ModelBlock->Block_List[j].Max_Lag-ModelBlock->Block_List[j].Max_Lag_Exo))*ModelBlock->Block_List[j].nb_exo+varr+1 << ") = "; + writeDerivative(output, eq, symbol_table.getID(eExogenous, var), k, oMatlabDynamicModelSparse, temporary_terms); + output << "; % variable (exogenous)=" << symbol_table.getName(var) + << "(" << k << ") " << var+1 << " " << varr+1 + << ", equation=" << eq+1 << endl; + } + }*/ + 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; + if (block_triangular.incidencematrix.Model_Max_Lag_Endo - ModelBlock->Block_List[j].Max_Lag +m >=0) + { + for (i=0;iBlock_List[j].IM_lead_lag[m].size_other_endo;i++) + { + int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index_other_endo[i]; + 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 << ", " + << 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)) + << "(" << k << ") " << var+1 + << ", equation=" << eq+1 << endl; + } + } + } + output << " varargout{1}=g1_x;\n"; + output << " varargout{2}=g1_o;\n"; + output << " end;\n"; + //output << " ya = y;\n"; + output << " end;\n"; + break; + default: + break; + } + prev_Simulation_Type=ModelBlock->Block_List[j].Simulation_Type; + output.close(); + } + } void DynamicModel::writeModelEquationsCodeOrdered(const string file_name, const Model_Block *ModelBlock, const string bin_basename, map_idx_type map_idx) const -{ - struct Uff_l { - int u, var, lag; - Uff_l *pNext; - }; + struct Uff_l + { + int u, var, lag; + Uff_l *pNext; + }; - struct Uff - { - Uff_l *Ufl, *Ufl_First; - int eqr; - }; + struct Uff + { + Uff_l *Ufl, *Ufl_First; + int eqr; + }; - int i,j,k,m, v, ModelBlock_Aggregated_Count, k0, k1; - 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 reference_count; - map ModelBlock_Aggregated_Size, ModelBlock_Aggregated_Number; - int prev_Simulation_Type=-1; - //SymbolicGaussElimination SGE; - bool file_open=false; - temporary_terms_type::const_iterator it_temp=temporary_terms.begin(); - //---------------------------------------------------------------------- - string main_name=file_name; - main_name+=".cod"; - code_file.open(main_name.c_str(), ios::out | ios::binary | ios::ate ); - if (!code_file.is_open()) - { - cout << "Error : Can't open file \"" << main_name << "\" for writing\n"; - exit(EXIT_FAILURE); - } - //Temporary variables declaration - code_file.write(&FDIMT, sizeof(FDIMT)); - k=temporary_terms.size(); - code_file.write(reinterpret_cast(&k),sizeof(k)); - //search for successive and identical blocks - i=k=k0=0; - ModelBlock_Aggregated_Count=-1; - for (j = 0;j < ModelBlock->Size;j++) - { - if (BlockTriangular::BlockSim(prev_Simulation_Type)==BlockTriangular::BlockSim(ModelBlock->Block_List[j].Simulation_Type) - && (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 )) - { - } - else - { - k=k0=0; - ModelBlock_Aggregated_Count++; - } - k0+=ModelBlock->Block_List[j].Size; - ModelBlock_Aggregated_Number[ModelBlock_Aggregated_Count]=k0; - ModelBlock_Aggregated_Size[ModelBlock_Aggregated_Count]=++k; - prev_Simulation_Type=ModelBlock->Block_List[j].Simulation_Type; - } - ModelBlock_Aggregated_Count++; - //For each block - j=0; - for (k0 = 0;k0 < ModelBlock_Aggregated_Count;k0++) - { - k1=j; - if (k0>0) - code_file.write(&FENDBLOCK, sizeof(FENDBLOCK)); - code_file.write(&FBEGINBLOCK, sizeof(FBEGINBLOCK)); - v=ModelBlock_Aggregated_Number[k0]; - code_file.write(reinterpret_cast(&v),sizeof(v)); - v=ModelBlock->Block_List[j].Simulation_Type; - code_file.write(reinterpret_cast(&v),sizeof(v)); - for (k=0; kBlock_List[j].Size;i++) - { - code_file.write(reinterpret_cast(&ModelBlock->Block_List[j].Variable[i]),sizeof(ModelBlock->Block_List[j].Variable[i])); - code_file.write(reinterpret_cast(&ModelBlock->Block_List[j].Equation[i]),sizeof(ModelBlock->Block_List[j].Equation[i])); - code_file.write(reinterpret_cast(&ModelBlock->Block_List[j].Own_Derivative[i]),sizeof(ModelBlock->Block_List[j].Own_Derivative[i])); - } - j++; - } - j=k1; - if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_SIMPLE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE || - ModelBlock->Block_List[j].Simulation_Type==SOLVE_BACKWARD_COMPLETE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_FORWARD_COMPLETE) - { - code_file.write(reinterpret_cast(&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; - code_file.write(reinterpret_cast(&v),sizeof(v)); - v=symbol_table.endo_nbr(); - code_file.write(reinterpret_cast(&v),sizeof(v)); - v=block_triangular.ModelBlock->Block_List[j].Max_Lag; - code_file.write(reinterpret_cast(&v),sizeof(v)); - v=block_triangular.ModelBlock->Block_List[j].Max_Lead; - code_file.write(reinterpret_cast(&v),sizeof(v)); - //if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_SIMPLE) - //{ - int u_count_int=0; - 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); - v=u_count_int; - code_file.write(reinterpret_cast(&v),sizeof(v)); - file_open=true; - //} - } - for (k1 = 0; k1 < ModelBlock_Aggregated_Size[k0]; k1++) - { - //For a block composed of a single equation determines whether we have to evaluate or to solve the equation - 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++) - { - //ModelBlock->Block_List[j].Variable_Sorted[i] = variable_table.getID(eEndogenous, ModelBlock->Block_List[j].Variable[i], 0); - //The Temporary terms - temporary_terms_type tt2; + int i,j,k,m, v, ModelBlock_Aggregated_Count, k0, k1; + 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 reference_count; + map ModelBlock_Aggregated_Size, ModelBlock_Aggregated_Number; + int prev_Simulation_Type=-1; + //SymbolicGaussElimination SGE; + bool file_open=false; + //temporary_terms_type::const_iterator it_temp=temporary_terms.begin(); + //---------------------------------------------------------------------- + string main_name=file_name; + main_name+=".cod"; + code_file.open(main_name.c_str(), ios::out | ios::binary | ios::ate ); + if (!code_file.is_open()) + { + cout << "Error : Can't open file \"" << main_name << "\" for writing\n"; + exit(EXIT_FAILURE); + } + //Temporary variables declaration + code_file.write(&FDIMT, sizeof(FDIMT)); + k=temporary_terms.size(); + code_file.write(reinterpret_cast(&k),sizeof(k)); + //search for successive and identical blocks + i=k=k0=0; + ModelBlock_Aggregated_Count=-1; + for (j = 0;j < ModelBlock->Size;j++) + { + if (BlockTriangular::BlockSim(prev_Simulation_Type)==BlockTriangular::BlockSim(ModelBlock->Block_List[j].Simulation_Type) + && (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 */)) + { + } + else + { + k=k0=0; + ModelBlock_Aggregated_Count++; + } + k0+=ModelBlock->Block_List[j].Size; + ModelBlock_Aggregated_Number[ModelBlock_Aggregated_Count]=k0; + ModelBlock_Aggregated_Size[ModelBlock_Aggregated_Count]=++k; + prev_Simulation_Type=ModelBlock->Block_List[j].Simulation_Type; + } + ModelBlock_Aggregated_Count++; + //For each block + j=0; + for (k0 = 0;k0 < ModelBlock_Aggregated_Count;k0++) + { + k1=j; + if (k0>0) + code_file.write(&FENDBLOCK, sizeof(FENDBLOCK)); + code_file.write(&FBEGINBLOCK, sizeof(FBEGINBLOCK)); + v=ModelBlock_Aggregated_Number[k0]; + code_file.write(reinterpret_cast(&v),sizeof(v)); + v=ModelBlock->Block_List[j].Simulation_Type; + code_file.write(reinterpret_cast(&v),sizeof(v)); + for (k=0; kBlock_List[j].Size;i++) + { + code_file.write(reinterpret_cast(&ModelBlock->Block_List[j].Variable[i]),sizeof(ModelBlock->Block_List[j].Variable[i])); + code_file.write(reinterpret_cast(&ModelBlock->Block_List[j].Equation[i]),sizeof(ModelBlock->Block_List[j].Equation[i])); + code_file.write(reinterpret_cast(&ModelBlock->Block_List[j].Own_Derivative[i]),sizeof(ModelBlock->Block_List[j].Own_Derivative[i])); + } + j++; + } + j=k1; + if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_SIMPLE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE || + ModelBlock->Block_List[j].Simulation_Type==SOLVE_BACKWARD_COMPLETE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_FORWARD_COMPLETE) + { + code_file.write(reinterpret_cast(&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; + code_file.write(reinterpret_cast(&v),sizeof(v)); + v=symbol_table.endo_nbr(); + code_file.write(reinterpret_cast(&v),sizeof(v)); + v=block_triangular.ModelBlock->Block_List[j].Max_Lag; + code_file.write(reinterpret_cast(&v),sizeof(v)); + v=block_triangular.ModelBlock->Block_List[j].Max_Lead; + code_file.write(reinterpret_cast(&v),sizeof(v)); + //if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_SIMPLE) + //{ + int u_count_int=0; + 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); + v=u_count_int; + code_file.write(reinterpret_cast(&v),sizeof(v)); + file_open=true; + //} + } + for (k1 = 0; k1 < ModelBlock_Aggregated_Size[k0]; k1++) + { + //For a block composed of a single equation determines whether we have to evaluate or to solve the equation + 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++) + { + //ModelBlock->Block_List[j].Variable_Sorted[i] = variable_table.getID(eEndogenous, ModelBlock->Block_List[j].Variable[i], 0); + //The Temporary terms + temporary_terms_type tt2; #ifdef DEBUGC - k=0; + 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); - code_file.write(&FSTPT, sizeof(FSTPT)); - map_idx_type::const_iterator ii=map_idx.find((*it)->idx); - v=(int)ii->second; - code_file.write(reinterpret_cast(&v), sizeof(v)); - // Insert current node into tt2 - tt2.insert(*it); + 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); + code_file.write(&FSTPT, sizeof(FSTPT)); + map_idx_type::const_iterator ii=map_idx.find((*it)->idx); + v=(int)ii->second; + code_file.write(reinterpret_cast(&v), sizeof(v)); + // Insert current node into tt2 + tt2.insert(*it); #ifdef DEBUGC - cout << "FSTPT " << v << "\n"; - code_file.write(&FOK, sizeof(FOK)); - code_file.write(reinterpret_cast(&k), sizeof(k)); - ki++; + cout << "FSTPT " << v << "\n"; + code_file.write(&FOK, sizeof(FOK)); + code_file.write(reinterpret_cast(&k), sizeof(k)); + ki++; #endif - } + } #ifdef DEBUGC - for (temporary_terms_type::const_iterator it = ModelBlock->Block_List[j].Temporary_terms->begin(); - it != ModelBlock->Block_List[j].Temporary_terms->end(); it++) - { - map_idx_type::const_iterator ii=map_idx.find((*it)->idx); - cout << "map_idx[" << (*it)->idx <<"]=" << ii->second << "\n"; - } + for (temporary_terms_type::const_iterator it = ModelBlock->Block_List[j].Temporary_terms->begin(); + it != ModelBlock->Block_List[j].Temporary_terms->end(); it++) + { + map_idx_type::const_iterator ii=map_idx.find((*it)->idx); + 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) - { - case EVALUATE_BACKWARD: - case EVALUATE_FORWARD: - rhs->compile(code_file, false, temporary_terms, map_idx); - lhs->compile(code_file, true, temporary_terms, map_idx); - break; - case EVALUATE_BACKWARD_R: - case EVALUATE_FORWARD_R: - lhs->compile(code_file, false, temporary_terms, map_idx); - rhs->compile(code_file, true, temporary_terms, map_idx); - break; - case SOLVE_BACKWARD_COMPLETE: - case SOLVE_FORWARD_COMPLETE: - v=ModelBlock->Block_List[j].Equation[i]; - Uf[v].eqr=i; - Uf[v].Ufl=NULL; - goto end; - case SOLVE_TWO_BOUNDARIES_COMPLETE: - case SOLVE_TWO_BOUNDARIES_SIMPLE: - 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); - code_file.write(&FBINARY, sizeof(FBINARY)); - int v=oMinus; - code_file.write(reinterpret_cast(&v),sizeof(v)); - code_file.write(&FSTPR, sizeof(FSTPR)); - code_file.write(reinterpret_cast(&i), sizeof(i)); + 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) + { + case EVALUATE_BACKWARD: + 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); + } + 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); + } + break; + /*case EVALUATE_BACKWARD_R: + case EVALUATE_FORWARD_R: + lhs->compile(code_file, false, temporary_terms, map_idx); + rhs->compile(code_file, true, temporary_terms, map_idx); + break;*/ + case SOLVE_BACKWARD_COMPLETE: + case SOLVE_FORWARD_COMPLETE: + v=ModelBlock->Block_List[j].Equation[i]; + Uf[v].eqr=i; + Uf[v].Ufl=NULL; + goto end; + case SOLVE_TWO_BOUNDARIES_COMPLETE: + case SOLVE_TWO_BOUNDARIES_SIMPLE: + 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); + code_file.write(&FBINARY, sizeof(FBINARY)); + int v=oMinus; + code_file.write(reinterpret_cast(&v),sizeof(v)); + code_file.write(&FSTPR, sizeof(FSTPR)); + code_file.write(reinterpret_cast(&i), sizeof(i)); #ifdef CONDITION - if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE) - output << " condition[" << i << "]=0;\n"; + if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE) + output << " condition[" << i << "]=0;\n"; #endif - } - } - code_file.write(&FENDEQU, sizeof(FENDEQU)); - // The Jacobian if we have to solve the block - 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) - { - switch (ModelBlock->Block_List[j].Simulation_Type) - { - case SOLVE_BACKWARD_SIMPLE: - case SOLVE_FORWARD_SIMPLE: - compileDerivative(code_file, ModelBlock->Block_List[j].Equation[0], ModelBlock->Block_List[j].Variable[0], 0, map_idx); - code_file.write(&FSTPG, sizeof(FSTPG)); - v=0; - code_file.write(reinterpret_cast(&v), sizeof(v)); - break; - case SOLVE_BACKWARD_COMPLETE: - case SOLVE_FORWARD_COMPLETE: - m=ModelBlock->Block_List[j].Max_Lag; - for (i=0;iBlock_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].us[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; - compileDerivative(code_file, eq, var, 0, map_idx); - code_file.write(&FSTPU, sizeof(FSTPU)); - code_file.write(reinterpret_cast(&u), sizeof(u)); - } - for (i = 0;i < ModelBlock->Block_List[j].Size;i++) - { - code_file.write(&FLDR, sizeof(FLDR)); - code_file.write(reinterpret_cast(&i), sizeof(i)); - 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(&Uf[v].Ufl->u), sizeof(Uf[v].Ufl->u)); - code_file.write(&FLDV, sizeof(FLDV)); - char vc=eEndogenous; - code_file.write(reinterpret_cast(&vc), sizeof(vc)); - code_file.write(reinterpret_cast(&Uf[v].Ufl->var), sizeof(Uf[v].Ufl->var)); - int v1=0; - code_file.write(reinterpret_cast(&v1), sizeof(v1)); - code_file.write(&FBINARY, sizeof(FBINARY)); - v1=oTimes; - code_file.write(reinterpret_cast(&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(&v), sizeof(v)); - code_file.write(&FSTPU, sizeof(FSTPU)); - code_file.write(reinterpret_cast(&i), sizeof(i)); - } - break; - case SOLVE_TWO_BOUNDARIES_COMPLETE: - case SOLVE_TWO_BOUNDARIES_SIMPLE: - 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;iBlock_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(&u), sizeof(u)); + } + } + code_file.write(&FENDEQU, sizeof(FENDEQU)); + // The Jacobian if we have to solve the block + 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*/) + { + switch (ModelBlock->Block_List[j].Simulation_Type) + { + case SOLVE_BACKWARD_SIMPLE: + case SOLVE_FORWARD_SIMPLE: + compileDerivative(code_file, ModelBlock->Block_List[j].Equation[0], ModelBlock->Block_List[j].Variable[0], 0, map_idx); + code_file.write(&FSTPG, sizeof(FSTPG)); + v=0; + code_file.write(reinterpret_cast(&v), sizeof(v)); + break; + case SOLVE_BACKWARD_COMPLETE: + case SOLVE_FORWARD_COMPLETE: + m=ModelBlock->Block_List[j].Max_Lag; + for (i=0;iBlock_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].us[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; + compileDerivative(code_file, eq, var, 0, map_idx); + code_file.write(&FSTPU, sizeof(FSTPU)); + code_file.write(reinterpret_cast(&u), sizeof(u)); + } + for (i = 0;i < ModelBlock->Block_List[j].Size;i++) + { + code_file.write(&FLDR, sizeof(FLDR)); + code_file.write(reinterpret_cast(&i), sizeof(i)); + 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(&Uf[v].Ufl->u), sizeof(Uf[v].Ufl->u)); + code_file.write(&FLDV, sizeof(FLDV)); + char vc=eEndogenous; + code_file.write(reinterpret_cast(&vc), sizeof(vc)); + code_file.write(reinterpret_cast(&Uf[v].Ufl->var), sizeof(Uf[v].Ufl->var)); + int v1=0; + code_file.write(reinterpret_cast(&v1), sizeof(v1)); + code_file.write(&FBINARY, sizeof(FBINARY)); + v1=oTimes; + code_file.write(reinterpret_cast(&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(&v), sizeof(v)); + code_file.write(&FSTPU, sizeof(FSTPU)); + code_file.write(reinterpret_cast(&i), sizeof(i)); + } + break; + case SOLVE_TWO_BOUNDARIES_COMPLETE: + case SOLVE_TWO_BOUNDARIES_SIMPLE: + 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;iBlock_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(&u), sizeof(u)); #ifdef CONDITION - output << " if (fabs(condition[" << eqr << "])Block_List[j].Size;i++) - { - code_file.write(&FLDR, sizeof(FLDR)); - code_file.write(reinterpret_cast(&i), sizeof(i)); - 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(&Uf[v].Ufl->u), sizeof(Uf[v].Ufl->u)); - code_file.write(&FLDV, sizeof(FLDV)); - char vc=eEndogenous; - code_file.write(reinterpret_cast(&vc), sizeof(vc)); - int v1=Uf[v].Ufl->var; - code_file.write(reinterpret_cast(&v1), sizeof(v1)); - v1=Uf[v].Ufl->lag; - code_file.write(reinterpret_cast(&v1), sizeof(v1)); - code_file.write(&FBINARY, sizeof(FBINARY)); - v1=oTimes; - code_file.write(reinterpret_cast(&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(&v), sizeof(v)); - code_file.write(&FSTPU, sizeof(FSTPU)); - code_file.write(reinterpret_cast(&i), sizeof(i)); + } + } + for (i = 0;i < ModelBlock->Block_List[j].Size;i++) + { + code_file.write(&FLDR, sizeof(FLDR)); + code_file.write(reinterpret_cast(&i), sizeof(i)); + 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(&Uf[v].Ufl->u), sizeof(Uf[v].Ufl->u)); + code_file.write(&FLDV, sizeof(FLDV)); + char vc=eEndogenous; + code_file.write(reinterpret_cast(&vc), sizeof(vc)); + int v1=Uf[v].Ufl->var; + code_file.write(reinterpret_cast(&v1), sizeof(v1)); + v1=Uf[v].Ufl->lag; + code_file.write(reinterpret_cast(&v1), sizeof(v1)); + code_file.write(&FBINARY, sizeof(FBINARY)); + v1=oTimes; + code_file.write(reinterpret_cast(&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(&v), sizeof(v)); + code_file.write(&FSTPU, sizeof(FSTPU)); + code_file.write(reinterpret_cast(&i), sizeof(i)); #ifdef CONDITION - output << " if (fabs(condition[" << i << "])Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++) - { - k=m-ModelBlock->Block_List[j].Max_Lag; - for (i=0;iBlock_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"; + 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;iBlock_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; - } + break; + default: + break; + } - prev_Simulation_Type=ModelBlock->Block_List[j].Simulation_Type; - } - j++; - } - } - code_file.write(&FENDBLOCK, sizeof(FENDBLOCK)); - code_file.write(&FEND, sizeof(FEND)); - code_file.close(); -} + prev_Simulation_Type=ModelBlock->Block_List[j].Simulation_Type; + } + j++; + } + } + code_file.write(&FENDBLOCK, sizeof(FENDBLOCK)); + code_file.write(&FEND, sizeof(FEND)); + code_file.close(); + } void DynamicModel::writeDynamicMFile(const string &dynamic_basename) const -{ - string filename = dynamic_basename + ".m"; + { + string filename = dynamic_basename + ".m"; - ofstream mDynamicModelFile; - mDynamicModelFile.open(filename.c_str(), ios::out | ios::binary); - if (!mDynamicModelFile.is_open()) - { - cerr << "Error: Can't open file " << filename << " for writing" << endl; - exit(EXIT_FAILURE); - } - mDynamicModelFile << "function [residual, g1, g2, g3] = " << dynamic_basename << "(y, x, params, it_)" << endl - << "%" << endl - << "% Status : Computes dynamic model for Dynare" << endl - << "%" << endl - << "% Warning : this file is generated automatically by Dynare" << endl - << "% from model file (.mod)" << endl << endl; + ofstream mDynamicModelFile; + mDynamicModelFile.open(filename.c_str(), ios::out | ios::binary); + if (!mDynamicModelFile.is_open()) + { + cerr << "Error: Can't open file " << filename << " for writing" << endl; + exit(EXIT_FAILURE); + } + mDynamicModelFile << "function [residual, g1, g2, g3] = " << dynamic_basename << "(y, x, params, it_)" << endl + << "%" << endl + << "% Status : Computes dynamic model for Dynare" << endl + << "%" << endl + << "% Warning : this file is generated automatically by Dynare" << endl + << "% from model file (.mod)" << endl << endl; - writeDynamicModel(mDynamicModelFile); + writeDynamicModel(mDynamicModelFile); - mDynamicModelFile.close(); -} + mDynamicModelFile.close(); + } void DynamicModel::writeDynamicCFile(const string &dynamic_basename) const -{ - string filename = dynamic_basename + ".c"; - ofstream mDynamicModelFile; + { + string filename = dynamic_basename + ".c"; + ofstream mDynamicModelFile; - mDynamicModelFile.open(filename.c_str(), ios::out | ios::binary); - if (!mDynamicModelFile.is_open()) - { - cerr << "Error: Can't open file " << filename << " for writing" << endl; - exit(EXIT_FAILURE); - } - mDynamicModelFile << "/*" << endl - << " * " << filename << " : Computes dynamic model for Dynare" << endl - << " *" << endl - << " * Warning : this file is generated automatically by Dynare" << endl - << " * from model file (.mod)" << endl - << endl - << " */" << endl - << "#include " << endl - << "#include \"mex.h\"" << endl; + mDynamicModelFile.open(filename.c_str(), ios::out | ios::binary); + if (!mDynamicModelFile.is_open()) + { + cerr << "Error: Can't open file " << filename << " for writing" << endl; + exit(EXIT_FAILURE); + } + mDynamicModelFile << "/*" << endl + << " * " << filename << " : Computes dynamic model for Dynare" << endl + << " *" << endl + << " * Warning : this file is generated automatically by Dynare" << endl + << " * from model file (.mod)" << endl + << endl + << " */" << endl + << "#include " << endl + << "#include \"mex.h\"" << endl; - // Writing the function body - writeDynamicModel(mDynamicModelFile); + // Writing the function body + writeDynamicModel(mDynamicModelFile); - // Writing the gateway routine - mDynamicModelFile << "/* The gateway routine */" << endl - << "void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])" << endl - << "{" << endl - << " double *y, *x, *params;" << endl - << " double *residual, *g1, *g2;" << endl - << " int nb_row_x, it_;" << endl - << endl - << " /* Create a pointer to the input matrix y. */" << endl - << " y = mxGetPr(prhs[0]);" << endl - << endl - << " /* Create a pointer to the input matrix x. */" << endl - << " x = mxGetPr(prhs[1]);" << endl - << endl - << " /* Create a pointer to the input matrix params. */" << endl - << " params = mxGetPr(prhs[2]);" << endl - << endl - << " /* Fetch time index */" << endl - << " it_ = (int) mxGetScalar(prhs[3]) - 1;" << endl - << endl - << " /* Gets number of rows of matrix x. */" << endl - << " nb_row_x = mxGetM(prhs[1]);" << endl - << endl - << " residual = NULL;" << endl - << " if (nlhs >= 1)" << endl - << " {" << endl - << " /* Set the output pointer to the output matrix residual. */" << endl - << " plhs[0] = mxCreateDoubleMatrix(" << equations.size() << ",1, mxREAL);" << endl - << " /* Create a C pointer to a copy of the output matrix residual. */" << endl - << " residual = mxGetPr(plhs[0]);" << endl - << " }" << endl - << endl - << " g1 = NULL;" << endl - << " if (nlhs >= 2)" << endl - << " {" << endl - << " /* Set the output pointer to the output matrix g1. */" << endl + // Writing the gateway routine + mDynamicModelFile << "/* The gateway routine */" << endl + << "void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])" << endl + << "{" << endl + << " double *y, *x, *params;" << endl + << " double *residual, *g1, *g2;" << endl + << " int nb_row_x, it_;" << endl + << endl + << " /* Create a pointer to the input matrix y. */" << endl + << " y = mxGetPr(prhs[0]);" << endl + << endl + << " /* Create a pointer to the input matrix x. */" << endl + << " x = mxGetPr(prhs[1]);" << endl + << endl + << " /* Create a pointer to the input matrix params. */" << endl + << " params = mxGetPr(prhs[2]);" << endl + << endl + << " /* Fetch time index */" << endl + << " it_ = (int) mxGetScalar(prhs[3]) - 1;" << endl + << endl + << " /* Gets number of rows of matrix x. */" << endl + << " nb_row_x = mxGetM(prhs[1]);" << endl + << endl + << " residual = NULL;" << endl + << " if (nlhs >= 1)" << endl + << " {" << endl + << " /* Set the output pointer to the output matrix residual. */" << endl + << " plhs[0] = mxCreateDoubleMatrix(" << equations.size() << ",1, mxREAL);" << endl + << " /* Create a C pointer to a copy of the output matrix residual. */" << endl + << " residual = mxGetPr(plhs[0]);" << endl + << " }" << endl + << endl + << " g1 = NULL;" << endl + << " if (nlhs >= 2)" << endl + << " {" << endl + << " /* Set the output pointer to the output matrix g1. */" << endl - << " plhs[1] = mxCreateDoubleMatrix(" << equations.size() << ", " << dynJacobianColsNbr << ", mxREAL);" << endl - << " /* Create a C pointer to a copy of the output matrix g1. */" << endl - << " g1 = mxGetPr(plhs[1]);" << endl - << " }" << endl - << endl - << " g2 = NULL;" << endl - << " if (nlhs >= 3)" << endl - << " {" << endl - << " /* Set the output pointer to the output matrix g2. */" << endl - << " plhs[2] = mxCreateDoubleMatrix(" << equations.size() << ", " << dynJacobianColsNbr*dynJacobianColsNbr - << ", mxREAL);" << endl - << " /* Create a C pointer to a copy of the output matrix g1. */" << endl - << " g2 = mxGetPr(plhs[2]);" << endl - << " }" << endl - << endl - << " /* Call the C subroutines. */" << endl - << " Dynamic(y, x, nb_row_x, params, it_, residual, g1, g2);" << endl - << "}" << endl; - mDynamicModelFile.close(); -} + << " plhs[1] = mxCreateDoubleMatrix(" << equations.size() << ", " << dynJacobianColsNbr << ", mxREAL);" << endl + << " /* Create a C pointer to a copy of the output matrix g1. */" << endl + << " g1 = mxGetPr(plhs[1]);" << endl + << " }" << endl + << endl + << " g2 = NULL;" << endl + << " if (nlhs >= 3)" << endl + << " {" << endl + << " /* Set the output pointer to the output matrix g2. */" << endl + << " plhs[2] = mxCreateDoubleMatrix(" << equations.size() << ", " << dynJacobianColsNbr*dynJacobianColsNbr + << ", mxREAL);" << endl + << " /* Create a C pointer to a copy of the output matrix g1. */" << endl + << " g2 = mxGetPr(plhs[2]);" << endl + << " }" << endl + << endl + << " /* Call the C subroutines. */" << endl + << " Dynamic(y, x, nb_row_x, params, it_, residual, g1, g2);" << endl + << "}" << endl; + mDynamicModelFile.close(); + } string DynamicModel::reform(const string name1) const -{ - string name=name1; - int pos = name.find("\\", 0); - while (pos >= 0) - { - if (name.substr(pos + 1, 1) != "\\") - { - name = name.insert(pos, "\\"); - pos++; - } - pos++; - pos = name.find("\\", pos); - } - return (name); -} + { + string name=name1; + int pos = name.find("\\", 0); + while (pos >= 0) + { + if (name.substr(pos + 1, 1) != "\\") + { + name = name.insert(pos, "\\"); + pos++; + } + pos++; + pos = name.find("\\", pos); + } + return (name); + } void DynamicModel::Write_Inf_To_Bin_File(const string &dynamic_basename, const string &bin_basename, const int &num, int &u_count_int, bool &file_open, bool is_two_boundaries) const -{ - int j; - std::ofstream SaveCode; - if (file_open) - SaveCode.open((bin_basename + ".bin").c_str(), ios::out | ios::in | ios::binary | ios ::ate ); - else - SaveCode.open((bin_basename + ".bin").c_str(), ios::out | ios::binary); - if (!SaveCode.is_open()) - { - cout << "Error : Can't open file \"" << bin_basename << ".bin\" for writing\n"; - exit(EXIT_FAILURE); - } - u_count_int=0; - for (int m=0;m<=block_triangular.ModelBlock->Block_List[num].Max_Lead+block_triangular.ModelBlock->Block_List[num].Max_Lag;m++) - { - int k1=m-block_triangular.ModelBlock->Block_List[num].Max_Lag; - for (j=0;jBlock_List[num].IM_lead_lag[m].size;j++) - { - int varr=block_triangular.ModelBlock->Block_List[num].IM_lead_lag[m].Var[j]+k1*block_triangular.ModelBlock->Block_List[num].Size; - int u=block_triangular.ModelBlock->Block_List[num].IM_lead_lag[m].u[j]; - int eqr1=block_triangular.ModelBlock->Block_List[num].IM_lead_lag[m].Equ[j]; - SaveCode.write(reinterpret_cast(&eqr1), sizeof(eqr1)); - SaveCode.write(reinterpret_cast(&varr), sizeof(varr)); - SaveCode.write(reinterpret_cast(&k1), sizeof(k1)); - SaveCode.write(reinterpret_cast(&u), sizeof(u)); - u_count_int++; - } - } - if(is_two_boundaries) - { - for (j=0;jBlock_List[num].Size;j++) - { - int eqr1=j; - int varr=block_triangular.ModelBlock->Block_List[num].Size*(block_triangular.periods - +block_triangular.incidencematrix.Model_Max_Lead_Endo); - int k1=0; - SaveCode.write(reinterpret_cast(&eqr1), sizeof(eqr1)); - SaveCode.write(reinterpret_cast(&varr), sizeof(varr)); - SaveCode.write(reinterpret_cast(&k1), sizeof(k1)); - SaveCode.write(reinterpret_cast(&eqr1), sizeof(eqr1)); - u_count_int++; - } - } - //cout << "u_count_int=" << u_count_int << "\n"; - for (j=0;jBlock_List[num].Size;j++) - { - int varr=block_triangular.ModelBlock->Block_List[num].Variable[j]; - SaveCode.write(reinterpret_cast(&varr), sizeof(varr)); - } - for (j=0;jBlock_List[num].Size;j++) - { - int eqr1=block_triangular.ModelBlock->Block_List[num].Equation[j]; - SaveCode.write(reinterpret_cast(&eqr1), sizeof(eqr1)); - } - SaveCode.close(); -} + { + int j; + std::ofstream SaveCode; + if (file_open) + SaveCode.open((bin_basename + ".bin").c_str(), ios::out | ios::in | ios::binary | ios ::ate ); + else + SaveCode.open((bin_basename + ".bin").c_str(), ios::out | ios::binary); + if (!SaveCode.is_open()) + { + cout << "Error : Can't open file \"" << bin_basename << ".bin\" for writing\n"; + exit(EXIT_FAILURE); + } + u_count_int=0; + for (int m=0;m<=block_triangular.ModelBlock->Block_List[num].Max_Lead+block_triangular.ModelBlock->Block_List[num].Max_Lag;m++) + { + int k1=m-block_triangular.ModelBlock->Block_List[num].Max_Lag; + for (j=0;jBlock_List[num].IM_lead_lag[m].size;j++) + { + int varr=block_triangular.ModelBlock->Block_List[num].IM_lead_lag[m].Var[j]+k1*block_triangular.ModelBlock->Block_List[num].Size; + int u=block_triangular.ModelBlock->Block_List[num].IM_lead_lag[m].u[j]; + int eqr1=block_triangular.ModelBlock->Block_List[num].IM_lead_lag[m].Equ[j]; + SaveCode.write(reinterpret_cast(&eqr1), sizeof(eqr1)); + SaveCode.write(reinterpret_cast(&varr), sizeof(varr)); + SaveCode.write(reinterpret_cast(&k1), sizeof(k1)); + SaveCode.write(reinterpret_cast(&u), sizeof(u)); + u_count_int++; + } + } + if (is_two_boundaries) + { + for (j=0;jBlock_List[num].Size;j++) + { + int eqr1=j; + int varr=block_triangular.ModelBlock->Block_List[num].Size*(block_triangular.periods + +block_triangular.incidencematrix.Model_Max_Lead_Endo); + int k1=0; + SaveCode.write(reinterpret_cast(&eqr1), sizeof(eqr1)); + SaveCode.write(reinterpret_cast(&varr), sizeof(varr)); + SaveCode.write(reinterpret_cast(&k1), sizeof(k1)); + SaveCode.write(reinterpret_cast(&eqr1), sizeof(eqr1)); + u_count_int++; + } + } + //cout << "u_count_int=" << u_count_int << "\n"; + for (j=0;jBlock_List[num].Size;j++) + { + int varr=block_triangular.ModelBlock->Block_List[num].Variable[j]; + SaveCode.write(reinterpret_cast(&varr), sizeof(varr)); + } + for (j=0;jBlock_List[num].Size;j++) + { + int eqr1=block_triangular.ModelBlock->Block_List[num].Equation[j]; + SaveCode.write(reinterpret_cast(&eqr1), sizeof(eqr1)); + } + SaveCode.close(); + } void DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const string &basename, const int mode) const -{ - string sp; - ofstream mDynamicModelFile; - ostringstream tmp, tmp1, tmp_eq; - int prev_Simulation_Type, tmp_i; - //SymbolicGaussElimination SGE; - bool OK; - chdir(basename.c_str()); - string filename = dynamic_basename + ".m"; - mDynamicModelFile.open(filename.c_str(), ios::out | ios::binary); - if (!mDynamicModelFile.is_open()) - { - cerr << "Error: Can't open file " << filename << " for writing" << endl; - exit(EXIT_FAILURE); - } - mDynamicModelFile << "%\n"; - mDynamicModelFile << "% " << filename << " : Computes dynamic model for Dynare\n"; - mDynamicModelFile << "%\n"; - mDynamicModelFile << "% Warning : this file is generated automatically by Dynare\n"; - mDynamicModelFile << "% from model file (.mod)\n\n"; - mDynamicModelFile << "%/\n"; + { + string sp; + ofstream mDynamicModelFile; + ostringstream tmp, tmp1, tmp_eq; + int prev_Simulation_Type, tmp_i; + //SymbolicGaussElimination SGE; + bool OK; + chdir(basename.c_str()); + string filename = dynamic_basename + ".m"; + mDynamicModelFile.open(filename.c_str(), ios::out | ios::binary); + if (!mDynamicModelFile.is_open()) + { + cerr << "Error: Can't open file " << filename << " for writing" << endl; + exit(EXIT_FAILURE); + } + mDynamicModelFile << "%\n"; + mDynamicModelFile << "% " << filename << " : Computes dynamic model for Dynare\n"; + mDynamicModelFile << "%\n"; + mDynamicModelFile << "% Warning : this file is generated automatically by Dynare\n"; + mDynamicModelFile << "% from model file (.mod)\n\n"; + mDynamicModelFile << "%/\n"; - int i, k, Nb_SGE=0; - bool skip_head, open_par=false; + int i, k, Nb_SGE=0; + bool skip_head, open_par=false; - mDynamicModelFile << "function [varargout] = " << dynamic_basename << "(varargin)\n"; - mDynamicModelFile << " global oo_ options_ M_ ;\n"; - mDynamicModelFile << " g2=[];g3=[];\n"; - //Temporary variables declaration - OK=true; - ostringstream tmp_output; - for (temporary_terms_type::const_iterator it = temporary_terms.begin(); - it != temporary_terms.end(); it++) - { - if (OK) - OK=false; - else - tmp_output << " "; - (*it)->writeOutput(tmp_output, oMatlabStaticModelSparse, temporary_terms); - } - if (tmp_output.str().length()>0) - mDynamicModelFile << " global " << tmp_output.str() << " M_ ;\n"; + mDynamicModelFile << "function [varargout] = " << dynamic_basename << "(varargin)\n"; + mDynamicModelFile << " global oo_ options_ M_ ;\n"; + mDynamicModelFile << " g2=[];g3=[];\n"; + //Temporary variables declaration + OK=true; + ostringstream tmp_output; + for (temporary_terms_type::const_iterator it = temporary_terms.begin(); + it != temporary_terms.end(); it++) + { + if (OK) + OK=false; + else + tmp_output << " "; + (*it)->writeOutput(tmp_output, oMatlabStaticModelSparse, temporary_terms); + } + if (tmp_output.str().length()>0) + mDynamicModelFile << " global " << tmp_output.str() << " M_ ;\n"; - mDynamicModelFile << " T_init=zeros(1,options_.periods+M_.maximum_lag+M_.maximum_lead);\n"; - tmp_output.str(""); - for (temporary_terms_type::const_iterator it = temporary_terms.begin(); - it != temporary_terms.end(); it++) - { - tmp_output << " "; - (*it)->writeOutput(tmp_output, oMatlabDynamicModel, temporary_terms); - tmp_output << "=T_init;\n"; - } - if (tmp_output.str().length()>0) - mDynamicModelFile << tmp_output.str(); + mDynamicModelFile << " T_init=zeros(1,options_.periods+M_.maximum_lag+M_.maximum_lead);\n"; + tmp_output.str(""); + for (temporary_terms_type::const_iterator it = temporary_terms.begin(); + it != temporary_terms.end(); it++) + { + tmp_output << " "; + (*it)->writeOutput(tmp_output, oMatlabDynamicModel, temporary_terms); + tmp_output << "=T_init;\n"; + } + if (tmp_output.str().length()>0) + mDynamicModelFile << tmp_output.str(); - mDynamicModelFile << " y_kmin=M_.maximum_lag;\n"; - mDynamicModelFile << " y_kmax=M_.maximum_lead;\n"; - mDynamicModelFile << " y_size=M_.endo_nbr;\n"; - mDynamicModelFile << " if(length(varargin)>0)\n"; - mDynamicModelFile << " %it is a simple evaluation of the dynamic model for time _it\n"; - mDynamicModelFile << " params=varargin{3};\n"; - mDynamicModelFile << " it_=varargin{4};\n"; - /*i = symbol_table.endo_nbr*(variable_table.max_endo_lag+variable_table.max_endo_lead+1)+ - symbol_table.exo_nbr*(variable_table.max_exo_lag+variable_table.max_exo_lead+1); - mDynamicModelFile << " g1=spalloc(" << symbol_table.endo_nbr << ", " << i << ", " << i*symbol_table.endo_nbr << ");\n";*/ - mDynamicModelFile << " Per_u_=0;\n"; - mDynamicModelFile << " Per_y_=it_*y_size;\n"; - mDynamicModelFile << " y=varargin{1};\n"; - mDynamicModelFile << " ys=y(it_,:);\n"; - mDynamicModelFile << " x=varargin{2};\n"; - prev_Simulation_Type=-1; - tmp.str(""); - tmp_eq.str(""); - for (int count_call=1, i = 0;i < block_triangular.ModelBlock->Size;i++, count_call++) - { - 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=0;ikBlock_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) - { - if (i==block_triangular.ModelBlock->Size-1) - { - mDynamicModelFile << " y_index_eq=[" << tmp_eq.str() << "];\n"; - tmp_eq.str(""); - mDynamicModelFile << " y_index=[" << tmp.str() << "];\n"; - tmp.str(""); - mDynamicModelFile << tmp1.str(); - tmp1.str(""); - } - } - 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; - 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; - case SOLVE_FORWARD_SIMPLE: - case SOLVE_BACKWARD_SIMPLE: - 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 << " [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"; - 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;j0)\n"; + mDynamicModelFile << " %it is a simple evaluation of the dynamic model for time _it\n"; + mDynamicModelFile << " params=varargin{3};\n"; + mDynamicModelFile << " it_=varargin{4};\n"; + /*i = symbol_table.endo_nbr*(variable_table.max_endo_lag+variable_table.max_endo_lead+1)+ + symbol_table.exo_nbr*(variable_table.max_exo_lag+variable_table.max_exo_lead+1); + mDynamicModelFile << " g1=spalloc(" << symbol_table.endo_nbr << ", " << i << ", " << i*symbol_table.endo_nbr << ");\n";*/ + mDynamicModelFile << " Per_u_=0;\n"; + mDynamicModelFile << " Per_y_=it_*y_size;\n"; + mDynamicModelFile << " y=varargin{1};\n"; + mDynamicModelFile << " ys=y(it_,:);\n"; + mDynamicModelFile << " x=varargin{2};\n"; + prev_Simulation_Type=-1; + tmp.str(""); + tmp_eq.str(""); + for (int count_call=1, i = 0;i < block_triangular.ModelBlock->Size;i++, count_call++) + { + 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=0;ikBlock_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*/) + { + if (i==block_triangular.ModelBlock->Size-1) + { + mDynamicModelFile << " y_index_eq=[" << tmp_eq.str() << "];\n"; + tmp_eq.str(""); + mDynamicModelFile << " y_index=[" << tmp.str() << "];\n"; + tmp.str(""); + mDynamicModelFile << tmp1.str(); + tmp1.str(""); + } + } + 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; + 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; + case SOLVE_FORWARD_SIMPLE: + case SOLVE_BACKWARD_SIMPLE: + 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 << " [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"; + 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;jBlock_List[i].Size;ik++) + { + mDynamicModelFile << " " << block_triangular.ModelBlock->Block_List[i].Variable[ik]+1+j*symbol_table.endo_nbr(); + } + int tmp_ix=block_triangular.ModelBlock->Block_List[i].Max_Lag_Exo+block_triangular.ModelBlock->Block_List[i].Max_Lead_Exo+1; + for (j=0;jBlock_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 << " 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); + /*mDynamicModelFile << " ga=spalloc(" << block_triangular.ModelBlock->Block_List[i].Size << ", " << j << ", " << + block_triangular.ModelBlock->Block_List[i].Size*j << ");\n";*/ + tmp_i=block_triangular.ModelBlock->Block_List[i].Max_Lag_Endo+block_triangular.ModelBlock->Block_List[i].Max_Lead_Endo+1; + mDynamicModelFile << " [r, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, b, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_o]=" << dynamic_basename << "_" << i + 1 << "(y, x, params, it_-" << max_lag << ", 1, " << max_lag << ", " << block_triangular.ModelBlock->Block_List[i].Size-block_triangular.ModelBlock->Block_List[i].Nb_Recursives << ");\n"; + /*if(block_triangular.ModelBlock->Block_List[i].Max_Lag==variable_table.max_lag && block_triangular.ModelBlock->Block_List[i].Max_Lead==variable_table.max_lead) + mDynamicModelFile << " g1(y_index_eq,y_index) = ga;\n"; + else + mDynamicModelFile << " g1(y_index_eq,y_index) = ga(:," << 1+(variable_table.max_lag-block_triangular.ModelBlock->Block_List[i].Max_Lag)*block_triangular.ModelBlock->Block_List[i].Size << ":" << (variable_table.max_lag+1+block_triangular.ModelBlock->Block_List[i].Max_Lead)*block_triangular.ModelBlock->Block_List[i].Size << ");\n";*/ + mDynamicModelFile << " residual(y_index_eq)=r(:,M_.maximum_lag+1);\n"; + break; + } + prev_Simulation_Type=k; + } + if (tmp1.str().length()) + { + mDynamicModelFile << tmp1.str(); + tmp1.str(""); + } + mDynamicModelFile << " varargout{1}=residual;\n"; + mDynamicModelFile << " varargout{2}=dr;\n"; + mDynamicModelFile << " return;\n"; + mDynamicModelFile << " end;\n"; + mDynamicModelFile << " %it is the deterministic simulation of the block decomposed dynamic model\n"; + mDynamicModelFile << " if(options_.simulation_method==0)\n"; + mDynamicModelFile << " mthd='Sparse LU';\n"; + mDynamicModelFile << " elseif(options_.simulation_method==2)\n"; + mDynamicModelFile << " mthd='GMRES';\n"; + mDynamicModelFile << " elseif(options_.simulation_method==3)\n"; + mDynamicModelFile << " mthd='BICGSTAB';\n"; + mDynamicModelFile << " else\n"; + mDynamicModelFile << " mthd='UNKNOWN';\n"; + mDynamicModelFile << " end;\n"; + mDynamicModelFile << " disp (['-----------------------------------------------------']) ;\n"; + mDynamicModelFile << " disp (['MODEL SIMULATION: (method=' mthd ')']) ;\n"; + mDynamicModelFile << " fprintf('\\n') ;\n"; + mDynamicModelFile << " periods=options_.periods;\n"; + mDynamicModelFile << " maxit_=options_.maxit_;\n"; + mDynamicModelFile << " solve_tolf=options_.solve_tolf;\n"; + mDynamicModelFile << " y=oo_.endo_simul';\n"; + mDynamicModelFile << " x=oo_.exo_simul;\n"; + + prev_Simulation_Type=-1; + mDynamicModelFile << " params=M_.params;\n"; + mDynamicModelFile << " oo_.deterministic_simulation.status = 0;\n"; + for (i = 0;i < block_triangular.ModelBlock->Size;i++) + { + k = block_triangular.ModelBlock->Block_List[i].Simulation_Type; + 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; + if ((k == EVALUATE_FORWARD /*|| k == EVALUATE_FORWARD_R*/) && (block_triangular.ModelBlock->Block_List[i].Size)) + { + if (!skip_head) + { + if (open_par) + { + mDynamicModelFile << " end\n"; + } + mDynamicModelFile << " oo_.deterministic_simulation.status = 1;\n"; + mDynamicModelFile << " oo_.deterministic_simulation.error = 0;\n"; + mDynamicModelFile << " oo_.deterministic_simulation.iterations = 0;\n"; + mDynamicModelFile << " if(isfield(oo_.deterministic_simulation,'block'))\n"; + mDynamicModelFile << " blck_num = length(oo_.deterministic_simulation.block)+1;\n"; + mDynamicModelFile << " else\n"; + mDynamicModelFile << " blck_num = 1;\n"; + mDynamicModelFile << " end;\n"; + mDynamicModelFile << " oo_.deterministic_simulation.block(blck_num).status = 1;\n"; + mDynamicModelFile << " oo_.deterministic_simulation.block(blck_num).error = 0;\n"; + mDynamicModelFile << " oo_.deterministic_simulation.block(blck_num).iterations = 0;\n"; + mDynamicModelFile << " g1=[];g2=[];g3=[];\n"; + //mDynamicModelFile << " for it_ = y_kmin+1:(periods+y_kmin)\n"; + mDynamicModelFile << " y=" << dynamic_basename << "_" << i + 1 << "(y, x, params, 0, y_kmin, periods);\n"; + mDynamicModelFile << " tmp = y(:,M_.block_structure.block(" << i + 1 << ").variable);\n"; + mDynamicModelFile << " if(isnan(tmp) | isinf(tmp))\n"; + mDynamicModelFile << " disp(['Inf or Nan value during the evaluation of block " << i <<"']);\n"; + mDynamicModelFile << " return;\n"; + mDynamicModelFile << " end;\n"; + } + //open_par=true; + } + else if ((k == EVALUATE_BACKWARD /*|| k == EVALUATE_BACKWARD_R*/) && (block_triangular.ModelBlock->Block_List[i].Size)) + { + if (!skip_head) + { + if (open_par) + { + mDynamicModelFile << " end\n"; + } + mDynamicModelFile << " oo_.deterministic_simulation.status = 1;\n"; + mDynamicModelFile << " oo_.deterministic_simulation.error = 0;\n"; + mDynamicModelFile << " oo_.deterministic_simulation.iterations = 0;\n"; + mDynamicModelFile << " if(isfield(oo_.deterministic_simulation,'block'))\n"; + mDynamicModelFile << " blck_num = length(oo_.deterministic_simulation.block)+1;\n"; + mDynamicModelFile << " else\n"; + mDynamicModelFile << " blck_num = 1;\n"; + mDynamicModelFile << " end;\n"; + mDynamicModelFile << " oo_.deterministic_simulation.block(blck_num).status = 1;\n"; + mDynamicModelFile << " oo_.deterministic_simulation.block(blck_num).error = 0;\n"; + mDynamicModelFile << " oo_.deterministic_simulation.block(blck_num).iterations = 0;\n"; + mDynamicModelFile << " g1=[];g2=[];g3=[];\n"; + mDynamicModelFile << " " << dynamic_basename << "_" << i + 1 << "(y, x, params, 0, y_kmin, periods);\n"; + mDynamicModelFile << " tmp = y(:,M_.block_structure.block(" << i + 1 << ").variable);\n"; + mDynamicModelFile << " if(isnan(tmp) | isinf(tmp))\n"; + mDynamicModelFile << " disp(['Inf or Nan value during the evaluation of block " << i <<"']);\n"; + mDynamicModelFile << " return;\n"; + mDynamicModelFile << " end;\n"; + } + } + else if ((k == SOLVE_FORWARD_COMPLETE || k == SOLVE_FORWARD_SIMPLE) && (block_triangular.ModelBlock->Block_List[i].Size)) + { + if (open_par) + mDynamicModelFile << " end\n"; + open_par=false; + mDynamicModelFile << " g1=0;\n"; + mDynamicModelFile << " r=0;\n"; + tmp.str(""); for (int ik=0;ikBlock_List[i].Size;ik++) { - mDynamicModelFile << " " << block_triangular.ModelBlock->Block_List[i].Variable[ik]+1+j*symbol_table.endo_nbr(); + tmp << " " << block_triangular.ModelBlock->Block_List[i].Variable[ik]+1; } - int tmp_ix=block_triangular.ModelBlock->Block_List[i].Max_Lag_Exo+block_triangular.ModelBlock->Block_List[i].Max_Lead_Exo+1; - for (j=0;jBlock_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 << " 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); - /*mDynamicModelFile << " ga=spalloc(" << block_triangular.ModelBlock->Block_List[i].Size << ", " << j << ", " << - block_triangular.ModelBlock->Block_List[i].Size*j << ");\n";*/ - tmp_i=block_triangular.ModelBlock->Block_List[i].Max_Lag_Endo+block_triangular.ModelBlock->Block_List[i].Max_Lead_Endo+1; - mDynamicModelFile << " [r, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, b, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_o]=" << dynamic_basename << "_" << i + 1 << "(y, x, params, it_-" << max_lag << ", 1, " << max_lag << ", " << block_triangular.ModelBlock->Block_List[i].Size << ");\n"; - /*if(block_triangular.ModelBlock->Block_List[i].Max_Lag==variable_table.max_lag && block_triangular.ModelBlock->Block_List[i].Max_Lead==variable_table.max_lead) - mDynamicModelFile << " g1(y_index_eq,y_index) = ga;\n"; - else - mDynamicModelFile << " g1(y_index_eq,y_index) = ga(:," << 1+(variable_table.max_lag-block_triangular.ModelBlock->Block_List[i].Max_Lag)*block_triangular.ModelBlock->Block_List[i].Size << ":" << (variable_table.max_lag+1+block_triangular.ModelBlock->Block_List[i].Max_Lead)*block_triangular.ModelBlock->Block_List[i].Size << ");\n";*/ - mDynamicModelFile << " residual(y_index_eq)=r(:,M_.maximum_lag+1);\n"; - break; - } - prev_Simulation_Type=k; - } - if (tmp1.str().length()) - { - mDynamicModelFile << tmp1.str(); - tmp1.str(""); - } - mDynamicModelFile << " varargout{1}=residual;\n"; - mDynamicModelFile << " varargout{2}=dr;\n"; - mDynamicModelFile << " return;\n"; - mDynamicModelFile << " end;\n"; - mDynamicModelFile << " %it is the deterministic simulation of the block decomposed dynamic model\n"; - mDynamicModelFile << " if(options_.simulation_method==0)\n"; - mDynamicModelFile << " mthd='Sparse LU';\n"; - mDynamicModelFile << " elseif(options_.simulation_method==2)\n"; - mDynamicModelFile << " mthd='GMRES';\n"; - mDynamicModelFile << " elseif(options_.simulation_method==3)\n"; - mDynamicModelFile << " mthd='BICGSTAB';\n"; - mDynamicModelFile << " else\n"; - mDynamicModelFile << " mthd='UNKNOWN';\n"; - mDynamicModelFile << " end;\n"; - mDynamicModelFile << " disp (['-----------------------------------------------------']) ;\n"; - mDynamicModelFile << " disp (['MODEL SIMULATION: (method=' mthd ')']) ;\n"; - mDynamicModelFile << " fprintf('\\n') ;\n"; - mDynamicModelFile << " periods=options_.periods;\n"; - mDynamicModelFile << " maxit_=options_.maxit_;\n"; - mDynamicModelFile << " solve_tolf=options_.solve_tolf;\n"; - mDynamicModelFile << " y=oo_.endo_simul';\n"; - mDynamicModelFile << " x=oo_.exo_simul;\n"; - - prev_Simulation_Type=-1; - mDynamicModelFile << " params=M_.params;\n"; - mDynamicModelFile << " oo_.deterministic_simulation.status = 0;\n"; - for (i = 0;i < block_triangular.ModelBlock->Size;i++) - { - k = block_triangular.ModelBlock->Block_List[i].Simulation_Type; - 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; - if ((k == EVALUATE_FORWARD || k == EVALUATE_FORWARD_R) && (block_triangular.ModelBlock->Block_List[i].Size)) - { - if (!skip_head) - { - if (open_par) - { - mDynamicModelFile << " end\n"; - } - mDynamicModelFile << " oo_.deterministic_simulation.status = 1;\n"; - mDynamicModelFile << " oo_.deterministic_simulation.error = 0;\n"; - mDynamicModelFile << " oo_.deterministic_simulation.iterations = 0;\n"; - mDynamicModelFile << " if(isfield(oo_.deterministic_simulation,'block'))\n"; - mDynamicModelFile << " blck_num = length(oo_.deterministic_simulation.block)+1;\n"; - mDynamicModelFile << " else\n"; - mDynamicModelFile << " blck_num = 1;\n"; - mDynamicModelFile << " end;\n"; - mDynamicModelFile << " oo_.deterministic_simulation.block(blck_num).status = 1;\n"; - mDynamicModelFile << " oo_.deterministic_simulation.block(blck_num).error = 0;\n"; - mDynamicModelFile << " oo_.deterministic_simulation.block(blck_num).iterations = 0;\n"; - mDynamicModelFile << " g1=[];g2=[];g3=[];\n"; - //mDynamicModelFile << " for it_ = y_kmin+1:(periods+y_kmin)\n"; - mDynamicModelFile << " y=" << dynamic_basename << "_" << i + 1 << "(y, x, params, 0, y_kmin, periods);\n"; - } - //open_par=true; - } - else if ((k == EVALUATE_BACKWARD || k == EVALUATE_BACKWARD_R) && (block_triangular.ModelBlock->Block_List[i].Size)) - { - if (!skip_head) - { - if (open_par) - { - mDynamicModelFile << " end\n"; - } - mDynamicModelFile << " oo_.deterministic_simulation.status = 1;\n"; - mDynamicModelFile << " oo_.deterministic_simulation.error = 0;\n"; - mDynamicModelFile << " oo_.deterministic_simulation.iterations = 0;\n"; - mDynamicModelFile << " if(isfield(oo_.deterministic_simulation,'block'))\n"; - mDynamicModelFile << " blck_num = length(oo_.deterministic_simulation.block)+1;\n"; - mDynamicModelFile << " else\n"; - mDynamicModelFile << " blck_num = 1;\n"; - mDynamicModelFile << " end;\n"; - mDynamicModelFile << " oo_.deterministic_simulation.block(blck_num).status = 1;\n"; - mDynamicModelFile << " oo_.deterministic_simulation.block(blck_num).error = 0;\n"; - mDynamicModelFile << " oo_.deterministic_simulation.block(blck_num).iterations = 0;\n"; - mDynamicModelFile << " g1=[];g2=[];g3=[];\n"; - mDynamicModelFile << " " << dynamic_basename << "_" << i + 1 << "(y, x, params, 0, y_kmin, periods);\n"; - } - } - else if ((k == SOLVE_FORWARD_COMPLETE || k == SOLVE_FORWARD_SIMPLE) && (block_triangular.ModelBlock->Block_List[i].Size)) - { - if (open_par) - mDynamicModelFile << " end\n"; - open_par=false; - mDynamicModelFile << " g1=0;\n"; - mDynamicModelFile << " r=0;\n"; - tmp.str(""); - for (int ik=0;ikBlock_List[i].Size;ik++) - { - tmp << " " << block_triangular.ModelBlock->Block_List[i].Variable[ik]+1; - } - mDynamicModelFile << " y_index = [" << tmp.str() << "];\n"; - int nze, m; - for (nze=0,m=0;m<=block_triangular.ModelBlock->Block_List[i].Max_Lead+block_triangular.ModelBlock->Block_List[i].Max_Lag;m++) - nze+=block_triangular.ModelBlock->Block_List[i].IM_lead_lag[m].size; - mDynamicModelFile << " if(isfield(oo_.deterministic_simulation,'block'))\n"; - mDynamicModelFile << " blck_num = length(oo_.deterministic_simulation.block)+1;\n"; - mDynamicModelFile << " else\n"; - mDynamicModelFile << " blck_num = 1;\n"; - mDynamicModelFile << " end;\n"; - mDynamicModelFile << " y = solve_one_boundary('" << dynamic_basename << "_" << i + 1 << "'" << + mDynamicModelFile << " y_index = [" << tmp.str() << "];\n"; + int nze, m; + for (nze=0,m=0;m<=block_triangular.ModelBlock->Block_List[i].Max_Lead+block_triangular.ModelBlock->Block_List[i].Max_Lag;m++) + nze+=block_triangular.ModelBlock->Block_List[i].IM_lead_lag[m].size; + mDynamicModelFile << " if(isfield(oo_.deterministic_simulation,'block'))\n"; + mDynamicModelFile << " blck_num = length(oo_.deterministic_simulation.block)+1;\n"; + mDynamicModelFile << " else\n"; + mDynamicModelFile << " blck_num = 1;\n"; + mDynamicModelFile << " end;\n"; + mDynamicModelFile << " y = solve_one_boundary('" << dynamic_basename << "_" << i + 1 << "'" << ", y, x, params, y_index, " << nze << ", options_.periods, " << block_triangular.ModelBlock->Block_List[i].is_linear << ", blck_num, y_kmin, options_.maxit_, options_.solve_tolf, options_.slowc, options_.cutoff, options_.simulation_method, 1, 1, 0);\n"; - - } - else if ((k == SOLVE_BACKWARD_COMPLETE || k == SOLVE_BACKWARD_SIMPLE) && (block_triangular.ModelBlock->Block_List[i].Size)) - { - if (open_par) - mDynamicModelFile << " end\n"; - open_par=false; - mDynamicModelFile << " g1=0;\n"; - mDynamicModelFile << " r=0;\n"; - tmp.str(""); - for (int ik=0;ikBlock_List[i].Size;ik++) - { - tmp << " " << block_triangular.ModelBlock->Block_List[i].Variable[ik]+1; - } - mDynamicModelFile << " y_index = [" << tmp.str() << "];\n"; - int nze, m; - for (nze=0,m=0;m<=block_triangular.ModelBlock->Block_List[i].Max_Lead+block_triangular.ModelBlock->Block_List[i].Max_Lag;m++) - nze+=block_triangular.ModelBlock->Block_List[i].IM_lead_lag[m].size; - mDynamicModelFile << " if(isfield(oo_.deterministic_simulation,'block'))\n"; - mDynamicModelFile << " blck_num = length(oo_.deterministic_simulation.block)+1;\n"; - mDynamicModelFile << " else\n"; - mDynamicModelFile << " blck_num = 1;\n"; - mDynamicModelFile << " end;\n"; - mDynamicModelFile << " y = solve_one_boundary('" << dynamic_basename << "_" << i + 1 << "'" << + mDynamicModelFile << " tmp = y(:,M_.block_structure.block(" << i + 1 << ").variable);\n"; + mDynamicModelFile << " if(isnan(tmp) | isinf(tmp))\n"; + mDynamicModelFile << " disp(['Inf or Nan value during the resolution of block " << i <<"']);\n"; + mDynamicModelFile << " return;\n"; + mDynamicModelFile << " end;\n"; + } + else if ((k == SOLVE_BACKWARD_COMPLETE || k == SOLVE_BACKWARD_SIMPLE) && (block_triangular.ModelBlock->Block_List[i].Size)) + { + if (open_par) + mDynamicModelFile << " end\n"; + open_par=false; + mDynamicModelFile << " g1=0;\n"; + mDynamicModelFile << " r=0;\n"; + tmp.str(""); + for (int ik=0;ikBlock_List[i].Size;ik++) + { + if (ik>=block_triangular.ModelBlock->Block_List[i].Nb_Recursives) + tmp << " " << block_triangular.ModelBlock->Block_List[i].Variable[ik]+1; + } + mDynamicModelFile << " y_index = [" << tmp.str() << "];\n"; + int nze, m; + for (nze=0,m=0;m<=block_triangular.ModelBlock->Block_List[i].Max_Lead+block_triangular.ModelBlock->Block_List[i].Max_Lag;m++) + nze+=block_triangular.ModelBlock->Block_List[i].IM_lead_lag[m].size; + mDynamicModelFile << " if(isfield(oo_.deterministic_simulation,'block'))\n"; + mDynamicModelFile << " blck_num = length(oo_.deterministic_simulation.block)+1;\n"; + mDynamicModelFile << " else\n"; + mDynamicModelFile << " blck_num = 1;\n"; + mDynamicModelFile << " end;\n"; + mDynamicModelFile << " y = solve_one_boundary('" << dynamic_basename << "_" << i + 1 << "'" << ", y, x, params, y_index, " << nze << ", options_.periods, " << block_triangular.ModelBlock->Block_List[i].is_linear << ", blck_num, y_kmin, options_.maxit_, options_.solve_tolf, options_.slowc, options_.cutoff, options_.simulation_method, 1, 1, 0);\n"; - } - else if ((k == SOLVE_TWO_BOUNDARIES_COMPLETE || k == SOLVE_TWO_BOUNDARIES_SIMPLE) && (block_triangular.ModelBlock->Block_List[i].Size)) - { - if (open_par) - mDynamicModelFile << " end\n"; - open_par=false; - Nb_SGE++; - int nze, m; - for (nze=0,m=0;m<=block_triangular.ModelBlock->Block_List[i].Max_Lead+block_triangular.ModelBlock->Block_List[i].Max_Lag;m++) - nze+=block_triangular.ModelBlock->Block_List[i].IM_lead_lag[m].size; - mDynamicModelFile << " y_index=["; - for (int ik=0;ikBlock_List[i].Size;ik++) - { - mDynamicModelFile << " " << block_triangular.ModelBlock->Block_List[i].Variable[ik]+1; - } - mDynamicModelFile << " ];\n"; - mDynamicModelFile << " if(isfield(oo_.deterministic_simulation,'block'))\n"; - mDynamicModelFile << " blck_num = length(oo_.deterministic_simulation.block)+1;\n"; - mDynamicModelFile << " else\n"; - mDynamicModelFile << " blck_num = 1;\n"; - mDynamicModelFile << " end;\n"; - mDynamicModelFile << " y = solve_two_boundaries('" << dynamic_basename << "_" << i + 1 << "'" << + mDynamicModelFile << " tmp = y(:,M_.block_structure.block(" << i + 1 << ").variable);\n"; + mDynamicModelFile << " if(isnan(tmp) | isinf(tmp))\n"; + mDynamicModelFile << " disp(['Inf or Nan value during the resolution of block " << i <<"']);\n"; + mDynamicModelFile << " return;\n"; + mDynamicModelFile << " end;\n"; + } + else if ((k == SOLVE_TWO_BOUNDARIES_COMPLETE || k == SOLVE_TWO_BOUNDARIES_SIMPLE) && (block_triangular.ModelBlock->Block_List[i].Size)) + { + if (open_par) + mDynamicModelFile << " end\n"; + open_par=false; + Nb_SGE++; + int nze, m; + for (nze=0,m=0;m<=block_triangular.ModelBlock->Block_List[i].Max_Lead+block_triangular.ModelBlock->Block_List[i].Max_Lag;m++) + nze+=block_triangular.ModelBlock->Block_List[i].IM_lead_lag[m].size; + mDynamicModelFile << " y_index=["; + for (int ik=0;ikBlock_List[i].Size;ik++) + { + if (ik>=block_triangular.ModelBlock->Block_List[i].Nb_Recursives) + mDynamicModelFile << " " << block_triangular.ModelBlock->Block_List[i].Variable[ik]+1; + } + mDynamicModelFile << " ];\n"; + mDynamicModelFile << " if(isfield(oo_.deterministic_simulation,'block'))\n"; + mDynamicModelFile << " blck_num = length(oo_.deterministic_simulation.block)+1;\n"; + mDynamicModelFile << " else\n"; + mDynamicModelFile << " blck_num = 1;\n"; + mDynamicModelFile << " end;\n"; + mDynamicModelFile << " y = solve_two_boundaries('" << dynamic_basename << "_" << i + 1 << "'" << ", y, x, params, y_index, " << nze << ", options_.periods, " << block_triangular.ModelBlock->Block_List[i].Max_Lag << ", " << block_triangular.ModelBlock->Block_List[i].Max_Lead << ", " << block_triangular.ModelBlock->Block_List[i].is_linear << ", blck_num, y_kmin, options_.maxit_, options_.solve_tolf, options_.slowc, options_.cutoff, options_.simulation_method);\n"; + mDynamicModelFile << " tmp = y(:,M_.block_structure.block(" << i + 1 << ").variable);\n"; + mDynamicModelFile << " if(isnan(tmp) | isinf(tmp))\n"; + mDynamicModelFile << " disp(['Inf or Nan value during the resolution of block " << i <<"']);\n"; + mDynamicModelFile << " return;\n"; + mDynamicModelFile << " end;\n"; + } + prev_Simulation_Type=k; + } + if (open_par) + mDynamicModelFile << " end;\n"; + open_par=false; + mDynamicModelFile << " oo_.endo_simul = y';\n"; + mDynamicModelFile << "return;\n"; - } - prev_Simulation_Type=k; - } - if (open_par) - mDynamicModelFile << " end;\n"; - open_par=false; - mDynamicModelFile << " oo_.endo_simul = y';\n"; - mDynamicModelFile << "return;\n"; + mDynamicModelFile.close(); - mDynamicModelFile.close(); + writeModelEquationsOrdered_M( block_triangular.ModelBlock, dynamic_basename); - writeModelEquationsOrdered_M( block_triangular.ModelBlock, dynamic_basename); - - chdir(".."); -} + chdir(".."); + } void DynamicModel::writeDynamicModel(ostream &DynamicOutput) const -{ - ostringstream lsymetric; // Used when writing symetric elements in Hessian - ostringstream model_output; // Used for storing model equations - ostringstream jacobian_output; // Used for storing jacobian equations - ostringstream hessian_output; // Used for storing Hessian equations - ostringstream third_derivatives_output; + { + ostringstream lsymetric; // Used when writing symetric elements in Hessian + ostringstream model_output; // Used for storing model equations + ostringstream jacobian_output; // Used for storing jacobian equations + ostringstream hessian_output; // Used for storing Hessian equations + ostringstream third_derivatives_output; - ExprNodeOutputType output_type = (mode == eStandardMode || mode==eSparseMode ? oMatlabDynamicModel : oCDynamicModel); + ExprNodeOutputType output_type = (mode == eStandardMode || mode==eSparseMode ? oMatlabDynamicModel : oCDynamicModel); - writeModelLocalVariables(model_output, output_type); + writeModelLocalVariables(model_output, output_type); - writeTemporaryTerms(temporary_terms, model_output, output_type); + writeTemporaryTerms(temporary_terms, model_output, output_type); - writeModelEquations(model_output, output_type); + writeModelEquations(model_output, output_type); - int nrows = equations.size(); - int hessianColsNbr = dynJacobianColsNbr * dynJacobianColsNbr; + int nrows = equations.size(); + int hessianColsNbr = dynJacobianColsNbr * dynJacobianColsNbr; - // Writing Jacobian - for (first_derivatives_type::const_iterator it = first_derivatives.begin(); - it != first_derivatives.end(); it++) - { - int eq = it->first.first; - int var = it->first.second; - NodeID d1 = it->second; + // Writing Jacobian + for (first_derivatives_type::const_iterator it = first_derivatives.begin(); + it != first_derivatives.end(); it++) + { + int eq = it->first.first; + int var = it->first.second; + NodeID d1 = it->second; - ostringstream g1; - g1 << " g1"; - matrixHelper(g1, eq, getDynJacobianCol(var), output_type); + ostringstream g1; + g1 << " g1"; + matrixHelper(g1, eq, getDynJacobianCol(var), output_type); - jacobian_output << g1.str() << "=" << g1.str() << "+"; - d1->writeOutput(jacobian_output, output_type, temporary_terms); - jacobian_output << ";" << endl; - } + jacobian_output << g1.str() << "=" << g1.str() << "+"; + d1->writeOutput(jacobian_output, output_type, temporary_terms); + jacobian_output << ";" << endl; + } - // Writing Hessian - for (second_derivatives_type::const_iterator it = second_derivatives.begin(); - it != second_derivatives.end(); it++) - { - int eq = it->first.first; - int var1 = it->first.second.first; - int var2 = it->first.second.second; - NodeID d2 = it->second; + // Writing Hessian + for (second_derivatives_type::const_iterator it = second_derivatives.begin(); + it != second_derivatives.end(); it++) + { + int eq = it->first.first; + int var1 = it->first.second.first; + int var2 = it->first.second.second; + NodeID d2 = it->second; - int id1 = getDynJacobianCol(var1); - int id2 = getDynJacobianCol(var2); + int id1 = getDynJacobianCol(var1); + int id2 = getDynJacobianCol(var2); - int col_nb = id1 * dynJacobianColsNbr + id2; - int col_nb_sym = id2 * dynJacobianColsNbr + id1; + int col_nb = id1 * dynJacobianColsNbr + id2; + int col_nb_sym = id2 * dynJacobianColsNbr + id1; - hessian_output << " g2"; - matrixHelper(hessian_output, eq, col_nb, output_type); - hessian_output << " = "; - d2->writeOutput(hessian_output, output_type, temporary_terms); - hessian_output << ";" << endl; + hessian_output << " g2"; + matrixHelper(hessian_output, eq, col_nb, output_type); + hessian_output << " = "; + d2->writeOutput(hessian_output, output_type, temporary_terms); + hessian_output << ";" << endl; - // Treating symetric elements - if (id1 != id2) - { - lsymetric << " g2"; - matrixHelper(lsymetric, eq, col_nb_sym, output_type); - lsymetric << " = " << "g2"; - matrixHelper(lsymetric, eq, col_nb, output_type); - lsymetric << ";" << endl; - } - } - - // Writing third derivatives - for (third_derivatives_type::const_iterator it = third_derivatives.begin(); - it != third_derivatives.end(); it++) - { - int eq = it->first.first; - int var1 = it->first.second.first; - int var2 = it->first.second.second.first; - int var3 = it->first.second.second.second; - NodeID d3 = it->second; - - int id1 = getDynJacobianCol(var1); - int id2 = getDynJacobianCol(var2); - int id3 = getDynJacobianCol(var3); - - // Reference column number for the g3 matrix - int ref_col = id1 * hessianColsNbr + id2 * dynJacobianColsNbr + id3; - - third_derivatives_output << " g3"; - matrixHelper(third_derivatives_output, eq, ref_col, output_type); - third_derivatives_output << " = "; - d3->writeOutput(third_derivatives_output, output_type, temporary_terms); - third_derivatives_output << ";" << endl; - - // Compute the column numbers for the 5 other permutations of (id1,id2,id3) and store them in a set (to avoid duplicates if two indexes are equal) - set cols; - cols.insert(id1 * hessianColsNbr + id3 * dynJacobianColsNbr + id2); - cols.insert(id2 * hessianColsNbr + id1 * dynJacobianColsNbr + id3); - cols.insert(id2 * hessianColsNbr + id3 * dynJacobianColsNbr + id1); - cols.insert(id3 * hessianColsNbr + id1 * dynJacobianColsNbr + id2); - cols.insert(id3 * hessianColsNbr + id2 * dynJacobianColsNbr + id1); - - for (set::iterator it2 = cols.begin(); it2 != cols.end(); it2++) - if (*it2 != ref_col) + // Treating symetric elements + if (id1 != id2) { - third_derivatives_output << " g3"; - matrixHelper(third_derivatives_output, eq, *it2, output_type); - third_derivatives_output << " = " << "g3"; - matrixHelper(third_derivatives_output, eq, ref_col, output_type); - third_derivatives_output << ";" << endl; + lsymetric << " g2"; + matrixHelper(lsymetric, eq, col_nb_sym, output_type); + lsymetric << " = " << "g2"; + matrixHelper(lsymetric, eq, col_nb, output_type); + lsymetric << ";" << endl; } - } + } - if (mode == eStandardMode) - { - DynamicOutput << "%" << endl - << "% Model equations" << endl - << "%" << endl - << endl - << "residual = zeros(" << nrows << ", 1);" << endl - << model_output.str() + // Writing third derivatives + for (third_derivatives_type::const_iterator it = third_derivatives.begin(); + it != third_derivatives.end(); it++) + { + int eq = it->first.first; + int var1 = it->first.second.first; + int var2 = it->first.second.second.first; + int var3 = it->first.second.second.second; + NodeID d3 = it->second; + + int id1 = getDynJacobianCol(var1); + int id2 = getDynJacobianCol(var2); + int id3 = getDynJacobianCol(var3); + + // Reference column number for the g3 matrix + int ref_col = id1 * hessianColsNbr + id2 * dynJacobianColsNbr + id3; + + third_derivatives_output << " g3"; + matrixHelper(third_derivatives_output, eq, ref_col, output_type); + third_derivatives_output << " = "; + d3->writeOutput(third_derivatives_output, output_type, temporary_terms); + third_derivatives_output << ";" << endl; + + // Compute the column numbers for the 5 other permutations of (id1,id2,id3) and store them in a set (to avoid duplicates if two indexes are equal) + set cols; + cols.insert(id1 * hessianColsNbr + id3 * dynJacobianColsNbr + id2); + cols.insert(id2 * hessianColsNbr + id1 * dynJacobianColsNbr + id3); + cols.insert(id2 * hessianColsNbr + id3 * dynJacobianColsNbr + id1); + cols.insert(id3 * hessianColsNbr + id1 * dynJacobianColsNbr + id2); + cols.insert(id3 * hessianColsNbr + id2 * dynJacobianColsNbr + id1); + + for (set::iterator it2 = cols.begin(); it2 != cols.end(); it2++) + if (*it2 != ref_col) + { + third_derivatives_output << " g3"; + matrixHelper(third_derivatives_output, eq, *it2, output_type); + third_derivatives_output << " = " << "g3"; + matrixHelper(third_derivatives_output, eq, ref_col, output_type); + third_derivatives_output << ";" << endl; + } + } + + if (mode == eStandardMode) + { + DynamicOutput << "%" << endl + << "% Model equations" << endl + << "%" << endl + << endl + << "residual = zeros(" << nrows << ", 1);" << endl + << model_output.str() // Writing initialization instruction for matrix g1 - << "if nargout >= 2," << endl - << " g1 = zeros(" << nrows << ", " << dynJacobianColsNbr << ");" << endl - << endl - << "%" << endl - << "% Jacobian matrix" << endl - << "%" << endl - << endl - << jacobian_output.str() - << "end" << endl; + << "if nargout >= 2," << endl + << " g1 = zeros(" << nrows << ", " << dynJacobianColsNbr << ");" << endl + << endl + << "%" << endl + << "% Jacobian matrix" << endl + << "%" << endl + << endl + << jacobian_output.str() + << "end" << endl; - if (second_derivatives.size()) - { - // Writing initialization instruction for matrix g2 - DynamicOutput << "if nargout >= 3," << endl - << " g2 = sparse([],[],[], " << nrows << ", " << hessianColsNbr << ", " << NNZDerivatives[1] << ");" << endl - << endl - << "%" << endl - << "% Hessian matrix" << endl - << "%" << endl - << endl - << hessian_output.str() - << lsymetric.str() - << "end;" << endl; - } - if (third_derivatives.size()) - { - int ncols = hessianColsNbr * dynJacobianColsNbr; - DynamicOutput << "if nargout >= 4," << endl - << " g3 = sparse([],[],[], " << nrows << ", " << ncols << ", " << NNZDerivatives[2] << ");" << endl - << endl - << "%" << endl - << "% Third order derivatives" << endl - << "%" << endl - << endl - << third_derivatives_output.str() - << "end;" << endl; - } - } - else - { - DynamicOutput << "void Dynamic(double *y, double *x, int nb_row_x, double *params, int it_, double *residual, double *g1, double *g2)" << endl - << "{" << endl - << " double lhs, rhs;" << endl - << endl - << " /* Residual equations */" << endl - << model_output.str() - << " /* Jacobian */" << endl - << " if (g1 == NULL)" << endl - << " return;" << endl - << " else" << endl - << " {" << endl - << jacobian_output.str() - << " }" << endl; + if (second_derivatives.size()) + { + // Writing initialization instruction for matrix g2 + DynamicOutput << "if nargout >= 3," << endl + << " g2 = sparse([],[],[], " << nrows << ", " << hessianColsNbr << ", " << NNZDerivatives[1] << ");" << endl + << endl + << "%" << endl + << "% Hessian matrix" << endl + << "%" << endl + << endl + << hessian_output.str() + << lsymetric.str() + << "end;" << endl; + } + if (third_derivatives.size()) + { + int ncols = hessianColsNbr * dynJacobianColsNbr; + DynamicOutput << "if nargout >= 4," << endl + << " g3 = sparse([],[],[], " << nrows << ", " << ncols << ", " << NNZDerivatives[2] << ");" << endl + << endl + << "%" << endl + << "% Third order derivatives" << endl + << "%" << endl + << endl + << third_derivatives_output.str() + << "end;" << endl; + } + } + else + { + DynamicOutput << "void Dynamic(double *y, double *x, int nb_row_x, double *params, int it_, double *residual, double *g1, double *g2)" << endl + << "{" << endl + << " double lhs, rhs;" << endl + << endl + << " /* Residual equations */" << endl + << model_output.str() + << " /* Jacobian */" << endl + << " if (g1 == NULL)" << endl + << " return;" << endl + << " else" << endl + << " {" << endl + << jacobian_output.str() + << " }" << endl; - if (second_derivatives.size()) - { - DynamicOutput << " /* Hessian for endogenous and exogenous variables */" << endl - << " if (g2 == NULL)" << endl - << " return;" << endl - << " else" << endl - << " {" << endl - << hessian_output.str() - << lsymetric.str() - << " }" << endl; - } - DynamicOutput << "}" << endl << endl; - } -} + if (second_derivatives.size()) + { + DynamicOutput << " /* Hessian for endogenous and exogenous variables */" << endl + << " if (g2 == NULL)" << endl + << " return;" << endl + << " else" << endl + << " {" << endl + << hessian_output.str() + << lsymetric.str() + << " }" << endl; + } + DynamicOutput << "}" << endl << endl; + } + } void DynamicModel::writeOutput(ostream &output) const -{ - /* Writing initialisation for M_.lead_lag_incidence matrix - M_.lead_lag_incidence is a matrix with as many columns as there are - endogenous variables and as many rows as there are periods in the - models (nbr of rows = M_.max_lag+M_.max_lead+1) + { + /* Writing initialisation for M_.lead_lag_incidence matrix + M_.lead_lag_incidence is a matrix with as many columns as there are + endogenous variables and as many rows as there are periods in the + models (nbr of rows = M_.max_lag+M_.max_lead+1) - The matrix elements are equal to zero if a variable isn't present in the - model at a given period. - */ + The matrix elements are equal to zero if a variable isn't present in the + model at a given period. + */ - output << "M_.lead_lag_incidence = ["; - // Loop on endogenous variables - for (int endoID = 0; endoID < symbol_table.endo_nbr(); endoID++) - { - output << endl; - // Loop on periods - for (int lag = -max_endo_lag; lag <= max_endo_lead; lag++) - { - // Print variableID if exists with current period, otherwise print 0 - try - { - int varID = getDerivID(symbol_table.getID(eEndogenous, endoID), lag); - output << " " << getDynJacobianCol(varID) + 1; - } - catch(UnknownDerivIDException &e) - { - output << " 0"; - } - } - output << ";"; - } - output << "]';" << endl; - //In case of sparse model, writes the block structure of the model - - if (mode==eSparseMode || mode==eSparseDLLMode) - { - //int prev_Simulation_Type=-1; - //bool skip_the_head; - int k=0; - int count_lead_lag_incidence = 0; - int max_lead, max_lag, max_lag_endo, max_lead_endo, max_lag_exo, max_lead_exo; - for (int j = 0;j < block_triangular.ModelBlock->Size;j++) - { - //For a block composed of a single equation determines wether we have to evaluate or to solve the equation - //skip_the_head=false; - k++; - count_lead_lag_incidence = 0; - int Block_size=block_triangular.ModelBlock->Block_List[j].Size; - max_lag =block_triangular.ModelBlock->Block_List[j].Max_Lag ; - max_lead=block_triangular.ModelBlock->Block_List[j].Max_Lead; - max_lag_endo =block_triangular.ModelBlock->Block_List[j].Max_Lag_Endo ; - max_lead_endo=block_triangular.ModelBlock->Block_List[j].Max_Lead_Endo; - max_lag_exo =block_triangular.ModelBlock->Block_List[j].Max_Lag_Exo ; - max_lead_exo=block_triangular.ModelBlock->Block_List[j].Max_Lead_Exo; - bool evaluate=false; - vector exogenous; - vector::iterator it_exogenous; - exogenous.clear(); - ostringstream tmp_s, tmp_s_eq; - tmp_s.str(""); - tmp_s_eq.str(""); - for (int i=0;iBlock_List[j].Size;i++) - { - tmp_s << " " << block_triangular.ModelBlock->Block_List[j].Variable[i]+1; - tmp_s_eq << " " << block_triangular.ModelBlock->Block_List[j].Equation[i]+1; - } - for (int i=0;iBlock_List[j].nb_exo;i++) - { - int ii=block_triangular.ModelBlock->Block_List[j].Exogenous[i]; - for (it_exogenous=exogenous.begin();it_exogenous!=exogenous.end() && *it_exogenous!=ii;it_exogenous++) /*cout << "*it_exogenous=" << *it_exogenous << "\n"*/; - if (it_exogenous==exogenous.end() || exogenous.begin()==exogenous.end()) - exogenous.push_back(ii); - } - output << "M_.block_structure.block(" << k << ").num = " << j+1 << ";\n"; - output << "M_.block_structure.block(" << k << ").Simulation_Type = " << block_triangular.ModelBlock->Block_List[j].Simulation_Type << ";\n"; - output << "M_.block_structure.block(" << k << ").maximum_lag = " << max_lag << ";\n"; - output << "M_.block_structure.block(" << k << ").maximum_lead = " << max_lead << ";\n"; - output << "M_.block_structure.block(" << k << ").maximum_endo_lag = " << max_lag_endo << ";\n"; - output << "M_.block_structure.block(" << k << ").maximum_endo_lead = " << max_lead_endo << ";\n"; - output << "M_.block_structure.block(" << k << ").maximum_exo_lag = " << max_lag_exo << ";\n"; - output << "M_.block_structure.block(" << k << ").maximum_exo_lead = " << max_lead_exo << ";\n"; - output << "M_.block_structure.block(" << k << ").endo_nbr = " << Block_size << ";\n"; - output << "M_.block_structure.block(" << k << ").equation = [" << tmp_s_eq.str() << "];\n"; - output << "M_.block_structure.block(" << k << ").variable = [" << tmp_s.str() << "];\n"; - output << "M_.block_structure.block(" << k << ").exogenous = ["; - int i=0; - for (it_exogenous=exogenous.begin();it_exogenous!=exogenous.end();it_exogenous++) - if (*it_exogenous>=0) + output << "M_.lead_lag_incidence = ["; + // Loop on endogenous variables + for (int endoID = 0; endoID < symbol_table.endo_nbr(); endoID++) + { + output << endl; + // Loop on periods + for (int lag = -max_endo_lag; lag <= max_endo_lead; lag++) + { + // Print variableID if exists with current period, otherwise print 0 + try { - output << " " << *it_exogenous+1; - i++; + int varID = getDerivID(symbol_table.getID(eEndogenous, endoID), lag); + output << " " << getDynJacobianCol(varID) + 1; } - output << "];\n"; - output << "M_.block_structure.block(" << k << ").exo_nbr = " << i << ";\n"; + catch (UnknownDerivIDException &e) + { + output << " 0"; + } + } + output << ";"; + } + output << "]';" << endl; + //In case of sparse model, writes the block structure of the model - output << "M_.block_structure.block(" << k << ").exo_det_nbr = " << block_triangular.ModelBlock->Block_List[j].nb_exo_det << ";\n"; - - tmp_s.str(""); - - bool done_IM=false; - if (!evaluate) - { - output << "M_.block_structure.block(" << k << ").lead_lag_incidence = [];\n"; - for (int l=-max_lag_endo;lSize;j++) + { + //For a block composed of a single equation determines wether we have to evaluate or to solve the equation + //skip_the_head=false; + k++; + count_lead_lag_incidence = 0; + int Block_size=block_triangular.ModelBlock->Block_List[j].Size; + max_lag =block_triangular.ModelBlock->Block_List[j].Max_Lag ; + max_lead=block_triangular.ModelBlock->Block_List[j].Max_Lead; + max_lag_endo =block_triangular.ModelBlock->Block_List[j].Max_Lag_Endo ; + max_lead_endo=block_triangular.ModelBlock->Block_List[j].Max_Lead_Endo; + max_lag_exo =block_triangular.ModelBlock->Block_List[j].Max_Lag_Exo ; + max_lead_exo=block_triangular.ModelBlock->Block_List[j].Max_Lead_Exo; + bool evaluate=false; + vector exogenous; + vector::iterator it_exogenous; + exogenous.clear(); + ostringstream tmp_s, tmp_s_eq; + tmp_s.str(""); + tmp_s_eq.str(""); + for (int i=0;iBlock_List[j].Size;i++) + { + tmp_s << " " << block_triangular.ModelBlock->Block_List[j].Variable[i]+1; + tmp_s_eq << " " << block_triangular.ModelBlock->Block_List[j].Equation[i]+1; + } + for (int i=0;iBlock_List[j].nb_exo;i++) + { + int ii=block_triangular.ModelBlock->Block_List[j].Exogenous[i]; + for (it_exogenous=exogenous.begin();it_exogenous!=exogenous.end() && *it_exogenous!=ii;it_exogenous++) /*cout << "*it_exogenous=" << *it_exogenous << "\n"*/; + if (it_exogenous==exogenous.end() || exogenous.begin()==exogenous.end()) + exogenous.push_back(ii); + } + output << "M_.block_structure.block(" << k << ").num = " << j+1 << ";\n"; + output << "M_.block_structure.block(" << k << ").Simulation_Type = " << block_triangular.ModelBlock->Block_List[j].Simulation_Type << ";\n"; + output << "M_.block_structure.block(" << k << ").maximum_lag = " << max_lag << ";\n"; + output << "M_.block_structure.block(" << k << ").maximum_lead = " << max_lead << ";\n"; + output << "M_.block_structure.block(" << k << ").maximum_endo_lag = " << max_lag_endo << ";\n"; + output << "M_.block_structure.block(" << k << ").maximum_endo_lead = " << max_lead_endo << ";\n"; + output << "M_.block_structure.block(" << k << ").maximum_exo_lag = " << max_lag_exo << ";\n"; + output << "M_.block_structure.block(" << k << ").maximum_exo_lead = " << max_lead_exo << ";\n"; + output << "M_.block_structure.block(" << k << ").endo_nbr = " << Block_size << ";\n"; + output << "M_.block_structure.block(" << k << ").equation = [" << tmp_s_eq.str() << "];\n"; + output << "M_.block_structure.block(" << k << ").variable = [" << tmp_s.str() << "];\n"; + output << "M_.block_structure.block(" << k << ").exogenous = ["; + int i=0; + for (it_exogenous=exogenous.begin();it_exogenous!=exogenous.end();it_exogenous++) + if (*it_exogenous>=0) { - bool *tmp_IM; - tmp_IM=block_triangular.incidencematrix.Get_IM(l, eEndogenous); - if (tmp_IM) - { - for (int l_var=0;l_varBlock_List[j].Size;l_var++) - { - for (int l_equ=0;l_equBlock_List[j].Size;l_equ++) - if (tmp_IM[block_triangular.ModelBlock->Block_List[j].Equation[l_equ]*symbol_table.endo_nbr()+block_triangular.ModelBlock->Block_List[j].Variable[l_var]]) + output << " " << *it_exogenous+1; + i++; + } + output << "];\n"; + output << "M_.block_structure.block(" << k << ").exo_nbr = " << i << ";\n"; + + output << "M_.block_structure.block(" << k << ").exo_det_nbr = " << block_triangular.ModelBlock->Block_List[j].nb_exo_det << ";\n"; + + tmp_s.str(""); + + bool done_IM=false; + if (!evaluate) + { + output << "M_.block_structure.block(" << k << ").lead_lag_incidence = [];\n"; + for (int l=-max_lag_endo;lBlock_List[j].Size;l_var++) + { + for (int l_equ=0;l_equBlock_List[j].Size;l_equ++) + if (tmp_IM[block_triangular.ModelBlock->Block_List[j].Equation[l_equ]*symbol_table.endo_nbr()+block_triangular.ModelBlock->Block_List[j].Variable[l_var]]) + { + count_lead_lag_incidence++; + if (tmp_s.str().length()) + tmp_s << " "; + tmp_s << count_lead_lag_incidence; + done_IM=true; + break; + } + if (!done_IM) + tmp_s << " 0"; + done_IM=false; + } + output << "M_.block_structure.block(" << k << ").lead_lag_incidence = [ M_.block_structure.block(" << k << ").lead_lag_incidence; " << tmp_s.str() << "];\n"; + tmp_s.str(""); + } + } + } + else + { + bool done_some_where; + output << "M_.block_structure.block(" << k << ").lead_lag_incidence = [\n"; + for (int l=-max_lag_endo;lBlock_List[ii].Size;l_var++) { - count_lead_lag_incidence++; - if (tmp_s.str().length()) - tmp_s << " "; - tmp_s << count_lead_lag_incidence; - done_IM=true; - break; + for (int l_equ=0;l_equBlock_List[ii].Size;l_equ++) + if (tmp_IM[block_triangular.ModelBlock->Block_List[ii].Equation[l_equ]*symbol_table.endo_nbr()+block_triangular.ModelBlock->Block_List[ii].Variable[l_var]]) + { + //if(not_increm && l==-max_lag) + count_lead_lag_incidence++; + not_increm=false; + if (tmp_s.str().length()) + tmp_s << " "; + //tmp_s << count_lead_lag_incidence+(l+max_lag)*Block_size; + tmp_s << count_lead_lag_incidence; + done_IM=true; + break; + } + if (!done_IM) + tmp_s << " 0"; + else + done_some_where = true; + done_IM=false; } - if (!done_IM) - tmp_s << " 0"; - done_IM=false; - } - output << "M_.block_structure.block(" << k << ").lead_lag_incidence = [ M_.block_structure.block(" << k << ").lead_lag_incidence; " << tmp_s.str() << "];\n"; - tmp_s.str(""); - } - } - } - else - { - bool done_some_where; - output << "M_.block_structure.block(" << k << ").lead_lag_incidence = [\n"; - for (int l=-max_lag_endo;lBlock_List[ii].Size;l_var++) - { - for (int l_equ=0;l_equBlock_List[ii].Size;l_equ++) - if (tmp_IM[block_triangular.ModelBlock->Block_List[ii].Equation[l_equ]*symbol_table.endo_nbr()+block_triangular.ModelBlock->Block_List[ii].Variable[l_var]]) - { - //if(not_increm && l==-max_lag) - count_lead_lag_incidence++; - not_increm=false; - if (tmp_s.str().length()) - tmp_s << " "; - //tmp_s << count_lead_lag_incidence+(l+max_lag)*Block_size; - tmp_s << count_lead_lag_incidence; - done_IM=true; - break; - } - if (!done_IM) - tmp_s << " 0"; - else - done_some_where = true; - done_IM=false; - } - ii++; - } - output << tmp_s.str() << "\n"; - tmp_s.str(""); - } - } - output << "];\n"; - } + ii++; + } + output << tmp_s.str() << "\n"; + tmp_s.str(""); + } + } + output << "];\n"; + } - } - for (int j=-block_triangular.incidencematrix.Model_Max_Lag_Endo;j<=block_triangular.incidencematrix.Model_Max_Lead_Endo;j++) - { - bool* IM = block_triangular.incidencematrix.Get_IM(j, eEndogenous); - if (IM) - { - bool new_entry=true; - output << "M_.block_structure.incidence(" << block_triangular.incidencematrix.Model_Max_Lag_Endo+j+1 << ").lead_lag = " << j << ";\n"; - output << "M_.block_structure.incidence(" << block_triangular.incidencematrix.Model_Max_Lag_Endo+j+1 << ").sparse_IM = ["; - for (int i=0;i0) { @@ -2177,7 +2456,7 @@ DynamicModel::BlockLinear(Model_Block *ModelBlock) } } } - follow: +follow: i=0; } } @@ -2188,9 +2467,9 @@ DynamicModel::collect_first_order_derivatives_current_endogenous() { map, NodeID> curr_endo_derivatives; for (first_derivatives_type::iterator it2 = first_derivatives.begin(); - it2 != first_derivatives.end(); it2++) + it2 != first_derivatives.end(); it2++) { - if(getTypeByDerivID(it2->first.second)==eEndogenous) + if (getTypeByDerivID(it2->first.second)==eEndogenous) { int eq = it2->first.first; int var=symbol_table.getTypeSpecificID(getSymbIDByDerivID(it2->first.second)); @@ -2201,11 +2480,11 @@ DynamicModel::collect_first_order_derivatives_current_endogenous() cout << " derivative = "; (it2->second)->writeOutput(cout, output_type, temporary_terms); cout << "\n";*/ - if(lag==0) + if (lag==0) curr_endo_derivatives[make_pair(eq, var)] = it2->second; } } - return curr_endo_derivatives; + return curr_endo_derivatives; } @@ -2221,8 +2500,8 @@ DynamicModel::computingPass(bool jacobianExo, bool hessian, bool thirdDerivative // Compute derivatives w.r. to all endogenous, and possibly exogenous and exogenous deterministic set vars; - for(deriv_id_table_t::const_iterator it = deriv_id_table.begin(); - it != deriv_id_table.end(); it++) + for (deriv_id_table_t::const_iterator it = deriv_id_table.begin(); + it != deriv_id_table.end(); it++) { SymbolType type = symbol_table.getType(it->first.first); if (type == eEndogenous || (jacobianExo && (type == eExogenous || type == eExogenousDet))) @@ -2231,7 +2510,7 @@ DynamicModel::computingPass(bool jacobianExo, bool hessian, bool thirdDerivative // Launch computations cout << "Computing dynamic model derivatives:" << endl - << " - order 1" << endl; + << " - order 1" << endl; computeJacobian(vars); if (hessian) @@ -2284,56 +2563,56 @@ DynamicModel::computingPass(bool jacobianExo, bool hessian, bool thirdDerivative void DynamicModel::writeDynamicFile(const string &basename) const -{ - switch (mode) - { - case eStandardMode: - writeDynamicMFile(basename + "_dynamic"); - break; - case eSparseMode: + { + switch (mode) + { + case eStandardMode: + writeDynamicMFile(basename + "_dynamic"); + break; + case eSparseMode: #ifdef _WIN32 - mkdir(basename.c_str()); + mkdir(basename.c_str()); #else - mkdir(basename.c_str(), 0777); + mkdir(basename.c_str(), 0777); #endif - writeSparseDynamicMFile(basename + "_dynamic", basename, mode); - block_triangular.Free_Block(block_triangular.ModelBlock); - block_triangular.incidencematrix.Free_IM(); - //block_triangular.Free_IM_X(block_triangular.First_IM_X); - break; - case eDLLMode: - writeDynamicCFile(basename + "_dynamic"); - break; - case eSparseDLLMode: - // create a directory to store all the files + writeSparseDynamicMFile(basename + "_dynamic", basename, mode); + block_triangular.Free_Block(block_triangular.ModelBlock); + block_triangular.incidencematrix.Free_IM(); + //block_triangular.Free_IM_X(block_triangular.First_IM_X); + break; + case eDLLMode: + writeDynamicCFile(basename + "_dynamic"); + break; + case eSparseDLLMode: + // create a directory to store all the files #ifdef _WIN32 - mkdir(basename.c_str()); + mkdir(basename.c_str()); #else - mkdir(basename.c_str(), 0777); + mkdir(basename.c_str(), 0777); #endif - writeModelEquationsCodeOrdered(basename + "_dynamic", block_triangular.ModelBlock, basename, map_idx); - block_triangular.Free_Block(block_triangular.ModelBlock); - block_triangular.incidencematrix.Free_IM(); - //block_triangular.Free_IM_X(block_triangular.First_IM_X); - break; - } -} + writeModelEquationsCodeOrdered(basename + "_dynamic", block_triangular.ModelBlock, basename, map_idx); + block_triangular.Free_Block(block_triangular.ModelBlock); + block_triangular.incidencematrix.Free_IM(); + //block_triangular.Free_IM_X(block_triangular.First_IM_X); + break; + } + } void DynamicModel::toStatic(StaticModel &static_model) const -{ - static_model.mode = mode; + { + static_model.mode = mode; - // Convert model local variables (need to be done first) - for (map::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 model local variables (need to be done first) + for (map::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::const_iterator it = equations.begin(); - it != equations.end(); it++) - static_model.addEquation((*it)->toStatic(static_model)); -} + // Convert equations + for (vector::const_iterator it = equations.begin(); + it != equations.end(); it++) + static_model.addEquation((*it)->toStatic(static_model)); + } int DynamicModel::computeDerivID(int symb_id, int lag) @@ -2346,7 +2625,7 @@ DynamicModel::computeDerivID(int symb_id, int lag) SymbolType type = symbol_table.getType(symb_id); - switch(type) + switch (type) { case eEndogenous: if (max_endo_lead < lag) @@ -2432,8 +2711,8 @@ DynamicModel::computeDynJacobianCols(bool jacobianExo) and fill the dynamic columns for exogenous and exogenous deterministic */ map, int> ordered_dyn_endo; - for(deriv_id_table_t::const_iterator it = deriv_id_table.begin(); - it != deriv_id_table.end(); it++) + for (deriv_id_table_t::const_iterator it = deriv_id_table.begin(); + it != deriv_id_table.end(); it++) { const int &symb_id = it->first.first; const int &lag = it->first.second; @@ -2441,7 +2720,7 @@ DynamicModel::computeDynJacobianCols(bool jacobianExo) SymbolType type = symbol_table.getType(symb_id); int tsid = symbol_table.getTypeSpecificID(symb_id); - switch(type) + switch (type) { case eEndogenous: ordered_dyn_endo[make_pair(lag, tsid)] = deriv_id; @@ -2468,8 +2747,8 @@ DynamicModel::computeDynJacobianCols(bool jacobianExo) // Fill in dynamic jacobian columns for endogenous int sorted_id = 0; - for(map, int>::const_iterator it = ordered_dyn_endo.begin(); - it != ordered_dyn_endo.end(); it++) + for (map, int>::const_iterator it = ordered_dyn_endo.begin(); + it != ordered_dyn_endo.end(); it++) dyn_jacobian_cols_table[it->second] = sorted_id++; // Set final value for dynJacobianColsNbr @@ -2490,8 +2769,8 @@ DynamicModel::getDynJacobianCol(int deriv_id) const throw (UnknownDerivIDExcepti void DynamicModel::computeParamsDerivatives() { - for(deriv_id_table_t::const_iterator it = deriv_id_table.begin(); - it != deriv_id_table.end(); it++) + for (deriv_id_table_t::const_iterator it = deriv_id_table.begin(); + it != deriv_id_table.end(); it++) { if (symbol_table.getType(it->first.first) != eParameter) continue; @@ -2526,51 +2805,51 @@ DynamicModel::computeParamsDerivativesTemporaryTerms() void DynamicModel::writeParamsDerivativesFile(const string &basename) const -{ - if (!params_derivatives.size()) - return; + { + if (!params_derivatives.size()) + return; - string filename = basename + "_params_derivs.m"; + string filename = basename + "_params_derivs.m"; - ofstream paramsDerivsFile; - paramsDerivsFile.open(filename.c_str(), ios::out | ios::binary); - if (!paramsDerivsFile.is_open()) - { - cerr << "ERROR: Can't open file " << filename << " for writing" << endl; - exit(EXIT_FAILURE); - } - paramsDerivsFile << "function gp = " << basename << "_params_derivs(y, x, params, it_)" << endl - << "%" << endl - << "% Warning : this file is generated automatically by Dynare" << endl - << "% from model file (.mod)" << endl << endl; + ofstream paramsDerivsFile; + paramsDerivsFile.open(filename.c_str(), ios::out | ios::binary); + if (!paramsDerivsFile.is_open()) + { + cerr << "ERROR: Can't open file " << filename << " for writing" << endl; + exit(EXIT_FAILURE); + } + paramsDerivsFile << "function gp = " << basename << "_params_derivs(y, x, params, it_)" << endl + << "%" << endl + << "% Warning : this file is generated automatically by Dynare" << endl + << "% from model file (.mod)" << endl << endl; - writeTemporaryTerms(params_derivs_temporary_terms, paramsDerivsFile, oMatlabDynamicModel); + writeTemporaryTerms(params_derivs_temporary_terms, paramsDerivsFile, oMatlabDynamicModel); - paramsDerivsFile << "gp = zeros(" << equation_number() << ", " << dynJacobianColsNbr << ", " - << symbol_table.param_nbr() << ");" << endl; + paramsDerivsFile << "gp = zeros(" << equation_number() << ", " << dynJacobianColsNbr << ", " + << symbol_table.param_nbr() << ");" << endl; - for (second_derivatives_type::const_iterator it = params_derivatives.begin(); - it != params_derivatives.end(); it++) - { - int eq = it->first.first; - int var = it->first.second.first; - int param = it->first.second.second; - NodeID d2 = it->second; + for (second_derivatives_type::const_iterator it = params_derivatives.begin(); + it != params_derivatives.end(); it++) + { + int eq = it->first.first; + int var = it->first.second.first; + int param = it->first.second.second; + NodeID d2 = it->second; - int var_col = getDynJacobianCol(var) + 1; - int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1; + int var_col = getDynJacobianCol(var) + 1; + int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1; - paramsDerivsFile << "gp(" << eq+1 << ", " << var_col << ", " << param_col << ") = "; - d2->writeOutput(paramsDerivsFile, oMatlabDynamicModel, params_derivs_temporary_terms); - paramsDerivsFile << ";" << endl; - } + paramsDerivsFile << "gp(" << eq+1 << ", " << var_col << ", " << param_col << ") = "; + d2->writeOutput(paramsDerivsFile, oMatlabDynamicModel, params_derivs_temporary_terms); + paramsDerivsFile << ";" << endl; + } - paramsDerivsFile.close(); -} + paramsDerivsFile.close(); + } void DynamicModel::writeLatexFile(const string &basename) const -{ - writeLatexModelFile(basename + "_dynamic.tex", oLatexDynamicModel); -} + { + writeLatexModelFile(basename + "_dynamic.tex", oLatexDynamicModel); + } diff --git a/ExprNode.cc b/ExprNode.cc index 4e1cb6aa..e736633c 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -60,27 +60,53 @@ ExprNode::getDerivative(int deriv_id) } } + +NodeID +ExprNode::getChaineRuleDerivative(int deriv_id, map &recursive_variables, int var, int lag_) +{ + // Return zero if derivative is necessarily null (using symbolic a priori) + /*set::const_iterator it = non_null_derivatives.find(deriv_id); + if (it == non_null_derivatives.end()) + { + cout << "0\n"; + return datatree.Zero; + } + */ + + // If derivative is stored in cache, use the cached value, otherwise compute it (and cache it) + /*map::const_iterator it2 = derivatives.find(deriv_id); + if (it2 != derivatives.end()) + return it2->second; + else*/ + { + NodeID d = computeChaineRuleDerivative(deriv_id, recursive_variables, var, lag_); + //derivatives[deriv_id] = d; + return d; + } +} + + int ExprNode::precedence(ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const -{ - // For a constant, a variable, or a unary op, the precedence is maximal - return 100; -} + { + // For a constant, a variable, or a unary op, the precedence is maximal + return 100; + } int ExprNode::cost(const temporary_terms_type &temporary_terms, bool is_matlab) const -{ - // For a terminal node, the cost is null - return 0; -} + { + // For a terminal node, the cost is null + return 0; + } void ExprNode::computeTemporaryTerms(map &reference_count, temporary_terms_type &temporary_terms, bool is_matlab) const -{ - // Nothing to do for a terminal node -} + { + // Nothing to do for a terminal node + } void ExprNode::computeTemporaryTerms(map &reference_count, @@ -90,9 +116,17 @@ ExprNode::computeTemporaryTerms(map &reference_count, Model_Block *ModelBlock, int equation, map_idx_type &map_idx) const -{ - // Nothing to do for a terminal node -} + { + // Nothing to do for a terminal node + } + +void +ExprNode::writeOutput(ostream &output, ExprNodeOutputType output_type, + const temporary_terms_type &temporary_terms) const + { + //writeOutput(output, oMatlabOutsideModel, temporary_terms_type()); + } + void ExprNode::writeOutput(ostream &output) @@ -100,10 +134,15 @@ ExprNode::writeOutput(ostream &output) writeOutput(output, oMatlabOutsideModel, temporary_terms_type()); } +pair +ExprNode::normalizeLinearInEndoEquation(int var_endo, NodeID Derivative) const + { + return(make_pair(true, (NodeID)NULL)); + } NumConstNode::NumConstNode(DataTree &datatree_arg, int id_arg) : - ExprNode(datatree_arg), - id(id_arg) + ExprNode(datatree_arg), + id(id_arg) { // Add myself to the num const map datatree.num_const_node_map[id] = this; @@ -119,25 +158,26 @@ NumConstNode::computeDerivative(int deriv_id) void NumConstNode::collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const -{ - temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - ModelBlock->Block_List[Curr_Block].Temporary_InUse->insert(idx); -} + { + temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); + if (it != temporary_terms.end()) + ModelBlock->Block_List[Curr_Block].Temporary_InUse->insert(idx); + } void NumConstNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const -{ - temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - if (output_type == oMatlabDynamicModelSparse) - output << "T" << idx << "(it_)"; + { + //cout << "writeOutput constante\n"; + temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); + if (it != temporary_terms.end()) + if (output_type == oMatlabDynamicModelSparse) + output << "T" << idx << "(it_)"; + else + output << "T" << idx; else - output << "T" << idx; - else - output << datatree.num_constants.get(id); -} + output << datatree.num_constants.get(id); + } double NumConstNode::eval(const eval_context_type &eval_context) const throw (EvalException) @@ -147,38 +187,59 @@ NumConstNode::eval(const eval_context_type &eval_context) const throw (EvalExcep void NumConstNode::compile(ofstream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const -{ - CompileCode.write(&FLDC, sizeof(FLDC)); - double vard = datatree.num_constants.getDouble(id); + { + CompileCode.write(&FLDC, sizeof(FLDC)); + double vard = datatree.num_constants.getDouble(id); #ifdef DEBUGC - cout << "FLDC " << vard << "\n"; + cout << "FLDC " << vard << "\n"; #endif - CompileCode.write(reinterpret_cast(&vard),sizeof(vard)); -} + CompileCode.write(reinterpret_cast(&vard),sizeof(vard)); + } void NumConstNode::collectEndogenous(set > &result) const -{ -} + { + } void NumConstNode::collectExogenous(set > &result) const + { + } + +pair +NumConstNode::normalizeLinearInEndoEquation(int var_endo, NodeID Derivative) const + { + return(make_pair(false, datatree.AddNumConstant(datatree.num_constants.get(id)))); + } + +NodeID +NumConstNode::computeChaineRuleDerivative(int deriv_id, map &recursive_variables, int var, int lag_) { + return datatree.Zero; } + +/* +pair +NumConstNode::computeDerivativeRespectToFeedbackVariable(int equ, int var, int varr, int lag_, int max_lag, vector &recursive_variables, vector &feeback_variables) const + { + return(make_pair(false, datatree.Zero)); + } +*/ + NodeID NumConstNode::toStatic(DataTree &static_datatree) const -{ - return static_datatree.AddNumConstant(datatree.num_constants.get(id)); -} + { + return static_datatree.AddNumConstant(datatree.num_constants.get(id)); + } VariableNode::VariableNode(DataTree &datatree_arg, int symb_id_arg, int lag_arg, int deriv_id_arg) : - ExprNode(datatree_arg), - symb_id(symb_id_arg), - type(datatree.symbol_table.getType(symb_id_arg)), - lag(lag_arg), - deriv_id(deriv_id_arg) + ExprNode(datatree_arg), + symb_id(symb_id_arg), + type(datatree.symbol_table.getType(symb_id_arg)), + lag(lag_arg), + deriv_id(deriv_id_arg) { // Add myself to the variable map datatree.variable_node_map[make_pair(symb_id, lag)] = this; @@ -187,7 +248,7 @@ VariableNode::VariableNode(DataTree &datatree_arg, int symb_id_arg, int lag_arg, assert(lag == 0 || (type != eModelLocalVariable && type != eModFileLocalVariable && type != eUnknownFunction)); // Fill in non_null_derivatives - switch(type) + switch (type) { case eEndogenous: case eExogenous: @@ -212,7 +273,7 @@ VariableNode::VariableNode(DataTree &datatree_arg, int symb_id_arg, int lag_arg, NodeID VariableNode::computeDerivative(int deriv_id_arg) { - switch(type) + switch (type) { case eEndogenous: case eExogenous: @@ -237,178 +298,178 @@ VariableNode::computeDerivative(int deriv_id_arg) void VariableNode::collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const -{ - temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - ModelBlock->Block_List[Curr_Block].Temporary_InUse->insert(idx); - if(type== eModelLocalVariable) - datatree.local_variables_table[symb_id]->collectTemporary_terms(temporary_terms, ModelBlock, Curr_Block); -} + { + temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); + if (it != temporary_terms.end()) + ModelBlock->Block_List[Curr_Block].Temporary_InUse->insert(idx); + if (type== eModelLocalVariable) + datatree.local_variables_table[symb_id]->collectTemporary_terms(temporary_terms, ModelBlock, Curr_Block); + } void VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const -{ - // If node is a temporary term + { + // If node is a temporary term #ifdef DEBUGC - cout << "write_ouput output_type=" << output_type << "\n"; + cout << "write_ouput Variable output_type=" << output_type << "\n"; #endif - temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - if (output_type == oMatlabDynamicModelSparse) - output << "T" << idx << "(it_)"; - else - output << "T" << idx; - return; - } + temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); + if (it != temporary_terms.end()) + { + if (output_type == oMatlabDynamicModelSparse) + output << "T" << idx << "(it_)"; + else + output << "T" << idx; + return; + } - if (IS_LATEX(output_type)) - { - output << datatree.symbol_table.getTeXName(symb_id); - if (output_type == oLatexDynamicModel) - { - output << "_{t"; - if (lag != 0) - { - if (lag > 0) - output << "+"; - output << lag; - } - output << "}"; - } - return; - } + if (IS_LATEX(output_type)) + { + output << datatree.symbol_table.getTeXName(symb_id); + if (output_type == oLatexDynamicModel) + { + output << "_{t"; + if (lag != 0) + { + if (lag > 0) + output << "+"; + output << lag; + } + output << "}"; + } + return; + } - int i; - int tsid = datatree.symbol_table.getTypeSpecificID(symb_id); - switch(type) - { - case eParameter: - if (output_type == oMatlabOutsideModel) - output << "M_.params" << "(" << tsid + 1 << ")"; - else - output << "params" << LEFT_ARRAY_SUBSCRIPT(output_type) << tsid + ARRAY_SUBSCRIPT_OFFSET(output_type) << RIGHT_ARRAY_SUBSCRIPT(output_type); - break; + int i; + int tsid = datatree.symbol_table.getTypeSpecificID(symb_id); + switch (type) + { + case eParameter: + if (output_type == oMatlabOutsideModel) + output << "M_.params" << "(" << tsid + 1 << ")"; + else + output << "params" << LEFT_ARRAY_SUBSCRIPT(output_type) << tsid + ARRAY_SUBSCRIPT_OFFSET(output_type) << RIGHT_ARRAY_SUBSCRIPT(output_type); + break; - case eModelLocalVariable: - case eModFileLocalVariable: - if(output_type==oMatlabDynamicModelSparse || output_type==oMatlabStaticModelSparse) - { - output << "("; - datatree.local_variables_table[symb_id]->writeOutput(output, output_type,temporary_terms); - output << ")"; - } - else - output << datatree.symbol_table.getName(symb_id); - break; + case eModelLocalVariable: + case eModFileLocalVariable: + if (output_type==oMatlabDynamicModelSparse || output_type==oMatlabStaticModelSparse) + { + output << "("; + datatree.local_variables_table[symb_id]->writeOutput(output, output_type,temporary_terms); + output << ")"; + } + else + output << datatree.symbol_table.getName(symb_id); + break; - case eEndogenous: - switch(output_type) - { - case oMatlabDynamicModel: - case oCDynamicModel: - i = datatree.getDynJacobianCol(deriv_id) + ARRAY_SUBSCRIPT_OFFSET(output_type); - output << "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type); - break; - case oMatlabStaticModel: - case oMatlabStaticModelSparse: - case oCStaticModel: - i = tsid + ARRAY_SUBSCRIPT_OFFSET(output_type); - output << "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type); - break; - case oMatlabDynamicModelSparse: - i = tsid + ARRAY_SUBSCRIPT_OFFSET(output_type); - if (lag > 0) - output << "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_+" << lag << ", " << i << RIGHT_ARRAY_SUBSCRIPT(output_type); - else if (lag < 0) - output << "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_" << lag << ", " << i << RIGHT_ARRAY_SUBSCRIPT(output_type); - else - output << "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_, " << i << RIGHT_ARRAY_SUBSCRIPT(output_type); - break; - case oMatlabOutsideModel: - output << "oo_.steady_state" << "(" << tsid + 1 << ")"; - break; - default: - assert(false); - } - break; + case eEndogenous: + switch (output_type) + { + case oMatlabDynamicModel: + case oCDynamicModel: + i = datatree.getDynJacobianCol(deriv_id) + ARRAY_SUBSCRIPT_OFFSET(output_type); + output << "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type); + break; + case oMatlabStaticModel: + case oMatlabStaticModelSparse: + case oCStaticModel: + i = tsid + ARRAY_SUBSCRIPT_OFFSET(output_type); + output << "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type); + break; + case oMatlabDynamicModelSparse: + i = tsid + ARRAY_SUBSCRIPT_OFFSET(output_type); + if (lag > 0) + output << "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_+" << lag << ", " << i << RIGHT_ARRAY_SUBSCRIPT(output_type); + else if (lag < 0) + output << "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_" << lag << ", " << i << RIGHT_ARRAY_SUBSCRIPT(output_type); + else + output << "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_, " << i << RIGHT_ARRAY_SUBSCRIPT(output_type); + break; + case oMatlabOutsideModel: + output << "oo_.steady_state" << "(" << tsid + 1 << ")"; + break; + default: + assert(false); + } + break; - case eExogenous: - i = tsid + ARRAY_SUBSCRIPT_OFFSET(output_type); - switch(output_type) - { - case oMatlabDynamicModel: - case oMatlabDynamicModelSparse: - if (lag > 0) - output << "x(it_+" << lag << ", " << i << ")"; - else if (lag < 0) - output << "x(it_" << lag << ", " << i << ")"; - else - output << "x(it_, " << i << ")"; - break; - case oCDynamicModel: - if (lag == 0) - output << "x[it_+" << i << "*nb_row_x]"; - else if (lag > 0) - output << "x[it_+" << lag << "+" << i << "*nb_row_x]"; - else - output << "x[it_" << lag << "+" << i << "*nb_row_x]"; - break; - case oMatlabStaticModel: - case oMatlabStaticModelSparse: - case oCStaticModel: - output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type); - break; - case oMatlabOutsideModel: - assert(lag == 0); - output << "oo_.exo_steady_state" << "(" << i << ")"; - break; - default: - assert(false); - } - break; + case eExogenous: + i = tsid + ARRAY_SUBSCRIPT_OFFSET(output_type); + switch (output_type) + { + case oMatlabDynamicModel: + case oMatlabDynamicModelSparse: + if (lag > 0) + output << "x(it_+" << lag << ", " << i << ")"; + else if (lag < 0) + output << "x(it_" << lag << ", " << i << ")"; + else + output << "x(it_, " << i << ")"; + break; + case oCDynamicModel: + if (lag == 0) + output << "x[it_+" << i << "*nb_row_x]"; + else if (lag > 0) + output << "x[it_+" << lag << "+" << i << "*nb_row_x]"; + else + output << "x[it_" << lag << "+" << i << "*nb_row_x]"; + break; + case oMatlabStaticModel: + case oMatlabStaticModelSparse: + case oCStaticModel: + output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type); + break; + case oMatlabOutsideModel: + assert(lag == 0); + output << "oo_.exo_steady_state" << "(" << i << ")"; + break; + default: + assert(false); + } + break; - case eExogenousDet: - i = tsid + datatree.symbol_table.exo_nbr() + ARRAY_SUBSCRIPT_OFFSET(output_type); - switch(output_type) - { - case oMatlabDynamicModel: - case oMatlabDynamicModelSparse: - if (lag > 0) - output << "x(it_+" << lag << ", " << i << ")"; - else if (lag < 0) - output << "x(it_" << lag << ", " << i << ")"; - else - output << "x(it_, " << i << ")"; - break; - case oCDynamicModel: - if (lag == 0) - output << "x[it_+" << i << "*nb_row_xd]"; - else if (lag > 0) - output << "x[it_+" << lag << "+" << i << "*nb_row_xd]"; - else - output << "x[it_" << lag << "+" << i << "*nb_row_xd]"; - break; - case oMatlabStaticModel: - case oMatlabStaticModelSparse: - case oCStaticModel: - output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type); - break; - case oMatlabOutsideModel: - assert(lag == 0); - output << "oo_.exo_det_steady_state" << "(" << tsid + 1 << ")"; - break; - default: - assert(false); - } - break; + case eExogenousDet: + i = tsid + datatree.symbol_table.exo_nbr() + ARRAY_SUBSCRIPT_OFFSET(output_type); + switch (output_type) + { + case oMatlabDynamicModel: + case oMatlabDynamicModelSparse: + if (lag > 0) + output << "x(it_+" << lag << ", " << i << ")"; + else if (lag < 0) + output << "x(it_" << lag << ", " << i << ")"; + else + output << "x(it_, " << i << ")"; + break; + case oCDynamicModel: + if (lag == 0) + output << "x[it_+" << i << "*nb_row_xd]"; + else if (lag > 0) + output << "x[it_+" << lag << "+" << i << "*nb_row_xd]"; + else + output << "x[it_" << lag << "+" << i << "*nb_row_xd]"; + break; + case oMatlabStaticModel: + case oMatlabStaticModelSparse: + case oCStaticModel: + output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type); + break; + case oMatlabOutsideModel: + assert(lag == 0); + output << "oo_.exo_det_steady_state" << "(" << tsid + 1 << ")"; + break; + default: + assert(false); + } + break; - case eUnknownFunction: - cerr << "Impossible case" << endl; - exit(EXIT_FAILURE); - } -} + case eUnknownFunction: + cerr << "Impossible case" << endl; + exit(EXIT_FAILURE); + } + } double VariableNode::eval(const eval_context_type &eval_context) const throw (EvalException) @@ -422,54 +483,63 @@ VariableNode::eval(const eval_context_type &eval_context) const throw (EvalExcep void VariableNode::compile(ofstream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const -{ - int i, lagl; + { + int i, lagl; #ifdef DEBUGC - cout << "output_type=" << output_type << "\n"; + cout << "output_type=" << output_type << "\n"; #endif - if(!lhs_rhs) - CompileCode.write(&FLDV, sizeof(FLDV)); - else - CompileCode.write(&FSTPV, sizeof(FSTPV)); - char typel=(char)type; - CompileCode.write(&typel, sizeof(typel)); - int tsid = datatree.symbol_table.getTypeSpecificID(symb_id); - switch(type) - { - case eParameter: - i = tsid; - CompileCode.write(reinterpret_cast(&i), sizeof(i)); + if (!lhs_rhs) + { + CompileCode.write(&FLDV, sizeof(FLDV)); + } + else + { + CompileCode.write(&FSTPV, sizeof(FSTPV)); + } + char typel=(char)type; + CompileCode.write(&typel, sizeof(typel)); + int tsid = datatree.symbol_table.getTypeSpecificID(symb_id); + switch (type) + { + case eParameter: + //cout << "Parameter=" << tsid << "\n"; + i = tsid; + CompileCode.write(reinterpret_cast(&i), sizeof(i)); #ifdef DEBUGC - cout << "FLD Param[ " << i << ", symb_id=" << symb_id << "]\n"; + cout << "FLD Param[ " << i << ", symb_id=" << symb_id << "]\n"; #endif - break; - case eEndogenous : - i = symb_id; - CompileCode.write(reinterpret_cast(&i), sizeof(i)); - lagl=lag; - CompileCode.write(reinterpret_cast(&lagl), sizeof(lagl)); - break; - case eExogenous : - i = tsid; - CompileCode.write(reinterpret_cast(&i), sizeof(i)); - lagl=lag; - CompileCode.write(reinterpret_cast(&lagl), sizeof(lagl)); - break; - case eExogenousDet: - i = tsid + datatree.symbol_table.exo_nbr(); - CompileCode.write(reinterpret_cast(&i), sizeof(i)); - lagl=lag; - CompileCode.write(reinterpret_cast(&lagl), sizeof(lagl)); - break; - case eModelLocalVariable: - case eModFileLocalVariable: - datatree.local_variables_table[symb_id]->compile(CompileCode, lhs_rhs, temporary_terms, map_idx); - break; - case eUnknownFunction: - cerr << "Impossible case: eUnknownFuncion" << endl; - exit(EXIT_FAILURE); - } -} + break; + case eEndogenous : + //cout << "Endogenous=" << symb_id << "\n"; + i = tsid;//symb_id; + CompileCode.write(reinterpret_cast(&i), sizeof(i)); + lagl=lag; + CompileCode.write(reinterpret_cast(&lagl), sizeof(lagl)); + break; + case eExogenous : + //cout << "Exogenous=" << tsid << "\n"; + i = tsid; + CompileCode.write(reinterpret_cast(&i), sizeof(i)); + lagl=lag; + CompileCode.write(reinterpret_cast(&lagl), sizeof(lagl)); + break; + case eExogenousDet: + i = tsid + datatree.symbol_table.exo_nbr(); + //cout << "ExogenousDet=" << i << "\n"; + CompileCode.write(reinterpret_cast(&i), sizeof(i)); + lagl=lag; + CompileCode.write(reinterpret_cast(&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); + break; + case eUnknownFunction: + cerr << "Impossible case: eUnknownFuncion" << endl; + exit(EXIT_FAILURE); + } + } void VariableNode::computeTemporaryTerms(map &reference_count, @@ -479,40 +549,116 @@ VariableNode::computeTemporaryTerms(map &reference_count, Model_Block *ModelBlock, int equation, map_idx_type &map_idx) const -{ - if(type== eModelLocalVariable) - datatree.local_variables_table[symb_id]->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, ModelBlock, equation, map_idx); -} + { + if (type== eModelLocalVariable) + datatree.local_variables_table[symb_id]->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, ModelBlock, equation, map_idx); + } void VariableNode::collectEndogenous(set > &result) const -{ - if (type == eEndogenous) - result.insert(make_pair(symb_id, lag)); - else if (type == eModelLocalVariable) - datatree.local_variables_table[symb_id]->collectEndogenous(result); -} + { + if (type == eEndogenous) + result.insert(make_pair(datatree.symbol_table.getTypeSpecificID(symb_id), lag)); + else if (type == eModelLocalVariable) + datatree.local_variables_table[symb_id]->collectEndogenous(result); + } void VariableNode::collectExogenous(set > &result) const + { + if (type == eExogenous) + result.insert(make_pair(datatree.symbol_table.getTypeSpecificID(symb_id), lag)); + else if (type == eModelLocalVariable) + datatree.local_variables_table[symb_id]->collectExogenous(result); + } + +pair +VariableNode::normalizeLinearInEndoEquation(int var_endo, NodeID Derivative) const + { + if (type ==eEndogenous) + { + if (datatree.symbol_table.getTypeSpecificID(symb_id)==var_endo and lag==0) + return(make_pair(true, (NodeID)NULL)); + else + return(make_pair(false, 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))); + else + return(make_pair(false, datatree.AddVariableInternal(datatree.symbol_table.getName(symb_id), lag))); + } + } + +template +pair find_r ( InputIterator first, InputIterator last, const T& value ) { - if (type == eExogenous) - result.insert(make_pair(symb_id, lag)); - else if (type == eModelLocalVariable) - datatree.local_variables_table[symb_id]->collectExogenous(result); + int i=0; + for (; first!=last; first++) + { + if ( *first==value ) break; + i++; + } + return make_pair(first, i); } + +NodeID +VariableNode::computeChaineRuleDerivative(int deriv_id_arg, map &recursive_variables, int var, int lag_) +{ + switch (type) + { + case eEndogenous: + case eExogenous: + case eExogenousDet: + case eParameter: + //cout << "deriv_id=" << deriv_id << " deriv_id_arg=" << deriv_id_arg << " symb_id=" << symb_id << " type=" << type << " lag=" << lag << " var=" << var << " lag_ = " << lag_ << "\n"; + if (deriv_id == deriv_id_arg) + return datatree.One; + else + { + //if there is in the equation a recursive variable we could use a chaine rule derivation + if(lag == lag_) + { + map::const_iterator it = recursive_variables.find(deriv_id); + if (it != recursive_variables.end()) + { + recursive_variables.erase(it->first); + return datatree.AddUMinus(it->second->getChaineRuleDerivative(deriv_id_arg, recursive_variables, var, lag_)); + } + else + return datatree.Zero; + } + else + return datatree.Zero; + } + case eModelLocalVariable: + return datatree.local_variables_table[symb_id]->getChaineRuleDerivative(deriv_id_arg, recursive_variables, var, lag_); + case eModFileLocalVariable: + cerr << "ModFileLocalVariable is not derivable" << endl; + exit(EXIT_FAILURE); + case eUnknownFunction: + cerr << "Impossible case!" << endl; + exit(EXIT_FAILURE); + } + // Suppress GCC warning + exit(EXIT_FAILURE); +} + + + NodeID VariableNode::toStatic(DataTree &static_datatree) const -{ - return static_datatree.AddVariable(datatree.symbol_table.getName(symb_id)); -} + { + return static_datatree.AddVariable(datatree.symbol_table.getName(symb_id)); + } UnaryOpNode::UnaryOpNode(DataTree &datatree_arg, UnaryOpcode op_code_arg, const NodeID arg_arg) : - ExprNode(datatree_arg), - arg(arg_arg), - op_code(op_code_arg) + ExprNode(datatree_arg), + arg(arg_arg), + op_code(op_code_arg) { // Add myself to the unary op map datatree.unary_op_node_map[make_pair(arg, op_code)] = this; @@ -528,7 +674,7 @@ UnaryOpNode::computeDerivative(int deriv_id) NodeID t11, t12, t13; - switch(op_code) + switch (op_code) { case oUminus: return datatree.AddUMinus(darg); @@ -593,109 +739,109 @@ UnaryOpNode::computeDerivative(int deriv_id) int UnaryOpNode::cost(const temporary_terms_type &temporary_terms, bool is_matlab) const -{ - // For a temporary term, the cost is null - temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - return 0; + { + // For a temporary term, the cost is null + temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); + if (it != temporary_terms.end()) + return 0; - int cost = arg->cost(temporary_terms, is_matlab); + int cost = arg->cost(temporary_terms, is_matlab); - if (is_matlab) - // Cost for Matlab files - switch(op_code) - { - case oUminus: - return cost + 70; - case oExp: - return cost + 160; - case oLog: - return cost + 300; - case oLog10: - return cost + 16000; - case oCos: - case oSin: - case oCosh: - return cost + 210; - case oTan: - return cost + 230; - case oAcos: - return cost + 300; - case oAsin: - return cost + 310; - case oAtan: - return cost + 140; - case oSinh: - return cost + 240; - case oTanh: - return cost + 190; - case oAcosh: - return cost + 770; - case oAsinh: - return cost + 460; - case oAtanh: - return cost + 350; - case oSqrt: - return cost + 570; - } - else - // Cost for C files - switch(op_code) - { - case oUminus: - return cost + 3; - case oExp: - case oAcosh: - return cost + 210; - case oLog: - return cost + 137; - case oLog10: - return cost + 139; - case oCos: - case oSin: - return cost + 160; - case oTan: - return cost + 170; - case oAcos: - case oAtan: - return cost + 190; - case oAsin: - return cost + 180; - case oCosh: - case oSinh: - case oTanh: - return cost + 240; - case oAsinh: - return cost + 220; - case oAtanh: - return cost + 150; - case oSqrt: - return cost + 90; - } - // Suppress GCC warning - exit(EXIT_FAILURE); -} + if (is_matlab) + // Cost for Matlab files + switch (op_code) + { + case oUminus: + return cost + 70; + case oExp: + return cost + 160; + case oLog: + return cost + 300; + case oLog10: + return cost + 16000; + case oCos: + case oSin: + case oCosh: + return cost + 210; + case oTan: + return cost + 230; + case oAcos: + return cost + 300; + case oAsin: + return cost + 310; + case oAtan: + return cost + 140; + case oSinh: + return cost + 240; + case oTanh: + return cost + 190; + case oAcosh: + return cost + 770; + case oAsinh: + return cost + 460; + case oAtanh: + return cost + 350; + case oSqrt: + return cost + 570; + } + else + // Cost for C files + switch (op_code) + { + case oUminus: + return cost + 3; + case oExp: + case oAcosh: + return cost + 210; + case oLog: + return cost + 137; + case oLog10: + return cost + 139; + case oCos: + case oSin: + return cost + 160; + case oTan: + return cost + 170; + case oAcos: + case oAtan: + return cost + 190; + case oAsin: + return cost + 180; + case oCosh: + case oSinh: + case oTanh: + return cost + 240; + case oAsinh: + return cost + 220; + case oAtanh: + return cost + 150; + case oSqrt: + return cost + 90; + } + // Suppress GCC warning + exit(EXIT_FAILURE); + } void UnaryOpNode::computeTemporaryTerms(map &reference_count, temporary_terms_type &temporary_terms, bool is_matlab) const -{ - NodeID this2 = const_cast(this); + { + NodeID this2 = const_cast(this); - map::iterator it = reference_count.find(this2); - if (it == reference_count.end()) - { - reference_count[this2] = 1; - arg->computeTemporaryTerms(reference_count, temporary_terms, is_matlab); - } - else - { - reference_count[this2]++; - if (reference_count[this2] * cost(temporary_terms, is_matlab) > MIN_COST(is_matlab)) - temporary_terms.insert(this2); - } -} + map::iterator it = reference_count.find(this2); + if (it == reference_count.end()) + { + reference_count[this2] = 1; + arg->computeTemporaryTerms(reference_count, temporary_terms, is_matlab); + } + else + { + reference_count[this2]++; + if (reference_count[this2] * cost(temporary_terms, is_matlab) > MIN_COST(is_matlab)) + temporary_terms.insert(this2); + } + } void UnaryOpNode::computeTemporaryTerms(map &reference_count, @@ -705,142 +851,143 @@ UnaryOpNode::computeTemporaryTerms(map &reference_count, Model_Block *ModelBlock, int equation, map_idx_type &map_idx) const -{ - NodeID this2 = const_cast(this); - map::iterator it = reference_count.find(this2); - if (it == reference_count.end()) - { - reference_count[this2] = 1; - first_occurence[this2] = make_pair(Curr_block,equation); - arg->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, ModelBlock, equation, map_idx); - } - else - { - reference_count[this2]++; - if (reference_count[this2] * cost(temporary_terms, false) > MIN_COST_C) - { - temporary_terms.insert(this2); - ModelBlock->Block_List[first_occurence[this2].first].Temporary_Terms_in_Equation[first_occurence[this2].second]->insert(this2); - } - } -} + { + NodeID this2 = const_cast(this); + map::iterator it = reference_count.find(this2); + if (it == reference_count.end()) + { + reference_count[this2] = 1; + first_occurence[this2] = make_pair(Curr_block,equation); + arg->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, ModelBlock, equation, map_idx); + } + else + { + reference_count[this2]++; + if (reference_count[this2] * cost(temporary_terms, false) > MIN_COST_C) + { + temporary_terms.insert(this2); + ModelBlock->Block_List[first_occurence[this2].first].Temporary_Terms_in_Equation[first_occurence[this2].second]->insert(this2); + } + } + } void UnaryOpNode::collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const -{ - temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - ModelBlock->Block_List[Curr_Block].Temporary_InUse->insert(idx); - else - arg->collectTemporary_terms(temporary_terms, ModelBlock, Curr_Block); -} + { + temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); + if (it != temporary_terms.end()) + ModelBlock->Block_List[Curr_Block].Temporary_InUse->insert(idx); + else + arg->collectTemporary_terms(temporary_terms, ModelBlock, Curr_Block); + } void UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const -{ - // If node is a temporary term - temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - if (output_type == oMatlabDynamicModelSparse) - output << "T" << idx << "(it_)"; - else - output << "T" << idx; - return; - } + { + //cout << "writeOutput unary\n"; + // If node is a temporary term + temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); + if (it != temporary_terms.end()) + { + if (output_type == oMatlabDynamicModelSparse) + output << "T" << idx << "(it_)"; + else + output << "T" << idx; + return; + } - // Always put parenthesis around uminus nodes - if (op_code == oUminus) - output << LEFT_PAR(output_type); - - switch(op_code) - { - case oUminus: - output << "-"; - break; - case oExp: - output << "exp"; - break; - case oLog: - output << "log"; - break; - case oLog10: - if (IS_LATEX(output_type)) - output << "log_{10}"; - else - output << "log10"; - break; - case oCos: - output << "cos"; - break; - case oSin: - output << "sin"; - break; - case oTan: - output << "tan"; - break; - case oAcos: - output << "acos"; - break; - case oAsin: - output << "asin"; - break; - case oAtan: - output << "atan"; - break; - case oCosh: - output << "cosh"; - break; - case oSinh: - output << "sinh"; - break; - case oTanh: - output << "tanh"; - break; - case oAcosh: - output << "acosh"; - break; - case oAsinh: - output << "asinh"; - break; - case oAtanh: - output << "atanh"; - break; - case oSqrt: - output << "sqrt"; - break; - } - - bool close_parenthesis = false; - - /* Enclose argument with parentheses if: - - current opcode is not uminus, or - - current opcode is uminus and argument has lowest precedence - */ - if (op_code != oUminus - || (op_code == oUminus - && arg->precedence(output_type, temporary_terms) < precedence(output_type, temporary_terms))) - { + // Always put parenthesis around uminus nodes + if (op_code == oUminus) output << LEFT_PAR(output_type); - close_parenthesis = true; - } - // Write argument - arg->writeOutput(output, output_type, temporary_terms); + switch (op_code) + { + case oUminus: + output << "-"; + break; + case oExp: + output << "exp"; + break; + case oLog: + output << "log"; + break; + case oLog10: + if (IS_LATEX(output_type)) + output << "log_{10}"; + else + output << "log10"; + break; + case oCos: + output << "cos"; + break; + case oSin: + output << "sin"; + break; + case oTan: + output << "tan"; + break; + case oAcos: + output << "acos"; + break; + case oAsin: + output << "asin"; + break; + case oAtan: + output << "atan"; + break; + case oCosh: + output << "cosh"; + break; + case oSinh: + output << "sinh"; + break; + case oTanh: + output << "tanh"; + break; + case oAcosh: + output << "acosh"; + break; + case oAsinh: + output << "asinh"; + break; + case oAtanh: + output << "atanh"; + break; + case oSqrt: + output << "sqrt"; + break; + } - if (close_parenthesis) - output << RIGHT_PAR(output_type); + bool close_parenthesis = false; - // Close parenthesis for uminus - if (op_code == oUminus) - output << RIGHT_PAR(output_type); -} + /* Enclose argument with parentheses if: + - current opcode is not uminus, or + - current opcode is uminus and argument has lowest precedence + */ + if (op_code != oUminus + || (op_code == oUminus + && arg->precedence(output_type, temporary_terms) < precedence(output_type, temporary_terms))) + { + output << LEFT_PAR(output_type); + close_parenthesis = true; + } + + // Write argument + arg->writeOutput(output, output_type, temporary_terms); + + if (close_parenthesis) + output << RIGHT_PAR(output_type); + + // Close parenthesis for uminus + if (op_code == oUminus) + output << RIGHT_PAR(output_type); + } double UnaryOpNode::eval_opcode(UnaryOpcode op_code, double v) throw (EvalException) { - switch(op_code) + switch (op_code) { case oUminus: return(-v); @@ -891,85 +1038,206 @@ UnaryOpNode::eval(const eval_context_type &eval_context) const throw (EvalExcept void UnaryOpNode::compile(ofstream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const -{ - temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - CompileCode.write(&FLDT, sizeof(FLDT)); - int var=map_idx[idx]; - CompileCode.write(reinterpret_cast(&var), sizeof(var)); - return; - } - arg->compile(CompileCode, lhs_rhs, temporary_terms, map_idx); - CompileCode.write(&FUNARY, sizeof(FUNARY)); - UnaryOpcode op_codel=op_code; - CompileCode.write(reinterpret_cast(&op_codel), sizeof(op_codel)); -} + { + temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); + if (it != temporary_terms.end()) + { + CompileCode.write(&FLDT, sizeof(FLDT)); + int var=map_idx[idx]; + CompileCode.write(reinterpret_cast(&var), sizeof(var)); + return; + } + arg->compile(CompileCode, lhs_rhs, temporary_terms, map_idx); + CompileCode.write(&FUNARY, sizeof(FUNARY)); + UnaryOpcode op_codel=op_code; + CompileCode.write(reinterpret_cast(&op_codel), sizeof(op_codel)); + } void UnaryOpNode::collectEndogenous(set > &result) const -{ - arg->collectEndogenous(result); -} + { + arg->collectEndogenous(result); + } void UnaryOpNode::collectExogenous(set > &result) const -{ - arg->collectExogenous(result); -} + { + arg->collectExogenous(result); + } + +pair +UnaryOpNode::normalizeLinearInEndoEquation(int var_endo, NodeID Derivative) const + { + pair res = arg->normalizeLinearInEndoEquation(var_endo, Derivative); + bool is_endogenous_present = res.first; + NodeID New_NodeID = res.second; + if (not is_endogenous_present) + { + switch (op_code) + { + case oUminus: + return(make_pair(false, /*tmp_*/datatree.AddUMinus(New_NodeID))); + case oExp: + return(make_pair(false, /*tmp_*/datatree.AddExp(New_NodeID))); + case oLog: + return(make_pair(false, /*tmp_*/datatree.AddLog(New_NodeID))); + case oLog10: + return(make_pair(false, /*tmp_*/datatree.AddLog10(New_NodeID))); + case oCos: + return(make_pair(false, /*tmp_*/datatree.AddCos(New_NodeID))); + case oSin: + return(make_pair(false, /*tmp_*/datatree.AddSin(New_NodeID))); + case oTan: + return(make_pair(false, /*tmp_*/datatree.AddTan(New_NodeID))); + case oAcos: + return(make_pair(false, /*tmp_*/datatree.AddAcos(New_NodeID))); + case oAsin: + return(make_pair(false, /*tmp_*/datatree.AddAsin(New_NodeID))); + case oAtan: + return(make_pair(false, /*tmp_*/datatree.AddAtan(New_NodeID))); + case oCosh: + return(make_pair(false, /*tmp_*/datatree.AddCosh(New_NodeID))); + case oSinh: + return(make_pair(false, /*tmp_*/datatree.AddSinh(New_NodeID))); + case oTanh: + return(make_pair(false, /*tmp_*/datatree.AddTanh(New_NodeID))); + case oAcosh: + return(make_pair(false, /*tmp_*/datatree.AddAcosh(New_NodeID))); + case oAsinh: + return(make_pair(false, /*tmp_*/datatree.AddAsinh(New_NodeID))); + case oAtanh: + return(make_pair(false, /*tmp_*/datatree.AddAtanh(New_NodeID))); + case oSqrt: + return(make_pair(false, /*tmp_*/datatree.AddSqrt(New_NodeID))); + } + } + return(make_pair(true, (NodeID)NULL)); + } + NodeID -UnaryOpNode::toStatic(DataTree &static_datatree) const +UnaryOpNode::computeChaineRuleDerivative(int deriv_id, map &recursive_variables, int var, int lag_) { - NodeID sarg = arg->toStatic(static_datatree); - switch(op_code) + NodeID darg = arg->getChaineRuleDerivative(deriv_id, recursive_variables, var, lag_); + + NodeID t11, t12, t13; + + switch (op_code) { case oUminus: - return static_datatree.AddUMinus(sarg); + return datatree.AddUMinus(darg); case oExp: - return static_datatree.AddExp(sarg); + return datatree.AddTimes(darg, this); case oLog: - return static_datatree.AddLog(sarg); + return datatree.AddDivide(darg, arg); case oLog10: - return static_datatree.AddLog10(sarg); + t11 = datatree.AddExp(datatree.One); + t12 = datatree.AddLog10(t11); + t13 = datatree.AddDivide(darg, arg); + return datatree.AddTimes(t12, t13); case oCos: - return static_datatree.AddCos(sarg); + t11 = datatree.AddSin(arg); + t12 = datatree.AddUMinus(t11); + return datatree.AddTimes(darg, t12); case oSin: - return static_datatree.AddSin(sarg); + t11 = datatree.AddCos(arg); + return datatree.AddTimes(darg, t11); case oTan: - return static_datatree.AddTan(sarg); + t11 = datatree.AddTimes(this, this); + t12 = datatree.AddPlus(t11, datatree.One); + return datatree.AddTimes(darg, t12); case oAcos: - return static_datatree.AddAcos(sarg); + t11 = datatree.AddSin(this); + t12 = datatree.AddDivide(darg, t11); + return datatree.AddUMinus(t12); case oAsin: - return static_datatree.AddAsin(sarg); + t11 = datatree.AddCos(this); + return datatree.AddDivide(darg, t11); case oAtan: - return static_datatree.AddAtan(sarg); + t11 = datatree.AddTimes(arg, arg); + t12 = datatree.AddPlus(datatree.One, t11); + return datatree.AddDivide(darg, t12); case oCosh: - return static_datatree.AddCosh(sarg); + t11 = datatree.AddSinh(arg); + return datatree.AddTimes(darg, t11); case oSinh: - return static_datatree.AddSinh(sarg); + t11 = datatree.AddCosh(arg); + return datatree.AddTimes(darg, t11); case oTanh: - return static_datatree.AddTanh(sarg); + t11 = datatree.AddTimes(this, this); + t12 = datatree.AddMinus(datatree.One, t11); + return datatree.AddTimes(darg, t12); case oAcosh: - return static_datatree.AddAcosh(sarg); + t11 = datatree.AddSinh(this); + return datatree.AddDivide(darg, t11); case oAsinh: - return static_datatree.AddAsinh(sarg); + t11 = datatree.AddCosh(this); + return datatree.AddDivide(darg, t11); case oAtanh: - return static_datatree.AddAtanh(sarg); + t11 = datatree.AddTimes(arg, arg); + t12 = datatree.AddMinus(datatree.One, t11); + return datatree.AddTimes(darg, t12); case oSqrt: - return static_datatree.AddSqrt(sarg); + t11 = datatree.AddPlus(this, this); + return datatree.AddDivide(darg, t11); } // Suppress GCC warning exit(EXIT_FAILURE); } +NodeID +UnaryOpNode::toStatic(DataTree &static_datatree) const + { + NodeID sarg = arg->toStatic(static_datatree); + switch (op_code) + { + case oUminus: + return static_datatree.AddUMinus(sarg); + case oExp: + return static_datatree.AddExp(sarg); + case oLog: + return static_datatree.AddLog(sarg); + case oLog10: + return static_datatree.AddLog10(sarg); + case oCos: + return static_datatree.AddCos(sarg); + case oSin: + return static_datatree.AddSin(sarg); + case oTan: + return static_datatree.AddTan(sarg); + case oAcos: + return static_datatree.AddAcos(sarg); + case oAsin: + return static_datatree.AddAsin(sarg); + case oAtan: + return static_datatree.AddAtan(sarg); + case oCosh: + return static_datatree.AddCosh(sarg); + case oSinh: + return static_datatree.AddSinh(sarg); + case oTanh: + return static_datatree.AddTanh(sarg); + case oAcosh: + return static_datatree.AddAcosh(sarg); + case oAsinh: + return static_datatree.AddAsinh(sarg); + case oAtanh: + return static_datatree.AddAtanh(sarg); + case oSqrt: + return static_datatree.AddSqrt(sarg); + } + // Suppress GCC warning + exit(EXIT_FAILURE); + } + + BinaryOpNode::BinaryOpNode(DataTree &datatree_arg, const NodeID arg1_arg, BinaryOpcode op_code_arg, const NodeID arg2_arg) : - ExprNode(datatree_arg), - arg1(arg1_arg), - arg2(arg2_arg), - op_code(op_code_arg) + ExprNode(datatree_arg), + arg1(arg1_arg), + arg2(arg2_arg), + op_code(op_code_arg) { datatree.binary_op_node_map[make_pair(make_pair(arg1, arg2), op_code)] = this; @@ -990,7 +1258,7 @@ BinaryOpNode::computeDerivative(int deriv_id) NodeID t11, t12, t13, t14, t15; - switch(op_code) + switch (op_code) { case oPlus: return datatree.AddPlus(darg1, darg2); @@ -1001,11 +1269,16 @@ BinaryOpNode::computeDerivative(int deriv_id) t12 = datatree.AddTimes(darg2, arg1); return datatree.AddPlus(t11, t12); case oDivide: - t11 = datatree.AddTimes(darg1, arg2); - t12 = datatree.AddTimes(darg2, arg1); - t13 = datatree.AddMinus(t11, t12); - t14 = datatree.AddTimes(arg2, arg2); - return datatree.AddDivide(t13, t14); + if (darg2!=datatree.Zero) + { + t11 = datatree.AddTimes(darg1, arg2); + t12 = datatree.AddTimes(darg2, arg1); + t13 = datatree.AddMinus(t11, t12); + t14 = datatree.AddTimes(arg2, arg2); + return datatree.AddDivide(t13, t14); + } + else + return datatree.AddDivide(darg1, arg2); case oLess: case oGreater: case oLessEqual: @@ -1056,133 +1329,133 @@ BinaryOpNode::computeDerivative(int deriv_id) int BinaryOpNode::precedence(ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const -{ - temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); - // A temporary term behaves as a variable - if (it != temporary_terms.end()) - return 100; - - switch(op_code) - { - case oEqual: - return 0; - case oEqualEqual: - case oDifferent: - return 1; - case oLessEqual: - case oGreaterEqual: - case oLess: - case oGreater: - return 2; - case oPlus: - case oMinus: - return 3; - case oTimes: - case oDivide: - return 4; - case oPower: - if (IS_C(output_type)) - // In C, power operator is of the form pow(a, b) - return 100; - else - return 5; - case oMin: - case oMax: + { + temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); + // A temporary term behaves as a variable + if (it != temporary_terms.end()) return 100; - } - // Suppress GCC warning - exit(EXIT_FAILURE); -} + + switch (op_code) + { + case oEqual: + return 0; + case oEqualEqual: + case oDifferent: + return 1; + case oLessEqual: + case oGreaterEqual: + case oLess: + case oGreater: + return 2; + case oPlus: + case oMinus: + return 3; + case oTimes: + case oDivide: + return 4; + case oPower: + if (IS_C(output_type)) + // In C, power operator is of the form pow(a, b) + return 100; + else + return 5; + case oMin: + case oMax: + return 100; + } + // Suppress GCC warning + exit(EXIT_FAILURE); + } int BinaryOpNode::cost(const temporary_terms_type &temporary_terms, bool is_matlab) const -{ - temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); - // For a temporary term, the cost is null - if (it != temporary_terms.end()) - return 0; + { + temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); + // For a temporary term, the cost is null + if (it != temporary_terms.end()) + return 0; - int cost = arg1->cost(temporary_terms, is_matlab); - cost += arg2->cost(temporary_terms, is_matlab); + int cost = arg1->cost(temporary_terms, is_matlab); + cost += arg2->cost(temporary_terms, is_matlab); - if (is_matlab) - // Cost for Matlab files - switch(op_code) - { - case oLess: - case oGreater: - case oLessEqual: - case oGreaterEqual: - case oEqualEqual: - case oDifferent: - return cost + 60; - case oPlus: - case oMinus: - case oTimes: - return cost + 90; - case oMax: - case oMin: - return cost + 110; - case oDivide: - return cost + 990; - case oPower: - return cost + 1160; - case oEqual: - return cost; - } - else - // Cost for C files - switch(op_code) - { - case oLess: - case oGreater: - case oLessEqual: - case oGreaterEqual: - case oEqualEqual: - case oDifferent: - return cost + 2; - case oPlus: - case oMinus: - case oTimes: - return cost + 4; - case oMax: - case oMin: - return cost + 5; - case oDivide: - return cost + 15; - case oPower: - return cost + 520; - case oEqual: - return cost; - } - // Suppress GCC warning - exit(EXIT_FAILURE); -} + if (is_matlab) + // Cost for Matlab files + switch (op_code) + { + case oLess: + case oGreater: + case oLessEqual: + case oGreaterEqual: + case oEqualEqual: + case oDifferent: + return cost + 60; + case oPlus: + case oMinus: + case oTimes: + return cost + 90; + case oMax: + case oMin: + return cost + 110; + case oDivide: + return cost + 990; + case oPower: + return cost + 1160; + case oEqual: + return cost; + } + else + // Cost for C files + switch (op_code) + { + case oLess: + case oGreater: + case oLessEqual: + case oGreaterEqual: + case oEqualEqual: + case oDifferent: + return cost + 2; + case oPlus: + case oMinus: + case oTimes: + return cost + 4; + case oMax: + case oMin: + return cost + 5; + case oDivide: + return cost + 15; + case oPower: + return cost + 520; + case oEqual: + return cost; + } + // Suppress GCC warning + exit(EXIT_FAILURE); + } void BinaryOpNode::computeTemporaryTerms(map &reference_count, temporary_terms_type &temporary_terms, bool is_matlab) const -{ - NodeID this2 = const_cast(this); - map::iterator it = reference_count.find(this2); - if (it == reference_count.end()) - { - // If this node has never been encountered, set its ref count to one, - // and travel through its children - reference_count[this2] = 1; - arg1->computeTemporaryTerms(reference_count, temporary_terms, is_matlab); - arg2->computeTemporaryTerms(reference_count, temporary_terms, is_matlab); - } - else - { - // If the node has already been encountered, increment its ref count - // and declare it as a temporary term if it is too costly - reference_count[this2]++; - if (reference_count[this2] * cost(temporary_terms, is_matlab) > MIN_COST(is_matlab)) - temporary_terms.insert(this2); - } -} + { + NodeID this2 = const_cast(this); + map::iterator it = reference_count.find(this2); + if (it == reference_count.end()) + { + // If this node has never been encountered, set its ref count to one, + // and travel through its children + reference_count[this2] = 1; + arg1->computeTemporaryTerms(reference_count, temporary_terms, is_matlab); + arg2->computeTemporaryTerms(reference_count, temporary_terms, is_matlab); + } + else + { + // If the node has already been encountered, increment its ref count + // and declare it as a temporary term if it is too costly + reference_count[this2]++; + if (reference_count[this2] * cost(temporary_terms, is_matlab) > MIN_COST(is_matlab)) + temporary_terms.insert(this2); + } + } void BinaryOpNode::computeTemporaryTerms(map &reference_count, @@ -1192,31 +1465,31 @@ BinaryOpNode::computeTemporaryTerms(map &reference_count, Model_Block *ModelBlock, int equation, map_idx_type &map_idx) const -{ - NodeID this2 = const_cast(this); - map::iterator it = reference_count.find(this2); - if (it == reference_count.end()) - { - reference_count[this2] = 1; - first_occurence[this2] = make_pair(Curr_block, equation); - arg1->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, ModelBlock, equation, map_idx); - arg2->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, ModelBlock, equation, map_idx); - } - else - { - reference_count[this2]++; - if (reference_count[this2] * cost(temporary_terms, false) > MIN_COST_C) - { - temporary_terms.insert(this2); - ModelBlock->Block_List[first_occurence[this2].first].Temporary_Terms_in_Equation[first_occurence[this2].second]->insert(this2); - } - } -} + { + NodeID this2 = const_cast(this); + map::iterator it = reference_count.find(this2); + if (it == reference_count.end()) + { + reference_count[this2] = 1; + first_occurence[this2] = make_pair(Curr_block, equation); + arg1->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, ModelBlock, equation, map_idx); + arg2->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, ModelBlock, equation, map_idx); + } + else + { + reference_count[this2]++; + if (reference_count[this2] * cost(temporary_terms, false) > MIN_COST_C) + { + temporary_terms.insert(this2); + ModelBlock->Block_List[first_occurence[this2].first].Temporary_Terms_in_Equation[first_occurence[this2].second]->insert(this2); + } + } + } double BinaryOpNode::eval_opcode(double v1, BinaryOpcode op_code, double v2) throw (EvalException) { - switch(op_code) + switch (op_code) { case oPlus: return(v1 + v2); @@ -1268,260 +1541,468 @@ BinaryOpNode::eval(const eval_context_type &eval_context) const throw (EvalExcep void BinaryOpNode::compile(ofstream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const -{ - // If current node is a temporary term - temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - CompileCode.write(&FLDT, sizeof(FLDT)); - int var=map_idx[idx]; - CompileCode.write(reinterpret_cast(&var), sizeof(var)); - return; - } - arg1->compile(CompileCode, lhs_rhs, temporary_terms, map_idx); - arg2->compile(CompileCode, lhs_rhs, temporary_terms, map_idx); - CompileCode.write(&FBINARY, sizeof(FBINARY)); - BinaryOpcode op_codel=op_code; - CompileCode.write(reinterpret_cast(&op_codel),sizeof(op_codel)); -} + { + // If current node is a temporary term + temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); + if (it != temporary_terms.end()) + { + CompileCode.write(&FLDT, sizeof(FLDT)); + int var=map_idx[idx]; + CompileCode.write(reinterpret_cast(&var), sizeof(var)); + return; + } + arg1->compile(CompileCode, lhs_rhs, temporary_terms, map_idx); + arg2->compile(CompileCode, lhs_rhs, temporary_terms, map_idx); + CompileCode.write(&FBINARY, sizeof(FBINARY)); + BinaryOpcode op_codel=op_code; + CompileCode.write(reinterpret_cast(&op_codel),sizeof(op_codel)); + } void BinaryOpNode::collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const -{ - temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - ModelBlock->Block_List[Curr_Block].Temporary_InUse->insert(idx); - else - { - arg1->collectTemporary_terms(temporary_terms, ModelBlock, Curr_Block); - arg2->collectTemporary_terms(temporary_terms, ModelBlock, Curr_Block); - } -} + { + temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); + if (it != temporary_terms.end()) + ModelBlock->Block_List[Curr_Block].Temporary_InUse->insert(idx); + else + { + arg1->collectTemporary_terms(temporary_terms, ModelBlock, Curr_Block); + arg2->collectTemporary_terms(temporary_terms, ModelBlock, Curr_Block); + } + } void BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const -{ - // If current node is a temporary term - temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - if (output_type == oMatlabDynamicModelSparse) - output << "T" << idx << "(it_)"; - else - output << "T" << idx; - return; - } + { + //cout << "writeOutput binary\n"; + // If current node is a temporary term + temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); + if (it != temporary_terms.end()) + { + if (output_type == oMatlabDynamicModelSparse) + output << "T" << idx << "(it_)"; + else + output << "T" << idx; + return; + } - // Treat special case of power operator in C, and case of max and min operators - if ((op_code == oPower && IS_C(output_type)) || op_code == oMax || op_code == oMin ) - { - switch (op_code) - { - case oPower: - output << "pow("; - break; - case oMax: - output << "max("; - break; - case oMin: - output << "min("; - break; - default: - ; - } - arg1->writeOutput(output, output_type, temporary_terms); - output << ","; - arg2->writeOutput(output, output_type, temporary_terms); - output << ")"; - return; - } + // Treat special case of power operator in C, and case of max and min operators + if ((op_code == oPower && IS_C(output_type)) || op_code == oMax || op_code == oMin ) + { + switch (op_code) + { + case oPower: + output << "pow("; + break; + case oMax: + output << "max("; + break; + case oMin: + output << "min("; + break; + default: + ; + } + arg1->writeOutput(output, output_type, temporary_terms); + output << ","; + arg2->writeOutput(output, output_type, temporary_terms); + output << ")"; + return; + } - int prec = precedence(output_type, temporary_terms); + int prec = precedence(output_type, temporary_terms); - bool close_parenthesis = false; + bool close_parenthesis = false; - if (IS_LATEX(output_type) && op_code == oDivide) - output << "\\frac{"; - else - { - // If left argument has a lower precedence, or if current and left argument are both power operators, add parenthesis around left argument - BinaryOpNode *barg1 = dynamic_cast(arg1); - if (arg1->precedence(output_type, temporary_terms) < prec - || (op_code == oPower && barg1 != NULL && barg1->op_code == oPower)) - { - output << LEFT_PAR(output_type); - close_parenthesis = true; - } - } + if (IS_LATEX(output_type) && op_code == oDivide) + output << "\\frac{"; + else + { + // If left argument has a lower precedence, or if current and left argument are both power operators, add parenthesis around left argument + BinaryOpNode *barg1 = dynamic_cast(arg1); + if (arg1->precedence(output_type, temporary_terms) < prec + || (op_code == oPower && barg1 != NULL && barg1->op_code == oPower)) + { + output << LEFT_PAR(output_type); + close_parenthesis = true; + } + } - // Write left argument - arg1->writeOutput(output, output_type, temporary_terms); + // Write left argument + arg1->writeOutput(output, output_type, temporary_terms); - if (close_parenthesis) - output << RIGHT_PAR(output_type); + if (close_parenthesis) + output << RIGHT_PAR(output_type); - if (IS_LATEX(output_type) && op_code == oDivide) - output << "}"; + if (IS_LATEX(output_type) && op_code == oDivide) + output << "}"; - // Write current operator symbol - switch(op_code) - { - case oPlus: - output << "+"; - break; - case oMinus: - output << "-"; - break; - case oTimes: - if (IS_LATEX(output_type)) - output << "\\cdot "; - else - output << "*"; - break; - case oDivide: - if (!IS_LATEX(output_type)) - output << "/"; - break; - case oPower: - output << "^"; - break; - case oLess: - output << "<"; - break; - case oGreater: - output << ">"; - break; - case oLessEqual: - if (IS_LATEX(output_type)) - output << "\\leq "; - else - output << "<="; - break; - case oGreaterEqual: - if (IS_LATEX(output_type)) - output << "\\geq "; - else - output << ">="; - break; - case oEqualEqual: - output << "=="; - break; - case oDifferent: - if (IS_MATLAB(output_type)) - output << "~="; - else - { - if (IS_C(output_type)) - output << "!="; - else - output << "\\neq "; - } - break; - case oEqual: - output << "="; - break; - default: - ; - } + // Write current operator symbol + switch (op_code) + { + case oPlus: + output << "+"; + break; + case oMinus: + output << "-"; + break; + case oTimes: + if (IS_LATEX(output_type)) + output << "\\cdot "; + else + output << "*"; + break; + case oDivide: + if (!IS_LATEX(output_type)) + output << "/"; + break; + case oPower: + output << "^"; + break; + case oLess: + output << "<"; + break; + case oGreater: + output << ">"; + break; + case oLessEqual: + if (IS_LATEX(output_type)) + output << "\\leq "; + else + output << "<="; + break; + case oGreaterEqual: + if (IS_LATEX(output_type)) + output << "\\geq "; + else + output << ">="; + break; + case oEqualEqual: + output << "=="; + break; + case oDifferent: + if (IS_MATLAB(output_type)) + output << "~="; + else + { + if (IS_C(output_type)) + output << "!="; + else + output << "\\neq "; + } + break; + case oEqual: + output << "="; + break; + default: + ; + } - close_parenthesis = false; + close_parenthesis = false; - if (IS_LATEX(output_type) && (op_code == oPower || op_code == oDivide)) - output << "{"; - else - { - /* Add parenthesis around right argument if: - - its precedence is lower than those of the current node - - it is a power operator and current operator is also a power operator - - it is a minus operator with same precedence than current operator - - it is a divide operator with same precedence than current operator */ - BinaryOpNode *barg2 = dynamic_cast(arg2); - int arg2_prec = arg2->precedence(output_type, temporary_terms); - if (arg2_prec < prec - || (op_code == oPower && barg2 != NULL && barg2->op_code == oPower && !IS_LATEX(output_type)) - || (op_code == oMinus && arg2_prec == prec) - || (op_code == oDivide && arg2_prec == prec && !IS_LATEX(output_type))) - { - output << LEFT_PAR(output_type); - close_parenthesis = true; - } - } + if (IS_LATEX(output_type) && (op_code == oPower || op_code == oDivide)) + output << "{"; + else + { + /* Add parenthesis around right argument if: + - its precedence is lower than those of the current node + - it is a power operator and current operator is also a power operator + - it is a minus operator with same precedence than current operator + - it is a divide operator with same precedence than current operator */ + BinaryOpNode *barg2 = dynamic_cast(arg2); + int arg2_prec = arg2->precedence(output_type, temporary_terms); + if (arg2_prec < prec + || (op_code == oPower && barg2 != NULL && barg2->op_code == oPower && !IS_LATEX(output_type)) + || (op_code == oMinus && arg2_prec == prec) + || (op_code == oDivide && arg2_prec == prec && !IS_LATEX(output_type))) + { + output << LEFT_PAR(output_type); + close_parenthesis = true; + } + } - // Write right argument - arg2->writeOutput(output, output_type, temporary_terms); + // Write right argument + arg2->writeOutput(output, output_type, temporary_terms); - if (IS_LATEX(output_type) && (op_code == oPower || op_code == oDivide)) - output << "}"; + if (IS_LATEX(output_type) && (op_code == oPower || op_code == oDivide)) + output << "}"; - if (close_parenthesis) - output << RIGHT_PAR(output_type); -} + if (close_parenthesis) + output << RIGHT_PAR(output_type); + } void BinaryOpNode::collectEndogenous(set > &result) const -{ - arg1->collectEndogenous(result); - arg2->collectEndogenous(result); -} + { + arg1->collectEndogenous(result); + arg2->collectEndogenous(result); + } void BinaryOpNode::collectExogenous(set > &result) const -{ - arg1->collectExogenous(result); - arg2->collectExogenous(result); -} + { + arg1->collectExogenous(result); + arg2->collectExogenous(result); + } + +pair +BinaryOpNode::normalizeLinearInEndoEquation(int var_endo, NodeID Derivative) const + { + pair 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; + switch (op_code) + { + case oPlus: + if (not is_endogenous_present_1 and not is_endogenous_present_2) + return(make_pair(false, /*tmp_*/datatree.AddPlus(NodeID_1, NodeID_2))); + else if (is_endogenous_present_1 and is_endogenous_present_2) + return(make_pair(true, (NodeID)NULL)); + else if (not is_endogenous_present_1 and is_endogenous_present_2) + return(make_pair(false, NodeID_1)); + else if (is_endogenous_present_1 and not is_endogenous_present_2) + return(make_pair(false, NodeID_2)); + break; + case oMinus: + if (not is_endogenous_present_1 and not is_endogenous_present_2) + return(make_pair(false, /*tmp_*/datatree.AddMinus(NodeID_1, NodeID_2))); + else if (is_endogenous_present_1 and is_endogenous_present_2) + return(make_pair(true, (NodeID)NULL)); + else if (not is_endogenous_present_1 and is_endogenous_present_2) + return(make_pair(false, NodeID_1)); + else if (is_endogenous_present_1 and not is_endogenous_present_2) + return(make_pair(false, /*tmp_*/datatree.AddUMinus(NodeID_2))); + break; + case oTimes: + if (not is_endogenous_present_1 and not is_endogenous_present_2) + return(make_pair(false, /*tmp_*/datatree.AddTimes(NodeID_1, NodeID_2))); + else + return(make_pair(true, (NodeID)NULL)); + break; + case oDivide: + if (not is_endogenous_present_1 and not is_endogenous_present_2) + return(make_pair(false, datatree.AddDivide(NodeID_1, NodeID_2))); + else + return(make_pair(true, (NodeID)NULL)); + break; + case oPower: + if (not is_endogenous_present_1 and not is_endogenous_present_2) + return(make_pair(false, datatree.AddPower(NodeID_1, NodeID_2))); + else + return(make_pair(true, (NodeID)NULL)); + break; + case oEqual: + if (not is_endogenous_present_1 and not 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))) ); + } + else if (is_endogenous_present_1 and 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))); + } + else if (not is_endogenous_present_1 and 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)))); + } + else if (is_endogenous_present_1 and not 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))); + } + break; + case oMax: + if (not is_endogenous_present_1 and not is_endogenous_present_2) + return(make_pair(false, datatree.AddMax(NodeID_1, NodeID_2))); + else + return(make_pair(true, (NodeID)NULL)); + break; + case oMin: + if (not is_endogenous_present_1 and not is_endogenous_present_2) + return(make_pair(false, datatree.AddMin(NodeID_1, NodeID_2))); + else + return(make_pair(true, (NodeID)NULL)); + break; + case oLess: + if (not is_endogenous_present_1 and not is_endogenous_present_2) + return(make_pair(false, /*tmp_*/datatree.AddLess(NodeID_1, NodeID_2))); + else + return(make_pair(true, (NodeID)NULL)); + break; + case oGreater: + if (not is_endogenous_present_1 and not is_endogenous_present_2) + return(make_pair(false, /*tmp_*/datatree.AddGreater(NodeID_1, NodeID_2))); + else + return(make_pair(true, (NodeID)NULL)); + break; + case oLessEqual: + if (not is_endogenous_present_1 and not is_endogenous_present_2) + return(make_pair(false, /*tmp_*/datatree.AddLessEqual(NodeID_1, NodeID_2))); + else + return(make_pair(true, (NodeID)NULL)); + break; + case oGreaterEqual: + if (not is_endogenous_present_1 and not is_endogenous_present_2) + return(make_pair(false, /*tmp_*/datatree.AddGreaterEqual(NodeID_1, NodeID_2))); + else + return(make_pair(true, (NodeID)NULL)); + break; + case oEqualEqual: + if (not is_endogenous_present_1 and not is_endogenous_present_2) + return(make_pair(false, /*tmp_*/datatree.AddEqualEqual(NodeID_1, NodeID_2))); + else + return(make_pair(true, (NodeID)NULL)); + break; + case oDifferent: + if (not is_endogenous_present_1 and not is_endogenous_present_2) + return(make_pair(false, /*tmp_*/datatree.AddDifferent(NodeID_1, NodeID_2))); + else + return(make_pair(true, (NodeID)NULL)); + break; + } + // Suppress GCC warning + exit(EXIT_FAILURE); + } + NodeID -BinaryOpNode::toStatic(DataTree &static_datatree) const +BinaryOpNode::computeChaineRuleDerivative(int deriv_id, map &recursive_variables, int var, int lag_) { - NodeID sarg1 = arg1->toStatic(static_datatree); - NodeID sarg2 = arg2->toStatic(static_datatree); - switch(op_code) + NodeID darg1 = arg1->getChaineRuleDerivative(deriv_id, recursive_variables, var, lag_); + NodeID darg2 = arg2->getChaineRuleDerivative(deriv_id, recursive_variables, var, lag_); + + NodeID t11, t12, t13, t14, t15; + + switch (op_code) { case oPlus: - return static_datatree.AddPlus(sarg1, sarg2); + return datatree.AddPlus(darg1, darg2); case oMinus: - return static_datatree.AddMinus(sarg1, sarg2); + return datatree.AddMinus(darg1, darg2); case oTimes: - return static_datatree.AddTimes(sarg1, sarg2); + t11 = datatree.AddTimes(darg1, arg2); + t12 = datatree.AddTimes(darg2, arg1); + return datatree.AddPlus(t11, t12); case oDivide: - return static_datatree.AddDivide(sarg1, sarg2); - case oPower: - return static_datatree.AddPower(sarg1, sarg2); - case oEqual: - return static_datatree.AddEqual(sarg1, sarg2); - case oMax: - return static_datatree.AddMax(sarg1, sarg2); - case oMin: - return static_datatree.AddMin(sarg1, sarg2); + if (darg2!=datatree.Zero) + { + t11 = datatree.AddTimes(darg1, arg2); + t12 = datatree.AddTimes(darg2, arg1); + t13 = datatree.AddMinus(t11, t12); + t14 = datatree.AddTimes(arg2, arg2); + return datatree.AddDivide(t13, t14); + } + else + return datatree.AddDivide(darg1, arg2); case oLess: - return static_datatree.AddLess(sarg1, sarg2); case oGreater: - return static_datatree.AddGreater(sarg1, sarg2); case oLessEqual: - return static_datatree.AddLessEqual(sarg1, sarg2); case oGreaterEqual: - return static_datatree.AddGreaterEqual(sarg1, sarg2); case oEqualEqual: - return static_datatree.AddEqualEqual(sarg1, sarg2); case oDifferent: - return static_datatree.AddDifferent(sarg1, sarg2); + return datatree.Zero; + case oPower: + if (darg2 == datatree.Zero) + { + if (darg1 == datatree.Zero) + return datatree.Zero; + else + { + t11 = datatree.AddMinus(arg2, datatree.One); + t12 = datatree.AddPower(arg1, t11); + t13 = datatree.AddTimes(arg2, t12); + return datatree.AddTimes(darg1, t13); + } + } + else + { + t11 = datatree.AddLog(arg1); + t12 = datatree.AddTimes(darg2, t11); + t13 = datatree.AddTimes(darg1, arg2); + t14 = datatree.AddDivide(t13, arg1); + t15 = datatree.AddPlus(t12, t14); + return datatree.AddTimes(t15, this); + } + case oMax: + t11 = datatree.AddGreater(arg1,arg2); + t12 = datatree.AddTimes(t11,darg1); + t13 = datatree.AddMinus(datatree.One,t11); + t14 = datatree.AddTimes(t13,darg2); + return datatree.AddPlus(t14,t12); + case oMin: + t11 = datatree.AddGreater(arg2,arg1); + t12 = datatree.AddTimes(t11,darg1); + t13 = datatree.AddMinus(datatree.One,t11); + t14 = datatree.AddTimes(t13,darg2); + return datatree.AddPlus(t14,t12); + case oEqual: + return datatree.AddMinus(darg1, darg2); } // Suppress GCC warning exit(EXIT_FAILURE); } +NodeID +BinaryOpNode::toStatic(DataTree &static_datatree) const + { + NodeID sarg1 = arg1->toStatic(static_datatree); + NodeID sarg2 = arg2->toStatic(static_datatree); + switch (op_code) + { + case oPlus: + return static_datatree.AddPlus(sarg1, sarg2); + case oMinus: + return static_datatree.AddMinus(sarg1, sarg2); + case oTimes: + return static_datatree.AddTimes(sarg1, sarg2); + case oDivide: + return static_datatree.AddDivide(sarg1, sarg2); + case oPower: + return static_datatree.AddPower(sarg1, sarg2); + case oEqual: + return static_datatree.AddEqual(sarg1, sarg2); + case oMax: + return static_datatree.AddMax(sarg1, sarg2); + case oMin: + return static_datatree.AddMin(sarg1, sarg2); + case oLess: + return static_datatree.AddLess(sarg1, sarg2); + case oGreater: + return static_datatree.AddGreater(sarg1, sarg2); + case oLessEqual: + return static_datatree.AddLessEqual(sarg1, sarg2); + case oGreaterEqual: + return static_datatree.AddGreaterEqual(sarg1, sarg2); + case oEqualEqual: + return static_datatree.AddEqualEqual(sarg1, sarg2); + case oDifferent: + return static_datatree.AddDifferent(sarg1, sarg2); + } + // Suppress GCC warning + exit(EXIT_FAILURE); + } + TrinaryOpNode::TrinaryOpNode(DataTree &datatree_arg, const NodeID arg1_arg, TrinaryOpcode op_code_arg, const NodeID arg2_arg, const NodeID arg3_arg) : - ExprNode(datatree_arg), - arg1(arg1_arg), - arg2(arg2_arg), - arg3(arg3_arg), - op_code(op_code_arg) + ExprNode(datatree_arg), + arg1(arg1_arg), + arg2(arg2_arg), + arg3(arg3_arg), + op_code(op_code_arg) { datatree.trinary_op_node_map[make_pair(make_pair(make_pair(arg1, arg2), arg3), op_code)] = this; @@ -1549,7 +2030,7 @@ TrinaryOpNode::computeDerivative(int deriv_id) NodeID t11, t12, t13, t14, t15; - switch(op_code) + switch (op_code) { case oNormcdf: // normal pdf is inlined in the tree @@ -1593,75 +2074,75 @@ TrinaryOpNode::computeDerivative(int deriv_id) int TrinaryOpNode::precedence(ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const -{ - temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); - // A temporary term behaves as a variable - if (it != temporary_terms.end()) - return 100; - - switch(op_code) - { - case oNormcdf: + { + temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); + // A temporary term behaves as a variable + if (it != temporary_terms.end()) return 100; - } - // Suppress GCC warning - exit(EXIT_FAILURE); -} + + switch (op_code) + { + case oNormcdf: + return 100; + } + // Suppress GCC warning + exit(EXIT_FAILURE); + } int TrinaryOpNode::cost(const temporary_terms_type &temporary_terms, bool is_matlab) const -{ - temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); - // For a temporary term, the cost is null - if (it != temporary_terms.end()) - return 0; + { + temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); + // For a temporary term, the cost is null + if (it != temporary_terms.end()) + return 0; - int cost = arg1->cost(temporary_terms, is_matlab); - cost += arg2->cost(temporary_terms, is_matlab); + int cost = arg1->cost(temporary_terms, is_matlab); + cost += arg2->cost(temporary_terms, is_matlab); - if (is_matlab) - // Cost for Matlab files - switch(op_code) - { - case oNormcdf: - return cost+1000; - } - else - // Cost for C files - switch(op_code) - { - case oNormcdf: - return cost+1000; - } - // Suppress GCC warning - exit(EXIT_FAILURE); -} + if (is_matlab) + // Cost for Matlab files + switch (op_code) + { + case oNormcdf: + return cost+1000; + } + else + // Cost for C files + switch (op_code) + { + case oNormcdf: + return cost+1000; + } + // Suppress GCC warning + exit(EXIT_FAILURE); + } void TrinaryOpNode::computeTemporaryTerms(map &reference_count, temporary_terms_type &temporary_terms, bool is_matlab) const -{ - NodeID this2 = const_cast(this); - map::iterator it = reference_count.find(this2); - if (it == reference_count.end()) - { - // If this node has never been encountered, set its ref count to one, - // and travel through its children - reference_count[this2] = 1; - arg1->computeTemporaryTerms(reference_count, temporary_terms, is_matlab); - arg2->computeTemporaryTerms(reference_count, temporary_terms, is_matlab); - arg3->computeTemporaryTerms(reference_count, temporary_terms, is_matlab); - } - else - { - // If the node has already been encountered, increment its ref count - // and declare it as a temporary term if it is too costly - reference_count[this2]++; - if (reference_count[this2] * cost(temporary_terms, is_matlab) > MIN_COST(is_matlab)) - temporary_terms.insert(this2); - } -} + { + NodeID this2 = const_cast(this); + map::iterator it = reference_count.find(this2); + if (it == reference_count.end()) + { + // If this node has never been encountered, set its ref count to one, + // and travel through its children + reference_count[this2] = 1; + arg1->computeTemporaryTerms(reference_count, temporary_terms, is_matlab); + arg2->computeTemporaryTerms(reference_count, temporary_terms, is_matlab); + arg3->computeTemporaryTerms(reference_count, temporary_terms, is_matlab); + } + else + { + // If the node has already been encountered, increment its ref count + // and declare it as a temporary term if it is too costly + reference_count[this2]++; + if (reference_count[this2] * cost(temporary_terms, is_matlab) > MIN_COST(is_matlab)) + temporary_terms.insert(this2); + } + } void TrinaryOpNode::computeTemporaryTerms(map &reference_count, @@ -1671,32 +2152,32 @@ TrinaryOpNode::computeTemporaryTerms(map &reference_count, Model_Block *ModelBlock, int equation, map_idx_type &map_idx) const -{ - NodeID this2 = const_cast(this); - map::iterator it = reference_count.find(this2); - if (it == reference_count.end()) - { - reference_count[this2] = 1; - first_occurence[this2] = make_pair(Curr_block,equation); - arg1->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, ModelBlock, equation, map_idx); - arg2->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, ModelBlock, equation, map_idx); - arg3->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, ModelBlock, equation, map_idx); - } - else - { - reference_count[this2]++; - if (reference_count[this2] * cost(temporary_terms, false) > MIN_COST_C) - { - temporary_terms.insert(this2); - ModelBlock->Block_List[first_occurence[this2].first].Temporary_Terms_in_Equation[first_occurence[this2].second]->insert(this2); - } - } -} + { + NodeID this2 = const_cast(this); + map::iterator it = reference_count.find(this2); + if (it == reference_count.end()) + { + reference_count[this2] = 1; + first_occurence[this2] = make_pair(Curr_block,equation); + arg1->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, ModelBlock, equation, map_idx); + arg2->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, ModelBlock, equation, map_idx); + arg3->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, ModelBlock, equation, map_idx); + } + else + { + reference_count[this2]++; + if (reference_count[this2] * cost(temporary_terms, false) > MIN_COST_C) + { + temporary_terms.insert(this2); + ModelBlock->Block_List[first_occurence[this2].first].Temporary_Terms_in_Equation[first_occurence[this2].second]->insert(this2); + } + } + } double TrinaryOpNode::eval_opcode(double v1, TrinaryOpcode op_code, double v2, double v3) throw (EvalException) { - switch(op_code) + switch (op_code) { case oNormcdf: cerr << "NORMCDF: eval not implemented" << endl; @@ -1718,106 +2199,175 @@ TrinaryOpNode::eval(const eval_context_type &eval_context) const throw (EvalExce void TrinaryOpNode::compile(ofstream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const -{ - // If current node is a temporary term - temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - CompileCode.write(&FLDT, sizeof(FLDT)); - int var=map_idx[idx]; - CompileCode.write(reinterpret_cast(&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); - CompileCode.write(&FBINARY, sizeof(FBINARY)); - TrinaryOpcode op_codel=op_code; - CompileCode.write(reinterpret_cast(&op_codel),sizeof(op_codel)); -} + { + // If current node is a temporary term + temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); + if (it != temporary_terms.end()) + { + CompileCode.write(&FLDT, sizeof(FLDT)); + int var=map_idx[idx]; + CompileCode.write(reinterpret_cast(&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); + CompileCode.write(&FBINARY, sizeof(FBINARY)); + TrinaryOpcode op_codel=op_code; + CompileCode.write(reinterpret_cast(&op_codel),sizeof(op_codel)); + } void TrinaryOpNode::collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const -{ - temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - ModelBlock->Block_List[Curr_Block].Temporary_InUse->insert(idx); - else - { - arg1->collectTemporary_terms(temporary_terms, ModelBlock, Curr_Block); - arg2->collectTemporary_terms(temporary_terms, ModelBlock, Curr_Block); - arg3->collectTemporary_terms(temporary_terms, ModelBlock, Curr_Block); - } -} + { + temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); + if (it != temporary_terms.end()) + ModelBlock->Block_List[Curr_Block].Temporary_InUse->insert(idx); + else + { + arg1->collectTemporary_terms(temporary_terms, ModelBlock, Curr_Block); + arg2->collectTemporary_terms(temporary_terms, ModelBlock, Curr_Block); + arg3->collectTemporary_terms(temporary_terms, ModelBlock, Curr_Block); + } + } void TrinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const -{ - // TrinaryOpNode not implemented for C output - assert(!IS_C(output_type)); + { + // TrinaryOpNode not implemented for C output + assert(!IS_C(output_type)); - // If current node is a temporary term - temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - output << "T" << idx; - return; - } + // If current node is a temporary term + temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); + if (it != temporary_terms.end()) + { + output << "T" << idx; + return; + } + + switch (op_code) + { + case oNormcdf: + output << "normcdf("; + break; + } + arg1->writeOutput(output, output_type, temporary_terms); + output << ","; + arg2->writeOutput(output, output_type, temporary_terms); + output << ","; + arg3->writeOutput(output, output_type, temporary_terms); + output << ")"; + } + +void +TrinaryOpNode::collectEndogenous(set > &result) const + { + arg1->collectEndogenous(result); + arg2->collectEndogenous(result); + arg3->collectEndogenous(result); + } + +void +TrinaryOpNode::collectExogenous(set > &result) const + { + arg1->collectExogenous(result); + arg2->collectExogenous(result); + arg3->collectExogenous(result); + } + +pair +TrinaryOpNode::normalizeLinearInEndoEquation(int var_endo, NodeID Derivative) const + { + pair 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; + res = arg3->normalizeLinearInEndoEquation(var_endo, Derivative); + bool is_endogenous_present_3 = res.first; + NodeID NodeID_3 = res.second; + if (not is_endogenous_present_1 and not is_endogenous_present_2 and not is_endogenous_present_3) + return(make_pair(false, /*tmp_*/datatree.AddNormcdf(NodeID_1, NodeID_2, NodeID_3))); + else + return(make_pair(true, (NodeID)NULL)); + } + +NodeID +TrinaryOpNode::computeChaineRuleDerivative(int deriv_id, map &recursive_variables, int var, int lag_) +{ + NodeID darg1 = arg1->getChaineRuleDerivative(deriv_id, recursive_variables, var, lag_); + NodeID darg2 = arg2->getChaineRuleDerivative(deriv_id, recursive_variables, var, lag_); + NodeID darg3 = arg3->getChaineRuleDerivative(deriv_id, recursive_variables, var, lag_); + + NodeID t11, t12, t13, t14, t15; switch (op_code) { case oNormcdf: - output << "normcdf("; - break; - } - arg1->writeOutput(output, output_type, temporary_terms); - output << ","; - arg2->writeOutput(output, output_type, temporary_terms); - output << ","; - arg3->writeOutput(output, output_type, temporary_terms); - output << ")"; -} - -void -TrinaryOpNode::collectEndogenous(set > &result) const -{ - arg1->collectEndogenous(result); - arg2->collectEndogenous(result); - arg3->collectEndogenous(result); -} - -void -TrinaryOpNode::collectExogenous(set > &result) const -{ - arg1->collectExogenous(result); - arg2->collectExogenous(result); - arg3->collectExogenous(result); -} - -NodeID -TrinaryOpNode::toStatic(DataTree &static_datatree) const -{ - NodeID sarg1 = arg1->toStatic(static_datatree); - NodeID sarg2 = arg2->toStatic(static_datatree); - NodeID sarg3 = arg3->toStatic(static_datatree); - switch(op_code) - { - case oNormcdf: - return static_datatree.AddNormcdf(sarg1, sarg2, sarg3); + // normal pdf is inlined in the tree + NodeID y; + // sqrt(2*pi) + t14 = datatree.AddSqrt(datatree.AddTimes(datatree.Two, datatree.Pi)); + // x - mu + t12 = datatree.AddMinus(arg1,arg2); + // y = (x-mu)/sigma + y = datatree.AddDivide(t12,arg3); + // (x-mu)^2/sigma^2 + t12 = datatree.AddTimes(y,y); + // -(x-mu)^2/sigma^2 + t13 = datatree.AddUMinus(t12); + // -((x-mu)^2/sigma^2)/2 + t12 = datatree.AddDivide(t13, datatree.Two); + // exp(-((x-mu)^2/sigma^2)/2) + t13 = datatree.AddExp(t12); + // derivative of a standardized normal + // t15 = (1/sqrt(2*pi))*exp(-y^2/2) + t15 = datatree.AddDivide(t13,t14); + // derivatives thru x + t11 = datatree.AddDivide(darg1,arg3); + // derivatives thru mu + t12 = datatree.AddDivide(darg2,arg3); + // intermediary sum + t14 = datatree.AddMinus(t11,t12); + // derivatives thru sigma + t11 = datatree.AddDivide(y,arg3); + t12 = datatree.AddTimes(t11,darg3); + //intermediary sum + t11 = datatree.AddMinus(t14,t12); + // total derivative: + // (darg1/sigma - darg2/sigma - darg3*(x-mu)/sigma^2) * t15 + // where t15 is the derivative of a standardized normal + return datatree.AddTimes(t11, t15); } // Suppress GCC warning exit(EXIT_FAILURE); } +NodeID +TrinaryOpNode::toStatic(DataTree &static_datatree) const + { + NodeID sarg1 = arg1->toStatic(static_datatree); + NodeID sarg2 = arg2->toStatic(static_datatree); + NodeID sarg3 = arg3->toStatic(static_datatree); + switch (op_code) + { + case oNormcdf: + return static_datatree.AddNormcdf(sarg1, sarg2, sarg3); + } + // Suppress GCC warning + exit(EXIT_FAILURE); + } + UnknownFunctionNode::UnknownFunctionNode(DataTree &datatree_arg, - int symb_id_arg, - const vector &arguments_arg) : - ExprNode(datatree_arg), - symb_id(symb_id_arg), - arguments(arguments_arg) + int symb_id_arg, + const vector &arguments_arg) : + ExprNode(datatree_arg), + symb_id(symb_id_arg), + arguments(arguments_arg) { } @@ -1828,70 +2378,78 @@ UnknownFunctionNode::computeDerivative(int deriv_id) exit(EXIT_FAILURE); } -void -UnknownFunctionNode::computeTemporaryTerms(map &reference_count, - temporary_terms_type &temporary_terms, - bool is_matlab) const +NodeID +UnknownFunctionNode::computeChaineRuleDerivative(int deriv_id, map &recursive_variables, int var, int lag_) { - cerr << "UnknownFunctionNode::computeTemporaryTerms: operation impossible!" << endl; + cerr << "UnknownFunctionNode::computeDerivative: operation impossible!" << endl; exit(EXIT_FAILURE); } + +void +UnknownFunctionNode::computeTemporaryTerms(map &reference_count, + temporary_terms_type &temporary_terms, + bool is_matlab) const + { + cerr << "UnknownFunctionNode::computeTemporaryTerms: operation impossible!" << endl; + exit(EXIT_FAILURE); + } + void UnknownFunctionNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const -{ - output << datatree.symbol_table.getName(symb_id) << "("; - for(vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - { - if (it != arguments.begin()) - output << ","; + { + output << datatree.symbol_table.getName(symb_id) << "("; + for (vector::const_iterator it = arguments.begin(); + it != arguments.end(); it++) + { + if (it != arguments.begin()) + output << ","; - (*it)->writeOutput(output, output_type, temporary_terms); - } - output << ")"; -} + (*it)->writeOutput(output, output_type, temporary_terms); + } + output << ")"; + } void UnknownFunctionNode::computeTemporaryTerms(map &reference_count, - temporary_terms_type &temporary_terms, - map > &first_occurence, - int Curr_block, - Model_Block *ModelBlock, - int equation, - map_idx_type &map_idx) const -{ - cerr << "UnknownFunctionNode::computeTemporaryTerms: not implemented" << endl; - exit(EXIT_FAILURE); -} + temporary_terms_type &temporary_terms, + map > &first_occurence, + int Curr_block, + Model_Block *ModelBlock, + int equation, + map_idx_type &map_idx) const + { + cerr << "UnknownFunctionNode::computeTemporaryTerms: not implemented" << endl; + exit(EXIT_FAILURE); + } void UnknownFunctionNode::collectEndogenous(set > &result) const -{ - for(vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - (*it)->collectEndogenous(result); -} + { + for (vector::const_iterator it = arguments.begin(); + it != arguments.end(); it++) + (*it)->collectEndogenous(result); + } void UnknownFunctionNode::collectExogenous(set > &result) const -{ - for(vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - (*it)->collectExogenous(result); -} + { + for (vector::const_iterator it = arguments.begin(); + it != arguments.end(); it++) + (*it)->collectExogenous(result); + } void UnknownFunctionNode::collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const -{ - temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - ModelBlock->Block_List[Curr_Block].Temporary_InUse->insert(idx); - else - { - //arg->collectTemporary_terms(temporary_terms, result); - } -} + { + temporary_terms_type::const_iterator it = temporary_terms.find(const_cast(this)); + if (it != temporary_terms.end()) + ModelBlock->Block_List[Curr_Block].Temporary_InUse->insert(idx); + else + { + //arg->collectTemporary_terms(temporary_terms, result); + } + } double @@ -1902,17 +2460,36 @@ UnknownFunctionNode::eval(const eval_context_type &eval_context) const throw (Ev void UnknownFunctionNode::compile(ofstream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const -{ - cerr << "UnknownFunctionNode::compile: operation impossible!" << endl; - exit(EXIT_FAILURE); -} + { + cerr << "UnknownFunctionNode::compile: operation impossible!" << endl; + exit(EXIT_FAILURE); + } + +pair +UnknownFunctionNode::normalizeLinearInEndoEquation(int var_endo, NodeID Derivative) const + { + vector > V_arguments; + vector V_NodeID; + bool present = false; + for (vector::const_iterator it = arguments.begin(); + it != arguments.end(); it++) + { + V_arguments.push_back((*it)->normalizeLinearInEndoEquation(var_endo, Derivative)); + present = present or V_arguments[V_arguments.size()-1].first; + V_NodeID.push_back(V_arguments[V_arguments.size()-1].second); + } + if (not present) + return(make_pair(false, datatree.AddUnknownFunction(datatree.symbol_table.getName(symb_id), V_NodeID))); + else + return(make_pair(true, (NodeID)NULL)); + } NodeID UnknownFunctionNode::toStatic(DataTree &static_datatree) const -{ - vector static_arguments; - for(vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - static_arguments.push_back((*it)->toStatic(static_datatree)); - return static_datatree.AddUnknownFunction(datatree.symbol_table.getName(symb_id), static_arguments); -} + { + vector static_arguments; + for (vector::const_iterator it = arguments.begin(); + it != arguments.end(); it++) + static_arguments.push_back((*it)->toStatic(static_datatree)); + return static_datatree.AddUnknownFunction(datatree.symbol_table.getName(symb_id), static_arguments); + } diff --git a/ExprNode.hh b/ExprNode.hh index 7b096d2c..70050271 100644 --- a/ExprNode.hh +++ b/ExprNode.hh @@ -109,6 +109,10 @@ private: //! Computes derivative w.r. to a derivation ID (but doesn't store it in derivatives map) /*! You shoud use getDerivative() to get the benefit of symbolic a priori and of caching */ virtual NodeID computeDerivative(int deriv_id) = 0; + //! Computes derivative w.r. to a derivation ID and use chaine rule derivatives (but doesn't store it in derivatives map) + /*! You shoud use getDerivative() to get the benefit of symbolic a priori and of caching */ + virtual NodeID computeChaineRuleDerivative(int deriv_id, map &recursive_variables, int var, int lag_) = 0; + protected: //! Reference to the enclosing DataTree @@ -136,6 +140,10 @@ public: For an equal node, returns the derivative of lhs minus rhs */ NodeID getDerivative(int deriv_id); + //! Returns derivative w.r. to derivation ID and use if it possible chaine rule derivatives + NodeID getChaineRuleDerivative(int deriv_id, map &recursive_variables, int var, int lag_); + + //! Returns precedence of node /*! Equals 100 for constants, variables, unary ops, and temporary terms */ virtual int precedence(ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const; @@ -145,7 +153,7 @@ public: virtual void computeTemporaryTerms(map &reference_count, temporary_terms_type &temporary_terms, bool is_matlab) const; //! Writes output of node, using a Txxx notation for nodes in temporary_terms - virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const = 0; + virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const /*= 0*/; //! Writes output of node (with no temporary terms and with "outside model" output type) void writeOutput(ostream &output); @@ -174,6 +182,7 @@ public: map_idx_type &map_idx) const; class EvalException + { }; @@ -185,6 +194,8 @@ public: adds the result in the static_datatree argument (and not in the original datatree), and returns it. */ virtual NodeID toStatic(DataTree &static_datatree) const = 0; + //! Try to normalize an equation linear in its endogenous variable + virtual pair normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const; }; //! Object used to compare two nodes (using their indexes) @@ -204,6 +215,7 @@ private: //! Id from numerical constants table const int id; virtual NodeID computeDerivative(int deriv_id); + virtual NodeID computeChaineRuleDerivative(int deriv_id, map &recursive_variables, int var, int lag_); public: NumConstNode(DataTree &datatree_arg, int id_arg); virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const; @@ -213,6 +225,7 @@ public: virtual double eval(const eval_context_type &eval_context) const throw (EvalException); virtual void compile(ofstream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const; virtual NodeID toStatic(DataTree &static_datatree) const; + virtual pair normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const; }; //! Symbol or variable node @@ -226,6 +239,7 @@ private: //! Derivation ID const int deriv_id; virtual NodeID computeDerivative(int deriv_id_arg); + virtual NodeID computeChaineRuleDerivative(int deriv_id, map &recursive_variables, int var, int lag_); public: VariableNode(DataTree &datatree_arg, int symb_id_arg, int lag_arg, int deriv_id_arg); virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms = temporary_terms_type()) const; @@ -243,6 +257,7 @@ public: virtual void compile(ofstream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const; virtual NodeID toStatic(DataTree &static_datatree) const; int get_symb_id() const { return symb_id; }; + virtual pair normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const; }; //! Unary operator node @@ -252,6 +267,7 @@ private: const NodeID arg; const UnaryOpcode op_code; virtual NodeID computeDerivative(int deriv_id); + virtual NodeID computeChaineRuleDerivative(int deriv_id, map &recursive_variables, int var, int lag_); virtual int cost(const temporary_terms_type &temporary_terms, bool is_matlab) const; public: @@ -276,6 +292,7 @@ public: //! Returns op code UnaryOpcode get_op_code() const { return(op_code); }; virtual NodeID toStatic(DataTree &static_datatree) const; + virtual pair normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const; }; //! Binary operator node @@ -285,6 +302,8 @@ private: const NodeID arg1, arg2; const BinaryOpcode op_code; virtual NodeID computeDerivative(int deriv_id); + virtual NodeID computeChaineRuleDerivative(int deriv_id, map &recursive_variables, int var, int lag_); + virtual int cost(const temporary_terms_type &temporary_terms, bool is_matlab) const; public: BinaryOpNode(DataTree &datatree_arg, const NodeID arg1_arg, @@ -312,6 +331,7 @@ public: //! Returns op code BinaryOpcode get_op_code() const { return(op_code); }; virtual NodeID toStatic(DataTree &static_datatree) const; + pair normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const; }; //! Trinary operator node @@ -322,6 +342,8 @@ private: const NodeID arg1, arg2, arg3; const TrinaryOpcode op_code; virtual NodeID computeDerivative(int deriv_id); + virtual NodeID computeChaineRuleDerivative(int deriv_id, map &recursive_variables, int var, int lag_); + virtual int cost(const temporary_terms_type &temporary_terms, bool is_matlab) const; public: TrinaryOpNode(DataTree &datatree_arg, const NodeID arg1_arg, @@ -343,6 +365,7 @@ public: virtual double eval(const eval_context_type &eval_context) const throw (EvalException); virtual void compile(ofstream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const; virtual NodeID toStatic(DataTree &static_datatree) const; + virtual pair normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const; }; //! Unknown function node @@ -352,6 +375,7 @@ private: const int symb_id; const vector arguments; virtual NodeID computeDerivative(int deriv_id); + virtual NodeID computeChaineRuleDerivative(int deriv_id, map &recursive_variables, int var, int lag_); public: UnknownFunctionNode(DataTree &datatree_arg, int symb_id_arg, const vector &arguments_arg); @@ -370,6 +394,7 @@ public: virtual double eval(const eval_context_type &eval_context) const throw (EvalException); virtual void compile(ofstream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const; virtual NodeID toStatic(DataTree &static_datatree) const; + virtual pair normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const; }; //! For one lead/lag of one block, stores mapping of information between original model and block-decomposed model @@ -393,7 +418,8 @@ struct Block bool is_linear; int *Equation, *Own_Derivative; EquationType *Equation_Type; - int *Variable, *Other_Endogenous, *Exogenous, *Equation_Type_Var; + NodeID *Equation_Normalized; + int *Variable, *Other_Endogenous, *Exogenous; temporary_terms_type **Temporary_Terms_in_Equation; //temporary_terms_type *Temporary_terms; temporary_terms_inuse_type *Temporary_InUse; diff --git a/MinimumFeedbackSet.cc b/MinimumFeedbackSet.cc index cc546974..8216aab6 100644 --- a/MinimumFeedbackSet.cc +++ b/MinimumFeedbackSet.cc @@ -186,7 +186,6 @@ namespace MFS GraphvizDigraph_2_AdjacencyList(GraphvizDigraph& G1, set select_index) { unsigned int n = select_index.size(); - //cout << "n=" << n << "\n"; AdjacencyList_type G(n); property_map::type v_index = get(vertex_index, G); property_map::type v_index1 = get(vertex_index1, G); @@ -208,13 +207,7 @@ namespace MFS { int ii = target(*it_out, G1); if (select_index.find(ii) != select_index.end()) - { - /*cout << "*it=" << *it << " i = " << i << " ii=" << ii << " n=" << n << " *it_out=" << *it_out << "\n"; - cout << "source(*it_out, G1) = " << source(*it_out, G1) << " target(*it_out, G1) = " << target(*it_out, G1) << "\n"; - cout << "vertex(source(*it_out, G1), G) = " << vertex(source(*it_out, G1), G) << " vertex(target(*it_out, G1), G) = " << vertex(target(*it_out, G1), G) << "\n";*/ - add_edge( vertex(reverse_index[source(*it_out, G1)],G), vertex(reverse_index[target(*it_out, G1)], G), G); - //add_edge(vertex(source(*it_out, G1), G) , vertex(target(*it_out, G1), G), G); - } + add_edge( vertex(reverse_index[source(*it_out, G1)],G), vertex(reverse_index[target(*it_out, G1)], G), G); } } return G; @@ -367,110 +360,8 @@ namespace MFS return something_has_been_done; } - bool - Suppression_of_Edge_i_j_if_not_a_loop_and_if_for_all_i_k_edge_we_have_a_k_j_edge_Step(AdjacencyList_type& G) //Suppression - { - bool something_has_been_done = false; - AdjacencyList_type::vertex_iterator it, it_end; - int i = 0; - bool agree; - for (tie(it, it_end) = vertices(G);it != it_end; ++it, i++) - { - AdjacencyList_type::in_edge_iterator it_in, in_end; - AdjacencyList_type::out_edge_iterator it_out, out_end, it_out1, ita_out; - int j = 0; - for (tie(ita_out = it_out, out_end) = out_edges(*it, G); it_out != out_end; ++it_out, j++) - { - AdjacencyList_type::edge_descriptor ed; - bool exist; - tie(ed, exist) = edge(target(*it_out, G), source(*it_out, G) , G); - if (!exist) - { - agree = true; - for (tie(it_out1, out_end) = out_edges(*it, G); it_out1 != out_end; ++it_out1) - { - bool exist; - tie(ed, exist) = edge(target(*it_out1, G), target(*it_out, G) , G); - if (target(*it_out1, G) != target(*it_out, G) and !exist) - agree = false; - } - if (agree) - { - something_has_been_done = true; - remove_edge(*it_out, G); - if (out_degree(*it, G) == 0) - break; - if (j > 0) - { - it_out = ita_out; - tie(it_out1, out_end) = out_edges(*it, G); - } - else - { - tie(it_out, out_end) = out_edges(*it, G); - j--; - } - } - } - ita_out = it_out; - } - } - return something_has_been_done; - } - bool - Suppression_of_all_in_Edge_in_i_if_not_a_loop_and_if_all_doublet_i_eq_Min_inDegree_outDegree_Step(AdjacencyList_type& G) - { - bool something_has_been_done = false; - AdjacencyList_type::vertex_iterator it, it_end; - int i = 0; - for (tie(it, it_end) = vertices(G);it != it_end; ++it, i++) - { - AdjacencyList_type::in_edge_iterator it_in, in_end, it_in1, ita_in; - vector doublet = Collect_Doublet(*it, G); - if (doublet.size() == (unsigned int) min(in_degree(*it, G), out_degree(*it, G))) - { - int j = 0; - if (in_degree(*it, G)) - for (tie(ita_in = it_in, in_end) = in_edges(*it, G); it_in != in_end; ++it_in, j++) - { - vector::iterator it1 = doublet.begin(); - bool not_a_doublet = true; - while (it1 != doublet.end() and not_a_doublet) - { - if (target(*it_in, G) == *it1) - not_a_doublet = false; - it1++; - } - if (not_a_doublet and source(*it_in, G) != target(*it_in, G)) - { -#ifdef verbose - property_map::type v_index = get(vertex_index, G); - cout << "remove_edge(" << v_index[source(*it_in, G)] << ", " << v_index[target(*it_in, G)] << ", G) j=" << j << " it_in == in_end : " << (it_in == in_end) << " in_degree(*it, G)=" << in_degree(*it, G) << ";\n"; -#endif - something_has_been_done = true; - remove_edge(source(*it_in, G), target(*it_in, G), G); - cout << " in_degree(*it, G)=" << in_degree(*it, G) << ";\n"; - if (in_degree(*it, G) == 0) - break; - if (j > 0) - { - it_in = ita_in; - } - else - { - tie(it_in, in_end) = in_edges(*it, G); - j--; - } - } - ita_in = it_in; - } - } - } - return something_has_been_done; - } - bool Suppression_of_Vertex_X_if_it_loops_store_in_set_of_feedback_vertex_Step(set &feed_back_vertices, AdjacencyList_type& G) @@ -537,21 +428,9 @@ namespace MFS #endif //Rule 3 - //something_has_been_done=(Suppression_of_Edge_i_j_if_not_a_loop_and_if_for_all_i_k_edge_we_have_a_k_j_edge_Step(G) or something_has_been_done); -#ifdef verbose - cout << "3 something_has_been_done=" << something_has_been_done << "\n"; -#endif - - //Rule 4 - //something_has_been_done=(Suppression_of_all_in_Edge_in_i_if_not_a_loop_and_if_all_doublet_i_eq_Min_inDegree_outDegree_Step(G) or something_has_been_done); -#ifdef verbose - cout << "4 something_has_been_done=" << something_has_been_done << "\n"; -#endif - - //Rule 5 something_has_been_done = (Suppression_of_Vertex_X_if_it_loops_store_in_set_of_feedback_vertex_Step(feed_back_vertices, G) or something_has_been_done); #ifdef verbose - cout << "5 something_has_been_done=" << something_has_been_done << "\n"; + cout << "3 something_has_been_done=" << something_has_been_done << "\n"; #endif } vector circuit; diff --git a/MinimumFeedbackSet.hh b/MinimumFeedbackSet.hh index b33cd194..d33f5cb3 100644 --- a/MinimumFeedbackSet.hh +++ b/MinimumFeedbackSet.hh @@ -25,8 +25,6 @@ #include #include #include -#include -#include using namespace std; using namespace boost; @@ -44,25 +42,42 @@ using namespace boost; namespace MFS { + //! Eliminate a vertex i: + //! For a vertex i replace all edges e_k_i and e_i_j by a shorcut e_k_j and then Suppress the vertex i void Eliminate(AdjacencyList_type::vertex_descriptor vertex_to_eliminate, AdjacencyList_type& G); + //!collect all doublet (for each edge e_i_k there is an edge e_k_i with k!=i) in the graph + //! and return the vector of doublet vector_vertex_descriptor Collect_Doublet(AdjacencyList_type::vertex_descriptor vertex, AdjacencyList_type& G); + //! Detect all the clique (all vertex in a clique are related to each other) in the graph bool Vertex_Belong_to_a_Clique(AdjacencyList_type::vertex_descriptor vertex, AdjacencyList_type& G); - bool Elimination_of_Vertex_With_One_or_Less_Indegree_or_Outdegree_Step(AdjacencyList_type& G); //Graph reduction: eliminating purely intermediate variables or variables outside of any circuit - bool Elimination_of_Vertex_belonging_to_a_clique_Step(AdjacencyList_type& G); //Graphe reduction: eliminaion of Cliques - bool Suppression_of_Edge_i_j_if_not_a_loop_and_if_for_all_i_k_edge_we_have_a_k_j_edge_Step(AdjacencyList_type& G); //Suppression - bool Suppression_of_all_in_Edge_in_i_if_not_a_loop_and_if_all_doublet_i_eq_Min_inDegree_outDegree_Step(AdjacencyList_type& G); + //! Graph reduction: eliminating purely intermediate variables or variables outside of any circuit + bool Elimination_of_Vertex_With_One_or_Less_Indegree_or_Outdegree_Step(AdjacencyList_type& G); + //! Graphe reduction: elimination of a vertex inside a clique + bool Elimination_of_Vertex_belonging_to_a_clique_Step(AdjacencyList_type& G); + //! A vertex belong to the feedback vertex set if the vertex loop on itself. + //! We have to suppress this vertex and store it into the feedback set. bool Suppression_of_Vertex_X_if_it_loops_store_in_set_of_feedback_vertex_Step(vector > &looping_variable, AdjacencyList_type& G); - void Print(AdjacencyList_type& G); - AdjacencyList_type AM_2_AdjacencyList(bool* AMp,unsigned int n); + //! Print the Graph void Print(GraphvizDigraph& G); + void Print(AdjacencyList_type& G); + //! Create a GraphvizDigraph from a Adjacency Matrix (an incidence Matrix without the diagonal terms) GraphvizDigraph AM_2_GraphvizDigraph(bool* AM, unsigned int n); + //! Create an adjacency graph from a Adjacency Matrix (an incidence Matrix without the diagonal terms) + AdjacencyList_type AM_2_AdjacencyList(bool* AMp,unsigned int n); + //! Create an adjacency graph from a GraphvizDigraph AdjacencyList_type GraphvizDigraph_2_AdjacencyList(GraphvizDigraph& G1, set select_index); + //! Check if the graph contains any cycle (true if the model contains at least one cycle, false otherwise) bool has_cycle_dfs(AdjacencyList_type& g, AdjacencyList_type::vertex_descriptor u, color_type& color, vector &circuit_stack); bool has_cylce(AdjacencyList_type& g, vector &circuit_stack, int size); bool has_cycle(vector &circuit_stack, AdjacencyList_type& G); + //! Return the feedback set AdjacencyList_type Minimal_set_of_feedback_vertex(set &feed_back_vertices, const AdjacencyList_type& G); + //! clear all in and out edges of vertex_to_eliminate + //! and remove vertex_to_eliminate from the graph void Suppress(AdjacencyList_type::vertex_descriptor vertex_to_eliminate, AdjacencyList_type& G); void Suppress(int vertex_num, AdjacencyList_type& G); + //! reorder the recursive variable: + //! They appear first in a quasi triangular form and they are followed by the feedback variables vector Reorder_the_recursive_variables(const AdjacencyList_type& G1, set &feed_back_vertices); }; diff --git a/ModFile.cc b/ModFile.cc index d5e540b3..d081a1e1 100644 --- a/ModFile.cc +++ b/ModFile.cc @@ -147,7 +147,7 @@ ModFile::computingPass(bool no_tmp_terms) static_model.computingPass(false, no_tmp_terms); // Set things to compute for dynamic model - + if (mod_file_struct.simul_present) dynamic_model.computingPass(false, false, false, false, global_eval_context, no_tmp_terms); else diff --git a/ModelGraph.cc b/ModelGraph.cc deleted file mode 100644 index 87e459ef..00000000 --- a/ModelGraph.cc +++ /dev/null @@ -1,479 +0,0 @@ -/* - * Copyright (C) 2007-2008 Dynare Team - * - * This file is part of Dynare. - * - * Dynare is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Dynare is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Dynare. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "ModelTree.hh" -#include "ModelGraph.hh" -#include "BlockTriangular.hh" - -using namespace std; - -void -free_model_graph(t_model_graph* model_graph) -{ - int i; - for(i = 0;i < model_graph->nb_vertices;i++) - { - free(model_graph->vertex[i].in_degree_edge); - free(model_graph->vertex[i].out_degree_edge); - } - free(model_graph->vertex); - free(model_graph); -} - -void -print_Graph(t_model_graph* model_graph) -{ - int i, j; - for(i = 0;i < model_graph->nb_vertices;i++) - { - cout << "vertex " << model_graph->vertex[i].index << "(" << i << " ," << model_graph->vertex[i].nb_out_degree_edges << ")\n"; - cout << " -> "; - for(j = 0;j < model_graph->vertex[i].nb_out_degree_edges;j++) - cout << model_graph->vertex[model_graph->vertex[i].out_degree_edge[j].index].index << /*" -" << model_graph->vertex[i].out_degree_edge[j].index << "-*/" (" << model_graph->vertex[i].out_degree_edge[j].u_count << "), "; - cout << "\n"; - cout << " <- "; - for(j = 0;j < model_graph->vertex[i].nb_in_degree_edges;j++) - cout << model_graph->vertex[model_graph->vertex[i].in_degree_edge[j].index].index << /*" -" << model_graph->vertex[i].in_degree_edge[j].index << "-*/" (" << model_graph->vertex[i].in_degree_edge[j].u_count << "), "; - cout << "\n"; - } -} - - - -void Check_Graph(t_model_graph* model_graph) -{ - int i, j, k, i1, i2; - bool OK, OK_u_count; - for(i = 0;i < model_graph->nb_vertices;i++) - { - for(j = 0;j < model_graph->vertex[i].nb_in_degree_edges;j++) - { - i1 = model_graph->vertex[i].in_degree_edge[j].index; - i2 = model_graph->vertex[i].in_degree_edge[j].u_count; - OK = 0; - OK_u_count = 0; - for(k = 0;(k < model_graph->vertex[i1].nb_out_degree_edges) && (!OK);k++) - { - if(model_graph->vertex[i1].out_degree_edge[k].index == i) - { - OK = 1; - if(model_graph->vertex[i1].out_degree_edge[k].u_count == i2) - OK_u_count = 1; - } - } - if(!OK) - { - cout << "not symetric for edge between vertices " << model_graph->vertex[i1].index << " and " << model_graph->vertex[i].index << " (in_degree)\n"; - print_Graph(model_graph); - system("pause"); - exit(EXIT_FAILURE); - } - if(!OK_u_count) - { - cout << "valeur de u_count non symétrique sur l'arc entre " << model_graph->vertex[i1].index << " et " << model_graph->vertex[i].index << " (in_degree)\n"; - print_Graph(model_graph); - system("pause"); - exit(EXIT_FAILURE); - } - } - for(j = 0;j < model_graph->vertex[i].nb_out_degree_edges;j++) - { - i1 = model_graph->vertex[i].out_degree_edge[j].index; - i2 = model_graph->vertex[i].out_degree_edge[j].u_count; - OK = 0; - OK_u_count = 0; - for(k = 0;(k < model_graph->vertex[i1].nb_in_degree_edges) && (!OK);k++) - { - if(model_graph->vertex[i1].in_degree_edge[k].index == i) - { - OK = 1; - if(model_graph->vertex[i1].in_degree_edge[k].u_count == i2) - OK_u_count = 1; - } - } - if(!OK) - { - cout << "pas symétrique sur l'arc entre " << model_graph->vertex[i1].index << " et " << model_graph->vertex[i].index << " (out_degree)\n"; - print_Graph(model_graph); - system("pause"); - exit(EXIT_FAILURE); - } - if(!OK_u_count) - { - cout << "valeur de u_count non symétrique sur l'arc entre " << model_graph->vertex[i1].index << " et " << model_graph->vertex[i].index << " (out_degree)\n"; - print_Graph(model_graph); - system("pause"); - exit(EXIT_FAILURE); - } - } - } -} - -int -ModelBlock_Graph(Model_Block *ModelBlock, int Blck_num, bool dynamic, t_model_graph* model_graph, int nb_endo, int* block_u_count, int *starting_vertex, int *periods, int *nb_table_y, int *mean_var_in_equ) -{ - int i, j, k, l, m, lag, per, lag1, k2, complete_size = 0, u_count; - int max_lead, max_lag, size, Lead, Lag; - int *Used, *todo_lag, *todo_lead, *vertex_ref, *vertex_index, *todo_lag1, *todo_lead1 ; - max_lag = ModelBlock->Block_List[Blck_num].Max_Lag; - max_lead = ModelBlock->Block_List[Blck_num].Max_Lead; - if(!dynamic) - { - /*It's a static model that have to be solved at each period*/ - /*size=ModelBlock->Block_List[Blck_num].IM_lead_lag[max_lag].size;*/ - size = ModelBlock->Block_List[Blck_num].Size; - /*We add an extra vertex to take into account of the f(x0) constant term in f(x)=0 approximated by f(x0) + (x-x0) f'(x0) = 0*/ - //cout << "Static, Blck_num= " << Blck_num << "size= " << size << "\n"; - model_graph->nb_vertices = size + 1; - *starting_vertex = 0; - model_graph->vertex = (t_vertex*)malloc(model_graph->nb_vertices * sizeof(*model_graph->vertex)); - for(i = 0;i < size;i++) - { - /*It's not f(x0) vertex*/ - model_graph->vertex[i].in_degree_edge = (t_edge*)malloc((size + 1) * sizeof(t_edge)); - model_graph->vertex[i].out_degree_edge = (t_edge*)malloc((size + 1) * sizeof(t_edge)); - model_graph->vertex[i].nb_in_degree_edges = 0; - model_graph->vertex[i].nb_out_degree_edges = 0; - model_graph->vertex[i].index = ModelBlock->Block_List[Blck_num].Variable[i]; - model_graph->vertex[i].lag_lead = 0; - } - /*It's f(x0) vertex*/ - model_graph->vertex[size].in_degree_edge = (t_edge*)malloc(0 * sizeof(t_edge)); - model_graph->vertex[size].out_degree_edge = (t_edge*)malloc((size) * sizeof(t_edge)); - model_graph->vertex[size].nb_in_degree_edges = 0; - model_graph->vertex[size].index = -1; - model_graph->vertex[size].lag_lead = 0; - for(i = 0;i < ModelBlock->Block_List[Blck_num].IM_lead_lag[max_lag].size;i++) - { - k = ModelBlock->Block_List[Blck_num].IM_lead_lag[max_lag].Equ[i]; - m = ModelBlock->Block_List[Blck_num].IM_lead_lag[max_lag].Var[i]; - j = model_graph->vertex[k].nb_in_degree_edges++; - l = model_graph->vertex[m].nb_out_degree_edges++; - model_graph->vertex[k].in_degree_edge[j].index = m; - model_graph->vertex[m].out_degree_edge[l].index = k; - model_graph->vertex[k].in_degree_edge[j].u_count = ModelBlock->Block_List[Blck_num].IM_lead_lag[max_lag].us[i]; - model_graph->vertex[m].out_degree_edge[l].u_count = ModelBlock->Block_List[Blck_num].IM_lead_lag[max_lag].us[i]; - } - model_graph->vertex[size].nb_out_degree_edges = size; - for(i = 0;i < size;i++) - { - j = model_graph->vertex[i].nb_in_degree_edges++; - model_graph->vertex[i].in_degree_edge[j].index = size; - model_graph->vertex[i].in_degree_edge[j].u_count = i; - model_graph->vertex[size].out_degree_edge[i].index = i; - model_graph->vertex[size].out_degree_edge[i].u_count = i; - } - u_count = ModelBlock->Block_List[Blck_num].IM_lead_lag[max_lag].u_finish - ModelBlock->Block_List[Blck_num].IM_lead_lag[max_lag].u_init + 1 - + ModelBlock->Block_List[Blck_num].Size; - *block_u_count = u_count; - *nb_table_y = size; - return (u_count); - } - else - { - int sup; - Lead = ModelBlock->Block_List[Blck_num].Max_Lead; - Lag = ModelBlock->Block_List[Blck_num].Max_Lag; - cout << "---> *periods=" << *periods << "\n"; - if(*periods>3) - { - sup = Lead + Lag +3; - *periods = Lead + Lag + sup; - } -#ifdef PRINT_OUT - cout << "Lag=" << Lag << " Lead=" << Lead << "\n"; - cout << "periods=Lead+2*Lag+2= " << *periods << "\n"; -#endif - size = ModelBlock->Block_List[Blck_num].Size; - /*It's a dynamic model that have to be solved for all periods. - So we consider the incidence matrice for all lead and lags plus the current value*/ - model_graph->nb_vertices = 0; - vertex_ref = (int*)malloc(size * (Lag + Lead + *periods) * sizeof(int)); - memset(vertex_ref, -1, size*(Lag + Lead + *periods)*sizeof(int)); - vertex_index = (int*)malloc(size * (Lag + Lead + *periods) * sizeof(int)); - complete_size = ModelBlock->Block_List[Blck_num].IM_lead_lag[Lag].size * (*periods); - if(Lag > 0) - { - todo_lag = (int*)malloc(size * Lag * sizeof(int)); - todo_lag1 = (int*)malloc(size * Lag * sizeof(int)); - memset(todo_lag, -1, size*Lag*sizeof(int)); - memset(todo_lag1, -1, size*Lag*sizeof(int)); - Used = (int*)malloc(size * Lag * sizeof(int)); - for(lag = 0;lag < Lag;lag++) - { - memset(Used, -1, size*Lag*sizeof(int)); - complete_size += ModelBlock->Block_List[Blck_num].IM_lead_lag[lag].size; - for(i = 0;i < ModelBlock->Block_List[Blck_num].IM_lead_lag[lag].size;i++) - { - if(Used[ModelBlock->Block_List[Blck_num].IM_lead_lag[lag].Var[i]] < 0) - { - k = ModelBlock->Block_List[Blck_num].IM_lead_lag[lag].Var[i]; - todo_lag[lag*size + k] = k; - vertex_ref[lag*size + k] = model_graph->nb_vertices; - vertex_index[model_graph->nb_vertices] = lag * nb_endo + ModelBlock->Block_List[Blck_num].IM_lead_lag[lag].Var_Index[i]; - todo_lag1[lag*size + k] = i; - model_graph->nb_vertices++; - Used[k] = i; - } - } - if(lag > 0) - { - for(lag1 = 0;lag1 < lag;lag1++) - for(i = 0;i < size;i++) - if(todo_lag[(lag1)*size + i] >= 0) - { - if(Used[i] < 0) - { - todo_lag[lag*size + i] = i; - k = todo_lag[(lag1) * size + i]; - vertex_ref[lag*size + k] = model_graph->nb_vertices; - j = todo_lag1[(lag1) * size + i]; - vertex_index[model_graph->nb_vertices] = lag * nb_endo + ModelBlock->Block_List[Blck_num].IM_lead_lag[lag1].Var_Index[k]; - model_graph->nb_vertices++; - } - } - } - } - *starting_vertex = model_graph->nb_vertices; - free(Used); - free(todo_lag); - free(todo_lag1); - } - int nb_vertices_1=model_graph->nb_vertices; -#ifdef PRINT_OUT - cout << "nb_vertices in the first part: " << nb_vertices_1 << "\n"; -#endif - for(per = Lag;per < Lag + *periods;per++) - for(i = 0;i < size;i++) - { - vertex_ref[per*size + i] = model_graph->nb_vertices; - vertex_index[model_graph->nb_vertices] = (per) * nb_endo + ModelBlock->Block_List[Blck_num].Variable[i]; - model_graph->nb_vertices++; - } - int nb_vertices_2=model_graph->nb_vertices-nb_vertices_1; -#ifdef PRINT_OUT - cout << "nb_vertices in the second part: " << nb_vertices_2 << "\n"; -#endif - if(Lead > 0) - { - todo_lead = (int*)malloc(size * Lead * sizeof(int)); - todo_lead1 = (int*)malloc(size * Lead * sizeof(int)); - memset(todo_lead, -1, size*Lead*sizeof(int)); - memset(todo_lead1, -1, size*Lead*sizeof(int)); - Used = (int*)malloc(size * Lead * sizeof(int)); - k2 = model_graph->nb_vertices; - for(lag = Lag + Lead;lag > Lag;lag--) - { - complete_size += ModelBlock->Block_List[Blck_num].IM_lead_lag[lag].size; - memset(Used, -1, size*Lead*sizeof(int)); - for(i = 0;i < ModelBlock->Block_List[Blck_num].IM_lead_lag[lag].size;i++) - { - if(Used[ModelBlock->Block_List[Blck_num].IM_lead_lag[lag].Var[i]] < 0) - { - k = ModelBlock->Block_List[Blck_num].IM_lead_lag[lag].Var[i]; - todo_lead[(lag - Lag - 1)*size + k] = k; - todo_lead1[(lag - Lag - 1)*size + k] = i; - Used[k] = i; - model_graph->nb_vertices++; - } - } - if(lag < Lag + Lead) - { - for(lag1 = Lag + Lead;lag1 > lag;lag1--) - for(i = 0;i < size;i++) - { - if(todo_lead[(lag1 - Lag - 1)*size + i] >= 0) - { - if(Used[i] < 0) - { - k = todo_lead[(lag1 - Lag - 1) * size + i]; - model_graph->nb_vertices++; - } - } - } - } - } - k2 = model_graph->nb_vertices; - memset(todo_lead, -1, size*Lead*sizeof(int)); - for(lag = Lag + Lead;lag > Lag;lag--) - { - complete_size += ModelBlock->Block_List[Blck_num].IM_lead_lag[lag].size; - memset(Used, -1, size*Lead*sizeof(int)); - for(i = ModelBlock->Block_List[Blck_num].IM_lead_lag[lag].size - 1;i >= 0;i--) - { - if(Used[ModelBlock->Block_List[Blck_num].IM_lead_lag[lag].Var[i]] < 0) - { - k2--; - k = ModelBlock->Block_List[Blck_num].IM_lead_lag[lag].Var[i]; - todo_lead[(lag - Lag - 1)*size + k] = k; - todo_lead1[(lag - Lag - 1)*size + k] = i; - vertex_ref[(lag + *periods - 1)*size + k] = k2; - vertex_index[k2] = (lag + *periods - 1) * nb_endo + ModelBlock->Block_List[Blck_num].IM_lead_lag[lag].Var_Index[i]; - Used[k] = i; - } - } - if(lag < Lag + Lead) - { - for(lag1 = Lag + Lead;lag1 > lag;lag1--) - { - for(i = size - 1;i >= 0;i--) - { - if(todo_lead[(lag1 - Lag - 1)*size + i] >= 0) - { - if(Used[i] < 0) - { - k2--; - todo_lead[(lag - Lag - 1)*size + i] = i; - todo_lead1[(lag - Lag - 1)*size + i] = todo_lead1[(lag1 - Lag - 1)*size + i]; - k = todo_lead[(lag1 - Lag - 1) * size + i]; - vertex_ref[(lag + *periods - 1)*size + k] = k2; - //#ifdef PRINT_OUT - - //#endif - - j = todo_lead1[(lag1 - Lag - 1) * size + i]; - //#ifdef PRINT_OUT - if(j>ModelBlock->Block_List[Blck_num].IM_lead_lag[lag1].size||j==-1) - { - cout << "Error in model graph construction (lead part): j (" << j << ")>size (" << ModelBlock->Block_List[Blck_num].IM_lead_lag[lag1].size << ")\n"; - system("pause"); - exit(EXIT_FAILURE); - } - //#endif - vertex_index[k2] = (lag + *periods - 1) * nb_endo + ModelBlock->Block_List[Blck_num].IM_lead_lag[lag1].Var_Index[j]; - } - } - } - } - } - } - free(Used); - free(todo_lead); - free(todo_lead1); - } - int nb_vertices_3=model_graph->nb_vertices-nb_vertices_2-nb_vertices_1; -#ifdef PRINT_OUT - cout << "nb_vertices in the last part: " << nb_vertices_3 << "\n"; -#endif - /*We add an extra vertex to take into account of the f(x0) constant term in f(x)=0 approx f(x0) + (x-x0) f'(x0) = 0*/ - model_graph->nb_vertices++; - model_graph->vertex = (t_vertex*)malloc(model_graph->nb_vertices * sizeof(*model_graph->vertex)); - vertex_index[model_graph->nb_vertices - 1] = -1; -#ifdef PRINT_OUT - cout << "ok0\n"; - cout << "model_graph->nb_vertices=" << model_graph->nb_vertices << " Lag=" << Lag << " Lead=" << Lead << "\n"; - cout << "*periods=" << *periods << " size=" << size << "\n"; - cout << "allocated / vertex = " << (size + nb_vertices_1 + nb_vertices_3+ 1) << "\n"; -#endif - int nb_table_u= size+nb_vertices_1+nb_vertices_3+2; - for(k = 0;k < model_graph->nb_vertices-1;k++) - { - model_graph->vertex[k].index = vertex_index[k]; - model_graph->vertex[k].in_degree_edge = (t_edge*)malloc(nb_table_u * sizeof(t_edge)); - model_graph->vertex[k].out_degree_edge = (t_edge*)malloc(nb_table_u * sizeof(t_edge)); - model_graph->vertex[k].nb_in_degree_edges = 0; - model_graph->vertex[k].nb_out_degree_edges = 0; - model_graph->vertex[k].max_nb_in_degree_edges = nb_table_u; - model_graph->vertex[k].max_nb_out_degree_edges = nb_table_u; -#ifdef PRINT_OUT - //if(k==8) - { - cout << " model_graph->vertex[" << k << "].in_degree_edge=" << model_graph->vertex[k].in_degree_edge << "\n"; - } -#endif - } - model_graph->vertex[model_graph->nb_vertices-1].index = vertex_index[model_graph->nb_vertices-1]; - model_graph->vertex[model_graph->nb_vertices-1].in_degree_edge = (t_edge*)malloc(/*model_graph->nb_vertices **/ sizeof(t_edge)); - model_graph->vertex[model_graph->nb_vertices-1].out_degree_edge = (t_edge*)malloc(model_graph->nb_vertices * sizeof(t_edge)); - model_graph->vertex[model_graph->nb_vertices-1].nb_in_degree_edges = 0; - model_graph->vertex[model_graph->nb_vertices-1].nb_out_degree_edges = 0; - model_graph->vertex[model_graph->nb_vertices-1].max_nb_in_degree_edges = 0; - model_graph->vertex[model_graph->nb_vertices-1].max_nb_out_degree_edges = model_graph->nb_vertices; -#ifdef PRINT_OUT - cout << "ok1\n"; - system("pause"); -#endif - u_count = 0; - *mean_var_in_equ = 0; - for(per = 0;per < *periods;per++) - { - j = model_graph->nb_vertices - 1; - for(i = 0;i < size;i++) - { - k = vertex_ref[(Lag + per) * size + i]; - model_graph->vertex[k].in_degree_edge[model_graph->vertex[k].nb_in_degree_edges].index = j; - model_graph->vertex[j].out_degree_edge[model_graph->vertex[j].nb_out_degree_edges].index = k; - model_graph->vertex[k].in_degree_edge[model_graph->vertex[k].nb_in_degree_edges].u_count = u_count; - model_graph->vertex[j].out_degree_edge[model_graph->vertex[j].nb_out_degree_edges].u_count = u_count; - model_graph->vertex[k].nb_in_degree_edges++; - model_graph->vertex[j].nb_out_degree_edges++; - u_count++; - } - for(lag = 0;lag < Lag + Lead + 1;lag++) - { -#ifdef PRINT_OUT - cout << "ModelBlock->Block_List[" << Blck_num << "].IM_lead_lag[" << lag << "].size = " << ModelBlock->Block_List[Blck_num].IM_lead_lag[lag].size << "\n"; -#endif - - for(i = 0;i < ModelBlock->Block_List[Blck_num].IM_lead_lag[lag].size;i++) - { - j = vertex_ref[(lag + per) * size + ModelBlock->Block_List[Blck_num].IM_lead_lag[lag].Var[i]]; - k = vertex_ref[(Lag + per) * size + ModelBlock->Block_List[Blck_num].IM_lead_lag[lag].Equ[i]]; -#ifdef PRINT_OUT - - cout << "per=" << per << " lag=" << lag << " i=" << i << " j=" << j << " k=" << k << "\n"; -#endif - - model_graph->vertex[k].in_degree_edge[model_graph->vertex[k].nb_in_degree_edges].index = j; - model_graph->vertex[j].out_degree_edge[model_graph->vertex[j].nb_out_degree_edges].index = k; - model_graph->vertex[k].in_degree_edge[model_graph->vertex[k].nb_in_degree_edges].u_count = u_count; - model_graph->vertex[j].out_degree_edge[model_graph->vertex[j].nb_out_degree_edges].u_count = u_count; - if(per==(Lag+2))/*&&(lag==(Lag+1))*/ - (*mean_var_in_equ)++; - model_graph->vertex[k].nb_in_degree_edges++; - model_graph->vertex[j].nb_out_degree_edges++; - u_count++; - } - } - } - (*mean_var_in_equ) += size; - //cout << "Total variables=" << *mean_var_in_equ << " nb_endo=" << size << "\n"; - i=*mean_var_in_equ ; - i =int(ceil(double(i)/size)); - *mean_var_in_equ = i; - - //cout << "Mean var in equation=" << *mean_var_in_equ << "\n"; - *block_u_count = u_count / (*periods); - free(vertex_index); - free(vertex_ref); - if(nb_vertices_1+nb_vertices_3+1>size) - *nb_table_y = nb_vertices_1+nb_vertices_3+1; - else - *nb_table_y = size; - return (u_count); - } -} diff --git a/ModelGraph.hh b/ModelGraph.hh deleted file mode 100644 index 7a6dfa7c..00000000 --- a/ModelGraph.hh +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2007-2008 Dynare Team - * - * This file is part of Dynare. - * - * Dynare is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Dynare is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Dynare. If not, see . - */ - -#ifndef MODEL_GRAPH -#define MODEL_GRAPH -#define DIRECT_COMPUTE -#define SORTED -#define SIMPLIFY -#define SIMPLIFYS -#define SAVE -#define COMPUTE -//#define PRINT_OUT_OUT -//#define PRINT_OUT_1 -#define DIRECT_SAVE -#include "ModelTree.hh" -#include "BlockTriangular.hh" - -struct t_edge -{ - int index, u_count; -}; - -struct t_vertex -{ - t_edge *out_degree_edge, *in_degree_edge; - int nb_out_degree_edges, nb_in_degree_edges; - int max_nb_out_degree_edges, max_nb_in_degree_edges; - int index, lag_lead; -}; - -struct t_model_graph -{ - int nb_vertices; - t_vertex* vertex; -}; - -void free_model_graph(t_model_graph* model_graph); -void print_Graph(t_model_graph* model_graph); -void Check_Graph(t_model_graph* model_graph); -int ModelBlock_Graph(Model_Block *ModelBlock, int Blck_num,bool dynamic, t_model_graph* model_graph, int nb_endo, int *block_u_count, int *starting_vertex, int* periods, int *nb_table_y, int *mean_var_in_equ); -#endif