- 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
File diff suppressed because it is too large
Load Diff
|
@ -24,21 +24,23 @@
|
|||
#include "CodeInterpreter.hh"
|
||||
#include "ExprNode.hh"
|
||||
#include "SymbolTable.hh"
|
||||
#include "ModelNormalization.hh"
|
||||
#include "ModelBlocks.hh"
|
||||
//#include "ModelNormalization.hh"
|
||||
//#include "ModelBlocks.hh"
|
||||
#include "IncidenceMatrix.hh"
|
||||
#include "ModelTree.hh"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//! Sparse matrix of double to store the values of the Jacobian
|
||||
typedef map<pair<int ,int >,double> jacob_map;
|
||||
|
||||
typedef vector<pair<BlockSimulationType, pair<int, int> > > t_type;
|
||||
|
||||
typedef vector<pair<EquationType, int> > t_etype;
|
||||
//! Vector describing equations: BlockSimulationType, if BlockSimulationType == EVALUATE_s then a NodeID on the new normalized equation
|
||||
typedef vector<pair<EquationType, NodeID > > t_etype;
|
||||
|
||||
//! Vector describing variables: max_lag in the block, max_lead in the block
|
||||
typedef vector<pair< int, int> > t_vtype;
|
||||
|
||||
//! Creates the incidence matrix, computes prologue & epilogue, normalizes the model and computes the block decomposition
|
||||
class BlockTriangular
|
||||
|
@ -52,27 +54,32 @@ private:
|
|||
bool Compute_Normalization(bool *IM, int equation_number, int prologue, int epilogue, bool verbose, bool *IM0, vector<int> &Index_Var_IM) const;
|
||||
//! Decomposes into recurive blocks the non purely recursive equations and determines for each block the minimum feedback variables
|
||||
void Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Block(bool *IM, int nb_var, int prologue, int epilogue, vector<int> &Index_Equ_IM, vector<int> &Index_Var_IM, vector<pair<int, int> > &blocks, t_etype &Equation_Type, bool verbose_) const;
|
||||
//! determine the type of each equation of the model (couble evaluated or need to be solved)
|
||||
//! determines the type of each equation of the model (could be evaluated or need to be solved)
|
||||
t_etype Equation_Type_determination(vector<BinaryOpNode *> &equations, map<pair<int, int >, NodeID> &first_cur_endo_derivatives, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM);
|
||||
//! Tries to merge the consecutive blocks in a single block and determine the type of each block: recursive, simultaneous, ...
|
||||
t_type Reduce_Blocks_and_type_determination(int prologue, int epilogue, vector<pair<int, int> > &blocks, vector<BinaryOpNode *> &equations, t_etype &Equation_Type);
|
||||
//! Compute for each variable its maximum lead and lag in its block
|
||||
t_vtype Get_Variable_LeadLag_By_Block(vector<int > &components_set, int nb_blck_sim, int prologue, int epilogue) const;
|
||||
public:
|
||||
const SymbolTable &symbol_table;
|
||||
BlockTriangular(const SymbolTable &symbol_table_arg);
|
||||
SymbolTable &symbol_table;
|
||||
/*Blocks blocks;
|
||||
Normalization normalization;*/
|
||||
IncidenceMatrix incidencematrix;
|
||||
NumericalConstants &num_const;
|
||||
DataTree *Normalized_Equation;
|
||||
BlockTriangular(SymbolTable &symbol_table_arg, NumericalConstants &num_const_arg);
|
||||
~BlockTriangular();
|
||||
//! Frees the Model structure describing the content of each block
|
||||
void Free_Block(Model_Block* ModelBlock) const;
|
||||
//BlockTriangular(const IncidenceMatrix &incidence_matrix_arg);
|
||||
//const SymbolTable &symbol_table;
|
||||
Blocks blocks;
|
||||
Normalization normalization;
|
||||
IncidenceMatrix incidencematrix;
|
||||
|
||||
|
||||
|
||||
void Normalize_and_BlockDecompose_Static_0_Model(jacob_map &j_m, vector<BinaryOpNode *> &equations, t_etype &V_Equation_Type, map<pair<int, int >, NodeID> &first_cur_endo_derivatives);
|
||||
void Normalize_and_BlockDecompose(bool* IM, Model_Block* ModelBlock, int n, int &prologue, int &epilogue, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM, bool* IM_0 , jacob_map &j_m, vector<BinaryOpNode *> &equations, t_etype &equation_simulation_type, map<pair<int, int >, NodeID> &first_cur_endo_derivatives);
|
||||
vector<int> Index_Equ_IM;
|
||||
vector<int> Index_Var_IM;
|
||||
int prologue, epilogue;
|
||||
bool bt_verbose;
|
||||
//int endo_nbr, exo_nbr;
|
||||
Model_Block* ModelBlock;
|
||||
int periods;
|
||||
inline static std::string BlockType0(int type)
|
||||
|
@ -101,11 +108,11 @@ public:
|
|||
switch (type)
|
||||
{
|
||||
case EVALUATE_FORWARD:
|
||||
case EVALUATE_FORWARD_R:
|
||||
//case EVALUATE_FORWARD_R:
|
||||
return ("EVALUATE FORWARD ");
|
||||
break;
|
||||
case EVALUATE_BACKWARD:
|
||||
case EVALUATE_BACKWARD_R:
|
||||
//case EVALUATE_BACKWARD_R:
|
||||
return ("EVALUATE BACKWARD ");
|
||||
break;
|
||||
case SOLVE_FORWARD_SIMPLE:
|
||||
|
@ -137,7 +144,7 @@ public:
|
|||
{
|
||||
"E_UNKNOWN ",
|
||||
"E_EVALUATE ",
|
||||
"E_EVALUATE_R",
|
||||
//"E_EVALUATE_R",
|
||||
"E_EVALUATE_S",
|
||||
"E_SOLVE "
|
||||
};
|
||||
|
|
|
@ -53,8 +53,8 @@ enum EquationType
|
|||
{
|
||||
E_UNKNOWN, //!< Unknown equation type
|
||||
E_EVALUATE, //!< Simple evaluation, normalized variable on left-hand side
|
||||
E_EVALUATE_R, //!< Simple evaluation, normalized variable on right-hand side
|
||||
E_EVALUATE_S, //!< Simple evaluation, normalize using the first order derivative which does not involve the normalized variable
|
||||
//E_EVALUATE_R, //!< Simple evaluation, normalized variable on right-hand side
|
||||
E_EVALUATE_S, //!< Simple evaluation, normalize using the first order derivative
|
||||
E_SOLVE //!< No simple evaluation of the equation, it has to be solved
|
||||
};
|
||||
|
||||
|
@ -71,8 +71,8 @@ enum BlockSimulationType
|
|||
SOLVE_FORWARD_COMPLETE, //!< Block of several equations, newton solver needed, forward
|
||||
SOLVE_BACKWARD_COMPLETE, //!< Block of several equations, newton solver needed, backward
|
||||
SOLVE_TWO_BOUNDARIES_COMPLETE, //!< Block of several equations, newton solver needed, forward and backwar
|
||||
EVALUATE_FORWARD_R, //!< Simple evaluation, normalized variable on right-hand side, forward
|
||||
EVALUATE_BACKWARD_R //!< Simple evaluation, normalized variable on right-hand side, backward
|
||||
//EVALUATE_FORWARD_R, //!< Simple evaluation, normalized variable on right-hand side, forward
|
||||
//EVALUATE_BACKWARD_R //!< Simple evaluation, normalized variable on right-hand side, backward
|
||||
};
|
||||
|
||||
//! Enumeration of possible symbol types
|
||||
|
|
3951
DynamicModel.cc
3951
DynamicModel.cc
File diff suppressed because it is too large
Load Diff
2767
ExprNode.cc
2767
ExprNode.cc
File diff suppressed because it is too large
Load Diff
30
ExprNode.hh
30
ExprNode.hh
|
@ -109,6 +109,10 @@ private:
|
|||
//! Computes derivative w.r. to a derivation ID (but doesn't store it in derivatives map)
|
||||
/*! You shoud use getDerivative() to get the benefit of symbolic a priori and of caching */
|
||||
virtual NodeID computeDerivative(int deriv_id) = 0;
|
||||
//! Computes derivative w.r. to a derivation ID and use chaine rule derivatives (but doesn't store it in derivatives map)
|
||||
/*! You shoud use getDerivative() to get the benefit of symbolic a priori and of caching */
|
||||
virtual NodeID computeChaineRuleDerivative(int deriv_id, map<int, NodeID> &recursive_variables, int var, int lag_) = 0;
|
||||
|
||||
|
||||
protected:
|
||||
//! Reference to the enclosing DataTree
|
||||
|
@ -136,6 +140,10 @@ public:
|
|||
For an equal node, returns the derivative of lhs minus rhs */
|
||||
NodeID getDerivative(int deriv_id);
|
||||
|
||||
//! Returns derivative w.r. to derivation ID and use if it possible chaine rule derivatives
|
||||
NodeID getChaineRuleDerivative(int deriv_id, map<int, NodeID> &recursive_variables, int var, int lag_);
|
||||
|
||||
|
||||
//! Returns precedence of node
|
||||
/*! Equals 100 for constants, variables, unary ops, and temporary terms */
|
||||
virtual int precedence(ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const;
|
||||
|
@ -145,7 +153,7 @@ public:
|
|||
virtual void computeTemporaryTerms(map<NodeID, int> &reference_count, temporary_terms_type &temporary_terms, bool is_matlab) const;
|
||||
|
||||
//! Writes output of node, using a Txxx notation for nodes in temporary_terms
|
||||
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const = 0;
|
||||
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const /*= 0*/;
|
||||
|
||||
//! Writes output of node (with no temporary terms and with "outside model" output type)
|
||||
void writeOutput(ostream &output);
|
||||
|
@ -174,6 +182,7 @@ public:
|
|||
map_idx_type &map_idx) const;
|
||||
|
||||
class EvalException
|
||||
|
||||
{
|
||||
};
|
||||
|
||||
|
@ -185,6 +194,8 @@ public:
|
|||
adds the result in the static_datatree argument (and not in the original datatree), and returns it.
|
||||
*/
|
||||
virtual NodeID toStatic(DataTree &static_datatree) const = 0;
|
||||
//! Try to normalize an equation linear in its endogenous variable
|
||||
virtual pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const;
|
||||
};
|
||||
|
||||
//! Object used to compare two nodes (using their indexes)
|
||||
|
@ -204,6 +215,7 @@ private:
|
|||
//! Id from numerical constants table
|
||||
const int id;
|
||||
virtual NodeID computeDerivative(int deriv_id);
|
||||
virtual NodeID computeChaineRuleDerivative(int deriv_id, map<int, NodeID> &recursive_variables, int var, int lag_);
|
||||
public:
|
||||
NumConstNode(DataTree &datatree_arg, int id_arg);
|
||||
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const;
|
||||
|
@ -213,6 +225,7 @@ public:
|
|||
virtual double eval(const eval_context_type &eval_context) const throw (EvalException);
|
||||
virtual void compile(ofstream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const;
|
||||
virtual NodeID toStatic(DataTree &static_datatree) const;
|
||||
virtual pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const;
|
||||
};
|
||||
|
||||
//! Symbol or variable node
|
||||
|
@ -226,6 +239,7 @@ private:
|
|||
//! Derivation ID
|
||||
const int deriv_id;
|
||||
virtual NodeID computeDerivative(int deriv_id_arg);
|
||||
virtual NodeID computeChaineRuleDerivative(int deriv_id, map<int, NodeID> &recursive_variables, int var, int lag_);
|
||||
public:
|
||||
VariableNode(DataTree &datatree_arg, int symb_id_arg, int lag_arg, int deriv_id_arg);
|
||||
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms = temporary_terms_type()) const;
|
||||
|
@ -243,6 +257,7 @@ public:
|
|||
virtual void compile(ofstream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const;
|
||||
virtual NodeID toStatic(DataTree &static_datatree) const;
|
||||
int get_symb_id() const { return symb_id; };
|
||||
virtual pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const;
|
||||
};
|
||||
|
||||
//! Unary operator node
|
||||
|
@ -252,6 +267,7 @@ private:
|
|||
const NodeID arg;
|
||||
const UnaryOpcode op_code;
|
||||
virtual NodeID computeDerivative(int deriv_id);
|
||||
virtual NodeID computeChaineRuleDerivative(int deriv_id, map<int, NodeID> &recursive_variables, int var, int lag_);
|
||||
|
||||
virtual int cost(const temporary_terms_type &temporary_terms, bool is_matlab) const;
|
||||
public:
|
||||
|
@ -276,6 +292,7 @@ public:
|
|||
//! Returns op code
|
||||
UnaryOpcode get_op_code() const { return(op_code); };
|
||||
virtual NodeID toStatic(DataTree &static_datatree) const;
|
||||
virtual pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const;
|
||||
};
|
||||
|
||||
//! Binary operator node
|
||||
|
@ -285,6 +302,8 @@ private:
|
|||
const NodeID arg1, arg2;
|
||||
const BinaryOpcode op_code;
|
||||
virtual NodeID computeDerivative(int deriv_id);
|
||||
virtual NodeID computeChaineRuleDerivative(int deriv_id, map<int, NodeID> &recursive_variables, int var, int lag_);
|
||||
|
||||
virtual int cost(const temporary_terms_type &temporary_terms, bool is_matlab) const;
|
||||
public:
|
||||
BinaryOpNode(DataTree &datatree_arg, const NodeID arg1_arg,
|
||||
|
@ -312,6 +331,7 @@ public:
|
|||
//! Returns op code
|
||||
BinaryOpcode get_op_code() const { return(op_code); };
|
||||
virtual NodeID toStatic(DataTree &static_datatree) const;
|
||||
pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const;
|
||||
};
|
||||
|
||||
//! Trinary operator node
|
||||
|
@ -322,6 +342,8 @@ private:
|
|||
const NodeID arg1, arg2, arg3;
|
||||
const TrinaryOpcode op_code;
|
||||
virtual NodeID computeDerivative(int deriv_id);
|
||||
virtual NodeID computeChaineRuleDerivative(int deriv_id, map<int, NodeID> &recursive_variables, int var, int lag_);
|
||||
|
||||
virtual int cost(const temporary_terms_type &temporary_terms, bool is_matlab) const;
|
||||
public:
|
||||
TrinaryOpNode(DataTree &datatree_arg, const NodeID arg1_arg,
|
||||
|
@ -343,6 +365,7 @@ public:
|
|||
virtual double eval(const eval_context_type &eval_context) const throw (EvalException);
|
||||
virtual void compile(ofstream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const;
|
||||
virtual NodeID toStatic(DataTree &static_datatree) const;
|
||||
virtual pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const;
|
||||
};
|
||||
|
||||
//! Unknown function node
|
||||
|
@ -352,6 +375,7 @@ private:
|
|||
const int symb_id;
|
||||
const vector<NodeID> arguments;
|
||||
virtual NodeID computeDerivative(int deriv_id);
|
||||
virtual NodeID computeChaineRuleDerivative(int deriv_id, map<int, NodeID> &recursive_variables, int var, int lag_);
|
||||
public:
|
||||
UnknownFunctionNode(DataTree &datatree_arg, int symb_id_arg,
|
||||
const vector<NodeID> &arguments_arg);
|
||||
|
@ -370,6 +394,7 @@ public:
|
|||
virtual double eval(const eval_context_type &eval_context) const throw (EvalException);
|
||||
virtual void compile(ofstream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const;
|
||||
virtual NodeID toStatic(DataTree &static_datatree) const;
|
||||
virtual pair<bool, NodeID> normalizeLinearInEndoEquation(int symb_id_endo, NodeID Derivative) const;
|
||||
};
|
||||
|
||||
//! For one lead/lag of one block, stores mapping of information between original model and block-decomposed model
|
||||
|
@ -393,7 +418,8 @@ struct Block
|
|||
bool is_linear;
|
||||
int *Equation, *Own_Derivative;
|
||||
EquationType *Equation_Type;
|
||||
int *Variable, *Other_Endogenous, *Exogenous, *Equation_Type_Var;
|
||||
NodeID *Equation_Normalized;
|
||||
int *Variable, *Other_Endogenous, *Exogenous;
|
||||
temporary_terms_type **Temporary_Terms_in_Equation;
|
||||
//temporary_terms_type *Temporary_terms;
|
||||
temporary_terms_inuse_type *Temporary_InUse;
|
||||
|
|
|
@ -186,7 +186,6 @@ namespace MFS
|
|||
GraphvizDigraph_2_AdjacencyList(GraphvizDigraph& G1, set<int> select_index)
|
||||
{
|
||||
unsigned int n = select_index.size();
|
||||
//cout << "n=" << n << "\n";
|
||||
AdjacencyList_type G(n);
|
||||
property_map<AdjacencyList_type, vertex_index_t>::type v_index = get(vertex_index, G);
|
||||
property_map<AdjacencyList_type, vertex_index1_t>::type v_index1 = get(vertex_index1, G);
|
||||
|
@ -208,13 +207,7 @@ namespace MFS
|
|||
{
|
||||
int ii = target(*it_out, G1);
|
||||
if (select_index.find(ii) != select_index.end())
|
||||
{
|
||||
/*cout << "*it=" << *it << " i = " << i << " ii=" << ii << " n=" << n << " *it_out=" << *it_out << "\n";
|
||||
cout << "source(*it_out, G1) = " << source(*it_out, G1) << " target(*it_out, G1) = " << target(*it_out, G1) << "\n";
|
||||
cout << "vertex(source(*it_out, G1), G) = " << vertex(source(*it_out, G1), G) << " vertex(target(*it_out, G1), G) = " << vertex(target(*it_out, G1), G) << "\n";*/
|
||||
add_edge( vertex(reverse_index[source(*it_out, G1)],G), vertex(reverse_index[target(*it_out, G1)], G), G);
|
||||
//add_edge(vertex(source(*it_out, G1), G) , vertex(target(*it_out, G1), G), G);
|
||||
}
|
||||
add_edge( vertex(reverse_index[source(*it_out, G1)],G), vertex(reverse_index[target(*it_out, G1)], G), G);
|
||||
}
|
||||
}
|
||||
return G;
|
||||
|
@ -367,110 +360,8 @@ namespace MFS
|
|||
return something_has_been_done;
|
||||
}
|
||||
|
||||
bool
|
||||
Suppression_of_Edge_i_j_if_not_a_loop_and_if_for_all_i_k_edge_we_have_a_k_j_edge_Step(AdjacencyList_type& G) //Suppression
|
||||
{
|
||||
bool something_has_been_done = false;
|
||||
AdjacencyList_type::vertex_iterator it, it_end;
|
||||
int i = 0;
|
||||
bool agree;
|
||||
for (tie(it, it_end) = vertices(G);it != it_end; ++it, i++)
|
||||
{
|
||||
AdjacencyList_type::in_edge_iterator it_in, in_end;
|
||||
AdjacencyList_type::out_edge_iterator it_out, out_end, it_out1, ita_out;
|
||||
int j = 0;
|
||||
for (tie(ita_out = it_out, out_end) = out_edges(*it, G); it_out != out_end; ++it_out, j++)
|
||||
{
|
||||
AdjacencyList_type::edge_descriptor ed;
|
||||
bool exist;
|
||||
tie(ed, exist) = edge(target(*it_out, G), source(*it_out, G) , G);
|
||||
if (!exist)
|
||||
{
|
||||
agree = true;
|
||||
for (tie(it_out1, out_end) = out_edges(*it, G); it_out1 != out_end; ++it_out1)
|
||||
{
|
||||
bool exist;
|
||||
tie(ed, exist) = edge(target(*it_out1, G), target(*it_out, G) , G);
|
||||
if (target(*it_out1, G) != target(*it_out, G) and !exist)
|
||||
agree = false;
|
||||
}
|
||||
if (agree)
|
||||
{
|
||||
something_has_been_done = true;
|
||||
remove_edge(*it_out, G);
|
||||
if (out_degree(*it, G) == 0)
|
||||
break;
|
||||
if (j > 0)
|
||||
{
|
||||
it_out = ita_out;
|
||||
tie(it_out1, out_end) = out_edges(*it, G);
|
||||
}
|
||||
else
|
||||
{
|
||||
tie(it_out, out_end) = out_edges(*it, G);
|
||||
j--;
|
||||
}
|
||||
}
|
||||
}
|
||||
ita_out = it_out;
|
||||
}
|
||||
}
|
||||
return something_has_been_done;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Suppression_of_all_in_Edge_in_i_if_not_a_loop_and_if_all_doublet_i_eq_Min_inDegree_outDegree_Step(AdjacencyList_type& G)
|
||||
{
|
||||
bool something_has_been_done = false;
|
||||
AdjacencyList_type::vertex_iterator it, it_end;
|
||||
int i = 0;
|
||||
for (tie(it, it_end) = vertices(G);it != it_end; ++it, i++)
|
||||
{
|
||||
AdjacencyList_type::in_edge_iterator it_in, in_end, it_in1, ita_in;
|
||||
vector<AdjacencyList_type::vertex_descriptor> doublet = Collect_Doublet(*it, G);
|
||||
if (doublet.size() == (unsigned int) min(in_degree(*it, G), out_degree(*it, G)))
|
||||
{
|
||||
int j = 0;
|
||||
if (in_degree(*it, G))
|
||||
for (tie(ita_in = it_in, in_end) = in_edges(*it, G); it_in != in_end; ++it_in, j++)
|
||||
{
|
||||
vector<AdjacencyList_type::vertex_descriptor>::iterator it1 = doublet.begin();
|
||||
bool not_a_doublet = true;
|
||||
while (it1 != doublet.end() and not_a_doublet)
|
||||
{
|
||||
if (target(*it_in, G) == *it1)
|
||||
not_a_doublet = false;
|
||||
it1++;
|
||||
}
|
||||
if (not_a_doublet and source(*it_in, G) != target(*it_in, G))
|
||||
{
|
||||
#ifdef verbose
|
||||
property_map<AdjacencyList_type, vertex_index_t>::type v_index = get(vertex_index, G);
|
||||
cout << "remove_edge(" << v_index[source(*it_in, G)] << ", " << v_index[target(*it_in, G)] << ", G) j=" << j << " it_in == in_end : " << (it_in == in_end) << " in_degree(*it, G)=" << in_degree(*it, G) << ";\n";
|
||||
#endif
|
||||
something_has_been_done = true;
|
||||
remove_edge(source(*it_in, G), target(*it_in, G), G);
|
||||
cout << " in_degree(*it, G)=" << in_degree(*it, G) << ";\n";
|
||||
if (in_degree(*it, G) == 0)
|
||||
break;
|
||||
if (j > 0)
|
||||
{
|
||||
it_in = ita_in;
|
||||
}
|
||||
else
|
||||
{
|
||||
tie(it_in, in_end) = in_edges(*it, G);
|
||||
j--;
|
||||
}
|
||||
}
|
||||
ita_in = it_in;
|
||||
}
|
||||
}
|
||||
}
|
||||
return something_has_been_done;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Suppression_of_Vertex_X_if_it_loops_store_in_set_of_feedback_vertex_Step(set<int> &feed_back_vertices, AdjacencyList_type& G)
|
||||
|
@ -537,21 +428,9 @@ namespace MFS
|
|||
#endif
|
||||
|
||||
//Rule 3
|
||||
//something_has_been_done=(Suppression_of_Edge_i_j_if_not_a_loop_and_if_for_all_i_k_edge_we_have_a_k_j_edge_Step(G) or something_has_been_done);
|
||||
#ifdef verbose
|
||||
cout << "3 something_has_been_done=" << something_has_been_done << "\n";
|
||||
#endif
|
||||
|
||||
//Rule 4
|
||||
//something_has_been_done=(Suppression_of_all_in_Edge_in_i_if_not_a_loop_and_if_all_doublet_i_eq_Min_inDegree_outDegree_Step(G) or something_has_been_done);
|
||||
#ifdef verbose
|
||||
cout << "4 something_has_been_done=" << something_has_been_done << "\n";
|
||||
#endif
|
||||
|
||||
//Rule 5
|
||||
something_has_been_done = (Suppression_of_Vertex_X_if_it_loops_store_in_set_of_feedback_vertex_Step(feed_back_vertices, G) or something_has_been_done);
|
||||
#ifdef verbose
|
||||
cout << "5 something_has_been_done=" << something_has_been_done << "\n";
|
||||
cout << "3 something_has_been_done=" << something_has_been_done << "\n";
|
||||
#endif
|
||||
}
|
||||
vector<int> circuit;
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
#include <vector>
|
||||
#include <boost/graph/graphviz.hpp>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
@ -44,25 +42,42 @@ using namespace boost;
|
|||
|
||||
namespace MFS
|
||||
{
|
||||
//! Eliminate a vertex i:
|
||||
//! For a vertex i replace all edges e_k_i and e_i_j by a shorcut e_k_j and then Suppress the vertex i
|
||||
void Eliminate(AdjacencyList_type::vertex_descriptor vertex_to_eliminate, AdjacencyList_type& G);
|
||||
//!collect all doublet (for each edge e_i_k there is an edge e_k_i with k!=i) in the graph
|
||||
//! and return the vector of doublet
|
||||
vector_vertex_descriptor Collect_Doublet(AdjacencyList_type::vertex_descriptor vertex, AdjacencyList_type& G);
|
||||
//! Detect all the clique (all vertex in a clique are related to each other) in the graph
|
||||
bool Vertex_Belong_to_a_Clique(AdjacencyList_type::vertex_descriptor vertex, AdjacencyList_type& G);
|
||||
bool Elimination_of_Vertex_With_One_or_Less_Indegree_or_Outdegree_Step(AdjacencyList_type& G); //Graph reduction: eliminating purely intermediate variables or variables outside of any circuit
|
||||
bool Elimination_of_Vertex_belonging_to_a_clique_Step(AdjacencyList_type& G); //Graphe reduction: eliminaion of Cliques
|
||||
bool Suppression_of_Edge_i_j_if_not_a_loop_and_if_for_all_i_k_edge_we_have_a_k_j_edge_Step(AdjacencyList_type& G); //Suppression
|
||||
bool Suppression_of_all_in_Edge_in_i_if_not_a_loop_and_if_all_doublet_i_eq_Min_inDegree_outDegree_Step(AdjacencyList_type& G);
|
||||
//! Graph reduction: eliminating purely intermediate variables or variables outside of any circuit
|
||||
bool Elimination_of_Vertex_With_One_or_Less_Indegree_or_Outdegree_Step(AdjacencyList_type& G);
|
||||
//! Graphe reduction: elimination of a vertex inside a clique
|
||||
bool Elimination_of_Vertex_belonging_to_a_clique_Step(AdjacencyList_type& G);
|
||||
//! A vertex belong to the feedback vertex set if the vertex loop on itself.
|
||||
//! We have to suppress this vertex and store it into the feedback set.
|
||||
bool Suppression_of_Vertex_X_if_it_loops_store_in_set_of_feedback_vertex_Step(vector<pair<int, AdjacencyList_type::vertex_descriptor> > &looping_variable, AdjacencyList_type& G);
|
||||
void Print(AdjacencyList_type& G);
|
||||
AdjacencyList_type AM_2_AdjacencyList(bool* AMp,unsigned int n);
|
||||
//! Print the Graph
|
||||
void Print(GraphvizDigraph& G);
|
||||
void Print(AdjacencyList_type& G);
|
||||
//! Create a GraphvizDigraph from a Adjacency Matrix (an incidence Matrix without the diagonal terms)
|
||||
GraphvizDigraph AM_2_GraphvizDigraph(bool* AM, unsigned int n);
|
||||
//! Create an adjacency graph from a Adjacency Matrix (an incidence Matrix without the diagonal terms)
|
||||
AdjacencyList_type AM_2_AdjacencyList(bool* AMp,unsigned int n);
|
||||
//! Create an adjacency graph from a GraphvizDigraph
|
||||
AdjacencyList_type GraphvizDigraph_2_AdjacencyList(GraphvizDigraph& G1, set<int> select_index);
|
||||
//! Check if the graph contains any cycle (true if the model contains at least one cycle, false otherwise)
|
||||
bool has_cycle_dfs(AdjacencyList_type& g, AdjacencyList_type::vertex_descriptor u, color_type& color, vector<int> &circuit_stack);
|
||||
bool has_cylce(AdjacencyList_type& g, vector<int> &circuit_stack, int size);
|
||||
bool has_cycle(vector<int> &circuit_stack, AdjacencyList_type& G);
|
||||
//! Return the feedback set
|
||||
AdjacencyList_type Minimal_set_of_feedback_vertex(set<int> &feed_back_vertices, const AdjacencyList_type& G);
|
||||
//! clear all in and out edges of vertex_to_eliminate
|
||||
//! and remove vertex_to_eliminate from the graph
|
||||
void Suppress(AdjacencyList_type::vertex_descriptor vertex_to_eliminate, AdjacencyList_type& G);
|
||||
void Suppress(int vertex_num, AdjacencyList_type& G);
|
||||
//! reorder the recursive variable:
|
||||
//! They appear first in a quasi triangular form and they are followed by the feedback variables
|
||||
vector<int> Reorder_the_recursive_variables(const AdjacencyList_type& G1, set<int> &feed_back_vertices);
|
||||
};
|
||||
|
||||
|
|
|
@ -147,7 +147,7 @@ ModFile::computingPass(bool no_tmp_terms)
|
|||
static_model.computingPass(false, no_tmp_terms);
|
||||
|
||||
// Set things to compute for dynamic model
|
||||
|
||||
|
||||
if (mod_file_struct.simul_present)
|
||||
dynamic_model.computingPass(false, false, false, false, global_eval_context, no_tmp_terms);
|
||||
else
|
||||
|
|
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