- 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-bf33cf982152
issue#70
ferhat 2009-06-05 14:45:23 +00:00
parent 518c5fba93
commit 3737c1aa2e
11 changed files with 4263 additions and 3973 deletions

View File

@ -17,7 +17,6 @@
* along with Dynare. If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream>
#include <sstream>
#include <fstream>
@ -38,25 +37,27 @@ using namespace std;
using namespace boost;
using namespace MFS;
BlockTriangular::BlockTriangular(const SymbolTable &symbol_table_arg) :
symbol_table(symbol_table_arg),
normalization(symbol_table_arg),
incidencematrix(symbol_table_arg)
BlockTriangular::BlockTriangular(SymbolTable &symbol_table_arg, NumericalConstants &num_const_arg)
: symbol_table(symbol_table_arg),
//normalization(symbol_table_arg),
incidencematrix(symbol_table_arg),
num_const(num_const_arg)
{
bt_verbose = 0;
ModelBlock = NULL;
periods = 0;
Normalized_Equation = new DataTree(symbol_table, num_const);
}
BlockTriangular::~BlockTriangular()
{
delete Normalized_Equation;
}
//------------------------------------------------------------------------------
// Find the prologue and the epilogue of the model
void
BlockTriangular::Prologue_Epilogue(bool* IM, int &prologue, int &epilogue, int n, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM, bool* IM0)
BlockTriangular::Prologue_Epilogue(bool *IM, int &prologue, int &epilogue, int n, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM, bool *IM0)
{
bool modifie = 1;
int i, j, k, l = 0;
@ -65,10 +66,10 @@ BlockTriangular::Prologue_Epilogue(bool* IM, int &prologue, int &epilogue, int n
while (modifie)
{
modifie = 0;
for (i = prologue;i < n;i++)
for (i = prologue; i < n; i++)
{
k = 0;
for (j = prologue;j < n;j++)
for (j = prologue; j < n; j++)
{
if (IM[i*n + j])
{
@ -89,10 +90,10 @@ BlockTriangular::Prologue_Epilogue(bool* IM, int &prologue, int &epilogue, int n
while (modifie)
{
modifie = 0;
for (i = prologue;i < n - epilogue;i++)
for (i = prologue; i < n - epilogue; i++)
{
k = 0;
for (j = prologue;j < n - epilogue;j++)
for (j = prologue; j < n - epilogue; j++)
{
if (IM[j*n + i])
{
@ -110,15 +111,13 @@ BlockTriangular::Prologue_Epilogue(bool* IM, int &prologue, int &epilogue, int n
}
}
//------------------------------------------------------------------------------
// Find a matching between equations and endogenous variables
bool
BlockTriangular::Compute_Normalization(bool *IM, int equation_number, int prologue, int epilogue, bool verbose, bool *IM0, vector<int> &Index_Equ_IM) const
{
{
int n = equation_number - prologue - epilogue;
typedef adjacency_list<vecS, vecS, undirectedS> BipartiteGraph;
/*
@ -132,7 +131,6 @@ BlockTriangular::Compute_Normalization(bool *IM, int equation_number, int prolog
if (IM0[(i+prologue) * equation_number+j+prologue])
add_edge(i + n, j, g);
// Compute maximum cardinality matching
typedef vector<graph_traits<BipartiteGraph>::vertex_descriptor> mate_map_t;
mate_map_t mate_map(2*n);
@ -156,29 +154,82 @@ BlockTriangular::Compute_Normalization(bool *IM, int equation_number, int prolog
}
vector<int> Index_Equ_IM_tmp(Index_Equ_IM);
bool *SIM;
SIM = (bool*)malloc(equation_number*equation_number*sizeof(bool));
SIM = (bool *) malloc(equation_number*equation_number*sizeof(bool));
memcpy(SIM, IM, equation_number*equation_number*sizeof(bool));
for (int i = 0; i < n; i++)
{
Index_Equ_IM[i + prologue] = Index_Equ_IM_tmp[mate_map[i] - n + prologue];
for (int k=0; k<n; k++)
for (int k = 0; k < n; k++)
IM[(i+prologue)*equation_number+k +prologue] = SIM[(mate_map[i]-n+prologue)*equation_number+k +prologue];
}
free(SIM);
}
return check;
}
t_vtype
BlockTriangular::Get_Variable_LeadLag_By_Block(vector<int > &components_set, int nb_blck_sim, int prologue, int epilogue) const
{
int nb_endo = symbol_table.endo_nbr();
vector<int> variable_blck(nb_endo), equation_blck(nb_endo);
t_vtype Variable_Type(nb_endo);
for (int i = 0; i < nb_endo; i++)
{
if (i < prologue)
{
variable_blck[Index_Var_IM[i]] = i;
equation_blck[Index_Equ_IM[i]] = i;
}
else if (i < components_set.size() + prologue)
{
variable_blck[Index_Var_IM[i]] = components_set[i-prologue] + prologue;
equation_blck[Index_Equ_IM[i]] = components_set[i-prologue] + prologue;
}
else
{
variable_blck[Index_Var_IM[i]] = i- (nb_endo - nb_blck_sim - prologue - epilogue);
equation_blck[Index_Equ_IM[i]] = i- (nb_endo - nb_blck_sim - prologue - epilogue);
}
//cout << "equation_blck[" << Index_Equ_IM[i] << "]=" << equation_blck[Index_Equ_IM[i]] << " variable_blck[" << Index_Var_IM[i] << "] = " << variable_blck[Index_Var_IM[i]] << "\n";
Variable_Type[i] = make_pair(0, 0);
}
for (int k = -incidencematrix.Model_Max_Lag_Endo; k <= incidencematrix.Model_Max_Lead_Endo; k++)
{
bool *Cur_IM = incidencematrix.Get_IM(k, eEndogenous);
if (Cur_IM)
{
for (int i = 0; i < nb_endo; i++)
{
int i_1 = Index_Var_IM[i];
for (int j = 0; j < nb_endo; j++)
{
if (Cur_IM[i_1 + Index_Equ_IM[ j] * nb_endo] and variable_blck[i_1] == equation_blck[Index_Equ_IM[ j]])
{
if (k > Variable_Type[i_1].second)
Variable_Type[i_1] = make_pair(Variable_Type[i_1].first, k);
if (k < -Variable_Type[i_1].first)
Variable_Type[i_1] = make_pair(-k, Variable_Type[i_1].second);
}
}
}
}
}
/*for(int i = 0; i < nb_endo; i++)
cout << "Variable_Type[" << Index_Equ_IM[i] << "].first = " << Variable_Type[Index_Equ_IM[i]].first << " Variable_Type[" << Index_Equ_IM[i] << "].second=" << Variable_Type[Index_Equ_IM[i]].second << "\n";*/
return (Variable_Type);
}
void
BlockTriangular::Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Block(bool *IM, int nb_var, int prologue, int epilogue, vector<int> &Index_Equ_IM, vector<int> &Index_Var_IM, vector<pair<int, int> > &blocks, t_etype &Equation_Type, bool verbose_) const
{
{
t_vtype V_Variable_Type;
int n = nb_var - prologue - epilogue;
bool *AMp;
AMp = (bool*) malloc(n*n*sizeof(bool));
AMp = (bool *) malloc(n*n*sizeof(bool));
//transforms the incidence matrix of the complet model into an adjancent matrix of the non-recursive part of the model
for (int i=prologue; i<nb_var - epilogue; i++)
for (int j=prologue; j<nb_var - epilogue; j++)
if (j!=i)
for (int i = prologue; i < nb_var - epilogue; i++)
for (int j = prologue; j < nb_var - epilogue; j++)
if (j != i)
AMp[(i-prologue)*n+j-prologue] = IM[i*nb_var + j];
else
AMp[(i-prologue)*n+j-prologue] = 0;
@ -190,7 +241,7 @@ BlockTriangular::Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Blo
int num = strong_components(G2, &component[0]);
blocks = vector<pair<int, int> >(num , make_pair(0,0));
blocks = vector<pair<int, int> >(num, make_pair(0, 0));
//This vector contains for each block:
// - first set = equations belonging to the block,
@ -198,28 +249,29 @@ BlockTriangular::Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Blo
// - third vector = the reordered non-feedback variables.
vector<pair<set<int>, pair<set<int>, vector<int> > > > components_set(num);
for (unsigned int i=0; i<component.size(); i++)
for (unsigned int i = 0; i < component.size(); i++)
{
blocks[component[i]].first++;
components_set[component[i]].first.insert(i);
}
V_Variable_Type = Get_Variable_LeadLag_By_Block(component, num, prologue, epilogue);
vector<int> tmp_Index_Equ_IM(Index_Equ_IM), tmp_Index_Var_IM(Index_Var_IM);
int order = prologue;
bool *SIM;
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));
//Add a loop on vertices which could not be normalized => force those vvertices to belong to the feedback set
for(int i=0; i<n; i++)
if(Equation_Type[Index_Equ_IM[i+prologue]].first == E_SOLVE or Equation_Type[Index_Equ_IM[i+prologue]].first == E_EVALUATE_S)
//Add a loop on vertices which could not be normalized or vertices related to lead variables => force those vertices to belong to the feedback set
for (int i = 0; i < n; i++)
if (Equation_Type[Index_Equ_IM[i+prologue]].first == E_SOLVE or V_Variable_Type[Index_Var_IM[i+prologue]].second >= 0 or V_Variable_Type[Index_Var_IM[i+prologue]].first > 0)
add_edge(i, i, G2);
//For each block, the minimum set of feedback variable is computed
// and the non-feedback variables are reordered to get
// a sub-recursive block without feedback variables
for (int i=0; i<num; i++)
for (int i = 0; i < num; i++)
{
AdjacencyList_type G = GraphvizDigraph_2_AdjacencyList(G2, components_set[i].first);
set<int> feed_back_vertices;
@ -231,7 +283,7 @@ BlockTriangular::Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Blo
vector<int> Reordered_Vertice;
Reordered_Vertice = Reorder_the_recursive_variables(G, feed_back_vertices);
//First we have the recursive equations conditional on feedback variables
for (vector<int>::iterator its=Reordered_Vertice.begin();its != Reordered_Vertice.end(); its++)
for (vector<int>::iterator its = Reordered_Vertice.begin(); its != Reordered_Vertice.end(); its++)
{
Index_Equ_IM[order] = tmp_Index_Equ_IM[*its+prologue];
Index_Var_IM[order] = tmp_Index_Var_IM[*its+prologue];
@ -239,7 +291,7 @@ BlockTriangular::Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Blo
}
components_set[i].second.second = Reordered_Vertice;
//Second we have the equations related to the feedback variables
for (set<int>::iterator its=feed_back_vertices.begin();its != feed_back_vertices.end(); its++)
for (set<int>::iterator its = feed_back_vertices.begin(); its != feed_back_vertices.end(); its++)
{
Index_Equ_IM[order] = tmp_Index_Equ_IM[v_index[vertex(*its, G)]+prologue];
Index_Var_IM[order] = tmp_Index_Var_IM[v_index[vertex(*its, G)]+prologue];
@ -248,10 +300,10 @@ BlockTriangular::Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Blo
}
free(AMp);
free(SIM);
}
}
void
BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, BlockType type, BlockSimulationType SimType, Model_Block * ModelBlock, t_etype &Equation_Type, int recurs_Size)
BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, BlockType type, BlockSimulationType SimType, Model_Block *ModelBlock, t_etype &Equation_Type, int recurs_Size)
{
int i, j, k, l, ls, m, i_1, Lead, Lag, first_count_equ, i1, li;
int *tmp_size, *tmp_size_other_endo, *tmp_size_exo, *tmp_var, *tmp_endo, *tmp_other_endo, *tmp_exo, tmp_nb_other_endo, tmp_nb_exo, nb_lead_lag_endo;
@ -260,36 +312,28 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
bool *IM, OK;
int Lag_Endo, Lead_Endo, Lag_Exo, Lead_Exo, Lag_Other_Endo, Lead_Other_Endo;
cout << "Allocate Block=" << count_Block << " recurs_Size=" << recurs_Size << "\n";
ModelBlock->Periods = periods;
ModelBlock->Block_List[count_Block].is_linear=true;
ModelBlock->Block_List[count_Block].is_linear = true;
ModelBlock->Block_List[count_Block].Size = size;
ModelBlock->Block_List[count_Block].Type = type;
ModelBlock->Block_List[count_Block].Nb_Recursives = recurs_Size;
ModelBlock->Block_List[count_Block].Temporary_InUse=new temporary_terms_inuse_type ();
ModelBlock->Block_List[count_Block].Temporary_InUse = new temporary_terms_inuse_type();
ModelBlock->Block_List[count_Block].Temporary_InUse->clear();
ModelBlock->Block_List[count_Block].Simulation_Type = SimType;
ModelBlock->Block_List[count_Block].Equation = (int*)malloc(ModelBlock->Block_List[count_Block].Size * sizeof(int));
ModelBlock->Block_List[count_Block].Equation_Type = (EquationType*)malloc(ModelBlock->Block_List[count_Block].Size * sizeof(EquationType));
ModelBlock->Block_List[count_Block].Equation_Type_Var = (int*)malloc(ModelBlock->Block_List[count_Block].Size * sizeof(int));
/*cout << "ModelBlock->Block_List[" << count_Block << "].Size = " << ModelBlock->Block_List[count_Block].Size << " E_UNKNOWN=" << E_UNKNOWN << "\n";
t_etype eType(size);
cout << "eType[0].first=" << eType[0].first << " eType[0].second=" << eType[0].second << " eType.size()=" << eType.size() << "\n";
ModelBlock->Block_List[count_Block].Equation_Type(eType);
cout << "after that\n";*/
ModelBlock->Block_List[count_Block].Variable = (int*)malloc(ModelBlock->Block_List[count_Block].Size * sizeof(int));
ModelBlock->Block_List[count_Block].Temporary_Terms_in_Equation = (temporary_terms_type**)malloc(ModelBlock->Block_List[count_Block].Size * sizeof(temporary_terms_type));
ModelBlock->Block_List[count_Block].Own_Derivative = (int*)malloc(ModelBlock->Block_List[count_Block].Size * sizeof(int));
ModelBlock->Block_List[count_Block].Equation = (int *) malloc(ModelBlock->Block_List[count_Block].Size * sizeof(int));
ModelBlock->Block_List[count_Block].Equation_Type = (EquationType *) malloc(ModelBlock->Block_List[count_Block].Size * sizeof(EquationType));
ModelBlock->Block_List[count_Block].Equation_Normalized = (NodeID *) malloc(ModelBlock->Block_List[count_Block].Size * sizeof(NodeID));
ModelBlock->Block_List[count_Block].Variable = (int *) malloc(ModelBlock->Block_List[count_Block].Size * sizeof(int));
ModelBlock->Block_List[count_Block].Temporary_Terms_in_Equation = (temporary_terms_type **) malloc(ModelBlock->Block_List[count_Block].Size * sizeof(temporary_terms_type));
ModelBlock->Block_List[count_Block].Own_Derivative = (int *) malloc(ModelBlock->Block_List[count_Block].Size * sizeof(int));
Lead = Lag = 0;
first_count_equ = *count_Equ;
tmp_var = (int*)malloc(size * sizeof(int));
tmp_endo = (int*)malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1) * sizeof(int));
tmp_other_endo = (int*)malloc(symbol_table.endo_nbr() * sizeof(int));
tmp_size = (int*)malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1) * sizeof(int));
//cout << "tmp_size = (int*)malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1= " << incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1 << ") * sizeof(int))\n";
tmp_size_other_endo = (int*)malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1) * sizeof(int));
tmp_size_exo = (int*)malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1) * sizeof(int));
tmp_var = (int *) malloc(size * sizeof(int));
tmp_endo = (int *) malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1) * sizeof(int));
tmp_other_endo = (int *) malloc(symbol_table.endo_nbr() * sizeof(int));
tmp_size = (int *) malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1) * sizeof(int));
tmp_size_other_endo = (int *) malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1) * sizeof(int));
tmp_size_exo = (int *) malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1) * sizeof(int));
memset(tmp_size_exo, 0, (incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1)*sizeof(int));
memset(tmp_size_other_endo, 0, (incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1)*sizeof(int));
memset(tmp_size, 0, (incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1)*sizeof(int));
@ -299,18 +343,25 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
Lag_Endo = Lead_Endo = Lag_Other_Endo = Lead_Other_Endo = Lag_Exo = Lead_Exo = 0;
//Variable by variable looking for all leads and lags its occurence in each equation of the block
tmp_variable_evaluated = (bool*)malloc(symbol_table.endo_nbr()*sizeof(bool));
tmp_variable_evaluated = (bool *) malloc(symbol_table.endo_nbr()*sizeof(bool));
memset(tmp_variable_evaluated, 0, symbol_table.endo_nbr()*sizeof(bool));
for (i = 0;i < size;i++)
for (i = 0; i < size; i++)
{
ModelBlock->Block_List[count_Block].Temporary_Terms_in_Equation[i]=new temporary_terms_type ();
ModelBlock->Block_List[count_Block].Temporary_Terms_in_Equation[i] = new temporary_terms_type();
ModelBlock->Block_List[count_Block].Temporary_Terms_in_Equation[i]->clear();
ModelBlock->Block_List[count_Block].Equation[i] = Index_Equ_IM[*count_Equ];
ModelBlock->Block_List[count_Block].Variable[i] = Index_Var_IM[*count_Equ];
ModelBlock->Block_List[count_Block].Equation_Type[i] = Equation_Type[Index_Equ_IM[*count_Equ]].first;
ModelBlock->Block_List[count_Block].Equation_Type_Var[i] = Equation_Type[Index_Equ_IM[*count_Equ]].second;
ModelBlock->Block_List[count_Block].Equation_Normalized[i] = Equation_Type[Index_Equ_IM[*count_Equ]].second;
/*if(Equation_Type[Index_Equ_IM[*count_Equ]].second)
{
temporary_terms_type temporary_terms;
cout << "Equation_Type[Index_Equ_IM[*count_Equ]].second->get_op_code()=" << Equation_Type[Index_Equ_IM[*count_Equ]].second->get_op_code() << "\n";
cout << "ModelBlock->Block_List[" << count_Block << "].Equation_Normalized[" << i << "]->get_op_code()=" << ModelBlock->Block_List[count_Block].Equation_Normalized[i]->get_op_code() << "\n";
ModelBlock->Block_List[count_Block].Equation_Normalized[i]->writeOutput(cout, oMatlabDynamicModelSparse, temporary_terms);
}*/
i_1 = Index_Var_IM[*count_Equ];
for (k = -incidencematrix.Model_Max_Lag_Endo; k<=incidencematrix.Model_Max_Lead_Endo; k++)
for (k = -incidencematrix.Model_Max_Lag_Endo; k <= incidencematrix.Model_Max_Lead_Endo; k++)
{
Cur_IM = incidencematrix.Get_IM(k, eEndogenous);
if (Cur_IM)
@ -318,7 +369,7 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
OK = false;
if (k >= 0)
{
for (j = 0;j < size;j++)
for (j = 0; j < size; j++)
{
if (Cur_IM[i_1 + Index_Equ_IM[first_count_equ + j]*symbol_table.endo_nbr()])
{
@ -337,7 +388,7 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
}
else
{
for (j = 0;j < size;j++)
for (j = 0; j < size; j++)
{
if (Cur_IM[i_1 + Index_Equ_IM[first_count_equ + j]*symbol_table.endo_nbr()])
{
@ -363,15 +414,15 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
Lead_Endo = Lead;
tmp_nb_other_endo = 0;
for (i = 0;i < size;i++)
for (i = 0; i < size; i++)
{
for (k = -incidencematrix.Model_Max_Lag_Endo; k<=incidencematrix.Model_Max_Lead_Endo; k++)
for (k = -incidencematrix.Model_Max_Lag_Endo; k <= incidencematrix.Model_Max_Lead_Endo; k++)
{
Cur_IM = incidencematrix.Get_IM(k, eEndogenous);
if (Cur_IM)
{
i_1 = Index_Equ_IM[first_count_equ+i] * symbol_table.endo_nbr();
for (j = 0;j < symbol_table.endo_nbr();j++)
for (j = 0; j < symbol_table.endo_nbr(); j++)
if (Cur_IM[i_1 + j])
{
if (!tmp_variable_evaluated[j])
@ -379,13 +430,13 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
tmp_other_endo[j] = 1;
tmp_nb_other_endo++;
}
if (k>0 && k>Lead_Other_Endo)
if (k > 0 && k > Lead_Other_Endo)
Lead_Other_Endo = k;
else if (k<0 && (-k)>Lag_Other_Endo)
else if (k < 0 && (-k) > Lag_Other_Endo)
Lag_Other_Endo = -k;
if (k>0 && k>Lead)
if (k > 0 && k > Lead)
Lead = k;
else if (k<0 && (-k)>Lag)
else if (k < 0 && (-k) > Lag)
Lag = -k;
tmp_size_other_endo[k+incidencematrix.Model_Max_Lag_Endo]++;
}
@ -393,21 +444,20 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
}
}
ModelBlock->Block_List[count_Block].nb_other_endo = tmp_nb_other_endo;
ModelBlock->Block_List[count_Block].Other_Endogenous = (int*)malloc(tmp_nb_other_endo * sizeof(int));
ModelBlock->Block_List[count_Block].Other_Endogenous = (int *) malloc(tmp_nb_other_endo * sizeof(int));
tmp_exo = (int*)malloc(symbol_table.exo_nbr() * sizeof(int));
tmp_exo = (int *) malloc(symbol_table.exo_nbr() * sizeof(int));
memset(tmp_exo, 0, symbol_table.exo_nbr() * sizeof(int));
tmp_nb_exo = 0;
for (i = 0;i < size;i++)
for (i = 0; i < size; i++)
{
for (k = -incidencematrix.Model_Max_Lag_Exo; k<=incidencematrix.Model_Max_Lead_Exo; k++)
for (k = -incidencematrix.Model_Max_Lag_Exo; k <= incidencematrix.Model_Max_Lead_Exo; k++)
{
Cur_IM = incidencematrix.Get_IM(k, eExogenous);
if (Cur_IM)
{
i_1 = Index_Equ_IM[first_count_equ+i] * symbol_table.exo_nbr();
for (j=0;j<symbol_table.exo_nbr();j++)
for (j = 0; j < symbol_table.exo_nbr(); j++)
if (Cur_IM[i_1 + j])
{
if (!tmp_exo[j])
@ -415,13 +465,13 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
tmp_exo[j] = 1;
tmp_nb_exo++;
}
if (k>0 && k>Lead_Exo)
if (k > 0 && k > Lead_Exo)
Lead_Exo = k;
else if (k<0 && (-k)>Lag_Exo)
else if (k < 0 && (-k) > Lag_Exo)
Lag_Exo = -k;
if (k>0 && k>Lead)
if (k > 0 && k > Lead)
Lead = k;
else if (k<0 && (-k)>Lag)
else if (k < 0 && (-k) > Lag)
Lag = -k;
tmp_size_exo[k+incidencematrix.Model_Max_Lag_Exo]++;
}
@ -429,11 +479,10 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
}
}
ModelBlock->Block_List[count_Block].nb_exo = tmp_nb_exo;
ModelBlock->Block_List[count_Block].Exogenous = (int*)malloc(tmp_nb_exo * sizeof(int));
ModelBlock->Block_List[count_Block].Exogenous = (int *) malloc(tmp_nb_exo * sizeof(int));
k = 0;
for (j=0;j<symbol_table.exo_nbr();j++)
for (j = 0; j < symbol_table.exo_nbr(); j++)
if (tmp_exo[j])
{
ModelBlock->Block_List[count_Block].Exogenous[k] = j;
@ -450,29 +499,29 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
ModelBlock->Block_List[count_Block].Max_Lead_Other_Endo = Lead_Other_Endo;
ModelBlock->Block_List[count_Block].Max_Lag_Exo = Lag_Exo;
ModelBlock->Block_List[count_Block].Max_Lead_Exo = Lead_Exo;
ModelBlock->Block_List[count_Block].IM_lead_lag = (IM_compact*)malloc((Lead + Lag + 1) * sizeof(IM_compact));
ModelBlock->Block_List[count_Block].IM_lead_lag = (IM_compact *) malloc((Lead + Lag + 1) * sizeof(IM_compact));
ls = l = li = size;
i1 = 0;
ModelBlock->Block_List[count_Block].Nb_Lead_Lag_Endo = nb_lead_lag_endo;
for (i = 0;i < Lead + Lag + 1;i++)
for (i = 0; i < Lead + Lag + 1; i++)
{
if (incidencematrix.Model_Max_Lag_Endo-Lag+i>=0)
if (incidencematrix.Model_Max_Lag_Endo-Lag+i >= 0)
{
ModelBlock->Block_List[count_Block].IM_lead_lag[i].size = tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i];
ModelBlock->Block_List[count_Block].IM_lead_lag[i].nb_endo = tmp_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i];
ModelBlock->Block_List[count_Block].IM_lead_lag[i].u = (int*)malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
ModelBlock->Block_List[count_Block].IM_lead_lag[i].us = (int*)malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
ModelBlock->Block_List[count_Block].IM_lead_lag[i].Var = (int*)malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ = (int*)malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
ModelBlock->Block_List[count_Block].IM_lead_lag[i].Var_Index = (int*)malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ_Index = (int*)malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
ModelBlock->Block_List[count_Block].IM_lead_lag[i].u = (int *) malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
ModelBlock->Block_List[count_Block].IM_lead_lag[i].us = (int *) malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
ModelBlock->Block_List[count_Block].IM_lead_lag[i].Var = (int *) malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ = (int *) malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
ModelBlock->Block_List[count_Block].IM_lead_lag[i].Var_Index = (int *) malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ_Index = (int *) malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
ModelBlock->Block_List[count_Block].IM_lead_lag[i].size_other_endo = tmp_size_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i];
ModelBlock->Block_List[count_Block].IM_lead_lag[i].nb_other_endo = tmp_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i];
ModelBlock->Block_List[count_Block].IM_lead_lag[i].u_other_endo = (int*)malloc(tmp_size_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
ModelBlock->Block_List[count_Block].IM_lead_lag[i].Var_other_endo = (int*)malloc(tmp_size_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ_other_endo = (int*)malloc(tmp_size_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
ModelBlock->Block_List[count_Block].IM_lead_lag[i].Var_Index_other_endo = (int*)malloc(tmp_size_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ_Index_other_endo = (int*)malloc(tmp_size_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
ModelBlock->Block_List[count_Block].IM_lead_lag[i].u_other_endo = (int *) malloc(tmp_size_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
ModelBlock->Block_List[count_Block].IM_lead_lag[i].Var_other_endo = (int *) malloc(tmp_size_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ_other_endo = (int *) malloc(tmp_size_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
ModelBlock->Block_List[count_Block].IM_lead_lag[i].Var_Index_other_endo = (int *) malloc(tmp_size_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ_Index_other_endo = (int *) malloc(tmp_size_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
}
else
ModelBlock->Block_List[count_Block].IM_lead_lag[i].size = 0;
@ -491,11 +540,11 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
IM = incidencematrix.Get_IM(i - Lag, eEndogenous);
if (IM)
{
for (j = first_count_equ;j < size + first_count_equ;j++)
for (j = first_count_equ; j < size + first_count_equ; j++)
{
i_1 = Index_Var_IM[j];
m = 0;
for (k = first_count_equ;k < size + first_count_equ;k++)
for (k = first_count_equ; k < size + first_count_equ; k++)
if (IM[i_1 + Index_Equ_IM[k] * symbol_table.endo_nbr()])
m++;
if (m > 0)
@ -505,10 +554,10 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
}
}
m = 0;
for (j = first_count_equ;j < size + first_count_equ;j++)
for (j = first_count_equ; j < size + first_count_equ; j++)
{
i_1 = Index_Equ_IM[j] * symbol_table.endo_nbr();
for (k = first_count_equ;k < size + first_count_equ;k++)
for (k = first_count_equ; k < size + first_count_equ; k++)
if (IM[Index_Var_IM[k] + i_1])
{
if (i == Lag)
@ -529,10 +578,10 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
}
ModelBlock->Block_List[count_Block].IM_lead_lag[i].u_finish = li - 1;
m = 0;
for (j = first_count_equ;j < size + first_count_equ;j++)
for (j = first_count_equ; j < size + first_count_equ; j++)
{
i_1 = Index_Equ_IM[j] * symbol_table.endo_nbr();
for (k = 0;k < symbol_table.endo_nbr();k++)
for (k = 0; k < symbol_table.endo_nbr(); k++)
if ((!tmp_variable_evaluated[Index_Var_IM[k]]) && IM[Index_Var_IM[k] + i_1])
{
ModelBlock->Block_List[count_Block].IM_lead_lag[i].u_other_endo[m] = l;
@ -577,25 +626,22 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
free(tmp_variable_evaluated);
}
void
BlockTriangular::Free_Block(Model_Block* ModelBlock) const
{
BlockTriangular::Free_Block(Model_Block *ModelBlock) const
{
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].Variable);
free(ModelBlock->Block_List[blk].Exogenous);
free(ModelBlock->Block_List[blk].Own_Derivative);
free(ModelBlock->Block_List[blk].Other_Endogenous);
free(ModelBlock->Block_List[blk].Equation_Type);
free(ModelBlock->Block_List[blk].Equation_Type_Var);
for (i = 0;i < ModelBlock->Block_List[blk].Max_Lag + ModelBlock->Block_List[blk].Max_Lead + 1;i++)
free(ModelBlock->Block_List[blk].Equation_Normalized);
for (i = 0; i < ModelBlock->Block_List[blk].Max_Lag + ModelBlock->Block_List[blk].Max_Lead + 1; i++)
{
if (incidencematrix.Model_Max_Lag_Endo-ModelBlock->Block_List[blk].Max_Lag+i>=0 /*&& ModelBlock->Block_List[blk].IM_lead_lag[i].size*/)
if (incidencematrix.Model_Max_Lag_Endo-ModelBlock->Block_List[blk].Max_Lag+i >= 0 /*&& ModelBlock->Block_List[blk].IM_lead_lag[i].size*/)
{
free(ModelBlock->Block_List[blk].IM_lead_lag[i].u);
free(ModelBlock->Block_List[blk].IM_lead_lag[i].us);
@ -618,14 +664,14 @@ BlockTriangular::Free_Block(Model_Block* ModelBlock) const
}*/
}
free(ModelBlock->Block_List[blk].IM_lead_lag);
for (i=0; i<ModelBlock->Block_List[blk].Size; i++)
for (i = 0; i < ModelBlock->Block_List[blk].Size; i++)
delete ModelBlock->Block_List[blk].Temporary_Terms_in_Equation[i];
free(ModelBlock->Block_List[blk].Temporary_Terms_in_Equation);
delete(ModelBlock->Block_List[blk].Temporary_InUse);
delete (ModelBlock->Block_List[blk].Temporary_InUse);
}
free(ModelBlock->Block_List);
free(ModelBlock);
}
}
t_etype
BlockTriangular::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)
@ -637,7 +683,7 @@ BlockTriangular::Equation_Type_determination(vector<BinaryOpNode *> &equations,
temporary_terms_type temporary_terms;
EquationType Equation_Simulation_Type;
t_etype V_Equation_Simulation_Type(equations.size());
for(unsigned int i = 0; i < equations.size(); i++)
for (unsigned int i = 0; i < equations.size(); i++)
{
temporary_terms.clear();
int eq = Index_Equ_IM[i];
@ -646,59 +692,57 @@ BlockTriangular::Equation_Type_determination(vector<BinaryOpNode *> &equations,
lhs = eq_node->get_arg1();
rhs = eq_node->get_arg2();
Equation_Simulation_Type = E_SOLVE;
int Var_To_Derivate = -1;
tmp_s.str("");
tmp_output.str("");
lhs->writeOutput(tmp_output, oMatlabDynamicModelSparse, temporary_terms);
tmp_s << "y(it_, " << Index_Var_IM[i]+1 << ")";
map<pair<int, int>, NodeID>::iterator derivative = first_cur_endo_derivatives.find(make_pair(eq, var));
/*cout << "eq=" << eq << " var=" << var << "=";
first_cur_endo_derivatives[make_pair(eq, var)]->writeOutput(cout, oMatlabDynamicModelSparse, temporary_terms);
cout << "\n";
cout << "equation : ";
eq_node->writeOutput(cout, oMatlabDynamicModelSparse, temporary_terms);
cout << "\n";*/
set<pair<int, int> > result;
//result.clear();
pair<bool, NodeID> res;
derivative->second->collectEndogenous(result);
/*for(set<pair<int, int> >::const_iterator iitt = result.begin(); iitt!=result.end(); iitt++)
cout << "result = " << iitt->first << ", " << iitt->second << "\n";*/
set<pair<int, int> >::const_iterator d_endo_variable = result.find(make_pair(var, 0));
//Determine whether the equation could be evaluated rather than to be solved
if (tmp_output.str() == tmp_s.str() and d_endo_variable == result.end())
Equation_Simulation_Type = E_EVALUATE;
else
{ //the equation could be normalized by a permutation of the rhs and the lhs
tmp_output.str("");
rhs->writeOutput(tmp_output, oMatlabDynamicModelSparse, temporary_terms);
if (tmp_output.str() == tmp_s.str() and d_endo_variable == result.end())
{
Equation_Simulation_Type = E_EVALUATE_R;
//cout << "Equation " << eq << " is reversed\n";
Equation_Simulation_Type = E_EVALUATE;
}
else
{ //the equation could be normalized using the derivative independant of the endogenous variable
if (d_endo_variable == result.end())
{
//the equation could be normalized by a permutation of the rhs and the lhs
if (d_endo_variable == result.end()) //the equation is linear in the endogenous and could be normalized using the derivative
{
Equation_Simulation_Type = E_EVALUATE_S;
Var_To_Derivate = var;
//cout << " gone normalized : ";
res = equations[eq]->normalizeLinearInEndoEquation(var, derivative->second);
/*res.second->writeOutput(cout, oMatlabDynamicModelSparse, temporary_terms);
cout << " done\n";*/
}
}
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);
}
t_type
BlockTriangular::Reduce_Blocks_and_type_determination(int prologue, int epilogue, vector<pair<int, int> > &blocks, vector<BinaryOpNode *> &equations, t_etype &Equation_Type)
{
int i=0;
int count_equ = 0, blck_count_simult =0;
int i = 0;
int count_equ = 0, blck_count_simult = 0;
int Blck_Size, Recurs_Size;
int Lead, Lag;
t_type Type;
bool *Cur_IM;
BlockSimulationType Simulation_Type , prev_Type=UNKNOWN;
BlockSimulationType Simulation_Type, prev_Type = UNKNOWN;
int eq = 0;
for ( i=0; i<prologue+(int)blocks.size()+epilogue; i++)
for (i = 0; i < prologue+(int) blocks.size()+epilogue; i++)
{
int first_count_equ = count_equ;
if (i < prologue)
@ -706,13 +750,13 @@ BlockTriangular::Reduce_Blocks_and_type_determination(int prologue, int epilogue
Blck_Size = 1;
Recurs_Size = 0;
}
else if (i < prologue+(int)blocks.size())
else if (i < prologue+(int) blocks.size())
{
Blck_Size = blocks[blck_count_simult].first;
Recurs_Size = Blck_Size - blocks[blck_count_simult].second;
blck_count_simult++;
}
else if (i < prologue+(int)blocks.size()+epilogue)
else if (i < prologue+(int) blocks.size()+epilogue)
{
Blck_Size = 1;
Recurs_Size = 0;
@ -722,12 +766,12 @@ BlockTriangular::Reduce_Blocks_and_type_determination(int prologue, int epilogue
for (count_equ = first_count_equ; count_equ < Blck_Size+first_count_equ; count_equ++)
{
int i_1 = Index_Var_IM[count_equ];
for (int k = -incidencematrix.Model_Max_Lag_Endo; k<=incidencematrix.Model_Max_Lead_Endo; k++)
for (int k = -incidencematrix.Model_Max_Lag_Endo; k <= incidencematrix.Model_Max_Lead_Endo; k++)
{
Cur_IM = incidencematrix.Get_IM(k, eEndogenous);
if (Cur_IM)
{
for (int j = 0;j < Blck_Size;j++)
for (int j = 0; j < Blck_Size; j++)
{
if (Cur_IM[i_1 + Index_Equ_IM[first_count_equ + j] * symbol_table.endo_nbr()])
{
@ -763,7 +807,7 @@ BlockTriangular::Reduce_Blocks_and_type_determination(int prologue, int epilogue
}
if (Blck_Size == 1)
{
if(Equation_Type[Index_Equ_IM[eq]].first==E_EVALUATE or Equation_Type[Index_Equ_IM[eq]].first==E_EVALUATE_R)
if (Equation_Type[Index_Equ_IM[eq]].first == E_EVALUATE /*or Equation_Type[Index_Equ_IM[eq]].first==E_EVALUATE_R*/ or Equation_Type[Index_Equ_IM[eq]].first == E_EVALUATE_S)
{
if (Simulation_Type == SOLVE_BACKWARD_SIMPLE)
Simulation_Type = EVALUATE_BACKWARD;
@ -777,7 +821,7 @@ BlockTriangular::Reduce_Blocks_and_type_determination(int prologue, int epilogue
{
BlockSimulationType c_Type = (Type[Type.size()-1]).first;
int c_Size = (Type[Type.size()-1]).second.first;
Type[Type.size()-1]=make_pair(c_Type, make_pair(++c_Size, Type[Type.size()-1].second.second));
Type[Type.size()-1] = make_pair(c_Type, make_pair(++c_Size, Type[Type.size()-1].second.second));
}
else
Type.push_back(make_pair(Simulation_Type, make_pair(Blck_Size, Recurs_Size)));
@ -792,53 +836,53 @@ BlockTriangular::Reduce_Blocks_and_type_determination(int prologue, int epilogue
prev_Type = Simulation_Type;
eq += Blck_Size;
}
return(Type);
return (Type);
}
void
BlockTriangular::Normalize_and_BlockDecompose(bool* IM, Model_Block* ModelBlock, int n, int &prologue, int &epilogue, vector<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)
{
int i, j, Nb_TotalBlocks, Nb_RecursBlocks, Nb_SimulBlocks;
BlockType Btype;
int count_Block, count_Equ;
bool* SIM0, *SIM00;
bool *SIM0, *SIM00;
SIM0 = (bool*)malloc(n * n * sizeof(bool));
memcpy(SIM0,IM_0,n*n*sizeof(bool));
SIM0 = (bool *) malloc(n * n * sizeof(bool));
memcpy(SIM0, IM_0, n*n*sizeof(bool));
Prologue_Epilogue(IM, prologue, epilogue, n, Index_Var_IM, Index_Equ_IM, SIM0);
free(SIM0);
int counted=0;
if (prologue+epilogue<n)
int counted = 0;
if (prologue+epilogue < n)
{
cout << "Normalizing the model ...\n";
double* max_val=(double*)malloc(n*sizeof(double));
memset(max_val,0,n*sizeof(double));
for ( map< pair< int, int >, double >::iterator iter = j_m.begin(); iter != j_m.end(); iter++ )
double *max_val = (double *) malloc(n*sizeof(double));
memset(max_val, 0, n*sizeof(double));
for (map< pair< int, int >, double >::iterator iter = j_m.begin(); iter != j_m.end(); iter++)
{
if (fabs(iter->second)>max_val[iter->first.first])
max_val[iter->first.first]=fabs(iter->second);
if (fabs(iter->second) > max_val[iter->first.first])
max_val[iter->first.first] = fabs(iter->second);
}
for ( map< pair< int, int >, double >::iterator iter = j_m.begin(); iter != j_m.end(); iter++ )
iter->second/=max_val[iter->first.first];
for (map< pair< int, int >, double >::iterator iter = j_m.begin(); iter != j_m.end(); iter++)
iter->second /= max_val[iter->first.first];
free(max_val);
bool OK=false;
double bi=0.99999999;
int suppressed=0;
bool OK = false;
double bi = 0.99999999;
//double bi=1e-13;
int suppressed = 0;
vector<int> Index_Equ_IM_save(Index_Equ_IM);
while (!OK && bi>1e-14)
while (!OK && bi > 1e-14)
{
int suppress=0;
int suppress = 0;
Index_Equ_IM = Index_Equ_IM_save;
SIM0 = (bool*)malloc(n * n * sizeof(bool));
memset(SIM0,0,n*n*sizeof(bool));
SIM00 = (bool*)malloc(n * n * sizeof(bool));
memset(SIM00,0,n*n*sizeof(bool));
for ( map< pair< int, int >, double >::iterator iter = j_m.begin(); iter != j_m.end(); iter++ )
SIM0 = (bool *) malloc(n * n * sizeof(bool));
memset(SIM0, 0, n*n*sizeof(bool));
SIM00 = (bool *) malloc(n * n * sizeof(bool));
memset(SIM00, 0, n*n*sizeof(bool));
for (map< pair< int, int >, double >::iterator iter = j_m.begin(); iter != j_m.end(); iter++)
{
if (fabs(iter->second)>bi)
if (fabs(iter->second) > bi)
{
SIM0[iter->first.first*n+iter->first.second]=1;
SIM0[iter->first.first*n+iter->first.second] = 1;
if (!IM_0[iter->first.first*n+iter->first.second])
{
cout << "Error nothing at IM_0[" << iter->first.first << ", " << iter->first.second << "]=" << IM_0[iter->first.first*n+iter->first.second] << " " << iter->second << "\n";
@ -847,32 +891,31 @@ BlockTriangular::Normalize_and_BlockDecompose(bool* IM, Model_Block* ModelBlock,
else
suppress++;
}
for (i = 0;i < n;i++)
for (j = 0;j < n;j++)
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
{
SIM00[i*n + j] = SIM0[Index_Equ_IM[i] * n + Index_Var_IM[j]];
}
free(SIM0);
if (suppress!=suppressed)
if (suppress != suppressed)
OK = Compute_Normalization(IM, n, prologue, epilogue, false, SIM00, Index_Equ_IM);
suppressed=suppress;
suppressed = suppress;
if (!OK)
//bi/=1.07;
bi/=3;
bi /= 2;
counted++;
if (bi>1e-14)
if (bi > 1e-14)
free(SIM00);
}
if (!OK)
Compute_Normalization(IM, n, prologue, epilogue, true, SIM00, Index_Equ_IM);
}
V_Equation_Type = Equation_Type_determination(equations, first_cur_endo_derivatives, Index_Var_IM, Index_Equ_IM);
cout << "Finding the optimal block decomposition of the model ...\n";
vector<pair<int, int> > blocks;
if (prologue+epilogue<n)
if (prologue+epilogue < n)
Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Block(IM, n, prologue, epilogue, Index_Equ_IM, Index_Var_IM, blocks, V_Equation_Type, false);
t_type Type = Reduce_Blocks_and_type_determination(prologue, epilogue, blocks, equations, V_Equation_Type);
@ -881,14 +924,14 @@ BlockTriangular::Normalize_and_BlockDecompose(bool* IM, Model_Block* ModelBlock,
j = 0;
Nb_SimulBlocks = 0;
int Nb_fv = 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 (it->first==SOLVE_FORWARD_COMPLETE || it->first==SOLVE_BACKWARD_COMPLETE || it->first==SOLVE_TWO_BOUNDARIES_COMPLETE)
if (it->first == SOLVE_FORWARD_COMPLETE || it->first == SOLVE_BACKWARD_COMPLETE || it->first == SOLVE_TWO_BOUNDARIES_COMPLETE)
{
Nb_SimulBlocks++;
if (it->second.first>j)
if (it->second.first > j)
{
j=it->second.first;
j = it->second.first;
Nb_fv = blocks[Nb_SimulBlocks-1].second;
}
}
@ -898,20 +941,21 @@ BlockTriangular::Normalize_and_BlockDecompose(bool* IM, Model_Block* ModelBlock,
Nb_RecursBlocks = Nb_TotalBlocks - Nb_SimulBlocks;
cout << Nb_TotalBlocks << " block(s) found:\n";
cout << " " << Nb_RecursBlocks << " recursive block(s) and " << blocks.size() << " simultaneous block(s). \n";
cout << " the largest simultaneous block has " << j << " equation(s)\n" <<
" and " << Nb_fv << " feedback variable(s).\n";
cout << " the largest simultaneous block has " << j << " equation(s)\n"
<<" and " << Nb_fv << " feedback variable(s).\n";
ModelBlock->Size = Nb_TotalBlocks;
ModelBlock->Periods = periods;
ModelBlock->Block_List = (Block*)malloc(sizeof(ModelBlock->Block_List[0]) * Nb_TotalBlocks);
ModelBlock->Block_List = (Block *) malloc(sizeof(ModelBlock->Block_List[0]) * Nb_TotalBlocks);
count_Equ = count_Block = 0;
for (t_type::const_iterator it = Type.begin(); it!=Type.end(); it++)
for (t_type::const_iterator it = Type.begin(); it != Type.end(); it++)
{
if (count_Equ<prologue)
if (count_Equ < prologue)
Btype = PROLOGUE;
else if (count_Equ<n-epilogue)
if (it->second.first==1)
else if (count_Equ < n-epilogue)
if (it->second.first == 1)
Btype = PROLOGUE;
else
Btype = SIMULTANS;
@ -921,26 +965,25 @@ BlockTriangular::Normalize_and_BlockDecompose(bool* IM, Model_Block* ModelBlock,
}
}
//------------------------------------------------------------------------------
// normalize each equation of the dynamic model
// and find the optimal block triangular decomposition of the static model
void
BlockTriangular::Normalize_and_BlockDecompose_Static_0_Model(jacob_map &j_m, vector<BinaryOpNode *> &equations, t_etype &equation_simulation_type, map<pair<int, int >, NodeID> &first_cur_endo_derivatives)
{
bool* SIM, *SIM_0;
bool* Cur_IM;
bool *SIM, *SIM_0;
bool *Cur_IM;
int i, k, size;
//First create a static model incidence matrix
size = symbol_table.endo_nbr() * symbol_table.endo_nbr() * sizeof(*SIM);
SIM = (bool*)malloc(size);
for (i = 0; i< symbol_table.endo_nbr() * symbol_table.endo_nbr(); i++) SIM[i] = 0;
for (k = -incidencematrix.Model_Max_Lag_Endo; k<=incidencematrix.Model_Max_Lead_Endo; k++)
SIM = (bool *) malloc(size);
for (i = 0; i < symbol_table.endo_nbr() * symbol_table.endo_nbr(); i++) SIM[i] = 0;
for (k = -incidencematrix.Model_Max_Lag_Endo; k <= incidencematrix.Model_Max_Lead_Endo; k++)
{
Cur_IM = incidencematrix.Get_IM(k, eEndogenous);
if (Cur_IM)
{
for (i = 0;i < symbol_table.endo_nbr()*symbol_table.endo_nbr();i++)
for (i = 0; i < symbol_table.endo_nbr()*symbol_table.endo_nbr(); i++)
{
SIM[i] = (SIM[i]) || (Cur_IM[i]);
}
@ -952,21 +995,21 @@ BlockTriangular::Normalize_and_BlockDecompose_Static_0_Model(jacob_map &j_m, vec
incidencematrix.Print_SIM(SIM, eEndogenous);
}
Index_Equ_IM = vector<int>(symbol_table.endo_nbr());
for (i = 0;i < symbol_table.endo_nbr();i++)
for (i = 0; i < symbol_table.endo_nbr(); i++)
{
Index_Equ_IM[i] = i;
}
Index_Var_IM = vector<int>(symbol_table.endo_nbr());
for (i = 0;i < symbol_table.endo_nbr();i++)
for (i = 0; i < symbol_table.endo_nbr(); i++)
{
Index_Var_IM[i] = i;
}
if (ModelBlock != NULL)
Free_Block(ModelBlock);
ModelBlock = (Model_Block*)malloc(sizeof(*ModelBlock));
ModelBlock = (Model_Block *) malloc(sizeof(*ModelBlock));
Cur_IM = incidencematrix.Get_IM(0, eEndogenous);
SIM_0 = (bool*)malloc(symbol_table.endo_nbr() * symbol_table.endo_nbr() * sizeof(*SIM_0));
for (i = 0;i < symbol_table.endo_nbr()*symbol_table.endo_nbr();i++)
SIM_0 = (bool *) malloc(symbol_table.endo_nbr() * symbol_table.endo_nbr() * sizeof(*SIM_0));
for (i = 0; i < symbol_table.endo_nbr()*symbol_table.endo_nbr(); i++)
SIM_0[i] = Cur_IM[i];
Normalize_and_BlockDecompose(SIM, ModelBlock, symbol_table.endo_nbr(), prologue, epilogue, Index_Var_IM, Index_Equ_IM, SIM_0, j_m, equations, equation_simulation_type, first_cur_endo_derivatives);
free(SIM_0);

View File

@ -24,21 +24,23 @@
#include "CodeInterpreter.hh"
#include "ExprNode.hh"
#include "SymbolTable.hh"
#include "ModelNormalization.hh"
#include "ModelBlocks.hh"
//#include "ModelNormalization.hh"
//#include "ModelBlocks.hh"
#include "IncidenceMatrix.hh"
#include "ModelTree.hh"
//! Sparse matrix of double to store the values of the Jacobian
typedef map<pair<int ,int >,double> jacob_map;
typedef vector<pair<BlockSimulationType, pair<int, int> > > t_type;
typedef vector<pair<EquationType, int> > t_etype;
//! Vector describing equations: BlockSimulationType, if BlockSimulationType == EVALUATE_s then a NodeID on the new normalized equation
typedef vector<pair<EquationType, NodeID > > t_etype;
//! Vector describing variables: max_lag in the block, max_lead in the block
typedef vector<pair< int, int> > t_vtype;
//! Creates the incidence matrix, computes prologue & epilogue, normalizes the model and computes the block decomposition
class BlockTriangular
@ -52,27 +54,32 @@ private:
bool Compute_Normalization(bool *IM, int equation_number, int prologue, int epilogue, bool verbose, bool *IM0, vector<int> &Index_Var_IM) const;
//! Decomposes into recurive blocks the non purely recursive equations and determines for each block the minimum feedback variables
void Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Block(bool *IM, int nb_var, int prologue, int epilogue, vector<int> &Index_Equ_IM, vector<int> &Index_Var_IM, vector<pair<int, int> > &blocks, t_etype &Equation_Type, bool verbose_) const;
//! determine the type of each equation of the model (couble evaluated or need to be solved)
//! determines the type of each equation of the model (could be evaluated or need to be solved)
t_etype Equation_Type_determination(vector<BinaryOpNode *> &equations, map<pair<int, int >, NodeID> &first_cur_endo_derivatives, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM);
//! Tries to merge the consecutive blocks in a single block and determine the type of each block: recursive, simultaneous, ...
t_type Reduce_Blocks_and_type_determination(int prologue, int epilogue, vector<pair<int, int> > &blocks, vector<BinaryOpNode *> &equations, t_etype &Equation_Type);
//! Compute for each variable its maximum lead and lag in its block
t_vtype Get_Variable_LeadLag_By_Block(vector<int > &components_set, int nb_blck_sim, int prologue, int epilogue) const;
public:
const SymbolTable &symbol_table;
BlockTriangular(const SymbolTable &symbol_table_arg);
SymbolTable &symbol_table;
/*Blocks blocks;
Normalization normalization;*/
IncidenceMatrix incidencematrix;
NumericalConstants &num_const;
DataTree *Normalized_Equation;
BlockTriangular(SymbolTable &symbol_table_arg, NumericalConstants &num_const_arg);
~BlockTriangular();
//! Frees the Model structure describing the content of each block
void Free_Block(Model_Block* ModelBlock) const;
//BlockTriangular(const IncidenceMatrix &incidence_matrix_arg);
//const SymbolTable &symbol_table;
Blocks blocks;
Normalization normalization;
IncidenceMatrix incidencematrix;
void Normalize_and_BlockDecompose_Static_0_Model(jacob_map &j_m, vector<BinaryOpNode *> &equations, t_etype &V_Equation_Type, map<pair<int, int >, NodeID> &first_cur_endo_derivatives);
void Normalize_and_BlockDecompose(bool* IM, Model_Block* ModelBlock, int n, int &prologue, int &epilogue, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM, bool* IM_0 , jacob_map &j_m, vector<BinaryOpNode *> &equations, t_etype &equation_simulation_type, map<pair<int, int >, NodeID> &first_cur_endo_derivatives);
vector<int> Index_Equ_IM;
vector<int> Index_Var_IM;
int prologue, epilogue;
bool bt_verbose;
//int endo_nbr, exo_nbr;
Model_Block* ModelBlock;
int periods;
inline static std::string BlockType0(int type)
@ -101,11 +108,11 @@ public:
switch (type)
{
case EVALUATE_FORWARD:
case EVALUATE_FORWARD_R:
//case EVALUATE_FORWARD_R:
return ("EVALUATE FORWARD ");
break;
case EVALUATE_BACKWARD:
case EVALUATE_BACKWARD_R:
//case EVALUATE_BACKWARD_R:
return ("EVALUATE BACKWARD ");
break;
case SOLVE_FORWARD_SIMPLE:
@ -137,7 +144,7 @@ public:
{
"E_UNKNOWN ",
"E_EVALUATE ",
"E_EVALUATE_R",
//"E_EVALUATE_R",
"E_EVALUATE_S",
"E_SOLVE "
};

View File

@ -53,8 +53,8 @@ enum EquationType
{
E_UNKNOWN, //!< Unknown equation type
E_EVALUATE, //!< Simple evaluation, normalized variable on left-hand side
E_EVALUATE_R, //!< Simple evaluation, normalized variable on right-hand side
E_EVALUATE_S, //!< Simple evaluation, normalize using the first order derivative which does not involve the normalized variable
//E_EVALUATE_R, //!< Simple evaluation, normalized variable on right-hand side
E_EVALUATE_S, //!< Simple evaluation, normalize using the first order derivative
E_SOLVE //!< No simple evaluation of the equation, it has to be solved
};
@ -71,8 +71,8 @@ enum BlockSimulationType
SOLVE_FORWARD_COMPLETE, //!< Block of several equations, newton solver needed, forward
SOLVE_BACKWARD_COMPLETE, //!< Block of several equations, newton solver needed, backward
SOLVE_TWO_BOUNDARIES_COMPLETE, //!< Block of several equations, newton solver needed, forward and backwar
EVALUATE_FORWARD_R, //!< Simple evaluation, normalized variable on right-hand side, forward
EVALUATE_BACKWARD_R //!< Simple evaluation, normalized variable on right-hand side, backward
//EVALUATE_FORWARD_R, //!< Simple evaluation, normalized variable on right-hand side, forward
//EVALUATE_BACKWARD_R //!< Simple evaluation, normalized variable on right-hand side, backward
};
//! Enumeration of possible symbol types

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -109,6 +109,10 @@ private:
//! Computes derivative w.r. to a derivation ID (but doesn't store it in derivatives map)
/*! You shoud use getDerivative() to get the benefit of symbolic a priori and of caching */
virtual NodeID computeDerivative(int deriv_id) = 0;
//! Computes derivative w.r. to a derivation ID and use chaine rule derivatives (but doesn't store it in derivatives map)
/*! You shoud use getDerivative() to get the benefit of symbolic a priori and of caching */
virtual NodeID computeChaineRuleDerivative(int deriv_id, map<int, NodeID> &recursive_variables, int var, int lag_) = 0;
protected:
//! Reference to the enclosing DataTree
@ -136,6 +140,10 @@ public:
For an equal node, returns the derivative of lhs minus rhs */
NodeID getDerivative(int deriv_id);
//! Returns derivative w.r. to derivation ID and use if it possible chaine rule derivatives
NodeID getChaineRuleDerivative(int deriv_id, map<int, NodeID> &recursive_variables, int var, int lag_);
//! Returns precedence of node
/*! Equals 100 for constants, variables, unary ops, and temporary terms */
virtual int precedence(ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const;
@ -145,7 +153,7 @@ public:
virtual void computeTemporaryTerms(map<NodeID, int> &reference_count, temporary_terms_type &temporary_terms, bool is_matlab) const;
//! Writes output of node, using a Txxx notation for nodes in temporary_terms
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const = 0;
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const /*= 0*/;
//! Writes output of node (with no temporary terms and with "outside model" output type)
void writeOutput(ostream &output);
@ -174,6 +182,7 @@ public:
map_idx_type &map_idx) const;
class EvalException
{
};
@ -185,6 +194,8 @@ public:
adds the result in the static_datatree argument (and not in the original datatree), and returns it.
*/
virtual NodeID toStatic(DataTree &static_datatree) const = 0;
//! Try to normalize an equation linear in its endogenous variable
virtual pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const;
};
//! Object used to compare two nodes (using their indexes)
@ -204,6 +215,7 @@ private:
//! Id from numerical constants table
const int id;
virtual NodeID computeDerivative(int deriv_id);
virtual NodeID computeChaineRuleDerivative(int deriv_id, map<int, NodeID> &recursive_variables, int var, int lag_);
public:
NumConstNode(DataTree &datatree_arg, int id_arg);
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const;
@ -213,6 +225,7 @@ public:
virtual double eval(const eval_context_type &eval_context) const throw (EvalException);
virtual void compile(ofstream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const;
virtual NodeID toStatic(DataTree &static_datatree) const;
virtual pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const;
};
//! Symbol or variable node
@ -226,6 +239,7 @@ private:
//! Derivation ID
const int deriv_id;
virtual NodeID computeDerivative(int deriv_id_arg);
virtual NodeID computeChaineRuleDerivative(int deriv_id, map<int, NodeID> &recursive_variables, int var, int lag_);
public:
VariableNode(DataTree &datatree_arg, int symb_id_arg, int lag_arg, int deriv_id_arg);
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms = temporary_terms_type()) const;
@ -243,6 +257,7 @@ public:
virtual void compile(ofstream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const;
virtual NodeID toStatic(DataTree &static_datatree) const;
int get_symb_id() const { return symb_id; };
virtual pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const;
};
//! Unary operator node
@ -252,6 +267,7 @@ private:
const NodeID arg;
const UnaryOpcode op_code;
virtual NodeID computeDerivative(int deriv_id);
virtual NodeID computeChaineRuleDerivative(int deriv_id, map<int, NodeID> &recursive_variables, int var, int lag_);
virtual int cost(const temporary_terms_type &temporary_terms, bool is_matlab) const;
public:
@ -276,6 +292,7 @@ public:
//! Returns op code
UnaryOpcode get_op_code() const { return(op_code); };
virtual NodeID toStatic(DataTree &static_datatree) const;
virtual pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const;
};
//! Binary operator node
@ -285,6 +302,8 @@ private:
const NodeID arg1, arg2;
const BinaryOpcode op_code;
virtual NodeID computeDerivative(int deriv_id);
virtual NodeID computeChaineRuleDerivative(int deriv_id, map<int, NodeID> &recursive_variables, int var, int lag_);
virtual int cost(const temporary_terms_type &temporary_terms, bool is_matlab) const;
public:
BinaryOpNode(DataTree &datatree_arg, const NodeID arg1_arg,
@ -312,6 +331,7 @@ public:
//! Returns op code
BinaryOpcode get_op_code() const { return(op_code); };
virtual NodeID toStatic(DataTree &static_datatree) const;
pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const;
};
//! Trinary operator node
@ -322,6 +342,8 @@ private:
const NodeID arg1, arg2, arg3;
const TrinaryOpcode op_code;
virtual NodeID computeDerivative(int deriv_id);
virtual NodeID computeChaineRuleDerivative(int deriv_id, map<int, NodeID> &recursive_variables, int var, int lag_);
virtual int cost(const temporary_terms_type &temporary_terms, bool is_matlab) const;
public:
TrinaryOpNode(DataTree &datatree_arg, const NodeID arg1_arg,
@ -343,6 +365,7 @@ public:
virtual double eval(const eval_context_type &eval_context) const throw (EvalException);
virtual void compile(ofstream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const;
virtual NodeID toStatic(DataTree &static_datatree) const;
virtual pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const;
};
//! Unknown function node
@ -352,6 +375,7 @@ private:
const int symb_id;
const vector<NodeID> arguments;
virtual NodeID computeDerivative(int deriv_id);
virtual NodeID computeChaineRuleDerivative(int deriv_id, map<int, NodeID> &recursive_variables, int var, int lag_);
public:
UnknownFunctionNode(DataTree &datatree_arg, int symb_id_arg,
const vector<NodeID> &arguments_arg);
@ -370,6 +394,7 @@ public:
virtual double eval(const eval_context_type &eval_context) const throw (EvalException);
virtual void compile(ofstream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const;
virtual NodeID toStatic(DataTree &static_datatree) const;
virtual pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const;
};
//! For one lead/lag of one block, stores mapping of information between original model and block-decomposed model
@ -393,7 +418,8 @@ struct Block
bool is_linear;
int *Equation, *Own_Derivative;
EquationType *Equation_Type;
int *Variable, *Other_Endogenous, *Exogenous, *Equation_Type_Var;
NodeID *Equation_Normalized;
int *Variable, *Other_Endogenous, *Exogenous;
temporary_terms_type **Temporary_Terms_in_Equation;
//temporary_terms_type *Temporary_terms;
temporary_terms_inuse_type *Temporary_InUse;

View File

@ -186,7 +186,6 @@ namespace MFS
GraphvizDigraph_2_AdjacencyList(GraphvizDigraph& G1, set<int> select_index)
{
unsigned int n = select_index.size();
//cout << "n=" << n << "\n";
AdjacencyList_type G(n);
property_map<AdjacencyList_type, vertex_index_t>::type v_index = get(vertex_index, G);
property_map<AdjacencyList_type, vertex_index1_t>::type v_index1 = get(vertex_index1, G);
@ -208,13 +207,7 @@ namespace MFS
{
int ii = target(*it_out, G1);
if (select_index.find(ii) != select_index.end())
{
/*cout << "*it=" << *it << " i = " << i << " ii=" << ii << " n=" << n << " *it_out=" << *it_out << "\n";
cout << "source(*it_out, G1) = " << source(*it_out, G1) << " target(*it_out, G1) = " << target(*it_out, G1) << "\n";
cout << "vertex(source(*it_out, G1), G) = " << vertex(source(*it_out, G1), G) << " vertex(target(*it_out, G1), G) = " << vertex(target(*it_out, G1), G) << "\n";*/
add_edge( vertex(reverse_index[source(*it_out, G1)],G), vertex(reverse_index[target(*it_out, G1)], G), G);
//add_edge(vertex(source(*it_out, G1), G) , vertex(target(*it_out, G1), G), G);
}
}
}
return G;
@ -367,110 +360,8 @@ namespace MFS
return something_has_been_done;
}
bool
Suppression_of_Edge_i_j_if_not_a_loop_and_if_for_all_i_k_edge_we_have_a_k_j_edge_Step(AdjacencyList_type& G) //Suppression
{
bool something_has_been_done = false;
AdjacencyList_type::vertex_iterator it, it_end;
int i = 0;
bool agree;
for (tie(it, it_end) = vertices(G);it != it_end; ++it, i++)
{
AdjacencyList_type::in_edge_iterator it_in, in_end;
AdjacencyList_type::out_edge_iterator it_out, out_end, it_out1, ita_out;
int j = 0;
for (tie(ita_out = it_out, out_end) = out_edges(*it, G); it_out != out_end; ++it_out, j++)
{
AdjacencyList_type::edge_descriptor ed;
bool exist;
tie(ed, exist) = edge(target(*it_out, G), source(*it_out, G) , G);
if (!exist)
{
agree = true;
for (tie(it_out1, out_end) = out_edges(*it, G); it_out1 != out_end; ++it_out1)
{
bool exist;
tie(ed, exist) = edge(target(*it_out1, G), target(*it_out, G) , G);
if (target(*it_out1, G) != target(*it_out, G) and !exist)
agree = false;
}
if (agree)
{
something_has_been_done = true;
remove_edge(*it_out, G);
if (out_degree(*it, G) == 0)
break;
if (j > 0)
{
it_out = ita_out;
tie(it_out1, out_end) = out_edges(*it, G);
}
else
{
tie(it_out, out_end) = out_edges(*it, G);
j--;
}
}
}
ita_out = it_out;
}
}
return something_has_been_done;
}
bool
Suppression_of_all_in_Edge_in_i_if_not_a_loop_and_if_all_doublet_i_eq_Min_inDegree_outDegree_Step(AdjacencyList_type& G)
{
bool something_has_been_done = false;
AdjacencyList_type::vertex_iterator it, it_end;
int i = 0;
for (tie(it, it_end) = vertices(G);it != it_end; ++it, i++)
{
AdjacencyList_type::in_edge_iterator it_in, in_end, it_in1, ita_in;
vector<AdjacencyList_type::vertex_descriptor> doublet = Collect_Doublet(*it, G);
if (doublet.size() == (unsigned int) min(in_degree(*it, G), out_degree(*it, G)))
{
int j = 0;
if (in_degree(*it, G))
for (tie(ita_in = it_in, in_end) = in_edges(*it, G); it_in != in_end; ++it_in, j++)
{
vector<AdjacencyList_type::vertex_descriptor>::iterator it1 = doublet.begin();
bool not_a_doublet = true;
while (it1 != doublet.end() and not_a_doublet)
{
if (target(*it_in, G) == *it1)
not_a_doublet = false;
it1++;
}
if (not_a_doublet and source(*it_in, G) != target(*it_in, G))
{
#ifdef verbose
property_map<AdjacencyList_type, vertex_index_t>::type v_index = get(vertex_index, G);
cout << "remove_edge(" << v_index[source(*it_in, G)] << ", " << v_index[target(*it_in, G)] << ", G) j=" << j << " it_in == in_end : " << (it_in == in_end) << " in_degree(*it, G)=" << in_degree(*it, G) << ";\n";
#endif
something_has_been_done = true;
remove_edge(source(*it_in, G), target(*it_in, G), G);
cout << " in_degree(*it, G)=" << in_degree(*it, G) << ";\n";
if (in_degree(*it, G) == 0)
break;
if (j > 0)
{
it_in = ita_in;
}
else
{
tie(it_in, in_end) = in_edges(*it, G);
j--;
}
}
ita_in = it_in;
}
}
}
return something_has_been_done;
}
bool
Suppression_of_Vertex_X_if_it_loops_store_in_set_of_feedback_vertex_Step(set<int> &feed_back_vertices, AdjacencyList_type& G)
@ -537,21 +428,9 @@ namespace MFS
#endif
//Rule 3
//something_has_been_done=(Suppression_of_Edge_i_j_if_not_a_loop_and_if_for_all_i_k_edge_we_have_a_k_j_edge_Step(G) or something_has_been_done);
#ifdef verbose
cout << "3 something_has_been_done=" << something_has_been_done << "\n";
#endif
//Rule 4
//something_has_been_done=(Suppression_of_all_in_Edge_in_i_if_not_a_loop_and_if_all_doublet_i_eq_Min_inDegree_outDegree_Step(G) or something_has_been_done);
#ifdef verbose
cout << "4 something_has_been_done=" << something_has_been_done << "\n";
#endif
//Rule 5
something_has_been_done = (Suppression_of_Vertex_X_if_it_loops_store_in_set_of_feedback_vertex_Step(feed_back_vertices, G) or something_has_been_done);
#ifdef verbose
cout << "5 something_has_been_done=" << something_has_been_done << "\n";
cout << "3 something_has_been_done=" << something_has_been_done << "\n";
#endif
}
vector<int> circuit;

View File

@ -25,8 +25,6 @@
#include <vector>
#include <boost/graph/graphviz.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
using namespace boost;
@ -44,25 +42,42 @@ using namespace boost;
namespace MFS
{
//! Eliminate a vertex i:
//! For a vertex i replace all edges e_k_i and e_i_j by a shorcut e_k_j and then Suppress the vertex i
void Eliminate(AdjacencyList_type::vertex_descriptor vertex_to_eliminate, AdjacencyList_type& G);
//!collect all doublet (for each edge e_i_k there is an edge e_k_i with k!=i) in the graph
//! and return the vector of doublet
vector_vertex_descriptor Collect_Doublet(AdjacencyList_type::vertex_descriptor vertex, AdjacencyList_type& G);
//! Detect all the clique (all vertex in a clique are related to each other) in the graph
bool Vertex_Belong_to_a_Clique(AdjacencyList_type::vertex_descriptor vertex, AdjacencyList_type& G);
bool Elimination_of_Vertex_With_One_or_Less_Indegree_or_Outdegree_Step(AdjacencyList_type& G); //Graph reduction: eliminating purely intermediate variables or variables outside of any circuit
bool Elimination_of_Vertex_belonging_to_a_clique_Step(AdjacencyList_type& G); //Graphe reduction: eliminaion of Cliques
bool Suppression_of_Edge_i_j_if_not_a_loop_and_if_for_all_i_k_edge_we_have_a_k_j_edge_Step(AdjacencyList_type& G); //Suppression
bool Suppression_of_all_in_Edge_in_i_if_not_a_loop_and_if_all_doublet_i_eq_Min_inDegree_outDegree_Step(AdjacencyList_type& G);
//! Graph reduction: eliminating purely intermediate variables or variables outside of any circuit
bool Elimination_of_Vertex_With_One_or_Less_Indegree_or_Outdegree_Step(AdjacencyList_type& G);
//! Graphe reduction: elimination of a vertex inside a clique
bool Elimination_of_Vertex_belonging_to_a_clique_Step(AdjacencyList_type& G);
//! A vertex belong to the feedback vertex set if the vertex loop on itself.
//! We have to suppress this vertex and store it into the feedback set.
bool Suppression_of_Vertex_X_if_it_loops_store_in_set_of_feedback_vertex_Step(vector<pair<int, AdjacencyList_type::vertex_descriptor> > &looping_variable, AdjacencyList_type& G);
void Print(AdjacencyList_type& G);
AdjacencyList_type AM_2_AdjacencyList(bool* AMp,unsigned int n);
//! Print the Graph
void Print(GraphvizDigraph& G);
void Print(AdjacencyList_type& G);
//! Create a GraphvizDigraph from a Adjacency Matrix (an incidence Matrix without the diagonal terms)
GraphvizDigraph AM_2_GraphvizDigraph(bool* AM, unsigned int n);
//! Create an adjacency graph from a Adjacency Matrix (an incidence Matrix without the diagonal terms)
AdjacencyList_type AM_2_AdjacencyList(bool* AMp,unsigned int n);
//! Create an adjacency graph from a GraphvizDigraph
AdjacencyList_type GraphvizDigraph_2_AdjacencyList(GraphvizDigraph& G1, set<int> select_index);
//! Check if the graph contains any cycle (true if the model contains at least one cycle, false otherwise)
bool has_cycle_dfs(AdjacencyList_type& g, AdjacencyList_type::vertex_descriptor u, color_type& color, vector<int> &circuit_stack);
bool has_cylce(AdjacencyList_type& g, vector<int> &circuit_stack, int size);
bool has_cycle(vector<int> &circuit_stack, AdjacencyList_type& G);
//! Return the feedback set
AdjacencyList_type Minimal_set_of_feedback_vertex(set<int> &feed_back_vertices, const AdjacencyList_type& G);
//! clear all in and out edges of vertex_to_eliminate
//! and remove vertex_to_eliminate from the graph
void Suppress(AdjacencyList_type::vertex_descriptor vertex_to_eliminate, AdjacencyList_type& G);
void Suppress(int vertex_num, AdjacencyList_type& G);
//! reorder the recursive variable:
//! They appear first in a quasi triangular form and they are followed by the feedback variables
vector<int> Reorder_the_recursive_variables(const AdjacencyList_type& G1, set<int> &feed_back_vertices);
};

View File

@ -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);
}
}

View File

@ -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