- 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/>.
|
* along with Dynare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
@ -38,20 +37,22 @@ using namespace std;
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
using namespace MFS;
|
using namespace MFS;
|
||||||
|
|
||||||
|
BlockTriangular::BlockTriangular(SymbolTable &symbol_table_arg, NumericalConstants &num_const_arg)
|
||||||
|
: symbol_table(symbol_table_arg),
|
||||||
|
//normalization(symbol_table_arg),
|
||||||
BlockTriangular::BlockTriangular(const SymbolTable &symbol_table_arg) :
|
incidencematrix(symbol_table_arg),
|
||||||
symbol_table(symbol_table_arg),
|
num_const(num_const_arg)
|
||||||
normalization(symbol_table_arg),
|
|
||||||
incidencematrix(symbol_table_arg)
|
|
||||||
{
|
{
|
||||||
bt_verbose = 0;
|
bt_verbose = 0;
|
||||||
ModelBlock = NULL;
|
ModelBlock = NULL;
|
||||||
periods = 0;
|
periods = 0;
|
||||||
|
Normalized_Equation = new DataTree(symbol_table, num_const);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BlockTriangular::~BlockTriangular()
|
||||||
|
{
|
||||||
|
delete Normalized_Equation;
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Find the prologue and the epilogue of the model
|
// 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
|
// Find a matching between equations and endogenous variables
|
||||||
bool
|
bool
|
||||||
|
@ -118,7 +118,6 @@ BlockTriangular::Compute_Normalization(bool *IM, int equation_number, int prolog
|
||||||
{
|
{
|
||||||
int n = equation_number - prologue - epilogue;
|
int n = equation_number - prologue - epilogue;
|
||||||
|
|
||||||
|
|
||||||
typedef adjacency_list<vecS, vecS, undirectedS> BipartiteGraph;
|
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])
|
if (IM0[(i+prologue) * equation_number+j+prologue])
|
||||||
add_edge(i + n, j, g);
|
add_edge(i + n, j, g);
|
||||||
|
|
||||||
|
|
||||||
// Compute maximum cardinality matching
|
// Compute maximum cardinality matching
|
||||||
typedef vector<graph_traits<BipartiteGraph>::vertex_descriptor> mate_map_t;
|
typedef vector<graph_traits<BipartiteGraph>::vertex_descriptor> mate_map_t;
|
||||||
mate_map_t mate_map(2*n);
|
mate_map_t mate_map(2*n);
|
||||||
|
@ -169,9 +167,62 @@ BlockTriangular::Compute_Normalization(bool *IM, int equation_number, int prolog
|
||||||
return check;
|
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
|
void
|
||||||
BlockTriangular::Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Block(bool *IM, int nb_var, int prologue, int epilogue, vector<int> &Index_Equ_IM, vector<int> &Index_Var_IM, vector<pair<int, int> > &blocks, t_etype &Equation_Type, bool verbose_) const
|
BlockTriangular::Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Block(bool *IM, int nb_var, int prologue, int epilogue, vector<int> &Index_Equ_IM, vector<int> &Index_Var_IM, vector<pair<int, int> > &blocks, t_etype &Equation_Type, bool verbose_) const
|
||||||
{
|
{
|
||||||
|
t_vtype V_Variable_Type;
|
||||||
int n = nb_var - prologue - epilogue;
|
int n = nb_var - prologue - epilogue;
|
||||||
bool *AMp;
|
bool *AMp;
|
||||||
AMp = (bool *) malloc(n*n*sizeof(bool));
|
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);
|
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);
|
vector<int> tmp_Index_Equ_IM(Index_Equ_IM), tmp_Index_Var_IM(Index_Var_IM);
|
||||||
int order = prologue;
|
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));
|
SIM = (bool *) malloc(nb_var*nb_var*sizeof(bool));
|
||||||
memcpy(SIM, IM, 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++)
|
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);
|
add_edge(i, i, G2);
|
||||||
|
|
||||||
//For each block, the minimum set of feedback variable is computed
|
//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;
|
bool *IM, OK;
|
||||||
int Lag_Endo, Lead_Endo, Lag_Exo, Lead_Exo, Lag_Other_Endo, Lead_Other_Endo;
|
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->Periods = periods;
|
||||||
ModelBlock->Block_List[count_Block].is_linear = true;
|
ModelBlock->Block_List[count_Block].is_linear = true;
|
||||||
ModelBlock->Block_List[count_Block].Size = size;
|
ModelBlock->Block_List[count_Block].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].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 = (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 = (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));
|
ModelBlock->Block_List[count_Block].Equation_Normalized = (NodeID *) malloc(ModelBlock->Block_List[count_Block].Size * sizeof(NodeID));
|
||||||
/*cout << "ModelBlock->Block_List[" << count_Block << "].Size = " << ModelBlock->Block_List[count_Block].Size << " E_UNKNOWN=" << E_UNKNOWN << "\n";
|
|
||||||
t_etype eType(size);
|
|
||||||
cout << "eType[0].first=" << eType[0].first << " eType[0].second=" << eType[0].second << " eType.size()=" << eType.size() << "\n";
|
|
||||||
ModelBlock->Block_List[count_Block].Equation_Type(eType);
|
|
||||||
cout << "after that\n";*/
|
|
||||||
ModelBlock->Block_List[count_Block].Variable = (int *) malloc(ModelBlock->Block_List[count_Block].Size * sizeof(int));
|
ModelBlock->Block_List[count_Block].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].Temporary_Terms_in_Equation = (temporary_terms_type **) malloc(ModelBlock->Block_List[count_Block].Size * sizeof(temporary_terms_type));
|
||||||
ModelBlock->Block_List[count_Block].Own_Derivative = (int *) malloc(ModelBlock->Block_List[count_Block].Size * sizeof(int));
|
ModelBlock->Block_List[count_Block].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_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_other_endo = (int *) malloc(symbol_table.endo_nbr() * sizeof(int));
|
||||||
tmp_size = (int *) malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1) * sizeof(int));
|
tmp_size = (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_other_endo = (int *) malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1) * sizeof(int));
|
||||||
tmp_size_exo = (int *) malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1) * sizeof(int));
|
tmp_size_exo = (int *) malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1) * sizeof(int));
|
||||||
memset(tmp_size_exo, 0, (incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1)*sizeof(int));
|
memset(tmp_size_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].Equation[i] = Index_Equ_IM[*count_Equ];
|
||||||
ModelBlock->Block_List[count_Block].Variable[i] = Index_Var_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[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];
|
i_1 = Index_Var_IM[*count_Equ];
|
||||||
for (k = -incidencematrix.Model_Max_Lag_Endo; k <= incidencematrix.Model_Max_Lead_Endo; k++)
|
for (k = -incidencematrix.Model_Max_Lag_Endo; k <= incidencematrix.Model_Max_Lead_Endo; k++)
|
||||||
{
|
{
|
||||||
|
@ -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].nb_other_endo = tmp_nb_other_endo;
|
||||||
ModelBlock->Block_List[count_Block].Other_Endogenous = (int *) malloc(tmp_nb_other_endo * sizeof(int));
|
ModelBlock->Block_List[count_Block].Other_Endogenous = (int *) malloc(tmp_nb_other_endo * sizeof(int));
|
||||||
|
|
||||||
|
|
||||||
tmp_exo = (int *) malloc(symbol_table.exo_nbr() * sizeof(int));
|
tmp_exo = (int *) malloc(symbol_table.exo_nbr() * sizeof(int));
|
||||||
memset(tmp_exo, 0, symbol_table.exo_nbr() * sizeof(int));
|
memset(tmp_exo, 0, symbol_table.exo_nbr() * sizeof(int));
|
||||||
tmp_nb_exo = 0;
|
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].nb_exo = tmp_nb_exo;
|
||||||
ModelBlock->Block_List[count_Block].Exogenous = (int *) malloc(tmp_nb_exo * sizeof(int));
|
ModelBlock->Block_List[count_Block].Exogenous = (int *) malloc(tmp_nb_exo * sizeof(int));
|
||||||
k = 0;
|
k = 0;
|
||||||
|
@ -577,22 +626,19 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
|
||||||
free(tmp_variable_evaluated);
|
free(tmp_variable_evaluated);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BlockTriangular::Free_Block(Model_Block *ModelBlock) const
|
BlockTriangular::Free_Block(Model_Block *ModelBlock) const
|
||||||
{
|
{
|
||||||
int blk, i;
|
int blk, i;
|
||||||
for (blk = 0; blk < ModelBlock->Size; blk++)
|
for (blk = 0; blk < ModelBlock->Size; blk++)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
free(ModelBlock->Block_List[blk].Equation);
|
free(ModelBlock->Block_List[blk].Equation);
|
||||||
free(ModelBlock->Block_List[blk].Variable);
|
free(ModelBlock->Block_List[blk].Variable);
|
||||||
free(ModelBlock->Block_List[blk].Exogenous);
|
free(ModelBlock->Block_List[blk].Exogenous);
|
||||||
free(ModelBlock->Block_List[blk].Own_Derivative);
|
free(ModelBlock->Block_List[blk].Own_Derivative);
|
||||||
free(ModelBlock->Block_List[blk].Other_Endogenous);
|
free(ModelBlock->Block_List[blk].Other_Endogenous);
|
||||||
free(ModelBlock->Block_List[blk].Equation_Type);
|
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++)
|
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*/)
|
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();
|
lhs = eq_node->get_arg1();
|
||||||
rhs = eq_node->get_arg2();
|
rhs = eq_node->get_arg2();
|
||||||
Equation_Simulation_Type = E_SOLVE;
|
Equation_Simulation_Type = E_SOLVE;
|
||||||
int Var_To_Derivate = -1;
|
|
||||||
tmp_s.str("");
|
tmp_s.str("");
|
||||||
tmp_output.str("");
|
tmp_output.str("");
|
||||||
lhs->writeOutput(tmp_output, oMatlabDynamicModelSparse, temporary_terms);
|
lhs->writeOutput(tmp_output, oMatlabDynamicModelSparse, temporary_terms);
|
||||||
tmp_s << "y(it_, " << Index_Var_IM[i]+1 << ")";
|
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));
|
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;
|
set<pair<int, int> > result;
|
||||||
//result.clear();
|
pair<bool, NodeID> res;
|
||||||
derivative->second->collectEndogenous(result);
|
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));
|
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
|
//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())
|
if (tmp_output.str() == tmp_s.str() and d_endo_variable == result.end())
|
||||||
{
|
{
|
||||||
Equation_Simulation_Type = E_EVALUATE_R;
|
Equation_Simulation_Type = E_EVALUATE;
|
||||||
//cout << "Equation " << eq << " is reversed\n";
|
|
||||||
}
|
}
|
||||||
else
|
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;
|
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";*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
V_Equation_Simulation_Type[eq] = make_pair(Equation_Simulation_Type, dynamic_cast<BinaryOpNode *>(res.second));
|
||||||
/*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);
|
|
||||||
}
|
}
|
||||||
return (V_Equation_Simulation_Type);
|
return (V_Equation_Simulation_Type);
|
||||||
}
|
}
|
||||||
|
@ -763,7 +807,7 @@ BlockTriangular::Reduce_Blocks_and_type_determination(int prologue, int epilogue
|
||||||
}
|
}
|
||||||
if (Blck_Size == 1)
|
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)
|
if (Simulation_Type == SOLVE_BACKWARD_SIMPLE)
|
||||||
Simulation_Type = EVALUATE_BACKWARD;
|
Simulation_Type = EVALUATE_BACKWARD;
|
||||||
|
@ -795,7 +839,6 @@ BlockTriangular::Reduce_Blocks_and_type_determination(int prologue, int epilogue
|
||||||
return (Type);
|
return (Type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
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)
|
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);
|
free(max_val);
|
||||||
bool OK = false;
|
bool OK = false;
|
||||||
double bi = 0.99999999;
|
double bi = 0.99999999;
|
||||||
|
//double bi=1e-13;
|
||||||
int suppressed = 0;
|
int suppressed = 0;
|
||||||
vector<int> Index_Equ_IM_save(Index_Equ_IM);
|
vector<int> Index_Equ_IM_save(Index_Equ_IM);
|
||||||
while (!OK && bi > 1e-14)
|
while (!OK && bi > 1e-14)
|
||||||
|
@ -858,14 +902,13 @@ BlockTriangular::Normalize_and_BlockDecompose(bool* IM, Model_Block* ModelBlock,
|
||||||
suppressed = suppress;
|
suppressed = suppress;
|
||||||
if (!OK)
|
if (!OK)
|
||||||
//bi/=1.07;
|
//bi/=1.07;
|
||||||
bi/=3;
|
bi /= 2;
|
||||||
counted++;
|
counted++;
|
||||||
if (bi > 1e-14)
|
if (bi > 1e-14)
|
||||||
free(SIM00);
|
free(SIM00);
|
||||||
}
|
}
|
||||||
if (!OK)
|
if (!OK)
|
||||||
Compute_Normalization(IM, n, prologue, epilogue, true, SIM00, Index_Equ_IM);
|
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);
|
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;
|
Nb_RecursBlocks = Nb_TotalBlocks - Nb_SimulBlocks;
|
||||||
cout << Nb_TotalBlocks << " block(s) found:\n";
|
cout << Nb_TotalBlocks << " block(s) found:\n";
|
||||||
cout << " " << Nb_RecursBlocks << " recursive block(s) and " << blocks.size() << " simultaneous block(s). \n";
|
cout << " " << Nb_RecursBlocks << " recursive block(s) and " << blocks.size() << " simultaneous block(s). \n";
|
||||||
cout << " the largest simultaneous block has " << j << " equation(s)\n" <<
|
cout << " the largest simultaneous block has " << j << " equation(s)\n"
|
||||||
" and " << Nb_fv << " feedback variable(s).\n";
|
<<" and " << Nb_fv << " feedback variable(s).\n";
|
||||||
|
|
||||||
ModelBlock->Size = Nb_TotalBlocks;
|
ModelBlock->Size = Nb_TotalBlocks;
|
||||||
ModelBlock->Periods = periods;
|
ModelBlock->Periods = periods;
|
||||||
ModelBlock->Block_List = (Block *) malloc(sizeof(ModelBlock->Block_List[0]) * Nb_TotalBlocks);
|
ModelBlock->Block_List = (Block *) malloc(sizeof(ModelBlock->Block_List[0]) * Nb_TotalBlocks);
|
||||||
|
|
||||||
count_Equ = count_Block = 0;
|
count_Equ = count_Block = 0;
|
||||||
|
|
||||||
for (t_type::const_iterator it = Type.begin(); it != Type.end(); it++)
|
for (t_type::const_iterator it = Type.begin(); it != Type.end(); it++)
|
||||||
{
|
{
|
||||||
if (count_Equ < prologue)
|
if (count_Equ < prologue)
|
||||||
|
@ -921,7 +965,6 @@ BlockTriangular::Normalize_and_BlockDecompose(bool* IM, Model_Block* ModelBlock,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// normalize each equation of the dynamic model
|
// normalize each equation of the dynamic model
|
||||||
// and find the optimal block triangular decomposition of the static model
|
// and find the optimal block triangular decomposition of the static model
|
||||||
|
|
|
@ -24,21 +24,23 @@
|
||||||
#include "CodeInterpreter.hh"
|
#include "CodeInterpreter.hh"
|
||||||
#include "ExprNode.hh"
|
#include "ExprNode.hh"
|
||||||
#include "SymbolTable.hh"
|
#include "SymbolTable.hh"
|
||||||
#include "ModelNormalization.hh"
|
//#include "ModelNormalization.hh"
|
||||||
#include "ModelBlocks.hh"
|
//#include "ModelBlocks.hh"
|
||||||
#include "IncidenceMatrix.hh"
|
#include "IncidenceMatrix.hh"
|
||||||
#include "ModelTree.hh"
|
#include "ModelTree.hh"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//! Sparse matrix of double to store the values of the Jacobian
|
//! Sparse matrix of double to store the values of the Jacobian
|
||||||
typedef map<pair<int ,int >,double> jacob_map;
|
typedef map<pair<int ,int >,double> jacob_map;
|
||||||
|
|
||||||
typedef vector<pair<BlockSimulationType, pair<int, int> > > t_type;
|
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
|
//! Creates the incidence matrix, computes prologue & epilogue, normalizes the model and computes the block decomposition
|
||||||
class BlockTriangular
|
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;
|
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
|
//! Decomposes into recurive blocks the non purely recursive equations and determines for each block the minimum feedback variables
|
||||||
void Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Block(bool *IM, int nb_var, int prologue, int epilogue, vector<int> &Index_Equ_IM, vector<int> &Index_Var_IM, vector<pair<int, int> > &blocks, t_etype &Equation_Type, bool verbose_) const;
|
void Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Block(bool *IM, int nb_var, int prologue, int epilogue, vector<int> &Index_Equ_IM, vector<int> &Index_Var_IM, vector<pair<int, int> > &blocks, t_etype &Equation_Type, bool verbose_) 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);
|
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, ...
|
//! 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);
|
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:
|
public:
|
||||||
const SymbolTable &symbol_table;
|
SymbolTable &symbol_table;
|
||||||
BlockTriangular(const SymbolTable &symbol_table_arg);
|
/*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
|
//! Frees the Model structure describing the content of each block
|
||||||
void Free_Block(Model_Block* ModelBlock) const;
|
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_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);
|
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_Equ_IM;
|
||||||
vector<int> Index_Var_IM;
|
vector<int> Index_Var_IM;
|
||||||
int prologue, epilogue;
|
int prologue, epilogue;
|
||||||
bool bt_verbose;
|
bool bt_verbose;
|
||||||
//int endo_nbr, exo_nbr;
|
|
||||||
Model_Block* ModelBlock;
|
Model_Block* ModelBlock;
|
||||||
int periods;
|
int periods;
|
||||||
inline static std::string BlockType0(int type)
|
inline static std::string BlockType0(int type)
|
||||||
|
@ -101,11 +108,11 @@ public:
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case EVALUATE_FORWARD:
|
case EVALUATE_FORWARD:
|
||||||
case EVALUATE_FORWARD_R:
|
//case EVALUATE_FORWARD_R:
|
||||||
return ("EVALUATE FORWARD ");
|
return ("EVALUATE FORWARD ");
|
||||||
break;
|
break;
|
||||||
case EVALUATE_BACKWARD:
|
case EVALUATE_BACKWARD:
|
||||||
case EVALUATE_BACKWARD_R:
|
//case EVALUATE_BACKWARD_R:
|
||||||
return ("EVALUATE BACKWARD ");
|
return ("EVALUATE BACKWARD ");
|
||||||
break;
|
break;
|
||||||
case SOLVE_FORWARD_SIMPLE:
|
case SOLVE_FORWARD_SIMPLE:
|
||||||
|
@ -137,7 +144,7 @@ public:
|
||||||
{
|
{
|
||||||
"E_UNKNOWN ",
|
"E_UNKNOWN ",
|
||||||
"E_EVALUATE ",
|
"E_EVALUATE ",
|
||||||
"E_EVALUATE_R",
|
//"E_EVALUATE_R",
|
||||||
"E_EVALUATE_S",
|
"E_EVALUATE_S",
|
||||||
"E_SOLVE "
|
"E_SOLVE "
|
||||||
};
|
};
|
||||||
|
|
|
@ -53,8 +53,8 @@ enum EquationType
|
||||||
{
|
{
|
||||||
E_UNKNOWN, //!< Unknown equation type
|
E_UNKNOWN, //!< Unknown equation type
|
||||||
E_EVALUATE, //!< Simple evaluation, normalized variable on left-hand side
|
E_EVALUATE, //!< Simple evaluation, normalized variable on left-hand side
|
||||||
E_EVALUATE_R, //!< Simple evaluation, normalized variable on right-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_S, //!< Simple evaluation, normalize using the first order derivative
|
||||||
E_SOLVE //!< No simple evaluation of the equation, it has to be solved
|
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_FORWARD_COMPLETE, //!< Block of several equations, newton solver needed, forward
|
||||||
SOLVE_BACKWARD_COMPLETE, //!< Block of several equations, newton solver needed, backward
|
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
|
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_FORWARD_R, //!< Simple evaluation, normalized variable on right-hand side, forward
|
||||||
EVALUATE_BACKWARD_R //!< Simple evaluation, normalized variable on right-hand side, backward
|
//EVALUATE_BACKWARD_R //!< Simple evaluation, normalized variable on right-hand side, backward
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Enumeration of possible symbol types
|
//! Enumeration of possible symbol types
|
||||||
|
|
461
DynamicModel.cc
461
DynamicModel.cc
|
@ -43,7 +43,7 @@ DynamicModel::DynamicModel(SymbolTable &symbol_table_arg,
|
||||||
dynJacobianColsNbr(0),
|
dynJacobianColsNbr(0),
|
||||||
cutoff(1e-15),
|
cutoff(1e-15),
|
||||||
markowitz(0.7),
|
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
|
void
|
||||||
DynamicModel::compileDerivative(ofstream &code_file, int eq, int symb_id, int lag, map_idx_type &map_idx) const
|
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())
|
if (it != first_derivatives.end())
|
||||||
(it->second)->compile(code_file, false, temporary_terms, map_idx);
|
(it->second)->compile(code_file, false, temporary_terms, map_idx);
|
||||||
else
|
else
|
||||||
|
@ -77,7 +78,7 @@ DynamicModel::BuildIncidenceMatrix()
|
||||||
Id->collectEndogenous(endogenous);
|
Id->collectEndogenous(endogenous);
|
||||||
for (set<pair<int, int> >::iterator it_endogenous=endogenous.begin();it_endogenous!=endogenous.end();it_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();
|
exogenous.clear();
|
||||||
Id = eq_node->get_arg1();
|
Id = eq_node->get_arg1();
|
||||||
|
@ -86,7 +87,7 @@ DynamicModel::BuildIncidenceMatrix()
|
||||||
Id->collectExogenous(exogenous);
|
Id->collectExogenous(exogenous);
|
||||||
for (set<pair<int, int> >::iterator it_exogenous=exogenous.begin();it_exogenous!=exogenous.end();it_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();
|
map_idx.clear();
|
||||||
for (j = 0;j < ModelBlock->Size;j++)
|
for (j = 0;j < ModelBlock->Size;j++)
|
||||||
{
|
{
|
||||||
//cerr << "block=" << j+1 << "\n";
|
|
||||||
// Compute the temporary terms reordered
|
// Compute the temporary terms reordered
|
||||||
for (i = 0;i < ModelBlock->Block_List[j].Size;i++)
|
for (i = 0;i < ModelBlock->Block_List[j].Size;i++)
|
||||||
{
|
{
|
||||||
eq_node = equations[ModelBlock->Block_List[j].Equation[i]];
|
eq_node = equations[ModelBlock->Block_List[j].Equation[i]];
|
||||||
eq_node->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, j, ModelBlock, i, map_idx);
|
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++)
|
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++)
|
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++)
|
for (i = 0;i < ModelBlock->Block_List[j].Size;i++)
|
||||||
{
|
{
|
||||||
eq_node = equations[ModelBlock->Block_List[j].Equation[i]];
|
eq_node = equations[ModelBlock->Block_List[j].Equation[i]];
|
||||||
eq_node->collectTemporary_terms(temporary_terms, ModelBlock, j);
|
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++)
|
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 prev_Simulation_Type=-1, count_derivates=0;
|
||||||
int jacobian_max_endo_col;
|
int jacobian_max_endo_col;
|
||||||
ofstream output;
|
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;
|
int nze, nze_exo, nze_other_endo;
|
||||||
|
map<int, NodeID> recursive_variables;
|
||||||
|
vector<int> feedback_variables;
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
//For each block
|
//For each block
|
||||||
for (j = 0;j < ModelBlock->Size;j++)
|
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
|
//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;
|
nze = nze_exo = nze_other_endo = 0;
|
||||||
for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++)
|
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;
|
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++)
|
/*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;
|
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+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;
|
nze_other_endo+=ModelBlock->Block_List[j].IM_lead_lag[m].size_other_endo;
|
||||||
|
}
|
||||||
tmp1_output.str("");
|
tmp1_output.str("");
|
||||||
tmp1_output << dynamic_basename << "_" << j+1 << ".m";
|
tmp1_output << dynamic_basename << "_" << j+1 << ".m";
|
||||||
output.open(tmp1_output.str().c_str(), ios::out | ios::binary);
|
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";
|
output << "%/\n";
|
||||||
if (ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD
|
if (ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD
|
||||||
||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD
|
||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD
|
||||||
||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD_R
|
/*||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD_R
|
||||||
||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD_R)
|
||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD_R*/)
|
||||||
{
|
{
|
||||||
output << "function [y, g1, g2, g3, varargout] = " << dynamic_basename << "_" << j+1 << "(y, x, params, jacobian_eval, y_kmin, periods)\n";
|
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
|
else if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_FORWARD_COMPLETE
|
||||||
|| ModelBlock->Block_List[j].Simulation_Type==SOLVE_BACKWARD_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
|
else if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_BACKWARD_SIMPLE
|
||||||
|| ModelBlock->Block_List[j].Simulation_Type==SOLVE_FORWARD_SIMPLE)
|
|| ModelBlock->Block_List[j].Simulation_Type==SOLVE_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
|
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
|
output << " % ////////////////////////////////////////////////////////////////////////" << endl
|
||||||
<< " % //" << string(" Block ").substr(int(log10(j + 1))) << j + 1 << " " << BlockTriangular::BlockType0(ModelBlock->Block_List[j].Type)
|
<< " % //" << string(" Block ").substr(int(log10(j + 1))) << j + 1 << " " << BlockTriangular::BlockType0(ModelBlock->Block_List[j].Type)
|
||||||
<< " //" << endl
|
<< " //" << endl
|
||||||
|
@ -274,26 +290,45 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
||||||
//The Temporary terms
|
//The Temporary terms
|
||||||
if (ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD
|
if (ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD
|
||||||
||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD
|
||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD
|
||||||
||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD_R
|
/*||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD_R
|
||||||
||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD_R)
|
||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD_R*/)
|
||||||
{
|
{
|
||||||
output << " if(jacobian_eval)\n";
|
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 = spalloc(" << ModelBlock->Block_List[j].Size-ModelBlock->Block_List[j].Nb_Recursives
|
||||||
//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";
|
<< ", " << (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)
|
||||||
//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";
|
<< ", " << 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";
|
output << " end;\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
output << " if(jacobian_eval)\n";
|
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 = 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 << " 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";
|
output << " else\n";
|
||||||
if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_SIMPLE)
|
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
|
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";
|
output << " end;\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,17 +341,16 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
||||||
tmp_output << " T" << *it;
|
tmp_output << " T" << *it;
|
||||||
output << " global" << tmp_output.str() << ";\n";
|
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 and ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_FORWARD)
|
||||||
if (ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD
|
output << " residual=zeros(" << ModelBlock->Block_List[j].Size-ModelBlock->Block_List[j].Nb_Recursives << ",1);\n";
|
||||||
||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD
|
if (ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD)
|
||||||
||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD_R
|
output << " for it_ = (y_kmin+periods):y_kmin+1\n";
|
||||||
||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD_R)
|
if (ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD)
|
||||||
output << " for it_ = y_kmin+1:(y_kmin+periods)\n";
|
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)
|
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 << " for it_ = y_kmin+1:(periods+y_kmin)\n";
|
||||||
output << " Per_y_=it_*y_size;\n";
|
output << " Per_y_=it_*y_size;\n";
|
||||||
output << " Per_J_=(it_-y_kmin-1)*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=" ";
|
sps=" ";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if(ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD || ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD ||
|
if (ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD || ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD )
|
||||||
ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD_R || ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD_R)
|
|
||||||
sps = " ";
|
sps = " ";
|
||||||
else
|
else
|
||||||
sps="";
|
sps="";
|
||||||
|
@ -347,7 +380,7 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
||||||
tt2.insert(*it);
|
tt2.insert(*it);
|
||||||
output << ";" << endl;
|
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]];
|
eq_node = equations[ModelBlock->Block_List[j].Equation[i]];
|
||||||
lhs = eq_node->get_arg1();
|
lhs = eq_node->get_arg1();
|
||||||
rhs = eq_node->get_arg2();
|
rhs = eq_node->get_arg2();
|
||||||
|
@ -367,35 +400,46 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
||||||
output << " = ";
|
output << " = ";
|
||||||
rhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms);
|
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);
|
rhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms);
|
||||||
output << " = ";
|
output << " = ";
|
||||||
output << tmp_output.str();
|
output << tmp_output.str();
|
||||||
output << "; %reversed " << ModelBlock->Block_List[j].Equation_Type[i] << " \n";
|
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
|
else
|
||||||
{
|
{
|
||||||
cerr << "Type missmatch for equation " << ModelBlock->Block_List[j].Equation[i]+1 << "\n";
|
cerr << "Type missmatch for equation " << ModelBlock->Block_List[j].Equation[i]+1 << "\n";
|
||||||
exit(-1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
output << ";\n";
|
output << ";\n";
|
||||||
break; /*case EVALUATE_BACKWARD_R:
|
break;
|
||||||
case EVALUATE_FORWARD_R:
|
|
||||||
output << " % equation " << ModelBlock->Block_List[j].Equation[i]+1 << " variable : " << sModel
|
|
||||||
<< " (" << ModelBlock->Block_List[j].Variable[i]+1 << ")" << endl;
|
|
||||||
output << " ";
|
|
||||||
rhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms);
|
|
||||||
output << " = ";
|
|
||||||
lhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms);
|
|
||||||
output << ";\n";
|
|
||||||
break;*/
|
|
||||||
case SOLVE_BACKWARD_SIMPLE:
|
case SOLVE_BACKWARD_SIMPLE:
|
||||||
case SOLVE_FORWARD_SIMPLE:
|
case SOLVE_FORWARD_SIMPLE:
|
||||||
case SOLVE_BACKWARD_COMPLETE:
|
case SOLVE_BACKWARD_COMPLETE:
|
||||||
case SOLVE_FORWARD_COMPLETE:
|
case SOLVE_FORWARD_COMPLETE:
|
||||||
if (i<ModelBlock->Block_List[j].Nb_Recursives)
|
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;
|
goto evaluation;
|
||||||
|
}
|
||||||
|
feedback_variables.push_back(ModelBlock->Block_List[j].Variable[i]);
|
||||||
output << " % equation " << ModelBlock->Block_List[j].Equation[i]+1 << " variable : " << sModel
|
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;
|
<< " (" << 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 << ") = (";
|
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_COMPLETE:
|
||||||
case SOLVE_TWO_BOUNDARIES_SIMPLE:
|
case SOLVE_TWO_BOUNDARIES_SIMPLE:
|
||||||
if (i<ModelBlock->Block_List[j].Nb_Recursives)
|
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;
|
goto evaluation;
|
||||||
|
}
|
||||||
|
feedback_variables.push_back(ModelBlock->Block_List[j].Variable[i]);
|
||||||
output << " % equation " << ModelBlock->Block_List[j].Equation[i]+1 << " variable : " << sModel
|
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;
|
<< " (" << 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_) = (";
|
output << " residual(" << i+1-ModelBlock->Block_List[j].Nb_Recursives << ", it_) = (";
|
||||||
goto end;
|
goto end;
|
||||||
default:
|
default:
|
||||||
|
@ -435,8 +486,8 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
||||||
{
|
{
|
||||||
case EVALUATE_BACKWARD:
|
case EVALUATE_BACKWARD:
|
||||||
case EVALUATE_FORWARD:
|
case EVALUATE_FORWARD:
|
||||||
case EVALUATE_BACKWARD_R:
|
/*case EVALUATE_BACKWARD_R:
|
||||||
case EVALUATE_FORWARD_R:
|
case EVALUATE_FORWARD_R:*/
|
||||||
count_derivates++;
|
count_derivates++;
|
||||||
for (m=0;m<ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag+1;m++)
|
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*/
|
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 << ") = ";
|
varr+1+m*ModelBlock->Block_List[j].Size << ") = ";
|
||||||
writeDerivative(output, eq, symbol_table.getID(eEndogenous, var), k, oMatlabDynamicModelSparse, temporary_terms);
|
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]))
|
<< "(" << k//variable_table.getLag(variable_table.getSymbolID(ModelBlock->Block_List[j].Variable[0]))
|
||||||
<< ") " << var+1
|
<< ") " << var+1
|
||||||
<< ", equation=" << eq+1 << endl;
|
<< ", equation=" << eq+1 << endl;
|
||||||
|
@ -488,7 +539,7 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
||||||
output << " g1_o(" << eqr+1 << ", "
|
output << " g1_o(" << eqr+1 << ", "
|
||||||
<< varr+1+(m+max_endo_lag-ModelBlock->Block_List[j].Max_Lag)*symbol_table.endo_nbr() << ") = ";
|
<< 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);
|
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
|
<< "(" << k << ") " << var+1
|
||||||
<< ", equation=" << eq+1 << endl;
|
<< ", equation=" << eq+1 << endl;
|
||||||
}
|
}
|
||||||
|
@ -497,6 +548,7 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
||||||
output << " varargout{1}=g1_x;\n";
|
output << " varargout{1}=g1_x;\n";
|
||||||
output << " varargout{2}=g1_o;\n";
|
output << " varargout{2}=g1_o;\n";
|
||||||
output << " end;" << endl;
|
output << " end;" << endl;
|
||||||
|
//output << " ya = y;\n";
|
||||||
output << " end;" << endl;
|
output << " end;" << endl;
|
||||||
break;
|
break;
|
||||||
case SOLVE_BACKWARD_SIMPLE:
|
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 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 eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ[i];
|
||||||
int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Var[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*/
|
output << " g1(" << eqr+1 << ", "
|
||||||
varr+1+m*ModelBlock->Block_List[j].Size << ") = ";
|
<< varr+1 + m*(ModelBlock->Block_List[j].Size) << ") = ";
|
||||||
writeDerivative(output, eq, symbol_table.getID(eEndogenous, var), k, oMatlabDynamicModelSparse, temporary_terms);
|
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
|
<< "(" << k << ") " << var+1
|
||||||
<< ") " << var+1
|
|
||||||
<< ", equation=" << eq+1 << endl;
|
<< ", 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 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 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];
|
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() << ") = ";
|
<< 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);
|
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
|
<< "(" << k << ") " << var+1
|
||||||
<< ", equation=" << eq+1 << endl;
|
<< ", equation=" << eq+1 << endl;
|
||||||
}
|
}
|
||||||
|
@ -563,19 +614,77 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
||||||
output << " else" << endl;
|
output << " else" << endl;
|
||||||
|
|
||||||
m=ModelBlock->Block_List[j].Max_Lag;
|
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++)
|
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 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 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 eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ[i];
|
||||||
int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Var[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);
|
writeDerivative(output, eq, symbol_table.getID(eEndogenous, var), 0, oMatlabDynamicModelSparse, temporary_terms);
|
||||||
output << "; % variable=" << symbol_table.getName(var)
|
output << "; % variable=" << symbol_table.getName(var)
|
||||||
<< "(0) " << var+1
|
<< "(0) " << var+1
|
||||||
<< ", equation=" << eq+1 << endl;
|
<< ", equation=" << eq+1 << endl;*/
|
||||||
}
|
}
|
||||||
output << " end;\n";
|
output << " end;\n";
|
||||||
|
//output << " ya = y;\n";
|
||||||
break;
|
break;
|
||||||
case SOLVE_TWO_BOUNDARIES_SIMPLE:
|
case SOLVE_TWO_BOUNDARIES_SIMPLE:
|
||||||
case SOLVE_TWO_BOUNDARIES_COMPLETE:
|
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 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 eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ[i];
|
||||||
int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Var[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)
|
if (k==0)
|
||||||
Uf[ModelBlock->Block_List[j].Equation[eqr]] << "+g1(" << eqr+1 << "+Per_J_, " << varr+1 << "+Per_K_)*y(it_, " << var+1 << ")";
|
Uf[ModelBlock->Block_List[j].Equation[eqr]] << "+g1_tmp_r(" << eqr+1
|
||||||
else if (k==1)
|
<< ", " << varr+1
|
||||||
Uf[ModelBlock->Block_List[j].Equation[eqr]] << "+g1(" << eqr+1 << "+Per_J_, " << varr+1 << "+Per_y_)*y(it_+1, " << var+1 << ")";
|
<< "+" << ModelBlock->Block_List[j].Size*ModelBlock->Block_List[j].Max_Lag << ")*y(it_, " << var+1 << ")";
|
||||||
else if (k>0)
|
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)
|
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)
|
if (k==0)
|
||||||
output << " g1(" << eqr+1 << "+Per_J_, " << varr+1 << "+Per_K_) = ";
|
tmp_output << " g1_tmp_r(" << eqr+1 << ", "
|
||||||
else if (k==1)
|
<< varr+1 << "+" << ModelBlock->Block_List[j].Size << "*" << ModelBlock->Block_List[j].Max_Lag << ") = ";
|
||||||
output << " g1(" << eqr+1 << "+Per_J_, " << varr+1 << "+Per_y_) = ";
|
|
||||||
else if (k>0)
|
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)
|
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);
|
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
|
<< "(" << k << ") " << var+1
|
||||||
<< ", equation=" << eq+1 << endl;
|
<< ", 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
|
#ifdef CONDITION
|
||||||
output << " if (fabs(condition[" << eqr << "])<fabs(u[" << u << "+Per_u_]))\n";
|
output << " if (fabs(condition[" << eqr << "])<fabs(u[" << u << "+Per_u_]))\n";
|
||||||
output << " condition(" << eqr << ")=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++)
|
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";
|
output << " " << Uf[ModelBlock->Block_List[j].Equation[i]].str() << ";\n";
|
||||||
#ifdef CONDITION
|
#ifdef CONDITION
|
||||||
output << " if (fabs(condition(" << i+1 << "))<fabs(u(" << i << "+Per_u_)))\n";
|
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];
|
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 << ") = ";
|
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);
|
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
|
<< "(" << k << ") " << var+1
|
||||||
<< ", equation=" << eq+1 << endl;
|
<< ", equation=" << eq+1 << endl;
|
||||||
}
|
}
|
||||||
|
@ -689,7 +930,7 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
||||||
output << " g1_o(" << eqr+1 << ", "
|
output << " g1_o(" << eqr+1 << ", "
|
||||||
<< varr+1+(m+max_endo_lag-ModelBlock->Block_List[j].Max_Lag)*symbol_table.endo_nbr() << ") = ";
|
<< 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);
|
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
|
<< "(" << k << ") " << var+1
|
||||||
<< ", equation=" << eq+1 << endl;
|
<< ", equation=" << eq+1 << endl;
|
||||||
}
|
}
|
||||||
|
@ -698,6 +939,7 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
|
||||||
output << " varargout{1}=g1_x;\n";
|
output << " varargout{1}=g1_x;\n";
|
||||||
output << " varargout{2}=g1_o;\n";
|
output << " varargout{2}=g1_o;\n";
|
||||||
output << " end;\n";
|
output << " end;\n";
|
||||||
|
//output << " ya = y;\n";
|
||||||
output << " end;\n";
|
output << " end;\n";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -736,7 +978,7 @@ DynamicModel::writeModelEquationsCodeOrdered(const string file_name, const Model
|
||||||
int prev_Simulation_Type=-1;
|
int prev_Simulation_Type=-1;
|
||||||
//SymbolicGaussElimination SGE;
|
//SymbolicGaussElimination SGE;
|
||||||
bool file_open=false;
|
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;
|
string main_name=file_name;
|
||||||
main_name+=".cod";
|
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)
|
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_BACKWARD
|
||||||
||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD
|
||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD
|
||||||
||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD_R
|
/*||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD_R
|
||||||
||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD_R ))
|
||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD_R */))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -875,14 +1117,26 @@ DynamicModel::writeModelEquationsCodeOrdered(const string file_name, const Model
|
||||||
{
|
{
|
||||||
case EVALUATE_BACKWARD:
|
case EVALUATE_BACKWARD:
|
||||||
case EVALUATE_FORWARD:
|
case EVALUATE_FORWARD:
|
||||||
|
if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE)
|
||||||
|
{
|
||||||
rhs->compile(code_file, false, temporary_terms, map_idx);
|
rhs->compile(code_file, false, temporary_terms, map_idx);
|
||||||
lhs->compile(code_file, true, 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;
|
break;
|
||||||
case EVALUATE_BACKWARD_R:
|
/*case EVALUATE_BACKWARD_R:
|
||||||
case EVALUATE_FORWARD_R:
|
case EVALUATE_FORWARD_R:
|
||||||
lhs->compile(code_file, false, temporary_terms, map_idx);
|
lhs->compile(code_file, false, temporary_terms, map_idx);
|
||||||
rhs->compile(code_file, true, temporary_terms, map_idx);
|
rhs->compile(code_file, true, temporary_terms, map_idx);
|
||||||
break;
|
break;*/
|
||||||
case SOLVE_BACKWARD_COMPLETE:
|
case SOLVE_BACKWARD_COMPLETE:
|
||||||
case SOLVE_FORWARD_COMPLETE:
|
case SOLVE_FORWARD_COMPLETE:
|
||||||
v=ModelBlock->Block_List[j].Equation[i];
|
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
|
// The Jacobian if we have to solve the block
|
||||||
if (ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_BACKWARD
|
if (ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_BACKWARD
|
||||||
&& ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_FORWARD
|
&& ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_FORWARD
|
||||||
&& ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_BACKWARD_R
|
/*&& ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_BACKWARD_R
|
||||||
&& ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_FORWARD_R)
|
&& ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_FORWARD_R*/)
|
||||||
{
|
{
|
||||||
switch (ModelBlock->Block_List[j].Simulation_Type)
|
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;
|
k=block_triangular.ModelBlock->Block_List[i].Simulation_Type;
|
||||||
if ((BlockTriangular::BlockSim(prev_Simulation_Type)!=BlockTriangular::BlockSim(k)) &&
|
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)
|
((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)))
|
|| (k==EVALUATE_FORWARD || k==EVALUATE_BACKWARD /*|| k==EVALUATE_FORWARD_R || k==EVALUATE_BACKWARD_R*/)))
|
||||||
{
|
{
|
||||||
mDynamicModelFile << " y_index_eq=[" << tmp_eq.str() << "];\n";
|
mDynamicModelFile << " y_index_eq=[" << tmp_eq.str() << "];\n";
|
||||||
tmp_eq.str("");
|
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 << " " << block_triangular.ModelBlock->Block_List[i].Variable[ik]+1;
|
||||||
tmp_eq << " " << block_triangular.ModelBlock->Block_List[i].Equation[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)
|
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) &&
|
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;
|
skip_head=true;
|
||||||
else
|
else
|
||||||
skip_head=false;
|
skip_head=false;
|
||||||
|
@ -1393,8 +1647,8 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
|
||||||
{
|
{
|
||||||
case EVALUATE_FORWARD:
|
case EVALUATE_FORWARD:
|
||||||
case EVALUATE_BACKWARD:
|
case EVALUATE_BACKWARD:
|
||||||
case EVALUATE_FORWARD_R:
|
/*case EVALUATE_FORWARD_R:
|
||||||
case EVALUATE_BACKWARD_R:
|
case EVALUATE_BACKWARD_R:*/
|
||||||
if (!skip_head)
|
if (!skip_head)
|
||||||
{
|
{
|
||||||
tmp1 << " [y, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_o]=" << dynamic_basename << "_" << i + 1 << "(y, x, params, 1, it_-1, 1);\n";
|
tmp1 << " [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 << ", " <<
|
/*mDynamicModelFile << " ga=spalloc(" << block_triangular.ModelBlock->Block_List[i].Size << ", " << j << ", " <<
|
||||||
block_triangular.ModelBlock->Block_List[i].Size*j << ");\n";*/
|
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;
|
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)
|
/*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";
|
mDynamicModelFile << " g1(y_index_eq,y_index) = ga;\n";
|
||||||
else
|
else
|
||||||
|
@ -1484,11 +1738,11 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
|
||||||
{
|
{
|
||||||
k = block_triangular.ModelBlock->Block_List[i].Simulation_Type;
|
k = block_triangular.ModelBlock->Block_List[i].Simulation_Type;
|
||||||
if (BlockTriangular::BlockSim(prev_Simulation_Type)==BlockTriangular::BlockSim(k) &&
|
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;
|
skip_head=true;
|
||||||
else
|
else
|
||||||
skip_head=false;
|
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)
|
if (!skip_head)
|
||||||
{
|
{
|
||||||
|
@ -1510,10 +1764,15 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
|
||||||
mDynamicModelFile << " g1=[];g2=[];g3=[];\n";
|
mDynamicModelFile << " g1=[];g2=[];g3=[];\n";
|
||||||
//mDynamicModelFile << " for it_ = y_kmin+1:(periods+y_kmin)\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 << " 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;
|
//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)
|
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 << " oo_.deterministic_simulation.block(blck_num).iterations = 0;\n";
|
||||||
mDynamicModelFile << " g1=[];g2=[];g3=[];\n";
|
mDynamicModelFile << " g1=[];g2=[];g3=[];\n";
|
||||||
mDynamicModelFile << " " << dynamic_basename << "_" << i + 1 << "(y, x, params, 0, y_kmin, periods);\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))
|
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 <<
|
", y, x, params, y_index, " << nze <<
|
||||||
", options_.periods, " << block_triangular.ModelBlock->Block_List[i].is_linear <<
|
", 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";
|
", 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))
|
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("");
|
tmp.str("");
|
||||||
for (int ik=0;ik<block_triangular.ModelBlock->Block_List[i].Size;ik++)
|
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;
|
tmp << " " << block_triangular.ModelBlock->Block_List[i].Variable[ik]+1;
|
||||||
}
|
}
|
||||||
mDynamicModelFile << " y_index = [" << tmp.str() << "];\n";
|
mDynamicModelFile << " y_index = [" << tmp.str() << "];\n";
|
||||||
|
@ -1588,6 +1857,11 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
|
||||||
", y, x, params, y_index, " << nze <<
|
", y, x, params, y_index, " << nze <<
|
||||||
", options_.periods, " << block_triangular.ModelBlock->Block_List[i].is_linear <<
|
", 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";
|
", 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))
|
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=[";
|
mDynamicModelFile << " y_index=[";
|
||||||
for (int ik=0;ik<block_triangular.ModelBlock->Block_List[i].Size;ik++)
|
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 << " " << block_triangular.ModelBlock->Block_List[i].Variable[ik]+1;
|
||||||
}
|
}
|
||||||
mDynamicModelFile << " ];\n";
|
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].Max_Lead <<
|
||||||
", " << block_triangular.ModelBlock->Block_List[i].is_linear <<
|
", " << 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";
|
", 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;
|
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
|
int
|
||||||
ExprNode::precedence(ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const
|
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
|
// 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
|
void
|
||||||
ExprNode::writeOutput(ostream &output)
|
ExprNode::writeOutput(ostream &output)
|
||||||
{
|
{
|
||||||
writeOutput(output, oMatlabOutsideModel, temporary_terms_type());
|
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) :
|
NumConstNode::NumConstNode(DataTree &datatree_arg, int id_arg) :
|
||||||
ExprNode(datatree_arg),
|
ExprNode(datatree_arg),
|
||||||
|
@ -129,6 +168,7 @@ void
|
||||||
NumConstNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
NumConstNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
||||||
const temporary_terms_type &temporary_terms) const
|
const temporary_terms_type &temporary_terms) const
|
||||||
{
|
{
|
||||||
|
//cout << "writeOutput constante\n";
|
||||||
temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<NumConstNode *>(this));
|
temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<NumConstNode *>(this));
|
||||||
if (it != temporary_terms.end())
|
if (it != temporary_terms.end())
|
||||||
if (output_type == oMatlabDynamicModelSparse)
|
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
|
NodeID
|
||||||
NumConstNode::toStatic(DataTree &static_datatree) const
|
NumConstNode::toStatic(DataTree &static_datatree) const
|
||||||
{
|
{
|
||||||
|
@ -251,7 +312,7 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
||||||
{
|
{
|
||||||
// If node is a temporary term
|
// If node is a temporary term
|
||||||
#ifdef DEBUGC
|
#ifdef DEBUGC
|
||||||
cout << "write_ouput output_type=" << output_type << "\n";
|
cout << "write_ouput Variable output_type=" << output_type << "\n";
|
||||||
#endif
|
#endif
|
||||||
temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<VariableNode *>(this));
|
temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<VariableNode *>(this));
|
||||||
if (it != temporary_terms.end())
|
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";
|
cout << "output_type=" << output_type << "\n";
|
||||||
#endif
|
#endif
|
||||||
if (!lhs_rhs)
|
if (!lhs_rhs)
|
||||||
|
{
|
||||||
CompileCode.write(&FLDV, sizeof(FLDV));
|
CompileCode.write(&FLDV, sizeof(FLDV));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
CompileCode.write(&FSTPV, sizeof(FSTPV));
|
CompileCode.write(&FSTPV, sizeof(FSTPV));
|
||||||
|
}
|
||||||
char typel=(char)type;
|
char typel=(char)type;
|
||||||
CompileCode.write(&typel, sizeof(typel));
|
CompileCode.write(&typel, sizeof(typel));
|
||||||
int tsid = datatree.symbol_table.getTypeSpecificID(symb_id);
|
int tsid = datatree.symbol_table.getTypeSpecificID(symb_id);
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case eParameter:
|
case eParameter:
|
||||||
|
//cout << "Parameter=" << tsid << "\n";
|
||||||
i = tsid;
|
i = tsid;
|
||||||
CompileCode.write(reinterpret_cast<char *>(&i), sizeof(i));
|
CompileCode.write(reinterpret_cast<char *>(&i), sizeof(i));
|
||||||
#ifdef DEBUGC
|
#ifdef DEBUGC
|
||||||
|
@ -444,12 +510,14 @@ VariableNode::compile(ofstream &CompileCode, bool lhs_rhs, const temporary_terms
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case eEndogenous :
|
case eEndogenous :
|
||||||
i = symb_id;
|
//cout << "Endogenous=" << symb_id << "\n";
|
||||||
|
i = tsid;//symb_id;
|
||||||
CompileCode.write(reinterpret_cast<char *>(&i), sizeof(i));
|
CompileCode.write(reinterpret_cast<char *>(&i), sizeof(i));
|
||||||
lagl=lag;
|
lagl=lag;
|
||||||
CompileCode.write(reinterpret_cast<char *>(&lagl), sizeof(lagl));
|
CompileCode.write(reinterpret_cast<char *>(&lagl), sizeof(lagl));
|
||||||
break;
|
break;
|
||||||
case eExogenous :
|
case eExogenous :
|
||||||
|
//cout << "Exogenous=" << tsid << "\n";
|
||||||
i = tsid;
|
i = tsid;
|
||||||
CompileCode.write(reinterpret_cast<char *>(&i), sizeof(i));
|
CompileCode.write(reinterpret_cast<char *>(&i), sizeof(i));
|
||||||
lagl=lag;
|
lagl=lag;
|
||||||
|
@ -457,12 +525,14 @@ VariableNode::compile(ofstream &CompileCode, bool lhs_rhs, const temporary_terms
|
||||||
break;
|
break;
|
||||||
case eExogenousDet:
|
case eExogenousDet:
|
||||||
i = tsid + datatree.symbol_table.exo_nbr();
|
i = tsid + datatree.symbol_table.exo_nbr();
|
||||||
|
//cout << "ExogenousDet=" << i << "\n";
|
||||||
CompileCode.write(reinterpret_cast<char *>(&i), sizeof(i));
|
CompileCode.write(reinterpret_cast<char *>(&i), sizeof(i));
|
||||||
lagl=lag;
|
lagl=lag;
|
||||||
CompileCode.write(reinterpret_cast<char *>(&lagl), sizeof(lagl));
|
CompileCode.write(reinterpret_cast<char *>(&lagl), sizeof(lagl));
|
||||||
break;
|
break;
|
||||||
case eModelLocalVariable:
|
case eModelLocalVariable:
|
||||||
case eModFileLocalVariable:
|
case eModFileLocalVariable:
|
||||||
|
//cout << "eModelLocalVariable=" << symb_id << "\n";
|
||||||
datatree.local_variables_table[symb_id]->compile(CompileCode, lhs_rhs, temporary_terms, map_idx);
|
datatree.local_variables_table[symb_id]->compile(CompileCode, lhs_rhs, temporary_terms, map_idx);
|
||||||
break;
|
break;
|
||||||
case eUnknownFunction:
|
case eUnknownFunction:
|
||||||
|
@ -488,7 +558,7 @@ void
|
||||||
VariableNode::collectEndogenous(set<pair<int, int> > &result) const
|
VariableNode::collectEndogenous(set<pair<int, int> > &result) const
|
||||||
{
|
{
|
||||||
if (type == eEndogenous)
|
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)
|
else if (type == eModelLocalVariable)
|
||||||
datatree.local_variables_table[symb_id]->collectEndogenous(result);
|
datatree.local_variables_table[symb_id]->collectEndogenous(result);
|
||||||
}
|
}
|
||||||
|
@ -497,11 +567,87 @@ void
|
||||||
VariableNode::collectExogenous(set<pair<int, int> > &result) const
|
VariableNode::collectExogenous(set<pair<int, int> > &result) const
|
||||||
{
|
{
|
||||||
if (type == eExogenous)
|
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)
|
else if (type == eModelLocalVariable)
|
||||||
datatree.local_variables_table[symb_id]->collectExogenous(result);
|
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
|
NodeID
|
||||||
VariableNode::toStatic(DataTree &static_datatree) const
|
VariableNode::toStatic(DataTree &static_datatree) const
|
||||||
{
|
{
|
||||||
|
@ -739,6 +885,7 @@ void
|
||||||
UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
||||||
const temporary_terms_type &temporary_terms) const
|
const temporary_terms_type &temporary_terms) const
|
||||||
{
|
{
|
||||||
|
//cout << "writeOutput unary\n";
|
||||||
// If node is a temporary term
|
// If node is a temporary term
|
||||||
temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<UnaryOpNode *>(this));
|
temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<UnaryOpNode *>(this));
|
||||||
if (it != temporary_terms.end())
|
if (it != temporary_terms.end())
|
||||||
|
@ -918,6 +1065,127 @@ UnaryOpNode::collectExogenous(set<pair<int, int> > &result) const
|
||||||
arg->collectExogenous(result);
|
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
|
NodeID
|
||||||
UnaryOpNode::toStatic(DataTree &static_datatree) const
|
UnaryOpNode::toStatic(DataTree &static_datatree) const
|
||||||
{
|
{
|
||||||
|
@ -1001,11 +1269,16 @@ BinaryOpNode::computeDerivative(int deriv_id)
|
||||||
t12 = datatree.AddTimes(darg2, arg1);
|
t12 = datatree.AddTimes(darg2, arg1);
|
||||||
return datatree.AddPlus(t11, t12);
|
return datatree.AddPlus(t11, t12);
|
||||||
case oDivide:
|
case oDivide:
|
||||||
|
if (darg2!=datatree.Zero)
|
||||||
|
{
|
||||||
t11 = datatree.AddTimes(darg1, arg2);
|
t11 = datatree.AddTimes(darg1, arg2);
|
||||||
t12 = datatree.AddTimes(darg2, arg1);
|
t12 = datatree.AddTimes(darg2, arg1);
|
||||||
t13 = datatree.AddMinus(t11, t12);
|
t13 = datatree.AddMinus(t11, t12);
|
||||||
t14 = datatree.AddTimes(arg2, arg2);
|
t14 = datatree.AddTimes(arg2, arg2);
|
||||||
return datatree.AddDivide(t13, t14);
|
return datatree.AddDivide(t13, t14);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return datatree.AddDivide(darg1, arg2);
|
||||||
case oLess:
|
case oLess:
|
||||||
case oGreater:
|
case oGreater:
|
||||||
case oLessEqual:
|
case oLessEqual:
|
||||||
|
@ -1303,6 +1576,7 @@ void
|
||||||
BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
||||||
const temporary_terms_type &temporary_terms) const
|
const temporary_terms_type &temporary_terms) const
|
||||||
{
|
{
|
||||||
|
//cout << "writeOutput binary\n";
|
||||||
// If current node is a temporary term
|
// If current node is a temporary term
|
||||||
temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<BinaryOpNode *>(this));
|
temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<BinaryOpNode *>(this));
|
||||||
if (it != temporary_terms.end())
|
if (it != temporary_terms.end())
|
||||||
|
@ -1474,6 +1748,213 @@ BinaryOpNode::collectExogenous(set<pair<int, int> > &result) const
|
||||||
arg2->collectExogenous(result);
|
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
|
NodeID
|
||||||
BinaryOpNode::toStatic(DataTree &static_datatree) const
|
BinaryOpNode::toStatic(DataTree &static_datatree) const
|
||||||
{
|
{
|
||||||
|
@ -1796,6 +2277,75 @@ TrinaryOpNode::collectExogenous(set<pair<int, int> > &result) const
|
||||||
arg3->collectExogenous(result);
|
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
|
NodeID
|
||||||
TrinaryOpNode::toStatic(DataTree &static_datatree) const
|
TrinaryOpNode::toStatic(DataTree &static_datatree) const
|
||||||
{
|
{
|
||||||
|
@ -1828,6 +2378,14 @@ UnknownFunctionNode::computeDerivative(int deriv_id)
|
||||||
exit(EXIT_FAILURE);
|
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
|
void
|
||||||
UnknownFunctionNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
|
UnknownFunctionNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
|
||||||
temporary_terms_type &temporary_terms,
|
temporary_terms_type &temporary_terms,
|
||||||
|
@ -1907,6 +2465,25 @@ UnknownFunctionNode::compile(ofstream &CompileCode, bool lhs_rhs, const temporar
|
||||||
exit(EXIT_FAILURE);
|
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
|
NodeID
|
||||||
UnknownFunctionNode::toStatic(DataTree &static_datatree) const
|
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)
|
//! 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 */
|
/*! You shoud use getDerivative() to get the benefit of symbolic a priori and of caching */
|
||||||
virtual NodeID computeDerivative(int deriv_id) = 0;
|
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:
|
protected:
|
||||||
//! Reference to the enclosing DataTree
|
//! Reference to the enclosing DataTree
|
||||||
|
@ -136,6 +140,10 @@ public:
|
||||||
For an equal node, returns the derivative of lhs minus rhs */
|
For an equal node, returns the derivative of lhs minus rhs */
|
||||||
NodeID getDerivative(int deriv_id);
|
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
|
//! Returns precedence of node
|
||||||
/*! Equals 100 for constants, variables, unary ops, and temporary terms */
|
/*! Equals 100 for constants, variables, unary ops, and temporary terms */
|
||||||
virtual int precedence(ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const;
|
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;
|
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
|
//! 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)
|
//! Writes output of node (with no temporary terms and with "outside model" output type)
|
||||||
void writeOutput(ostream &output);
|
void writeOutput(ostream &output);
|
||||||
|
@ -174,6 +182,7 @@ public:
|
||||||
map_idx_type &map_idx) const;
|
map_idx_type &map_idx) const;
|
||||||
|
|
||||||
class EvalException
|
class EvalException
|
||||||
|
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -185,6 +194,8 @@ public:
|
||||||
adds the result in the static_datatree argument (and not in the original datatree), and returns it.
|
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;
|
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)
|
//! Object used to compare two nodes (using their indexes)
|
||||||
|
@ -204,6 +215,7 @@ private:
|
||||||
//! Id from numerical constants table
|
//! Id from numerical constants table
|
||||||
const int id;
|
const int id;
|
||||||
virtual NodeID computeDerivative(int deriv_id);
|
virtual NodeID computeDerivative(int deriv_id);
|
||||||
|
virtual NodeID computeChaineRuleDerivative(int deriv_id, map<int, NodeID> &recursive_variables, int var, int lag_);
|
||||||
public:
|
public:
|
||||||
NumConstNode(DataTree &datatree_arg, int id_arg);
|
NumConstNode(DataTree &datatree_arg, int id_arg);
|
||||||
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const;
|
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 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 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 NodeID toStatic(DataTree &static_datatree) const;
|
||||||
|
virtual pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Symbol or variable node
|
//! Symbol or variable node
|
||||||
|
@ -226,6 +239,7 @@ private:
|
||||||
//! Derivation ID
|
//! Derivation ID
|
||||||
const int deriv_id;
|
const int deriv_id;
|
||||||
virtual NodeID computeDerivative(int deriv_id_arg);
|
virtual NodeID computeDerivative(int deriv_id_arg);
|
||||||
|
virtual NodeID computeChaineRuleDerivative(int deriv_id, map<int, NodeID> &recursive_variables, int var, int lag_);
|
||||||
public:
|
public:
|
||||||
VariableNode(DataTree &datatree_arg, int symb_id_arg, int lag_arg, int deriv_id_arg);
|
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;
|
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 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 NodeID toStatic(DataTree &static_datatree) const;
|
||||||
int get_symb_id() const { return symb_id; };
|
int get_symb_id() const { return symb_id; };
|
||||||
|
virtual pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Unary operator node
|
//! Unary operator node
|
||||||
|
@ -252,6 +267,7 @@ private:
|
||||||
const NodeID arg;
|
const NodeID arg;
|
||||||
const UnaryOpcode op_code;
|
const UnaryOpcode op_code;
|
||||||
virtual NodeID computeDerivative(int deriv_id);
|
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;
|
virtual int cost(const temporary_terms_type &temporary_terms, bool is_matlab) const;
|
||||||
public:
|
public:
|
||||||
|
@ -276,6 +292,7 @@ public:
|
||||||
//! Returns op code
|
//! Returns op code
|
||||||
UnaryOpcode get_op_code() const { return(op_code); };
|
UnaryOpcode get_op_code() const { return(op_code); };
|
||||||
virtual NodeID toStatic(DataTree &static_datatree) const;
|
virtual NodeID toStatic(DataTree &static_datatree) const;
|
||||||
|
virtual pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Binary operator node
|
//! Binary operator node
|
||||||
|
@ -285,6 +302,8 @@ private:
|
||||||
const NodeID arg1, arg2;
|
const NodeID arg1, arg2;
|
||||||
const BinaryOpcode op_code;
|
const BinaryOpcode op_code;
|
||||||
virtual NodeID computeDerivative(int deriv_id);
|
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;
|
virtual int cost(const temporary_terms_type &temporary_terms, bool is_matlab) const;
|
||||||
public:
|
public:
|
||||||
BinaryOpNode(DataTree &datatree_arg, const NodeID arg1_arg,
|
BinaryOpNode(DataTree &datatree_arg, const NodeID arg1_arg,
|
||||||
|
@ -312,6 +331,7 @@ public:
|
||||||
//! Returns op code
|
//! Returns op code
|
||||||
BinaryOpcode get_op_code() const { return(op_code); };
|
BinaryOpcode get_op_code() const { return(op_code); };
|
||||||
virtual NodeID toStatic(DataTree &static_datatree) const;
|
virtual NodeID toStatic(DataTree &static_datatree) const;
|
||||||
|
pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Trinary operator node
|
//! Trinary operator node
|
||||||
|
@ -322,6 +342,8 @@ private:
|
||||||
const NodeID arg1, arg2, arg3;
|
const NodeID arg1, arg2, arg3;
|
||||||
const TrinaryOpcode op_code;
|
const TrinaryOpcode op_code;
|
||||||
virtual NodeID computeDerivative(int deriv_id);
|
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;
|
virtual int cost(const temporary_terms_type &temporary_terms, bool is_matlab) const;
|
||||||
public:
|
public:
|
||||||
TrinaryOpNode(DataTree &datatree_arg, const NodeID arg1_arg,
|
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 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 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 NodeID toStatic(DataTree &static_datatree) const;
|
||||||
|
virtual pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Unknown function node
|
//! Unknown function node
|
||||||
|
@ -352,6 +375,7 @@ private:
|
||||||
const int symb_id;
|
const int symb_id;
|
||||||
const vector<NodeID> arguments;
|
const vector<NodeID> arguments;
|
||||||
virtual NodeID computeDerivative(int deriv_id);
|
virtual NodeID computeDerivative(int deriv_id);
|
||||||
|
virtual NodeID computeChaineRuleDerivative(int deriv_id, map<int, NodeID> &recursive_variables, int var, int lag_);
|
||||||
public:
|
public:
|
||||||
UnknownFunctionNode(DataTree &datatree_arg, int symb_id_arg,
|
UnknownFunctionNode(DataTree &datatree_arg, int symb_id_arg,
|
||||||
const vector<NodeID> &arguments_arg);
|
const vector<NodeID> &arguments_arg);
|
||||||
|
@ -370,6 +394,7 @@ public:
|
||||||
virtual double eval(const eval_context_type &eval_context) const throw (EvalException);
|
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 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 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
|
//! 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;
|
bool is_linear;
|
||||||
int *Equation, *Own_Derivative;
|
int *Equation, *Own_Derivative;
|
||||||
EquationType *Equation_Type;
|
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_in_Equation;
|
||||||
//temporary_terms_type *Temporary_terms;
|
//temporary_terms_type *Temporary_terms;
|
||||||
temporary_terms_inuse_type *Temporary_InUse;
|
temporary_terms_inuse_type *Temporary_InUse;
|
||||||
|
|
|
@ -186,7 +186,6 @@ namespace MFS
|
||||||
GraphvizDigraph_2_AdjacencyList(GraphvizDigraph& G1, set<int> select_index)
|
GraphvizDigraph_2_AdjacencyList(GraphvizDigraph& G1, set<int> select_index)
|
||||||
{
|
{
|
||||||
unsigned int n = select_index.size();
|
unsigned int n = select_index.size();
|
||||||
//cout << "n=" << n << "\n";
|
|
||||||
AdjacencyList_type G(n);
|
AdjacencyList_type G(n);
|
||||||
property_map<AdjacencyList_type, vertex_index_t>::type v_index = get(vertex_index, G);
|
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);
|
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);
|
int ii = target(*it_out, G1);
|
||||||
if (select_index.find(ii) != select_index.end())
|
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(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;
|
return G;
|
||||||
|
@ -367,110 +360,8 @@ namespace MFS
|
||||||
return something_has_been_done;
|
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
|
bool
|
||||||
Suppression_of_Vertex_X_if_it_loops_store_in_set_of_feedback_vertex_Step(set<int> &feed_back_vertices, AdjacencyList_type& G)
|
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
|
#endif
|
||||||
|
|
||||||
//Rule 3
|
//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);
|
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
|
#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
|
#endif
|
||||||
}
|
}
|
||||||
vector<int> circuit;
|
vector<int> circuit;
|
||||||
|
|
|
@ -25,8 +25,6 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <boost/graph/graphviz.hpp>
|
#include <boost/graph/graphviz.hpp>
|
||||||
#include <boost/graph/adjacency_list.hpp>
|
#include <boost/graph/adjacency_list.hpp>
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
|
@ -44,25 +42,42 @@ using namespace boost;
|
||||||
|
|
||||||
namespace MFS
|
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);
|
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);
|
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 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
|
//! 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 Elimination_of_Vertex_With_One_or_Less_Indegree_or_Outdegree_Step(AdjacencyList_type& G);
|
||||||
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
|
//! Graphe reduction: elimination of a vertex inside a clique
|
||||||
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 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);
|
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);
|
//! Print the Graph
|
||||||
AdjacencyList_type AM_2_AdjacencyList(bool* AMp,unsigned int n);
|
|
||||||
void Print(GraphvizDigraph& G);
|
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);
|
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);
|
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_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_cylce(AdjacencyList_type& g, vector<int> &circuit_stack, int size);
|
||||||
bool has_cycle(vector<int> &circuit_stack, AdjacencyList_type& G);
|
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);
|
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(AdjacencyList_type::vertex_descriptor vertex_to_eliminate, AdjacencyList_type& G);
|
||||||
void Suppress(int vertex_num, 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);
|
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