Minor corrections (comments corrected in MinimumFeedBackSet.hh, makefile updated and ModelNormalization erased)
git-svn-id: https://www.dynare.org/svn/dynare/trunk@2727 ac1d8469-bf42-47a9-8791-bf33cf982152issue#70
parent
3737c1aa2e
commit
983d7e030a
202
Makefile.in
202
Makefile.in
|
@ -1,102 +1,100 @@
|
||||||
CXX = @CXX@
|
CXX = @CXX@
|
||||||
CXXFLAGS = @CXXFLAGS@
|
CXXFLAGS = @CXXFLAGS@
|
||||||
CPPFLAGS = @CPPFLAGS@ @DEFS@
|
CPPFLAGS = @CPPFLAGS@ @DEFS@
|
||||||
LDFLAGS = @LDFLAGS@
|
LDFLAGS = @LDFLAGS@
|
||||||
|
|
||||||
FLEX = @FLEX@
|
FLEX = @FLEX@
|
||||||
BISON = @BISON@
|
BISON = @BISON@
|
||||||
|
|
||||||
DYNARE_M = dynare_m@EXEEXT@
|
DYNARE_M = dynare_m@EXEEXT@
|
||||||
|
|
||||||
MAIN_OBJS = \
|
MAIN_OBJS = \
|
||||||
DynareFlex.o \
|
DynareFlex.o \
|
||||||
DynareBison.o \
|
DynareBison.o \
|
||||||
ComputingTasks.o \
|
ComputingTasks.o \
|
||||||
ModelTree.o \
|
ModelTree.o \
|
||||||
StaticModel.o \
|
StaticModel.o \
|
||||||
DynamicModel.o \
|
DynamicModel.o \
|
||||||
NumericalConstants.o \
|
NumericalConstants.o \
|
||||||
NumericalInitialization.o \
|
NumericalInitialization.o \
|
||||||
Shocks.o \
|
Shocks.o \
|
||||||
SigmaeInitialization.o \
|
SigmaeInitialization.o \
|
||||||
SymbolTable.o \
|
SymbolTable.o \
|
||||||
SymbolList.o \
|
SymbolList.o \
|
||||||
ParsingDriver.o \
|
ParsingDriver.o \
|
||||||
DataTree.o \
|
DataTree.o \
|
||||||
ModFile.o \
|
ModFile.o \
|
||||||
Statement.o \
|
Statement.o \
|
||||||
ExprNode.o \
|
ExprNode.o \
|
||||||
ModelNormalization.o \
|
ModelBlocks.o \
|
||||||
ModelBlocks.o \
|
MinimumFeedbackSet.o \
|
||||||
MinimumFeedbackSet.o \
|
IncidenceMatrix.o \
|
||||||
IncidenceMatrix.o \
|
BlockTriangular.o \
|
||||||
BlockTriangular.o \
|
DynareMain.o \
|
||||||
ModelGraph.o \
|
DynareMain2.o
|
||||||
DynareMain.o \
|
|
||||||
DynareMain2.o
|
MACRO_OBJS = \
|
||||||
|
macro/MacroFlex.o \
|
||||||
MACRO_OBJS = \
|
macro/MacroBison.o \
|
||||||
macro/MacroFlex.o \
|
macro/MacroDriver.o \
|
||||||
macro/MacroBison.o \
|
macro/MacroValue.o
|
||||||
macro/MacroDriver.o \
|
|
||||||
macro/MacroValue.o
|
|
||||||
|
# Build rules
|
||||||
|
|
||||||
# Build rules
|
.PHONY: all
|
||||||
|
all: $(DYNARE_M)
|
||||||
.PHONY: all
|
|
||||||
all: $(DYNARE_M)
|
$(DYNARE_M): $(MAIN_OBJS) $(MACRO_OBJS)
|
||||||
|
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $(DYNARE_M) $(MAIN_OBJS) $(MACRO_OBJS)
|
||||||
$(DYNARE_M): $(MAIN_OBJS) $(MACRO_OBJS)
|
cp $(DYNARE_M) ../matlab/
|
||||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $(DYNARE_M) $(MAIN_OBJS) $(MACRO_OBJS)
|
|
||||||
cp $(DYNARE_M) ../matlab/
|
|
||||||
|
# Build rules for Flex and Bison files
|
||||||
|
|
||||||
# Build rules for Flex and Bison files
|
DynareFlex.cc: DynareFlex.ll
|
||||||
|
$(FLEX) -oDynareFlex.cc DynareFlex.ll
|
||||||
DynareFlex.cc: DynareFlex.ll
|
|
||||||
$(FLEX) -oDynareFlex.cc DynareFlex.ll
|
DynareBison.cc DynareBison.hh location.hh stack.hh position.hh: DynareBison.yy
|
||||||
|
$(BISON) --verbose -o DynareBison.cc DynareBison.yy
|
||||||
DynareBison.cc DynareBison.hh location.hh stack.hh position.hh: DynareBison.yy
|
|
||||||
$(BISON) --verbose -o DynareBison.cc DynareBison.yy
|
macro/MacroFlex.cc: macro/MacroFlex.ll
|
||||||
|
cd macro && $(FLEX) -oMacroFlex.cc MacroFlex.ll
|
||||||
macro/MacroFlex.cc: macro/MacroFlex.ll
|
|
||||||
cd macro && $(FLEX) -oMacroFlex.cc MacroFlex.ll
|
macro/MacroBison.cc macro/MacroBison.hh macro/location.hh macro/stack.hh macro/position.hh: macro/MacroBison.yy
|
||||||
|
cd macro && $(BISON) --verbose -o MacroBison.cc MacroBison.yy
|
||||||
macro/MacroBison.cc macro/MacroBison.hh macro/location.hh macro/stack.hh macro/position.hh: macro/MacroBison.yy
|
|
||||||
cd macro && $(BISON) --verbose -o MacroBison.cc MacroBison.yy
|
|
||||||
|
# Dependencies
|
||||||
|
|
||||||
# Dependencies
|
%.d: %.cc DynareBison.hh macro/MacroBison.hh
|
||||||
|
@set -e; rm -f $@; \
|
||||||
%.d: %.cc DynareBison.hh macro/MacroBison.hh
|
$(CXX) -MM $(CPPFLAGS) $< > $@.$$$$; \
|
||||||
@set -e; rm -f $@; \
|
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
|
||||||
$(CXX) -MM $(CPPFLAGS) $< > $@.$$$$; \
|
rm -f $@.$$$$
|
||||||
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
|
|
||||||
rm -f $@.$$$$
|
-include $(MAIN_OBJS:.o=.d)
|
||||||
|
-include $(MACRO_OBJS:.o=.d)
|
||||||
-include $(MAIN_OBJS:.o=.d)
|
|
||||||
-include $(MACRO_OBJS:.o=.d)
|
|
||||||
|
# Clean
|
||||||
|
|
||||||
# Clean
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
.PHONY: clean
|
rm -f *.o *.d *~ \
|
||||||
clean:
|
DynareFlex.cc \
|
||||||
rm -f *.o *.d *~ \
|
DynareBison.output \
|
||||||
DynareFlex.cc \
|
DynareBison.cc \
|
||||||
DynareBison.output \
|
position.hh \
|
||||||
DynareBison.cc \
|
stack.hh \
|
||||||
position.hh \
|
location.hh \
|
||||||
stack.hh \
|
DynareBison.hh \
|
||||||
location.hh \
|
$(DYNARE_M)
|
||||||
DynareBison.hh \
|
cd macro && rm -f *.o *.d *~ \
|
||||||
$(DYNARE_M)
|
MacroFlex.cc \
|
||||||
cd macro && rm -f *.o *.d *~ \
|
MacroBison.output \
|
||||||
MacroFlex.cc \
|
MacroBison.cc \
|
||||||
MacroBison.output \
|
MacroBison.hh \
|
||||||
MacroBison.cc \
|
location.hh \
|
||||||
MacroBison.hh \
|
stack.hh \
|
||||||
location.hh \
|
position.hh
|
||||||
stack.hh \
|
|
||||||
position.hh
|
|
||||||
|
|
|
@ -43,10 +43,10 @@ using namespace boost;
|
||||||
namespace MFS
|
namespace MFS
|
||||||
{
|
{
|
||||||
//! Eliminate a vertex i:
|
//! 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
|
/*! For a vertex i replace all edges e_k_i and e_i_j by a shorcut e_k_j and then Suppress the vertex i*/
|
||||||
void Eliminate(AdjacencyList_type::vertex_descriptor vertex_to_eliminate, AdjacencyList_type& G);
|
void Eliminate(AdjacencyList_type::vertex_descriptor vertex_to_eliminate, AdjacencyList_type& G);
|
||||||
//!collect all doublet (for each edge e_i_k there is an edge e_k_i with k!=i) in the graph
|
//!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
|
/*! and return the vector of doublet*/
|
||||||
vector_vertex_descriptor Collect_Doublet(AdjacencyList_type::vertex_descriptor vertex, AdjacencyList_type& G);
|
vector_vertex_descriptor Collect_Doublet(AdjacencyList_type::vertex_descriptor vertex, AdjacencyList_type& G);
|
||||||
//! Detect all the clique (all vertex in a clique are related to each other) in the graph
|
//! Detect all the clique (all vertex in a clique are related to each other) in the graph
|
||||||
bool Vertex_Belong_to_a_Clique(AdjacencyList_type::vertex_descriptor vertex, AdjacencyList_type& G);
|
bool Vertex_Belong_to_a_Clique(AdjacencyList_type::vertex_descriptor vertex, AdjacencyList_type& G);
|
||||||
|
@ -55,7 +55,7 @@ namespace MFS
|
||||||
//! Graphe reduction: elimination of a vertex inside a clique
|
//! Graphe reduction: elimination of a vertex inside a clique
|
||||||
bool Elimination_of_Vertex_belonging_to_a_clique_Step(AdjacencyList_type& G);
|
bool Elimination_of_Vertex_belonging_to_a_clique_Step(AdjacencyList_type& G);
|
||||||
//! A vertex belong to the feedback vertex set if the vertex loop on itself.
|
//! 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.
|
/*! We have to suppress this vertex and store it into the feedback set.*/
|
||||||
bool Suppression_of_Vertex_X_if_it_loops_store_in_set_of_feedback_vertex_Step(vector<pair<int, AdjacencyList_type::vertex_descriptor> > &looping_variable, AdjacencyList_type& G);
|
bool Suppression_of_Vertex_X_if_it_loops_store_in_set_of_feedback_vertex_Step(vector<pair<int, AdjacencyList_type::vertex_descriptor> > &looping_variable, AdjacencyList_type& G);
|
||||||
//! Print the Graph
|
//! Print the Graph
|
||||||
void Print(GraphvizDigraph& G);
|
void Print(GraphvizDigraph& G);
|
||||||
|
@ -73,11 +73,11 @@ namespace MFS
|
||||||
//! Return the feedback set
|
//! Return the feedback set
|
||||||
AdjacencyList_type Minimal_set_of_feedback_vertex(set<int> &feed_back_vertices, const AdjacencyList_type& G);
|
AdjacencyList_type Minimal_set_of_feedback_vertex(set<int> &feed_back_vertices, const AdjacencyList_type& G);
|
||||||
//! clear all in and out edges of vertex_to_eliminate
|
//! clear all in and out edges of vertex_to_eliminate
|
||||||
//! and remove vertex_to_eliminate from the graph
|
/*! and remove vertex_to_eliminate from the graph*/
|
||||||
void Suppress(AdjacencyList_type::vertex_descriptor vertex_to_eliminate, AdjacencyList_type& G);
|
void Suppress(AdjacencyList_type::vertex_descriptor vertex_to_eliminate, AdjacencyList_type& G);
|
||||||
void Suppress(int vertex_num, AdjacencyList_type& G);
|
void Suppress(int vertex_num, AdjacencyList_type& G);
|
||||||
//! reorder the recursive variable:
|
//! reorder the recursive variable:
|
||||||
//! They appear first in a quasi triangular form and they are followed by the feedback variables
|
/*! They appear first in a quasi triangular form and they are followed by the feedback variables*/
|
||||||
vector<int> Reorder_the_recursive_variables(const AdjacencyList_type& G1, set<int> &feed_back_vertices);
|
vector<int> Reorder_the_recursive_variables(const AdjacencyList_type& G1, set<int> &feed_back_vertices);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,557 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2007-2009 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
//#define DEBUG
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <iostream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <fstream>
|
|
||||||
#include "ModelNormalization.hh"
|
|
||||||
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
|
|
||||||
Normalization::Normalization(const SymbolTable &symbol_table_arg) :
|
|
||||||
symbol_table(symbol_table_arg), fp_verbose(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Normalization::IM_to_Gr(int n0, int prologue, int epilogue, bool* IM, Equation_set *Equation, Variable_set *Variable )
|
|
||||||
// Create a non-oriented graph of the model from the incidence matrix
|
|
||||||
{
|
|
||||||
int i, j, edges, n;
|
|
||||||
Edge *e1;
|
|
||||||
#ifdef DEBUG
|
|
||||||
cout << "in IM_to_Gr\n";
|
|
||||||
#endif
|
|
||||||
//Normalize only the earth block (the prologue and the epilogue are still normalized)
|
|
||||||
n = n0 - prologue - epilogue;
|
|
||||||
Equation->size = n;
|
|
||||||
Variable->size = n;
|
|
||||||
Equation->Number = (Equation_vertex*)malloc(n * sizeof(Equation_vertex));
|
|
||||||
Variable->Number = (Variable_vertex*)malloc(n * sizeof(Variable_vertex));
|
|
||||||
edges = 0;
|
|
||||||
for(i = 0;i < n;i++)
|
|
||||||
{
|
|
||||||
Equation->Number[i].First_Edge = NULL;
|
|
||||||
Equation->Number[i].matched = -1;
|
|
||||||
Variable->Number[i].matched = -1;
|
|
||||||
for(j = 0;j < n;j++)
|
|
||||||
{
|
|
||||||
if(IM[(j + prologue)*n0 + (i + prologue)])
|
|
||||||
{
|
|
||||||
edges++;
|
|
||||||
e1 = (Edge *) malloc(sizeof(Edge));
|
|
||||||
e1->next = Equation->Number[i].First_Edge;
|
|
||||||
Equation->Number[i].First_Edge = e1;
|
|
||||||
e1->Vertex_Index = j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//The maximum number of vertex in each equation is set to the total amount of edges in the model
|
|
||||||
Equation->edges = edges;
|
|
||||||
#ifdef DEBUG
|
|
||||||
cout << "end of IM_to_Gr\n";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Normalization::Inits(Equation_set *Equation)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
#ifdef DEBUG
|
|
||||||
cout << "in Inits\n";
|
|
||||||
#endif
|
|
||||||
eq = eex = 0;
|
|
||||||
IndexUnmatched = Equation->edges * 2;
|
|
||||||
Local_Heap = (t_Heap*)malloc(IndexUnmatched * sizeof(t_Heap));
|
|
||||||
for(i = 0; i < Equation->size; i++)
|
|
||||||
{
|
|
||||||
Equation->Number[i].Next_Edge = Equation->Number[i].First_Edge;
|
|
||||||
visited[i] = 0;
|
|
||||||
// we put all unmatched vertices from Equation at the other end of the Local_Heap
|
|
||||||
if(Equation->Number[i].matched == -1)
|
|
||||||
{
|
|
||||||
Local_Heap[--IndexUnmatched].u = i;
|
|
||||||
#ifdef DEBUG
|
|
||||||
cout << i << " is unmatched\n";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef DEBUG
|
|
||||||
cout << "end of Inits\n";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Normalization::UpdatePath(Equation_set *Equation, Variable_set *Variable, int i1, int i2)
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
#ifdef DEBUG
|
|
||||||
cout << "in UpdatePath \n";
|
|
||||||
#endif
|
|
||||||
while(i2 >= 0)
|
|
||||||
{
|
|
||||||
i = Local_Heap[i2].u;
|
|
||||||
j = Local_Heap[i1].v;
|
|
||||||
Variable->Number[j].matched = i;
|
|
||||||
Equation->Number[i].matched = j;
|
|
||||||
i1 = i2;
|
|
||||||
i2 = Local_Heap[i2].i_parent;
|
|
||||||
eex++;
|
|
||||||
}
|
|
||||||
#ifdef DEBUG
|
|
||||||
cout << "end of UpdatePath \n";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Normalization::FindAugmentingPaths(Equation_set *Equation, Variable_set *Variable)
|
|
||||||
{
|
|
||||||
// augmenting paths using breadth-first search.
|
|
||||||
int Bottom;
|
|
||||||
int Top;
|
|
||||||
int u, i;
|
|
||||||
Edge *e, *e2;
|
|
||||||
#ifdef DEBUG
|
|
||||||
cout << "in FindAugmentingPaths\n";
|
|
||||||
#endif
|
|
||||||
// external loop gets unmatched u vertices from far end of array Local_Heap
|
|
||||||
while(IndexUnmatched < Equation->edges*2)
|
|
||||||
{
|
|
||||||
Top = Bottom = 0;
|
|
||||||
Local_Heap[Top].u = Local_Heap[IndexUnmatched++].u;
|
|
||||||
Local_Heap[Top].i_parent = -1; /* root of BFS tree */
|
|
||||||
#ifdef DEBUG
|
|
||||||
cout << "unmatched u" << Local_Heap[Top].u << " will be processed\n";
|
|
||||||
#endif
|
|
||||||
// Local_Heap processing
|
|
||||||
while(Bottom >= Top)
|
|
||||||
{
|
|
||||||
u = Local_Heap[Top++].u;
|
|
||||||
e = Equation->Number[u].First_Edge;
|
|
||||||
eq++;
|
|
||||||
// adjacency list scanning
|
|
||||||
while(e != NULL)
|
|
||||||
{
|
|
||||||
if (!visited[Variable->Number[e->Vertex_Index].matched])
|
|
||||||
{
|
|
||||||
// extend tree
|
|
||||||
Local_Heap[++Bottom].u = u = Variable->Number[e->Vertex_Index].matched;
|
|
||||||
Local_Heap[Bottom].i_parent = Top - 1;
|
|
||||||
Local_Heap[Bottom].v = e->Vertex_Index;
|
|
||||||
visited[u] = 1;
|
|
||||||
e2 = Equation->Number[u].Next_Edge;
|
|
||||||
eq++;
|
|
||||||
while ((e2 != NULL) && (Variable->Number[e2->Vertex_Index].matched != -1))
|
|
||||||
{
|
|
||||||
e2 = e2->next;
|
|
||||||
eq++;
|
|
||||||
}
|
|
||||||
Equation->Number[u].Next_Edge = e2;
|
|
||||||
if(e2 != NULL)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
cout << "augmenting path found\n";
|
|
||||||
#endif
|
|
||||||
// u in the Local_Heap but not the edge to v
|
|
||||||
Variable->Number[e2->Vertex_Index].matched = u;
|
|
||||||
Equation->Number[u].matched = e2->Vertex_Index;
|
|
||||||
// now for the rest of the path
|
|
||||||
UpdatePath(Equation, Variable, Bottom, Top - 1);
|
|
||||||
// temporary cut is emptied
|
|
||||||
for(i = 0; i <= Bottom; i++)
|
|
||||||
visited[Local_Heap[i].u] = 0;
|
|
||||||
Bottom = Top - 1;
|
|
||||||
// to get off from Local_Heap loop
|
|
||||||
// to get off from adj list scan loop
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
e = e->next;
|
|
||||||
eq++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef DEBUG
|
|
||||||
cout << "end of FindAugmentingPaths\n";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Normalization::CheapMatching(Equation_set *Equation, Variable_set *Variable)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
Edge *e;
|
|
||||||
int count = 0;
|
|
||||||
#ifdef DEBUG
|
|
||||||
cout << "in CheapMatching Equation->size : " << Equation->size << "\n";
|
|
||||||
#endif
|
|
||||||
for(i = 0; i < Equation->size; i++)
|
|
||||||
{
|
|
||||||
e = Equation->Number[i].First_Edge;
|
|
||||||
while(e != (Edge *) NULL)
|
|
||||||
{
|
|
||||||
if(Variable->Number[e->Vertex_Index].matched == -1)
|
|
||||||
{
|
|
||||||
Variable->Number[e->Vertex_Index].matched = i;
|
|
||||||
Equation->Number[i].matched = e->Vertex_Index;
|
|
||||||
#ifdef DEBUG
|
|
||||||
cout << i << " matched to " << e->Vertex_Index << "\n";
|
|
||||||
#endif
|
|
||||||
count++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
e = e->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(fp_verbose)
|
|
||||||
cout << count << " vertices in Equation were initially matched (" << (float) 100*count / Equation->size << "%)\n";
|
|
||||||
#ifdef DEBUG
|
|
||||||
cout << "end of CheapMatching\n";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Normalization::MaximumMatching(Equation_set *Equation, Variable_set *Variable)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
cout << "in MaximumMatching\n";
|
|
||||||
#endif
|
|
||||||
CheapMatching(Equation, Variable);
|
|
||||||
Inits(Equation);
|
|
||||||
FindAugmentingPaths(Equation, Variable);
|
|
||||||
#ifdef DEBUG
|
|
||||||
cout << "end of MaximumMatching\n";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
Normalization::MeasureMatching(Equation_set *Equation)
|
|
||||||
{
|
|
||||||
int size = 0, i;
|
|
||||||
for(i = 0; i < Equation->size; i++)
|
|
||||||
if(Equation->Number[i].matched != -1)
|
|
||||||
size++;
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Normalization::OutputMatching(Equation_set* Equation)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
Edge* e1;
|
|
||||||
cout << "Maximum Matching Results for |Equation|=" << Equation->size << " |Edges|=" << Equation->edges << "\n";
|
|
||||||
for(i = 0; i < Equation->size; i++)
|
|
||||||
{
|
|
||||||
if(Equation->Number[i].matched != -1)
|
|
||||||
cout << "equation " << i << " matched to variable " << Equation->Number[i].matched;
|
|
||||||
else
|
|
||||||
cout << "equation " << i << " not matched \n";
|
|
||||||
e1 = Equation->Number[i].First_Edge;
|
|
||||||
while(e1 != NULL)
|
|
||||||
{
|
|
||||||
cout << " " << e1->Vertex_Index;
|
|
||||||
e1 = e1->next;
|
|
||||||
}
|
|
||||||
cout << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Normalization::Gr_to_IM_basic(int n0, int prologue, int epilogue, bool* IM, Equation_set *Equation, bool transpose)
|
|
||||||
{
|
|
||||||
int i, j, edges, n;
|
|
||||||
Edge *e1, *e2;
|
|
||||||
n = n0 - prologue - epilogue;
|
|
||||||
Equation->size = n;
|
|
||||||
if(Equation->Number)
|
|
||||||
{
|
|
||||||
for(i = 0;i < n;i++)
|
|
||||||
{
|
|
||||||
e1 = Equation->Number[i].First_Edge;
|
|
||||||
while(e1 != NULL)
|
|
||||||
{
|
|
||||||
e2 = e1->next;
|
|
||||||
free(e1);
|
|
||||||
e1 = e2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(Equation->Number);
|
|
||||||
}
|
|
||||||
Equation->Number = (Equation_vertex*)malloc(n * sizeof(Equation_vertex));
|
|
||||||
edges = 0;
|
|
||||||
if(transpose)
|
|
||||||
{
|
|
||||||
for(i = 0;i < n;i++)
|
|
||||||
{
|
|
||||||
Equation->Number[i].First_Edge = NULL;
|
|
||||||
Equation->Number[i].matched = -1;
|
|
||||||
for(j = 0;j < n;j++)
|
|
||||||
{
|
|
||||||
if ((IM[(j + prologue)*n0 + (i + prologue)]) && (i != j))
|
|
||||||
{
|
|
||||||
edges++;
|
|
||||||
e1 = (Edge *) malloc(sizeof(Edge));
|
|
||||||
e1->next = Equation->Number[i].First_Edge;
|
|
||||||
Equation->Number[i].First_Edge = e1;
|
|
||||||
e1->Vertex_Index = j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(i = 0;i < n;i++)
|
|
||||||
{
|
|
||||||
Equation->Number[i].First_Edge = NULL;
|
|
||||||
Equation->Number[i].matched = -1;
|
|
||||||
for(j = 0;j < n;j++)
|
|
||||||
{
|
|
||||||
if ((IM[(i + prologue)*n0 + (j + prologue)]) && (i != j))
|
|
||||||
{
|
|
||||||
edges++;
|
|
||||||
e1 = (Edge *) malloc(sizeof(Edge));
|
|
||||||
e1->next = Equation->Number[i].First_Edge;
|
|
||||||
Equation->Number[i].First_Edge = e1;
|
|
||||||
e1->Vertex_Index = j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//The maximum number of vertex in each equation is set to the total amount of edges in the model
|
|
||||||
Equation->edges = edges;
|
|
||||||
#ifdef DEBUG
|
|
||||||
cout << "end of IM_to_Gr\n";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Normalization::Gr_to_IM(int n0, int prologue, int epilogue, bool* IM, vector<int> &Index_Equ_IM, Equation_set *Equation, bool mixing, bool* IM_s)
|
|
||||||
{
|
|
||||||
int i, j, n, l;
|
|
||||||
Edge *e1, *e2;
|
|
||||||
Equation_set* Equation_p;
|
|
||||||
vector<int> Index_Equ_IM_tmp(Index_Equ_IM);
|
|
||||||
bool* SIM = (bool*)malloc(n0 * n0 * sizeof(bool));
|
|
||||||
#ifdef DEBUG
|
|
||||||
cout << "in Gr_to_IM\n";
|
|
||||||
#endif
|
|
||||||
n = n0 - prologue - epilogue;
|
|
||||||
if(mixing)
|
|
||||||
{
|
|
||||||
for(i = 0;i < n0*n0;i++)
|
|
||||||
SIM[i] = IM_s[i];
|
|
||||||
for(i = 0;i < n;i++)
|
|
||||||
{
|
|
||||||
/*Index_Var_IM[j+prologue].index=Index_Var_IM_tmp[Equation->Number[j].matched+prologue].index;*/
|
|
||||||
if(fp_verbose)
|
|
||||||
cout << "Equation->Number[" << i << "].matched=" << Equation->Number[i].matched << "\n";
|
|
||||||
Index_Equ_IM[i + prologue] = Index_Equ_IM_tmp[Equation->Number[i].matched + prologue];
|
|
||||||
for(j = 0;j < n0;j++)
|
|
||||||
SIM[(i + prologue)*n0 + j] = IM_s[(Equation->Number[i].matched + prologue) * n0 + j];
|
|
||||||
}
|
|
||||||
for(i = 0;i < n0*n0;i++)
|
|
||||||
IM[i] = SIM[i];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(i = 0;i < n0*n0;i++)
|
|
||||||
SIM[i] = IM[i];
|
|
||||||
for(i = 0;i < n0;i++)
|
|
||||||
Index_Equ_IM_tmp[i] = Index_Equ_IM[i];
|
|
||||||
for(j = 0;j < n;j++)
|
|
||||||
{
|
|
||||||
if(fp_verbose)
|
|
||||||
cout << "Equation->Number[" << j << "].matched=" << Equation->Number[j].matched << "\n";
|
|
||||||
Index_Equ_IM[j + prologue] = Index_Equ_IM_tmp[Equation->Number[j].matched + prologue];
|
|
||||||
for(i = 0;i < n0;i++)
|
|
||||||
SIM[(i)*n0 + j + prologue] = IM[(i) * n0 + Equation->Number[j].matched + prologue];
|
|
||||||
}
|
|
||||||
for(i = 0;i < n0*n0;i++)
|
|
||||||
IM[i] = SIM[i];
|
|
||||||
}
|
|
||||||
free(SIM);
|
|
||||||
//cout << "mixing=" << mixing << "\n";
|
|
||||||
if(mixing)
|
|
||||||
{
|
|
||||||
//Free_Equation(n,Equation);
|
|
||||||
Gr_to_IM_basic(n0, prologue, epilogue, IM, Equation, true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// In this step we :
|
|
||||||
// 1) get ride of the edge from the equation to its explain variable
|
|
||||||
// 2) resort the equation in the order of the matched variable
|
|
||||||
// 3) transpose the graph
|
|
||||||
// in order to get the oriented graph needed to find strong connex components
|
|
||||||
Equation_p = (Equation_set*)malloc(sizeof(Equation_set));
|
|
||||||
Equation_p->size = Equation->size;
|
|
||||||
Equation_p->edges = Equation->edges;
|
|
||||||
Equation_p->Number = (Equation_vertex*)malloc(n * sizeof(Equation_vertex));
|
|
||||||
for(i = 0;i < n;i++)
|
|
||||||
{
|
|
||||||
Equation_p->Number[i].First_Edge = NULL;
|
|
||||||
Equation_p->Number[i].Next_Edge = NULL;
|
|
||||||
}
|
|
||||||
for(i = 0;i < n;i++)
|
|
||||||
{
|
|
||||||
l = Equation->Number[i].matched;
|
|
||||||
e1 = Equation->Number[l].First_Edge;
|
|
||||||
while(e1 != NULL)
|
|
||||||
{
|
|
||||||
if(e1->Vertex_Index != i)
|
|
||||||
{
|
|
||||||
j = e1->Vertex_Index;
|
|
||||||
if(Equation_p->Number[j].First_Edge != NULL)
|
|
||||||
{
|
|
||||||
Equation_p->Number[j].Next_Edge->next = (Edge*)malloc(sizeof(Edge*));
|
|
||||||
Equation_p->Number[j].Next_Edge = Equation_p->Number[j].Next_Edge->next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Equation_p->Number[j].First_Edge = (Edge*)malloc(sizeof(Edge*));
|
|
||||||
Equation_p->Number[j].Next_Edge = Equation_p->Number[j].First_Edge;
|
|
||||||
}
|
|
||||||
Equation_p->Number[j].Next_Edge->next = NULL;
|
|
||||||
Equation_p->Number[j].Next_Edge->Vertex_Index = i;
|
|
||||||
}
|
|
||||||
e2 = e1->next;
|
|
||||||
free(e1);
|
|
||||||
e1 = e2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(i = 0;i < n;i++)
|
|
||||||
{
|
|
||||||
Equation->Number[i].matched = Equation_p->Number[i].matched;
|
|
||||||
Equation->Number[i].First_Edge = Equation_p->Number[i].First_Edge;
|
|
||||||
Equation->Number[i].Next_Edge = Equation_p->Number[i].Next_Edge;
|
|
||||||
}
|
|
||||||
free(Equation_p->Number);
|
|
||||||
free(Equation_p);
|
|
||||||
}
|
|
||||||
#ifdef DEBUG
|
|
||||||
cout << "end of Gr_to_IM\n";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Normalization::Free_Equation(int n, Equation_set* Equation)
|
|
||||||
{
|
|
||||||
//free unused space
|
|
||||||
Edge *e1, *e2;
|
|
||||||
int i;
|
|
||||||
for(i = 0;i < n;i++)
|
|
||||||
{
|
|
||||||
e1 = Equation->Number[i].First_Edge;
|
|
||||||
while(e1 != NULL)
|
|
||||||
{
|
|
||||||
e2 = e1->next;
|
|
||||||
free(e1);
|
|
||||||
e1 = e2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(Equation->Number);
|
|
||||||
//free(Equation);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Normalization::Free_Other(Variable_set* Variable)
|
|
||||||
{
|
|
||||||
//free unused space
|
|
||||||
#ifdef DEBUG
|
|
||||||
cout << "Free_Other\n";
|
|
||||||
#endif
|
|
||||||
free(Local_Heap);
|
|
||||||
free(Variable->Number);
|
|
||||||
free(Variable);
|
|
||||||
free(visited);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Normalization::Free_All(int n, Equation_set* Equation, Variable_set* Variable)
|
|
||||||
{
|
|
||||||
Free_Equation(n, Equation);
|
|
||||||
Free_Other(Variable);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Normalization::Set_fp_verbose(bool ok)
|
|
||||||
{
|
|
||||||
fp_verbose=ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Normalization::Normalize(int n, int prologue, int epilogue, bool* IM, vector<int> &Index_Equ_IM, Equation_set* Equation, bool mixing, bool* IM_s)
|
|
||||||
{
|
|
||||||
int matchingSize, effective_n;
|
|
||||||
int save_fp_verbose=fp_verbose;
|
|
||||||
fp_verbose = 0;
|
|
||||||
Variable_set* Variable = (Variable_set*) malloc(sizeof(Variable_set));
|
|
||||||
#ifdef DEBUG
|
|
||||||
cout << "in Normalize\n";
|
|
||||||
#endif
|
|
||||||
visited = (bool*)malloc(n * sizeof(*visited));
|
|
||||||
IM_to_Gr(n, prologue, epilogue, IM, Equation, Variable);
|
|
||||||
MaximumMatching(Equation, Variable);
|
|
||||||
matchingSize = MeasureMatching(Equation);
|
|
||||||
effective_n = n - prologue - epilogue;
|
|
||||||
fp_verbose=save_fp_verbose;
|
|
||||||
if(matchingSize < effective_n && fp_verbose)
|
|
||||||
{
|
|
||||||
cout << "Error: dynare could not normalize the model.\n The following equations:\n - ";
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < Equation->size; i++)
|
|
||||||
if(Equation->Number[i].matched == -1)
|
|
||||||
cout << i << " ";
|
|
||||||
cout << "\n and the following variables:\n - ";
|
|
||||||
for(i = 0; i < Variable->size; i++)
|
|
||||||
if(Variable->Number[i].matched == -1)
|
|
||||||
cout << symbol_table.getName(Index_Equ_IM[i]) << " ";
|
|
||||||
cout << "\n could not be normalized\n";
|
|
||||||
//ErrorHandling(n, IM, Index_Equ_IM);
|
|
||||||
//system("PAUSE");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
if(matchingSize >= effective_n )
|
|
||||||
{
|
|
||||||
Gr_to_IM(n, prologue, epilogue, IM, Index_Equ_IM, Equation, mixing, IM_s);
|
|
||||||
if(fp_verbose)
|
|
||||||
{
|
|
||||||
OutputMatching(Equation);
|
|
||||||
for(int i = 0;i < n;i++)
|
|
||||||
cout << "Index_Equ_IM[" << i << "]=" << Index_Equ_IM[i]/*<< " == " "Index_Var_IM[" << i << "]=" << Index_Var_IM[i].index*/ << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Free_Other(Variable);
|
|
||||||
//Free_All(n,Equation,Variable);
|
|
||||||
#ifdef DEBUG
|
|
||||||
cout << "end of Normalize\n";
|
|
||||||
#endif
|
|
||||||
if(matchingSize < effective_n )
|
|
||||||
return(0);
|
|
||||||
else
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,96 +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 _MODELNORMALIZATION_HH
|
|
||||||
#define _MODELNORMALIZATION_HH
|
|
||||||
#include "SymbolTable.hh"
|
|
||||||
#include "CodeInterpreter.hh"
|
|
||||||
|
|
||||||
|
|
||||||
//! One edge in the bi-partite graph (equation side), stored in a chained-list
|
|
||||||
struct Edge
|
|
||||||
{
|
|
||||||
Edge *next;
|
|
||||||
int Vertex_Index; //!< Variable linked to the equation
|
|
||||||
};
|
|
||||||
|
|
||||||
//! Set of the edges going to a given equation
|
|
||||||
struct Equation_vertex
|
|
||||||
{
|
|
||||||
Edge *First_Edge;
|
|
||||||
Edge *Next_Edge;
|
|
||||||
int matched;
|
|
||||||
};
|
|
||||||
|
|
||||||
//! Bi-partite graph, seen from the equation side
|
|
||||||
struct Equation_set
|
|
||||||
{
|
|
||||||
Equation_vertex *Number;
|
|
||||||
int size;
|
|
||||||
int edges;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//! Computes the model normalization
|
|
||||||
class Normalization
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
//! Indicates if a given variable vertex is matched
|
|
||||||
struct Variable_vertex
|
|
||||||
{
|
|
||||||
int matched;
|
|
||||||
};
|
|
||||||
//! Data extracted from the bi-partite graph, seen from the variable side
|
|
||||||
struct Variable_set
|
|
||||||
{
|
|
||||||
Variable_vertex *Number;
|
|
||||||
int size;
|
|
||||||
};
|
|
||||||
struct t_Heap
|
|
||||||
{
|
|
||||||
int u; /* vertex */
|
|
||||||
int i_parent; /* index in t_Heap of parent vertex in tree of u */
|
|
||||||
int v; /* current matched of u */
|
|
||||||
};
|
|
||||||
public:
|
|
||||||
Normalization(const SymbolTable &symbol_table_arg);
|
|
||||||
bool Normalize(int n, int prologue, int epilogue, bool* IM, vector<int> &Index_Var_IM, Equation_set* Equation,bool mixing, bool* IM_s);
|
|
||||||
void Gr_to_IM_basic(int n0, int prologue, int epilogue, bool* IM, Equation_set *Equation,bool transpose);
|
|
||||||
const SymbolTable &symbol_table;
|
|
||||||
void Set_fp_verbose(bool ok);
|
|
||||||
void Free_Equation(int n, Equation_set* Equation);
|
|
||||||
private:
|
|
||||||
void IM_to_Gr(int n0, int prologue, int epilogue, bool* IM, Equation_set *Equation, Variable_set *Variable );
|
|
||||||
void Inits(Equation_set *Equation);
|
|
||||||
void UpdatePath(Equation_set *Equation, Variable_set *Variable, int i1, int i2);
|
|
||||||
void FindAugmentingPaths(Equation_set *Equation, Variable_set *Variable);
|
|
||||||
void CheapMatching(Equation_set *Equation, Variable_set *Variable);
|
|
||||||
void MaximumMatching(Equation_set *Equation, Variable_set *Variable);
|
|
||||||
int MeasureMatching(Equation_set *Equation);
|
|
||||||
void OutputMatching(Equation_set* Equation);
|
|
||||||
void Gr_to_IM(int n0, int prologue, int epilogue, bool* IM, vector<int> &Index_Var_IM, Equation_set *Equation,bool mixing, bool* IM_s);
|
|
||||||
void Free_Other(Variable_set* Variable);
|
|
||||||
void Free_All(int n, Equation_set* Equation, Variable_set* Variable);
|
|
||||||
int eq, eex;
|
|
||||||
int IndexUnmatched;
|
|
||||||
bool fp_verbose;
|
|
||||||
bool* visited;
|
|
||||||
t_Heap* Local_Heap;
|
|
||||||
};
|
|
||||||
#endif
|
|
Loading…
Reference in New Issue