- Correction of several bugs
- normalize an equation linear in its endogenous variable - Chained rule derivatives (necessary to reduce a block to the feedback equations and variables) git-svn-id: https://www.dynare.org/svn/dynare/trunk@2726 ac1d8469-bf42-47a9-8791-bf33cf982152issue#70
parent
518c5fba93
commit
3737c1aa2e
|
@ -17,7 +17,6 @@
|
|||
* along with Dynare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
|
@ -38,20 +37,22 @@ 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
|
||||
|
@ -110,7 +111,6 @@ BlockTriangular::Prologue_Epilogue(bool* IM, int &prologue, int &epilogue, int n
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Find a matching between equations and endogenous variables
|
||||
bool
|
||||
|
@ -118,7 +118,6 @@ BlockTriangular::Compute_Normalization(bool *IM, int equation_number, int prolog
|
|||
{
|
||||
int n = equation_number - prologue - epilogue;
|
||||
|
||||
|
||||
typedef adjacency_list<vecS, vecS, undirectedS> BipartiteGraph;
|
||||
|
||||
/*
|
||||
|
@ -132,7 +131,6 @@ BlockTriangular::Compute_Normalization(bool *IM, int equation_number, int prolog
|
|||
if (IM0[(i+prologue) * equation_number+j+prologue])
|
||||
add_edge(i + n, j, g);
|
||||
|
||||
|
||||
// Compute maximum cardinality matching
|
||||
typedef vector<graph_traits<BipartiteGraph>::vertex_descriptor> mate_map_t;
|
||||
mate_map_t mate_map(2*n);
|
||||
|
@ -169,9 +167,62 @@ BlockTriangular::Compute_Normalization(bool *IM, int equation_number, int prolog
|
|||
return check;
|
||||
}
|
||||
|
||||
t_vtype
|
||||
BlockTriangular::Get_Variable_LeadLag_By_Block(vector<int > &components_set, int nb_blck_sim, int prologue, int epilogue) const
|
||||
{
|
||||
int nb_endo = symbol_table.endo_nbr();
|
||||
vector<int> 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<int> &Index_Equ_IM, vector<int> &Index_Var_IM, vector<pair<int, int> > &blocks, t_etype &Equation_Type, bool verbose_) const
|
||||
{
|
||||
t_vtype V_Variable_Type;
|
||||
int n = nb_var - prologue - epilogue;
|
||||
bool *AMp;
|
||||
AMp = (bool *) malloc(n*n*sizeof(bool));
|
||||
|
@ -204,6 +255,7 @@ BlockTriangular::Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Blo
|
|||
components_set[component[i]].first.insert(i);
|
||||
}
|
||||
|
||||
V_Variable_Type = Get_Variable_LeadLag_By_Block(component, num, prologue, epilogue);
|
||||
|
||||
vector<int> tmp_Index_Equ_IM(Index_Equ_IM), tmp_Index_Var_IM(Index_Var_IM);
|
||||
int order = prologue;
|
||||
|
@ -211,9 +263,9 @@ BlockTriangular::Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Blo
|
|||
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
|
||||
//Add a loop on vertices which could not be normalized or vertices related to lead variables => force those vertices to belong to the feedback set
|
||||
for (int i = 0; i < n; i++)
|
||||
if(Equation_Type[Index_Equ_IM[i+prologue]].first == E_SOLVE or Equation_Type[Index_Equ_IM[i+prologue]].first == E_EVALUATE_S)
|
||||
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
|
||||
|
@ -260,8 +312,6 @@ 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].Size = size;
|
||||
|
@ -272,12 +322,7 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
|
|||
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].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));
|
||||
|
@ -287,7 +332,6 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
|
|||
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));
|
||||
memset(tmp_size_exo, 0, (incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1)*sizeof(int));
|
||||
|
@ -308,7 +352,14 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
|
|||
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++)
|
||||
{
|
||||
|
@ -395,7 +446,6 @@ 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));
|
||||
|
||||
|
||||
tmp_exo = (int *) malloc(symbol_table.exo_nbr() * sizeof(int));
|
||||
memset(tmp_exo, 0, symbol_table.exo_nbr() * sizeof(int));
|
||||
tmp_nb_exo = 0;
|
||||
|
@ -429,7 +479,6 @@ 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));
|
||||
k = 0;
|
||||
|
@ -577,22 +626,19 @@ 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);
|
||||
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*/)
|
||||
|
@ -646,43 +692,41 @@ BlockTriangular::Equation_Type_determination(vector<BinaryOpNode *> &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<pair<int, int>, 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<pair<int, int> > result;
|
||||
//result.clear();
|
||||
pair<bool, NodeID> res;
|
||||
derivative->second->collectEndogenous(result);
|
||||
/*for(set<pair<int, int> >::const_iterator iitt = result.begin(); iitt!=result.end(); iitt++)
|
||||
cout << "result = " << iitt->first << ", " << iitt->second << "\n";*/
|
||||
set<pair<int, int> >::const_iterator d_endo_variable = result.find(make_pair(var, 0));
|
||||
//Determine whether the equation could be evaluated rather than to be solved
|
||||
if (tmp_output.str() == tmp_s.str() and d_endo_variable == result.end())
|
||||
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())
|
||||
{
|
||||
Equation_Simulation_Type = E_EVALUATE_R;
|
||||
//cout << "Equation " << eq << " is reversed\n";
|
||||
Equation_Simulation_Type = E_EVALUATE;
|
||||
}
|
||||
else
|
||||
{ //the equation could be normalized using the derivative independant of the endogenous variable
|
||||
if (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_S;
|
||||
Var_To_Derivate = var;
|
||||
//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<BinaryOpNode *>(res.second));
|
||||
}
|
||||
return (V_Equation_Simulation_Type);
|
||||
}
|
||||
|
@ -763,7 +807,7 @@ BlockTriangular::Reduce_Blocks_and_type_determination(int prologue, int epilogue
|
|||
}
|
||||
if (Blck_Size == 1)
|
||||
{
|
||||
if(Equation_Type[Index_Equ_IM[eq]].first==E_EVALUATE or Equation_Type[Index_Equ_IM[eq]].first==E_EVALUATE_R)
|
||||
if (Equation_Type[Index_Equ_IM[eq]].first == E_EVALUATE /*or Equation_Type[Index_Equ_IM[eq]].first==E_EVALUATE_R*/ or Equation_Type[Index_Equ_IM[eq]].first == E_EVALUATE_S)
|
||||
{
|
||||
if (Simulation_Type == SOLVE_BACKWARD_SIMPLE)
|
||||
Simulation_Type = EVALUATE_BACKWARD;
|
||||
|
@ -795,7 +839,6 @@ BlockTriangular::Reduce_Blocks_and_type_determination(int prologue, int epilogue
|
|||
return (Type);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BlockTriangular::Normalize_and_BlockDecompose(bool *IM, Model_Block *ModelBlock, int n, int &prologue, int &epilogue, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM, bool *IM_0, jacob_map &j_m, vector<BinaryOpNode *> &equations, t_etype &V_Equation_Type, map<pair<int, int >, NodeID> &first_cur_endo_derivatives)
|
||||
{
|
||||
|
@ -824,6 +867,7 @@ BlockTriangular::Normalize_and_BlockDecompose(bool* IM, Model_Block* ModelBlock,
|
|||
free(max_val);
|
||||
bool OK = false;
|
||||
double bi = 0.99999999;
|
||||
//double bi=1e-13;
|
||||
int suppressed = 0;
|
||||
vector<int> Index_Equ_IM_save(Index_Equ_IM);
|
||||
while (!OK && bi > 1e-14)
|
||||
|
@ -858,14 +902,13 @@ BlockTriangular::Normalize_and_BlockDecompose(bool* IM, Model_Block* ModelBlock,
|
|||
suppressed = suppress;
|
||||
if (!OK)
|
||||
//bi/=1.07;
|
||||
bi/=3;
|
||||
bi /= 2;
|
||||
counted++;
|
||||
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);
|
||||
|
@ -898,14 +941,15 @@ 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);
|
||||
|
||||
count_Equ = count_Block = 0;
|
||||
|
||||
for (t_type::const_iterator it = Type.begin(); it != Type.end(); it++)
|
||||
{
|
||||
if (count_Equ < prologue)
|
||||
|
@ -921,7 +965,6 @@ 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
|
||||
|
|
|
@ -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<pair<int ,int >,double> jacob_map;
|
||||
|
||||
typedef vector<pair<BlockSimulationType, pair<int, int> > > t_type;
|
||||
|
||||
typedef vector<pair<EquationType, int> > t_etype;
|
||||
//! Vector describing equations: BlockSimulationType, if BlockSimulationType == EVALUATE_s then a NodeID on the new normalized equation
|
||||
typedef vector<pair<EquationType, NodeID > > t_etype;
|
||||
|
||||
//! Vector describing variables: max_lag in the block, max_lead in the block
|
||||
typedef vector<pair< int, int> > 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<int> &Index_Var_IM) const;
|
||||
//! Decomposes into recurive blocks the non purely recursive equations and determines for each block the minimum feedback variables
|
||||
void Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Block(bool *IM, int nb_var, int prologue, int epilogue, vector<int> &Index_Equ_IM, vector<int> &Index_Var_IM, vector<pair<int, int> > &blocks, t_etype &Equation_Type, bool verbose_) const;
|
||||
//! 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<BinaryOpNode *> &equations, map<pair<int, int >, NodeID> &first_cur_endo_derivatives, vector<int> &Index_Var_IM, vector<int> &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<pair<int, int> > &blocks, vector<BinaryOpNode *> &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<int > &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<BinaryOpNode *> &equations, t_etype &V_Equation_Type, map<pair<int, int >, NodeID> &first_cur_endo_derivatives);
|
||||
void Normalize_and_BlockDecompose(bool* IM, Model_Block* ModelBlock, int n, int &prologue, int &epilogue, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM, bool* IM_0 , jacob_map &j_m, vector<BinaryOpNode *> &equations, t_etype &equation_simulation_type, map<pair<int, int >, NodeID> &first_cur_endo_derivatives);
|
||||
vector<int> Index_Equ_IM;
|
||||
vector<int> 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 "
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
461
DynamicModel.cc
461
DynamicModel.cc
|
@ -43,7 +43,7 @@ DynamicModel::DynamicModel(SymbolTable &symbol_table_arg,
|
|||
dynJacobianColsNbr(0),
|
||||
cutoff(1e-15),
|
||||
markowitz(0.7),
|
||||
block_triangular(symbol_table_arg)
|
||||
block_triangular(symbol_table_arg, num_constants_arg)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,8 @@ 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)));
|
||||
//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
|
||||
|
@ -77,7 +78,7 @@ DynamicModel::BuildIncidenceMatrix()
|
|||
Id->collectEndogenous(endogenous);
|
||||
for (set<pair<int, int> >::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<pair<int, int> >::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++)
|
||||
{
|
||||
|
@ -227,20 +235,28 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
|||
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();
|
||||
//temporary_terms_type::const_iterator it_temp=temporary_terms.begin();
|
||||
int nze, nze_exo, nze_other_endo;
|
||||
map<int, NodeID> recursive_variables;
|
||||
vector<int> 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_Other_Endo+ModelBlock->Block_List[j].Max_Lag_Other_Endo;m++)
|
||||
/*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);
|
||||
|
@ -252,19 +268,19 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
|||
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)
|
||||
/*||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";
|
||||
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, g1, g2, g3, varargout] = " << dynamic_basename << "_" << j+1 << "(y, x, params, it_, jacobian_eval)\n";
|
||||
output << "function [residual, y, 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 << "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
|
||||
|
@ -274,26 +290,45 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
|||
//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)
|
||||
/*||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 << " 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_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";
|
||||
{
|
||||
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].Size << ", " << nze << ");\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 << ", " << 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";
|
||||
}
|
||||
|
||||
|
@ -306,17 +341,16 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
|||
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)
|
||||
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 = [];\n";
|
||||
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";
|
||||
|
@ -324,8 +358,7 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
|||
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)
|
||||
if (ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD || ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD )
|
||||
sps = " ";
|
||||
else
|
||||
sps="";
|
||||
|
@ -347,7 +380,7 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
|||
tt2.insert(*it);
|
||||
output << ";" << endl;
|
||||
}
|
||||
string sModel = symbol_table.getName(ModelBlock->Block_List[j].Variable[i]) ;
|
||||
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();
|
||||
|
@ -367,35 +400,46 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
|||
output << " = ";
|
||||
rhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms);
|
||||
}
|
||||
else if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE_R)
|
||||
/*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(-1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
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;*/
|
||||
break;
|
||||
case SOLVE_BACKWARD_SIMPLE:
|
||||
case SOLVE_FORWARD_SIMPLE:
|
||||
case SOLVE_BACKWARD_COMPLETE:
|
||||
case SOLVE_FORWARD_COMPLETE:
|
||||
if (i<ModelBlock->Block_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 << ") = (";
|
||||
|
@ -403,10 +447,17 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
|||
case SOLVE_TWO_BOUNDARIES_COMPLETE:
|
||||
case SOLVE_TWO_BOUNDARIES_SIMPLE:
|
||||
if (i<ModelBlock->Block_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 << ", it_)";
|
||||
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:
|
||||
|
@ -435,8 +486,8 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
|||
{
|
||||
case EVALUATE_BACKWARD:
|
||||
case EVALUATE_FORWARD:
|
||||
case EVALUATE_BACKWARD_R:
|
||||
case EVALUATE_FORWARD_R:
|
||||
/*case EVALUATE_BACKWARD_R:
|
||||
case EVALUATE_FORWARD_R:*/
|
||||
count_derivates++;
|
||||
for (m=0;m<ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag+1;m++)
|
||||
{
|
||||
|
@ -450,7 +501,7 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
|||
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)
|
||||
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;
|
||||
|
@ -488,7 +539,7 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
|||
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)
|
||||
output << "; % variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, var))
|
||||
<< "(" << k << ") " << var+1
|
||||
<< ", equation=" << eq+1 << endl;
|
||||
}
|
||||
|
@ -497,6 +548,7 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
|||
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:
|
||||
|
@ -513,12 +565,11 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
|||
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 << ") = ";
|
||||
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(var)
|
||||
<< "(" << k
|
||||
<< ") " << var+1
|
||||
output << "; % variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, var))
|
||||
<< "(" << k << ") " << var+1
|
||||
<< ", equation=" << eq+1 << endl;
|
||||
}
|
||||
}
|
||||
|
@ -549,10 +600,10 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
|||
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 << ", "
|
||||
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(var)
|
||||
output << "; % variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, var))
|
||||
<< "(" << k << ") " << var+1
|
||||
<< ", equation=" << eq+1 << endl;
|
||||
}
|
||||
|
@ -563,19 +614,77 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
|||
output << " else" << endl;
|
||||
|
||||
m=ModelBlock->Block_List[j].Max_Lag;
|
||||
//cout << "\nDerivatives in Block " << j << "\n";
|
||||
for (i=0;i<ModelBlock->Block_List[j].IM_lead_lag[m].size;i++)
|
||||
{
|
||||
int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index[i];
|
||||
int var=ModelBlock->Block_List[j].IM_lead_lag[m].Var_Index[i];
|
||||
int 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 << ") = ";
|
||||
bool derivative_exist;
|
||||
ostringstream tmp_output;
|
||||
if (eqr<ModelBlock->Block_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<int, NodeID> 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 (eqr<ModelBlock->Block_List[j].Nb_Recursives or 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), 0, oMatlabDynamicModelSparse, temporary_terms);
|
||||
output << "; % variable=" << symbol_table.getName(var)
|
||||
<< "(0) " << var+1
|
||||
<< ", equation=" << eq+1 << endl;
|
||||
<< ", equation=" << eq+1 << endl;*/
|
||||
}
|
||||
output << " end;\n";
|
||||
//output << " ya = y;\n";
|
||||
break;
|
||||
case SOLVE_TWO_BOUNDARIES_SIMPLE:
|
||||
case SOLVE_TWO_BOUNDARIES_COMPLETE:
|
||||
|
@ -589,26 +698,157 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
|||
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 (eqr<ModelBlock->Block_List[j].Nb_Recursives)
|
||||
{
|
||||
/*if (varr<ModelBlock->Block_List[j].Nb_Recursives)
|
||||
{
|
||||
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 << ")";
|
||||
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(" << eqr+1 << "+Per_J_, " << varr+1 << "+y_size*(it_+" << k-1 << "))*y(it_+" << k << ", " << var+1 << ")";
|
||||
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(" << eqr+1 << "+Per_J_, " << varr+1 << "+y_size*(it_" << k-1 << "))*y(it_" << k << ", " << var+1 << ")";
|
||||
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)
|
||||
output << " g1(" << eqr+1 << "+Per_J_, " << varr+1 << "+Per_K_) = ";
|
||||
else if (k==1)
|
||||
output << " g1(" << eqr+1 << "+Per_J_, " << varr+1 << "+Per_y_) = ";
|
||||
tmp_output << " g1_tmp_r(" << eqr+1 << ", "
|
||||
<< varr+1 << "+" << ModelBlock->Block_List[j].Size << "*" << ModelBlock->Block_List[j].Max_Lag << ") = ";
|
||||
else if (k>0)
|
||||
output << " g1(" << eqr+1 << "+Per_J_, " << varr+1 << "+y_size*(it_+" << k-1 << ")) = ";
|
||||
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)
|
||||
output << " g1(" << eqr+1 << "+Per_J_, " << varr+1 << "+y_size*(it_" << k-1 << ")) = ";
|
||||
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<int, NodeID> 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 << "; % variable=" << symbol_table.getName(var)
|
||||
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;
|
||||
}*/
|
||||
}
|
||||
|
||||
#ifdef CONDITION
|
||||
output << " if (fabs(condition[" << eqr << "])<fabs(u[" << u << "+Per_u_]))\n";
|
||||
output << " condition(" << eqr << ")=u(" << u << "+Per_u_);\n";
|
||||
|
@ -617,6 +857,7 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
|||
}
|
||||
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 << "))<fabs(u(" << i << "+Per_u_)))\n";
|
||||
|
@ -652,7 +893,7 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
|||
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)
|
||||
output << "; % variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, var))
|
||||
<< "(" << k << ") " << var+1
|
||||
<< ", equation=" << eq+1 << endl;
|
||||
}
|
||||
|
@ -689,7 +930,7 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
|||
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)
|
||||
output << "; % variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, var))
|
||||
<< "(" << k << ") " << var+1
|
||||
<< ", equation=" << eq+1 << endl;
|
||||
}
|
||||
|
@ -698,6 +939,7 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
|||
output << " varargout{1}=g1_x;\n";
|
||||
output << " varargout{2}=g1_o;\n";
|
||||
output << " end;\n";
|
||||
//output << " ya = y;\n";
|
||||
output << " end;\n";
|
||||
break;
|
||||
default:
|
||||
|
@ -736,7 +978,7 @@ DynamicModel::writeModelEquationsCodeOrdered(const string file_name, const Model
|
|||
int prev_Simulation_Type=-1;
|
||||
//SymbolicGaussElimination SGE;
|
||||
bool file_open=false;
|
||||
temporary_terms_type::const_iterator it_temp=temporary_terms.begin();
|
||||
//temporary_terms_type::const_iterator it_temp=temporary_terms.begin();
|
||||
//----------------------------------------------------------------------
|
||||
string main_name=file_name;
|
||||
main_name+=".cod";
|
||||
|
@ -758,8 +1000,8 @@ DynamicModel::writeModelEquationsCodeOrdered(const string file_name, const Model
|
|||
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 ))
|
||||
/*||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD_R
|
||||
||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD_R */))
|
||||
{
|
||||
}
|
||||
else
|
||||
|
@ -875,14 +1117,26 @@ DynamicModel::writeModelEquationsCodeOrdered(const string file_name, const Model
|
|||
{
|
||||
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_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;
|
||||
break;*/
|
||||
case SOLVE_BACKWARD_COMPLETE:
|
||||
case SOLVE_FORWARD_COMPLETE:
|
||||
v=ModelBlock->Block_List[j].Equation[i];
|
||||
|
@ -914,8 +1168,8 @@ DynamicModel::writeModelEquationsCodeOrdered(const string file_name, const Model
|
|||
// 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)
|
||||
/*&& 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)
|
||||
{
|
||||
|
@ -1357,8 +1611,8 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
|
|||
{
|
||||
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)))
|
||||
((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("");
|
||||
|
@ -1372,7 +1626,7 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
|
|||
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 (k==EVALUATE_FORWARD || k==EVALUATE_BACKWARD /*|| k==EVALUATE_FORWARD_R || k==EVALUATE_BACKWARD_R*/)
|
||||
{
|
||||
if (i==block_triangular.ModelBlock->Size-1)
|
||||
{
|
||||
|
@ -1385,7 +1639,7 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
|
|||
}
|
||||
}
|
||||
if (BlockTriangular::BlockSim(prev_Simulation_Type)==BlockTriangular::BlockSim(k) &&
|
||||
(k==EVALUATE_FORWARD || k==EVALUATE_BACKWARD || k==EVALUATE_FORWARD_R || k==EVALUATE_BACKWARD_R))
|
||||
(k==EVALUATE_FORWARD || k==EVALUATE_BACKWARD /*|| k==EVALUATE_FORWARD_R || k==EVALUATE_BACKWARD_R*/))
|
||||
skip_head=true;
|
||||
else
|
||||
skip_head=false;
|
||||
|
@ -1393,8 +1647,8 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
|
|||
{
|
||||
case EVALUATE_FORWARD:
|
||||
case EVALUATE_BACKWARD:
|
||||
case EVALUATE_FORWARD_R:
|
||||
case EVALUATE_BACKWARD_R:
|
||||
/*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";
|
||||
|
@ -1439,7 +1693,7 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
|
|||
/*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";
|
||||
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
|
||||
|
@ -1484,11 +1738,11 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
|
|||
{
|
||||
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))
|
||||
(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 ((k == EVALUATE_FORWARD /*|| k == EVALUATE_FORWARD_R*/) && (block_triangular.ModelBlock->Block_List[i].Size))
|
||||
{
|
||||
if (!skip_head)
|
||||
{
|
||||
|
@ -1510,10 +1764,15 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
|
|||
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))
|
||||
else if ((k == EVALUATE_BACKWARD /*|| k == EVALUATE_BACKWARD_R*/) && (block_triangular.ModelBlock->Block_List[i].Size))
|
||||
{
|
||||
if (!skip_head)
|
||||
{
|
||||
|
@ -1534,6 +1793,11 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
|
|||
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))
|
||||
|
@ -1561,7 +1825,11 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
|
|||
", 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";
|
||||
|
||||
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))
|
||||
{
|
||||
|
@ -1573,6 +1841,7 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
|
|||
tmp.str("");
|
||||
for (int ik=0;ik<block_triangular.ModelBlock->Block_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";
|
||||
|
@ -1588,6 +1857,11 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
|
|||
", 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";
|
||||
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))
|
||||
{
|
||||
|
@ -1601,6 +1875,7 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
|
|||
mDynamicModelFile << " y_index=[";
|
||||
for (int ik=0;ik<block_triangular.ModelBlock->Block_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";
|
||||
|
@ -1615,7 +1890,11 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
|
|||
", " << 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;
|
||||
}
|
||||
|
|
585
ExprNode.cc
585
ExprNode.cc
|
@ -60,6 +60,32 @@ ExprNode::getDerivative(int deriv_id)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
NodeID
|
||||
ExprNode::getChaineRuleDerivative(int deriv_id, map<int, NodeID> &recursive_variables, int var, int lag_)
|
||||
{
|
||||
// Return zero if derivative is necessarily null (using symbolic a priori)
|
||||
/*set<int>::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<int, NodeID>::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
|
||||
{
|
||||
|
@ -94,12 +120,25 @@ ExprNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
|
|||
// 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)
|
||||
{
|
||||
writeOutput(output, oMatlabOutsideModel, temporary_terms_type());
|
||||
}
|
||||
|
||||
pair<bool, NodeID>
|
||||
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),
|
||||
|
@ -129,6 +168,7 @@ void
|
|||
NumConstNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
||||
const temporary_terms_type &temporary_terms) const
|
||||
{
|
||||
//cout << "writeOutput constante\n";
|
||||
temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<NumConstNode *>(this));
|
||||
if (it != temporary_terms.end())
|
||||
if (output_type == oMatlabDynamicModelSparse)
|
||||
|
@ -166,6 +206,27 @@ NumConstNode::collectExogenous(set<pair<int, int> > &result) const
|
|||
{
|
||||
}
|
||||
|
||||
pair<bool, NodeID>
|
||||
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<int, NodeID> &recursive_variables, int var, int lag_)
|
||||
{
|
||||
return datatree.Zero;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
pair<bool, NodeID>
|
||||
NumConstNode::computeDerivativeRespectToFeedbackVariable(int equ, int var, int varr, int lag_, int max_lag, vector<int> &recursive_variables, vector<int> &feeback_variables) const
|
||||
{
|
||||
return(make_pair(false, datatree.Zero));
|
||||
}
|
||||
*/
|
||||
|
||||
NodeID
|
||||
NumConstNode::toStatic(DataTree &static_datatree) const
|
||||
{
|
||||
|
@ -251,7 +312,7 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
|||
{
|
||||
// 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<VariableNode *>(this));
|
||||
if (it != temporary_terms.end())
|
||||
|
@ -428,15 +489,20 @@ VariableNode::compile(ofstream &CompileCode, bool lhs_rhs, const temporary_terms
|
|||
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:
|
||||
//cout << "Parameter=" << tsid << "\n";
|
||||
i = tsid;
|
||||
CompileCode.write(reinterpret_cast<char *>(&i), sizeof(i));
|
||||
#ifdef DEBUGC
|
||||
|
@ -444,12 +510,14 @@ VariableNode::compile(ofstream &CompileCode, bool lhs_rhs, const temporary_terms
|
|||
#endif
|
||||
break;
|
||||
case eEndogenous :
|
||||
i = symb_id;
|
||||
//cout << "Endogenous=" << symb_id << "\n";
|
||||
i = tsid;//symb_id;
|
||||
CompileCode.write(reinterpret_cast<char *>(&i), sizeof(i));
|
||||
lagl=lag;
|
||||
CompileCode.write(reinterpret_cast<char *>(&lagl), sizeof(lagl));
|
||||
break;
|
||||
case eExogenous :
|
||||
//cout << "Exogenous=" << tsid << "\n";
|
||||
i = tsid;
|
||||
CompileCode.write(reinterpret_cast<char *>(&i), sizeof(i));
|
||||
lagl=lag;
|
||||
|
@ -457,12 +525,14 @@ VariableNode::compile(ofstream &CompileCode, bool lhs_rhs, const temporary_terms
|
|||
break;
|
||||
case eExogenousDet:
|
||||
i = tsid + datatree.symbol_table.exo_nbr();
|
||||
//cout << "ExogenousDet=" << i << "\n";
|
||||
CompileCode.write(reinterpret_cast<char *>(&i), sizeof(i));
|
||||
lagl=lag;
|
||||
CompileCode.write(reinterpret_cast<char *>(&lagl), sizeof(lagl));
|
||||
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:
|
||||
|
@ -488,7 +558,7 @@ void
|
|||
VariableNode::collectEndogenous(set<pair<int, int> > &result) const
|
||||
{
|
||||
if (type == eEndogenous)
|
||||
result.insert(make_pair(symb_id, lag));
|
||||
result.insert(make_pair(datatree.symbol_table.getTypeSpecificID(symb_id), lag));
|
||||
else if (type == eModelLocalVariable)
|
||||
datatree.local_variables_table[symb_id]->collectEndogenous(result);
|
||||
}
|
||||
|
@ -497,11 +567,87 @@ void
|
|||
VariableNode::collectExogenous(set<pair<int, int> > &result) const
|
||||
{
|
||||
if (type == eExogenous)
|
||||
result.insert(make_pair(symb_id, lag));
|
||||
result.insert(make_pair(datatree.symbol_table.getTypeSpecificID(symb_id), lag));
|
||||
else if (type == eModelLocalVariable)
|
||||
datatree.local_variables_table[symb_id]->collectExogenous(result);
|
||||
}
|
||||
|
||||
pair<bool, NodeID>
|
||||
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<class InputIterator, class T>
|
||||
pair<InputIterator, int> find_r ( InputIterator first, InputIterator last, const T& value )
|
||||
{
|
||||
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<int, NodeID> &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<int, NodeID>::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
|
||||
{
|
||||
|
@ -739,6 +885,7 @@ void
|
|||
UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
||||
const temporary_terms_type &temporary_terms) const
|
||||
{
|
||||
//cout << "writeOutput unary\n";
|
||||
// If node is a temporary term
|
||||
temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<UnaryOpNode *>(this));
|
||||
if (it != temporary_terms.end())
|
||||
|
@ -918,6 +1065,127 @@ UnaryOpNode::collectExogenous(set<pair<int, int> > &result) const
|
|||
arg->collectExogenous(result);
|
||||
}
|
||||
|
||||
pair<bool, NodeID>
|
||||
UnaryOpNode::normalizeLinearInEndoEquation(int var_endo, NodeID Derivative) const
|
||||
{
|
||||
pair<bool, NodeID> 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::computeChaineRuleDerivative(int deriv_id, map<int, NodeID> &recursive_variables, int var, int lag_)
|
||||
{
|
||||
NodeID darg = arg->getChaineRuleDerivative(deriv_id, recursive_variables, var, lag_);
|
||||
|
||||
NodeID t11, t12, t13;
|
||||
|
||||
switch (op_code)
|
||||
{
|
||||
case oUminus:
|
||||
return datatree.AddUMinus(darg);
|
||||
case oExp:
|
||||
return datatree.AddTimes(darg, this);
|
||||
case oLog:
|
||||
return datatree.AddDivide(darg, arg);
|
||||
case oLog10:
|
||||
t11 = datatree.AddExp(datatree.One);
|
||||
t12 = datatree.AddLog10(t11);
|
||||
t13 = datatree.AddDivide(darg, arg);
|
||||
return datatree.AddTimes(t12, t13);
|
||||
case oCos:
|
||||
t11 = datatree.AddSin(arg);
|
||||
t12 = datatree.AddUMinus(t11);
|
||||
return datatree.AddTimes(darg, t12);
|
||||
case oSin:
|
||||
t11 = datatree.AddCos(arg);
|
||||
return datatree.AddTimes(darg, t11);
|
||||
case oTan:
|
||||
t11 = datatree.AddTimes(this, this);
|
||||
t12 = datatree.AddPlus(t11, datatree.One);
|
||||
return datatree.AddTimes(darg, t12);
|
||||
case oAcos:
|
||||
t11 = datatree.AddSin(this);
|
||||
t12 = datatree.AddDivide(darg, t11);
|
||||
return datatree.AddUMinus(t12);
|
||||
case oAsin:
|
||||
t11 = datatree.AddCos(this);
|
||||
return datatree.AddDivide(darg, t11);
|
||||
case oAtan:
|
||||
t11 = datatree.AddTimes(arg, arg);
|
||||
t12 = datatree.AddPlus(datatree.One, t11);
|
||||
return datatree.AddDivide(darg, t12);
|
||||
case oCosh:
|
||||
t11 = datatree.AddSinh(arg);
|
||||
return datatree.AddTimes(darg, t11);
|
||||
case oSinh:
|
||||
t11 = datatree.AddCosh(arg);
|
||||
return datatree.AddTimes(darg, t11);
|
||||
case oTanh:
|
||||
t11 = datatree.AddTimes(this, this);
|
||||
t12 = datatree.AddMinus(datatree.One, t11);
|
||||
return datatree.AddTimes(darg, t12);
|
||||
case oAcosh:
|
||||
t11 = datatree.AddSinh(this);
|
||||
return datatree.AddDivide(darg, t11);
|
||||
case oAsinh:
|
||||
t11 = datatree.AddCosh(this);
|
||||
return datatree.AddDivide(darg, t11);
|
||||
case oAtanh:
|
||||
t11 = datatree.AddTimes(arg, arg);
|
||||
t12 = datatree.AddMinus(datatree.One, t11);
|
||||
return datatree.AddTimes(darg, t12);
|
||||
case oSqrt:
|
||||
t11 = datatree.AddPlus(this, this);
|
||||
return datatree.AddDivide(darg, t11);
|
||||
}
|
||||
// Suppress GCC warning
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
NodeID
|
||||
UnaryOpNode::toStatic(DataTree &static_datatree) const
|
||||
{
|
||||
|
@ -1001,11 +1269,16 @@ BinaryOpNode::computeDerivative(int deriv_id)
|
|||
t12 = datatree.AddTimes(darg2, arg1);
|
||||
return datatree.AddPlus(t11, t12);
|
||||
case oDivide:
|
||||
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:
|
||||
|
@ -1303,6 +1576,7 @@ void
|
|||
BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
||||
const temporary_terms_type &temporary_terms) const
|
||||
{
|
||||
//cout << "writeOutput binary\n";
|
||||
// If current node is a temporary term
|
||||
temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<BinaryOpNode *>(this));
|
||||
if (it != temporary_terms.end())
|
||||
|
@ -1474,6 +1748,213 @@ BinaryOpNode::collectExogenous(set<pair<int, int> > &result) const
|
|||
arg2->collectExogenous(result);
|
||||
}
|
||||
|
||||
pair<bool, NodeID>
|
||||
BinaryOpNode::normalizeLinearInEndoEquation(int var_endo, NodeID Derivative) const
|
||||
{
|
||||
pair<bool, NodeID> res = arg1->normalizeLinearInEndoEquation(var_endo, Derivative);
|
||||
bool is_endogenous_present_1 = res.first;
|
||||
NodeID NodeID_1 = res.second;
|
||||
res = arg2->normalizeLinearInEndoEquation(var_endo, Derivative);
|
||||
bool is_endogenous_present_2 = res.first;
|
||||
NodeID NodeID_2 = res.second;
|
||||
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::computeChaineRuleDerivative(int deriv_id, map<int, NodeID> &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 t11, t12, t13, t14, t15;
|
||||
|
||||
switch (op_code)
|
||||
{
|
||||
case oPlus:
|
||||
return datatree.AddPlus(darg1, darg2);
|
||||
case oMinus:
|
||||
return datatree.AddMinus(darg1, darg2);
|
||||
case oTimes:
|
||||
t11 = datatree.AddTimes(darg1, arg2);
|
||||
t12 = datatree.AddTimes(darg2, arg1);
|
||||
return datatree.AddPlus(t11, t12);
|
||||
case oDivide:
|
||||
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:
|
||||
case oGreaterEqual:
|
||||
case oEqualEqual:
|
||||
case oDifferent:
|
||||
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
|
||||
{
|
||||
|
@ -1796,6 +2277,75 @@ TrinaryOpNode::collectExogenous(set<pair<int, int> > &result) const
|
|||
arg3->collectExogenous(result);
|
||||
}
|
||||
|
||||
pair<bool, NodeID>
|
||||
TrinaryOpNode::normalizeLinearInEndoEquation(int var_endo, NodeID Derivative) const
|
||||
{
|
||||
pair<bool, NodeID> res = arg1->normalizeLinearInEndoEquation(var_endo, Derivative);
|
||||
bool is_endogenous_present_1 = res.first;
|
||||
NodeID NodeID_1 = res.second;
|
||||
res = arg2->normalizeLinearInEndoEquation(var_endo, Derivative);
|
||||
bool is_endogenous_present_2 = res.first;
|
||||
NodeID NodeID_2 = res.second;
|
||||
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<int, NodeID> &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:
|
||||
// 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
|
||||
{
|
||||
|
@ -1828,6 +2378,14 @@ UnknownFunctionNode::computeDerivative(int deriv_id)
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
NodeID
|
||||
UnknownFunctionNode::computeChaineRuleDerivative(int deriv_id, map<int, NodeID> &recursive_variables, int var, int lag_)
|
||||
{
|
||||
cerr << "UnknownFunctionNode::computeDerivative: operation impossible!" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
UnknownFunctionNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
|
||||
temporary_terms_type &temporary_terms,
|
||||
|
@ -1907,6 +2465,25 @@ UnknownFunctionNode::compile(ofstream &CompileCode, bool lhs_rhs, const temporar
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
pair<bool, NodeID>
|
||||
UnknownFunctionNode::normalizeLinearInEndoEquation(int var_endo, NodeID Derivative) const
|
||||
{
|
||||
vector<pair<bool, NodeID> > V_arguments;
|
||||
vector<NodeID> V_NodeID;
|
||||
bool present = false;
|
||||
for (vector<NodeID>::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
|
||||
{
|
||||
|
|
30
ExprNode.hh
30
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<int, NodeID> &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<int, NodeID> &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<NodeID, int> &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<bool, NodeID> 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<int, NodeID> &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<bool, NodeID> 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<int, NodeID> &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<bool, NodeID> 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<int, NodeID> &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<bool, NodeID> 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<int, NodeID> &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<bool, NodeID> 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<int, NodeID> &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<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const;
|
||||
};
|
||||
|
||||
//! Unknown function node
|
||||
|
@ -352,6 +375,7 @@ private:
|
|||
const int symb_id;
|
||||
const vector<NodeID> arguments;
|
||||
virtual NodeID computeDerivative(int deriv_id);
|
||||
virtual NodeID computeChaineRuleDerivative(int deriv_id, map<int, NodeID> &recursive_variables, int var, int lag_);
|
||||
public:
|
||||
UnknownFunctionNode(DataTree &datatree_arg, int symb_id_arg,
|
||||
const vector<NodeID> &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<bool, NodeID> 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;
|
||||
|
|
|
@ -186,7 +186,6 @@ namespace MFS
|
|||
GraphvizDigraph_2_AdjacencyList(GraphvizDigraph& G1, set<int> select_index)
|
||||
{
|
||||
unsigned int n = select_index.size();
|
||||
//cout << "n=" << n << "\n";
|
||||
AdjacencyList_type G(n);
|
||||
property_map<AdjacencyList_type, vertex_index_t>::type v_index = get(vertex_index, G);
|
||||
property_map<AdjacencyList_type, vertex_index1_t>::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);
|
||||
}
|
||||
}
|
||||
}
|
||||
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<AdjacencyList_type::vertex_descriptor> 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<AdjacencyList_type::vertex_descriptor>::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<AdjacencyList_type, vertex_index_t>::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<int> &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<int> circuit;
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
#include <vector>
|
||||
#include <boost/graph/graphviz.hpp>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
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<pair<int, AdjacencyList_type::vertex_descriptor> > &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<int> 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<int> &circuit_stack);
|
||||
bool has_cylce(AdjacencyList_type& g, vector<int> &circuit_stack, int size);
|
||||
bool has_cycle(vector<int> &circuit_stack, AdjacencyList_type& G);
|
||||
//! Return the feedback set
|
||||
AdjacencyList_type Minimal_set_of_feedback_vertex(set<int> &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<int> Reorder_the_recursive_variables(const AdjacencyList_type& G1, set<int> &feed_back_vertices);
|
||||
};
|
||||
|
||||
|
|
479
ModelGraph.cc
479
ModelGraph.cc
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <ctime>
|
||||
#include <stack>
|
||||
#include <cmath>
|
||||
#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);
|
||||
}
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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
|
Loading…
Reference in New Issue