trunk preprocessor: added new statements "write_latex_dynamic_model" and "write_latex_static_model" which list model equations in LaTeX code

git-svn-id: https://www.dynare.org/svn/dynare/trunk@2654 ac1d8469-bf42-47a9-8791-bf33cf982152
time-shift
sebastien 2009-04-30 13:14:33 +00:00
parent e96420b3a7
commit 44c864f9f7
16 changed files with 309 additions and 84 deletions

View File

@ -965,3 +965,25 @@ void
IdentificationStatement::writeOutput(ostream &output, const string &basename) const IdentificationStatement::writeOutput(ostream &output, const string &basename) const
{ {
} }
WriteLatexDynamicModelStatement::WriteLatexDynamicModelStatement(const DynamicModel &dynamic_model_arg) :
dynamic_model(dynamic_model_arg)
{
}
void
WriteLatexDynamicModelStatement::writeOutput(ostream &output, const string &basename) const
{
dynamic_model.writeLatexFile(basename);
}
WriteLatexStaticModelStatement::WriteLatexStaticModelStatement(const StaticModel &static_model_arg) :
static_model(static_model_arg)
{
}
void
WriteLatexStaticModelStatement::writeOutput(ostream &output, const string &basename) const
{
static_model.writeLatexFile(basename);
}

View File

@ -26,6 +26,7 @@
#include "SymbolTable.hh" #include "SymbolTable.hh"
#include "Statement.hh" #include "Statement.hh"
#include "StaticModel.hh" #include "StaticModel.hh"
#include "DynamicModel.hh"
class SteadyStatement : public Statement class SteadyStatement : public Statement
{ {
@ -438,4 +439,22 @@ public:
virtual void writeOutput(ostream &output, const string &basename) const; virtual void writeOutput(ostream &output, const string &basename) const;
}; };
class WriteLatexDynamicModelStatement : public Statement
{
private:
const DynamicModel &dynamic_model;
public:
WriteLatexDynamicModelStatement(const DynamicModel &dynamic_model_arg);
virtual void writeOutput(ostream &output, const string &basename) const;
};
class WriteLatexStaticModelStatement : public Statement
{
private:
const StaticModel &static_model;
public:
WriteLatexStaticModelStatement(const StaticModel &static_model_arg);
virtual void writeOutput(ostream &output, const string &basename) const;
};
#endif #endif

View File

@ -2500,3 +2500,9 @@ DynamicModel::writeParamsDerivativesFile(const string &basename) const
paramsDerivsFile.close(); paramsDerivsFile.close();
} }
void
DynamicModel::writeLatexFile(const string &basename) const
{
writeLatexModelFile(basename + "_dynamic.tex", oLatexDynamicModel);
}

View File

@ -146,6 +146,10 @@ public:
//! Converts to static model (only the equations) //! Converts to static model (only the equations)
/*! It assumes that the static model given in argument has just been allocated */ /*! It assumes that the static model given in argument has just been allocated */
void toStatic(StaticModel &static_model) const; void toStatic(StaticModel &static_model) const;
//! Writes LaTeX file with the equations of the dynamic model
void writeLatexFile(const string &basename) const;
virtual int getDerivID(int symb_id, int lag) const throw (UnknownDerivIDException); virtual int getDerivID(int symb_id, int lag) const throw (UnknownDerivIDException);
virtual int getDynJacobianCol(int deriv_id) const throw (UnknownDerivIDException); virtual int getDynJacobianCol(int deriv_id) const throw (UnknownDerivIDException);
}; };

View File

@ -99,7 +99,7 @@ class ParsingDriver;
%token <string_val> FLOAT_NUMBER %token <string_val> FLOAT_NUMBER
%token FORECAST %token FORECAST
%token GAMMA_PDF GAUSSIAN_ELIMINATION GMRES GRAPH %token GAMMA_PDF GAUSSIAN_ELIMINATION GMRES GRAPH
%token HISTVAL HP_FILTER HP_NGRID %token HISTVAL HOMOTOPY_SETUP HOMOTOPY_MODE HOMOTOPY_STEPS HP_FILTER HP_NGRID
%token IDENTIFICATION INF_CONSTANT INITVAL INITVAL_FILE %token IDENTIFICATION INF_CONSTANT INITVAL INITVAL_FILE
%token <string_val> INT_NUMBER %token <string_val> INT_NUMBER
%token INV_GAMMA_PDF INV_GAMMA1_PDF INV_GAMMA2_PDF IRF %token INV_GAMMA_PDF INV_GAMMA1_PDF INV_GAMMA2_PDF IRF
@ -113,7 +113,7 @@ class ParsingDriver;
%token NAN_CONSTANT NOBS NOCONSTANT NOCORR NODIAGNOSTIC NOFUNCTIONS %token NAN_CONSTANT NOBS NOCONSTANT NOCORR NODIAGNOSTIC NOFUNCTIONS
%token NOGRAPH NOMOMENTS NOPRINT NORMAL_PDF %token NOGRAPH NOMOMENTS NOPRINT NORMAL_PDF
%token OBSERVATION_TRENDS OPTIM OPTIM_WEIGHTS ORDER OSR OSR_PARAMS %token OBSERVATION_TRENDS OPTIM OPTIM_WEIGHTS ORDER OSR OSR_PARAMS
%token PARAMETERS PERIODS PLANNER_OBJECTIVE PREFILTER PRESAMPLE %token PARAMETERS PERIODS PLANNER_OBJECTIVE PLOT_PRIORS PREFILTER PRESAMPLE
%token PRINT PRIOR_TRUNC PRIOR_ANALYSIS POSTERIOR_ANALYSIS %token PRINT PRIOR_TRUNC PRIOR_ANALYSIS POSTERIOR_ANALYSIS
%token <string_val> QUOTED_STRING %token <string_val> QUOTED_STRING
%token QZ_CRITERIUM %token QZ_CRITERIUM
@ -124,9 +124,8 @@ class ParsingDriver;
%token <string_val> TEX_NAME %token <string_val> TEX_NAME
%token UNIFORM_PDF UNIT_ROOT_VARS USE_DLL %token UNIFORM_PDF UNIT_ROOT_VARS USE_DLL
%token VALUES VAR VAREXO VAREXO_DET VAROBS %token VALUES VAR VAREXO VAREXO_DET VAROBS
%token XLS_SHEET XLS_RANGE PLOT_PRIORS %token WRITE_LATEX_DYNAMIC_MODEL WRITE_LATEX_STATIC_MODEL
%token NORMCDF %token XLS_SHEET XLS_RANGE
%token HOMOTOPY_SETUP HOMOTOPY_MODE HOMOTOPY_STEPS
%left COMMA %left COMMA
%left EQUAL_EQUAL EXCLAMATION_EQUAL %left EQUAL_EQUAL EXCLAMATION_EQUAL
%left LESS GREATER LESS_EQUAL GREATER_EQUAL %left LESS GREATER LESS_EQUAL GREATER_EQUAL
@ -134,7 +133,7 @@ class ParsingDriver;
%left TIMES DIVIDE %left TIMES DIVIDE
%left UMINUS UPLUS %left UMINUS UPLUS
%nonassoc POWER %nonassoc POWER
%token EXP LOG LN LOG10 SIN COS TAN ASIN ACOS ATAN SINH COSH TANH ASINH ACOSH ATANH SQRT %token EXP LOG LN LOG10 SIN COS TAN ASIN ACOS ATAN SINH COSH TANH ASINH ACOSH ATANH SQRT NORMCDF
/* GSA analysis */ /* GSA analysis */
%token DYNARE_SENSITIVITY MORRIS STAB REDFORM PPRIOR PRIOR_RANGE PPOST ILPTAU GLUE MORRIS_NLIV %token DYNARE_SENSITIVITY MORRIS STAB REDFORM PPRIOR PRIOR_RANGE PPOST ILPTAU GLUE MORRIS_NLIV
%token MORRIS_NTRA NSAM LOAD_REDFORM LOAD_RMSE LOAD_STAB ALPHA2_STAB KSSTAT LOGTRANS_REDFORM THRESHOLD_REDFORM %token MORRIS_NTRA NSAM LOAD_REDFORM LOAD_RMSE LOAD_STAB ALPHA2_STAB KSSTAT LOGTRANS_REDFORM THRESHOLD_REDFORM
@ -211,6 +210,8 @@ statement : parameters
| load_params_and_steady_state | load_params_and_steady_state
| save_params_and_steady_state | save_params_and_steady_state
| identification | identification
| write_latex_dynamic_model
| write_latex_static_model
; ;
dsample : DSAMPLE INT_NUMBER ';' dsample : DSAMPLE INT_NUMBER ';'
@ -1159,6 +1160,14 @@ ramsey_policy_options : stoch_simul_options
| o_planner_discount | o_planner_discount
; ;
write_latex_dynamic_model : WRITE_LATEX_DYNAMIC_MODEL ';'
{ driver.write_latex_dynamic_model(); }
;
write_latex_static_model : WRITE_LATEX_STATIC_MODEL ';'
{ driver.write_latex_static_model(); }
;
bvar_prior_option : o_bvar_prior_tau bvar_prior_option : o_bvar_prior_tau
| o_bvar_prior_decay | o_bvar_prior_decay
| o_bvar_prior_lambda | o_bvar_prior_lambda

View File

@ -116,6 +116,8 @@ int sigma_e = 0;
<INITIAL>change_type {BEGIN DYNARE_STATEMENT; return token::CHANGE_TYPE;} <INITIAL>change_type {BEGIN DYNARE_STATEMENT; return token::CHANGE_TYPE;}
<INITIAL>load_params_and_steady_state {BEGIN DYNARE_STATEMENT; return token::LOAD_PARAMS_AND_STEADY_STATE;} <INITIAL>load_params_and_steady_state {BEGIN DYNARE_STATEMENT; return token::LOAD_PARAMS_AND_STEADY_STATE;}
<INITIAL>save_params_and_steady_state {BEGIN DYNARE_STATEMENT; return token::SAVE_PARAMS_AND_STEADY_STATE;} <INITIAL>save_params_and_steady_state {BEGIN DYNARE_STATEMENT; return token::SAVE_PARAMS_AND_STEADY_STATE;}
<INITIAL>write_latex_dynamic_model {BEGIN DYNARE_STATEMENT; return token::WRITE_LATEX_DYNAMIC_MODEL;}
<INITIAL>write_latex_static_model {BEGIN DYNARE_STATEMENT; return token::WRITE_LATEX_STATIC_MODEL;}
<INITIAL>steady {BEGIN DYNARE_STATEMENT; return token::STEADY;} <INITIAL>steady {BEGIN DYNARE_STATEMENT; return token::STEADY;}
<INITIAL>check {BEGIN DYNARE_STATEMENT; return token::CHECK;} <INITIAL>check {BEGIN DYNARE_STATEMENT; return token::CHECK;}

View File

@ -263,6 +263,23 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
return; return;
} }
if (IS_LATEX(output_type))
{
output << datatree.symbol_table.getTeXName(symb_id);
if (output_type == oLatexDynamicModel)
{
output << "_{t";
if (lag != 0)
{
if (lag > 0)
output << "+";
output << lag;
}
output << "}";
}
return;
}
int i; int i;
int tsid = datatree.symbol_table.getTypeSpecificID(symb_id); int tsid = datatree.symbol_table.getTypeSpecificID(symb_id);
switch(type) switch(type)
@ -271,7 +288,7 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
if (output_type == oMatlabOutsideModel) if (output_type == oMatlabOutsideModel)
output << "M_.params" << "(" << tsid + 1 << ")"; output << "M_.params" << "(" << tsid + 1 << ")";
else else
output << "params" << LPAR(output_type) << tsid + OFFSET(output_type) << RPAR(output_type); output << "params" << LEFT_ARRAY_SUBSCRIPT(output_type) << tsid + ARRAY_SUBSCRIPT_OFFSET(output_type) << RIGHT_ARRAY_SUBSCRIPT(output_type);
break; break;
case eModelLocalVariable: case eModelLocalVariable:
@ -291,32 +308,34 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
{ {
case oMatlabDynamicModel: case oMatlabDynamicModel:
case oCDynamicModel: case oCDynamicModel:
i = datatree.getDynJacobianCol(deriv_id) + OFFSET(output_type); i = datatree.getDynJacobianCol(deriv_id) + ARRAY_SUBSCRIPT_OFFSET(output_type);
output << "y" << LPAR(output_type) << i << RPAR(output_type); output << "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type);
break; break;
case oMatlabStaticModel: case oMatlabStaticModel:
case oMatlabStaticModelSparse: case oMatlabStaticModelSparse:
case oCStaticModel: case oCStaticModel:
i = tsid + OFFSET(output_type); i = tsid + ARRAY_SUBSCRIPT_OFFSET(output_type);
output << "y" << LPAR(output_type) << i << RPAR(output_type); output << "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type);
break; break;
case oMatlabDynamicModelSparse: case oMatlabDynamicModelSparse:
i = tsid + OFFSET(output_type); i = tsid + ARRAY_SUBSCRIPT_OFFSET(output_type);
if (lag > 0) if (lag > 0)
output << "y" << LPAR(output_type) << "it_+" << lag << ", " << i << RPAR(output_type); output << "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_+" << lag << ", " << i << RIGHT_ARRAY_SUBSCRIPT(output_type);
else if (lag < 0) else if (lag < 0)
output << "y" << LPAR(output_type) << "it_" << lag << ", " << i << RPAR(output_type); output << "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_" << lag << ", " << i << RIGHT_ARRAY_SUBSCRIPT(output_type);
else else
output << "y" << LPAR(output_type) << "it_, " << i << RPAR(output_type); output << "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_, " << i << RIGHT_ARRAY_SUBSCRIPT(output_type);
break; break;
case oMatlabOutsideModel: case oMatlabOutsideModel:
output << "oo_.steady_state" << "(" << tsid + 1 << ")"; output << "oo_.steady_state" << "(" << tsid + 1 << ")";
break; break;
default:
assert(false);
} }
break; break;
case eExogenous: case eExogenous:
i = tsid + OFFSET(output_type); i = tsid + ARRAY_SUBSCRIPT_OFFSET(output_type);
switch(output_type) switch(output_type)
{ {
case oMatlabDynamicModel: case oMatlabDynamicModel:
@ -339,17 +358,19 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
case oMatlabStaticModel: case oMatlabStaticModel:
case oMatlabStaticModelSparse: case oMatlabStaticModelSparse:
case oCStaticModel: case oCStaticModel:
output << "x" << LPAR(output_type) << i << RPAR(output_type); output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type);
break; break;
case oMatlabOutsideModel: case oMatlabOutsideModel:
assert(lag == 0); assert(lag == 0);
output << "oo_.exo_steady_state" << "(" << i << ")"; output << "oo_.exo_steady_state" << "(" << i << ")";
break; break;
default:
assert(false);
} }
break; break;
case eExogenousDet: case eExogenousDet:
i = tsid + datatree.symbol_table.exo_nbr() + OFFSET(output_type); i = tsid + datatree.symbol_table.exo_nbr() + ARRAY_SUBSCRIPT_OFFSET(output_type);
switch(output_type) switch(output_type)
{ {
case oMatlabDynamicModel: case oMatlabDynamicModel:
@ -372,12 +393,14 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
case oMatlabStaticModel: case oMatlabStaticModel:
case oMatlabStaticModelSparse: case oMatlabStaticModelSparse:
case oCStaticModel: case oCStaticModel:
output << "x" << LPAR(output_type) << i << RPAR(output_type); output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type);
break; break;
case oMatlabOutsideModel: case oMatlabOutsideModel:
assert(lag == 0); assert(lag == 0);
output << "oo_.exo_det_steady_state" << "(" << tsid + 1 << ")"; output << "oo_.exo_det_steady_state" << "(" << tsid + 1 << ")";
break; break;
default:
assert(false);
} }
break; break;
@ -729,7 +752,7 @@ UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
// Always put parenthesis around uminus nodes // Always put parenthesis around uminus nodes
if (op_code == oUminus) if (op_code == oUminus)
output << "("; output << LEFT_PAR(output_type);
switch(op_code) switch(op_code)
{ {
@ -743,7 +766,10 @@ UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
output << "log"; output << "log";
break; break;
case oLog10: case oLog10:
output << "log10"; if (IS_LATEX(output_type))
output << "log_{10}";
else
output << "log10";
break; break;
case oCos: case oCos:
output << "cos"; output << "cos";
@ -796,7 +822,7 @@ UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|| (op_code == oUminus || (op_code == oUminus
&& arg->precedence(output_type, temporary_terms) < precedence(output_type, temporary_terms))) && arg->precedence(output_type, temporary_terms) < precedence(output_type, temporary_terms)))
{ {
output << "("; output << LEFT_PAR(output_type);
close_parenthesis = true; close_parenthesis = true;
} }
@ -804,11 +830,11 @@ UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
arg->writeOutput(output, output_type, temporary_terms); arg->writeOutput(output, output_type, temporary_terms);
if (close_parenthesis) if (close_parenthesis)
output << ")"; output << RIGHT_PAR(output_type);
// Close parenthesis for uminus // Close parenthesis for uminus
if (op_code == oUminus) if (op_code == oUminus)
output << ")"; output << RIGHT_PAR(output_type);
} }
double double
@ -1055,7 +1081,7 @@ BinaryOpNode::precedence(ExprNodeOutputType output_type, const temporary_terms_t
case oDivide: case oDivide:
return 4; return 4;
case oPower: case oPower:
if (!OFFSET(output_type)) if (IS_C(output_type))
// In C, power operator is of the form pow(a, b) // In C, power operator is of the form pow(a, b)
return 100; return 100;
else else
@ -1289,7 +1315,7 @@ BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
} }
// Treat special case of power operator in C, and case of max and min operators // Treat special case of power operator in C, and case of max and min operators
if ((op_code == oPower && !OFFSET(output_type)) || op_code == oMax || op_code == oMin ) if ((op_code == oPower && IS_C(output_type)) || op_code == oMax || op_code == oMin )
{ {
switch (op_code) switch (op_code)
{ {
@ -1316,20 +1342,29 @@ BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
bool close_parenthesis = false; bool close_parenthesis = false;
// If left argument has a lower precedence, or if current and left argument are both power operators, add parenthesis around left argument if (IS_LATEX(output_type) && op_code == oDivide)
BinaryOpNode *barg1 = dynamic_cast<BinaryOpNode *>(arg1); output << "\\frac{";
if (arg1->precedence(output_type, temporary_terms) < prec else
|| (op_code == oPower && barg1 != NULL && barg1->op_code == oPower))
{ {
output << "("; // If left argument has a lower precedence, or if current and left argument are both power operators, add parenthesis around left argument
close_parenthesis = true; BinaryOpNode *barg1 = dynamic_cast<BinaryOpNode *>(arg1);
if (arg1->precedence(output_type, temporary_terms) < prec
|| (op_code == oPower && barg1 != NULL && barg1->op_code == oPower))
{
output << LEFT_PAR(output_type);
close_parenthesis = true;
}
} }
// Write left argument // Write left argument
arg1->writeOutput(output, output_type, temporary_terms); arg1->writeOutput(output, output_type, temporary_terms);
if (close_parenthesis) if (close_parenthesis)
output << ")"; output << RIGHT_PAR(output_type);
if (IS_LATEX(output_type) && op_code == oDivide)
output << "}";
// Write current operator symbol // Write current operator symbol
switch(op_code) switch(op_code)
@ -1341,10 +1376,14 @@ BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
output << "-"; output << "-";
break; break;
case oTimes: case oTimes:
output << "*"; if (IS_LATEX(output_type))
output << "\\cdot ";
else
output << "*";
break; break;
case oDivide: case oDivide:
output << "/"; if (!IS_LATEX(output_type))
output << "/";
break; break;
case oPower: case oPower:
output << "^"; output << "^";
@ -1356,19 +1395,30 @@ BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
output << ">"; output << ">";
break; break;
case oLessEqual: case oLessEqual:
output << "<="; if (IS_LATEX(output_type))
output << "\\leq ";
else
output << "<=";
break; break;
case oGreaterEqual: case oGreaterEqual:
output << ">="; if (IS_LATEX(output_type))
output << "\\geq ";
else
output << ">=";
break; break;
case oEqualEqual: case oEqualEqual:
output << "=="; output << "==";
break; break;
case oDifferent: case oDifferent:
if (OFFSET(output_type)) if (IS_MATLAB(output_type))
output << "~="; output << "~=";
else else
output << "!="; {
if (IS_C(output_type))
output << "!=";
else
output << "\\neq ";
}
break; break;
case oEqual: case oEqual:
output << "="; output << "=";
@ -1379,27 +1429,35 @@ BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
close_parenthesis = false; close_parenthesis = false;
/* Add parenthesis around right argument if: if (IS_LATEX(output_type) && (op_code == oPower || op_code == oDivide))
- its precedence is lower than those of the current node output << "{";
- it is a power operator and current operator is also a power operator else
- it is a minus operator with same precedence than current operator
- it is a divide operator with same precedence than current operator */
BinaryOpNode *barg2 = dynamic_cast<BinaryOpNode *>(arg2);
int arg2_prec = arg2->precedence(output_type, temporary_terms);
if (arg2_prec < prec
|| (op_code == oPower && barg2 != NULL && barg2->op_code == oPower)
|| (op_code == oMinus && arg2_prec == prec)
|| (op_code == oDivide && arg2_prec == prec))
{ {
output << "("; /* Add parenthesis around right argument if:
close_parenthesis = true; - its precedence is lower than those of the current node
- it is a power operator and current operator is also a power operator
- it is a minus operator with same precedence than current operator
- it is a divide operator with same precedence than current operator */
BinaryOpNode *barg2 = dynamic_cast<BinaryOpNode *>(arg2);
int arg2_prec = arg2->precedence(output_type, temporary_terms);
if (arg2_prec < prec
|| (op_code == oPower && barg2 != NULL && barg2->op_code == oPower && !IS_LATEX(output_type))
|| (op_code == oMinus && arg2_prec == prec)
|| (op_code == oDivide && arg2_prec == prec && !IS_LATEX(output_type)))
{
output << LEFT_PAR(output_type);
close_parenthesis = true;
}
} }
// Write right argument // Write right argument
arg2->writeOutput(output, output_type, temporary_terms); arg2->writeOutput(output, output_type, temporary_terms);
if (IS_LATEX(output_type) && (op_code == oPower || op_code == oDivide))
output << "}";
if (close_parenthesis) if (close_parenthesis)
output << ")"; output << RIGHT_PAR(output_type);
} }
void void
@ -1698,7 +1756,7 @@ TrinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_type &temporary_terms) const const temporary_terms_type &temporary_terms) const
{ {
// TrinaryOpNode not implemented for C output // TrinaryOpNode not implemented for C output
assert(OFFSET(output_type)); assert(!IS_C(output_type));
// If current node is a temporary term // If current node is a temporary term
temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<TrinaryOpNode *>(this)); temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<TrinaryOpNode *>(this));

View File

@ -46,6 +46,10 @@ typedef set<NodeID, ExprNodeLess> temporary_terms_type;
typedef map<int,int> map_idx_type; typedef map<int,int> map_idx_type;
typedef set<int> temporary_terms_inuse_type; typedef set<int> temporary_terms_inuse_type;
//! Type for evaluation contexts
/*! The key is a symbol id. Lags are assumed to be null */
typedef map<int, double> eval_context_type;
//! Possible types of output when writing ExprNode(s) //! Possible types of output when writing ExprNode(s)
enum ExprNodeOutputType enum ExprNodeOutputType
{ {
@ -55,26 +59,34 @@ enum ExprNodeOutputType
oMatlabDynamicModelSparse,//!< Matlab code, dynamic block decomposed mode declaration oMatlabDynamicModelSparse,//!< Matlab code, dynamic block decomposed mode declaration
oCStaticModel, //!< C code, static model declarations oCStaticModel, //!< C code, static model declarations
oCDynamicModel, //!< C code, dynamic model declarations oCDynamicModel, //!< C code, dynamic model declarations
oMatlabOutsideModel //!< Matlab code, outside model block (for example in initval) oMatlabOutsideModel, //!< Matlab code, outside model block (for example in initval)
oLatexStaticModel, //!< LaTeX code, static model declarations
oLatexDynamicModel //!< LaTeX code, dynamic model declarations
}; };
//! Type for evaluation contexts #define IS_MATLAB(output_type) ((output_type) == oMatlabStaticModel \
/*! The key is a symbol id. Lags are assumed to be null */ || (output_type) == oMatlabDynamicModel \
typedef map<int, double> eval_context_type; || (output_type) == oMatlabOutsideModel \
|| (output_type) == oMatlabStaticModelSparse \
|| (output_type) == oMatlabDynamicModelSparse)
/* Equal to 1 for Matlab langage, or to 0 for C language #define IS_C(output_type) ((output_type) == oCStaticModel \
|| (output_type) == oCDynamicModel)
#define IS_LATEX(output_type) ((output_type) == oLatexStaticModel \
|| (output_type) == oLatexDynamicModel)
/* Equal to 1 for Matlab langage, or to 0 for C language. Not defined for LaTeX.
In Matlab, array indexes begin at 1, while they begin at 0 in C */ In Matlab, array indexes begin at 1, while they begin at 0 in C */
#define OFFSET(output_type) ((output_type == oMatlabStaticModel) \ #define ARRAY_SUBSCRIPT_OFFSET(output_type) ((int) IS_MATLAB(output_type))
|| (output_type == oMatlabDynamicModel) \
|| (output_type == oMatlabOutsideModel) \
|| (output_type == oMatlabStaticModelSparse) \
|| (output_type == oMatlabDynamicModelSparse))
// Left parenthesis: '(' for Matlab, '[' for C // Left and right array subscript delimiters: '(' and ')' for Matlab, '[' and ']' for C
#define LPAR(output_type) (OFFSET(output_type) ? '(' : '[') #define LEFT_ARRAY_SUBSCRIPT(output_type) (IS_MATLAB(output_type) ? '(' : '[')
#define RIGHT_ARRAY_SUBSCRIPT(output_type) (IS_MATLAB(output_type) ? ')' : ']')
// Right parenthesis: ')' for Matlab, ']' for C // Left and right parentheses
#define RPAR(output_type) (OFFSET(output_type) ? ')' : ']') #define LEFT_PAR(output_type) (IS_LATEX(output_type) ? "\\left(" : "(")
#define RIGHT_PAR(output_type) (IS_LATEX(output_type) ? "\\right)" : ")")
// Computing cost above which a node can be declared a temporary term // Computing cost above which a node can be declared a temporary term
#define MIN_COST_MATLAB (40*90) #define MIN_COST_MATLAB (40*90)

View File

@ -17,6 +17,7 @@
* along with Dynare. If not, see <http://www.gnu.org/licenses/>. * along with Dynare. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <cstdlib>
#include <cassert> #include <cassert>
#include <iostream> #include <iostream>
@ -149,13 +150,13 @@ ModelTree::writeTemporaryTerms(const temporary_terms_type &tt, ostream &output,
// Local var used to keep track of temp nodes already written // Local var used to keep track of temp nodes already written
temporary_terms_type tt2; temporary_terms_type tt2;
if (tt.size() > 0 && (!OFFSET(output_type))) if (tt.size() > 0 && (IS_C(output_type)))
output << "double" << endl; output << "double" << endl;
for (temporary_terms_type::const_iterator it = tt.begin(); for (temporary_terms_type::const_iterator it = tt.begin();
it != tt.end(); it++) it != tt.end(); it++)
{ {
if (!OFFSET(output_type) && it != tt.begin()) if (IS_C(output_type) && it != tt.begin())
output << "," << endl; output << "," << endl;
(*it)->writeOutput(output, output_type, tt); (*it)->writeOutput(output, output_type, tt);
@ -166,10 +167,10 @@ ModelTree::writeTemporaryTerms(const temporary_terms_type &tt, ostream &output,
// Insert current node into tt2 // Insert current node into tt2
tt2.insert(*it); tt2.insert(*it);
if (OFFSET(output_type)) if (IS_MATLAB(output_type))
output << ";" << endl; output << ";" << endl;
} }
if (!OFFSET(output_type)) if (IS_C(output_type))
output << ";" << endl; output << ";" << endl;
} }
@ -182,7 +183,7 @@ ModelTree::writeModelLocalVariables(ostream &output, ExprNodeOutputType output_t
int id = it->first; int id = it->first;
NodeID value = it->second; NodeID value = it->second;
if (!OFFSET(output_type)) if (IS_C(output_type))
output << "double "; output << "double ";
output << symbol_table.getName(id) << " = "; output << symbol_table.getName(id) << " = ";
@ -209,10 +210,54 @@ ModelTree::writeModelEquations(ostream &output, ExprNodeOutputType output_type)
rhs->writeOutput(output, output_type, temporary_terms); rhs->writeOutput(output, output_type, temporary_terms);
output << ";" << endl; output << ";" << endl;
output << "residual" << LPAR(output_type) << eq + OFFSET(output_type) << RPAR(output_type) << "= lhs-rhs;" << endl; output << "residual" << LEFT_ARRAY_SUBSCRIPT(output_type) << eq + ARRAY_SUBSCRIPT_OFFSET(output_type) << RIGHT_ARRAY_SUBSCRIPT(output_type) << "= lhs-rhs;" << endl;
} }
} }
void
ModelTree::writeLatexModelFile(const string &filename, ExprNodeOutputType output_type) const
{
ofstream output;
output.open(filename.c_str(), ios::out | ios::binary);
if (!output.is_open())
{
cerr << "ERROR: Can't open file " << filename << " for writing" << endl;
exit(EXIT_FAILURE);
}
output << "\\documentclass[10pt,a4paper]{article}" << endl
<< "\\usepackage[landscape]{geometry}" << endl
<< "\\usepackage{fullpage}" << endl
<< "\\begin{document}" << endl
<< "\\footnotesize" << endl;
// Write model local variables
for (map<int, NodeID>::const_iterator it = local_variables_table.begin();
it != local_variables_table.end(); it++)
{
int id = it->first;
NodeID value = it->second;
output << "\\begin{equation*}" << endl
<< symbol_table.getName(id) << " = ";
// Use an empty set for the temporary terms
value->writeOutput(output, output_type, temporary_terms_type());
output << endl << "\\end{equation*}" << endl;
}
for (int eq = 0; eq < (int) equations.size(); eq++)
{
output << "\\begin{equation}" << endl
<< "% Equation " << eq+1 << endl;
equations[eq]->writeOutput(output, output_type, temporary_terms_type());
output << endl << "\\end{equation}" << endl;
}
output << "\\end{document}" << endl;
output.close();
}
void void
ModelTree::addEquation(NodeID eq) ModelTree::addEquation(NodeID eq)
{ {
@ -225,10 +270,10 @@ ModelTree::addEquation(NodeID eq)
void void
ModelTree::matrixHelper(ostream &output, int eq_nb, int col_nb, ExprNodeOutputType output_type) const ModelTree::matrixHelper(ostream &output, int eq_nb, int col_nb, ExprNodeOutputType output_type) const
{ {
output << LPAR(output_type); output << LEFT_ARRAY_SUBSCRIPT(output_type);
if (OFFSET(output_type)) if (IS_MATLAB(output_type))
output << eq_nb + 1 << ", " << col_nb + 1; output << eq_nb + 1 << ", " << col_nb + 1;
else else
output << eq_nb + col_nb * equations.size(); output << eq_nb + col_nb * equations.size();
output << RPAR(output_type); output << RIGHT_ARRAY_SUBSCRIPT(output_type);
} }

View File

@ -99,6 +99,9 @@ protected:
//! Writes either (i+1,j+1) or [i+j*n_i] whether we are in Matlab or C mode //! Writes either (i+1,j+1) or [i+j*n_i] whether we are in Matlab or C mode
void matrixHelper(ostream &output, int eq_nb, int col_nb, ExprNodeOutputType output_type) const; void matrixHelper(ostream &output, int eq_nb, int col_nb, ExprNodeOutputType output_type) const;
//! Writes LaTeX model file
void writeLatexModelFile(const string &filename, ExprNodeOutputType output_type) const;
public: public:
ModelTree(SymbolTable &symbol_table_arg, NumericalConstants &num_constants); ModelTree(SymbolTable &symbol_table_arg, NumericalConstants &num_constants);
//! Mode in which the ModelTree is supposed to work (Matlab, DLL or SparseDLL) //! Mode in which the ModelTree is supposed to work (Matlab, DLL or SparseDLL)

View File

@ -101,7 +101,10 @@ ParsingDriver::declare_symbol(string *name, SymbolType type, string *tex_name)
{ {
try try
{ {
mod_file->symbol_table.addSymbol(*name, type, *tex_name); if (tex_name == NULL)
mod_file->symbol_table.addSymbol(*name, type);
else
mod_file->symbol_table.addSymbol(*name, type, *tex_name);
} }
catch(SymbolTable::AlreadyDeclaredException &e) catch(SymbolTable::AlreadyDeclaredException &e)
{ {
@ -112,7 +115,8 @@ ParsingDriver::declare_symbol(string *name, SymbolType type, string *tex_name)
} }
delete name; delete name;
delete tex_name; if (tex_name != NULL)
delete tex_name;
} }
void void
@ -1042,6 +1046,18 @@ ParsingDriver::ramsey_policy()
options_list.clear(); options_list.clear();
} }
void
ParsingDriver::write_latex_dynamic_model()
{
mod_file->addStatement(new WriteLatexDynamicModelStatement(mod_file->dynamic_model));
}
void
ParsingDriver::write_latex_static_model()
{
mod_file->addStatement(new WriteLatexStaticModelStatement(mod_file->static_model));
}
void void
ParsingDriver::bvar_density(string *maxnlags) ParsingDriver::bvar_density(string *maxnlags)
{ {

View File

@ -178,13 +178,13 @@ public:
//! Sets the FILENAME for the initial value in initval //! Sets the FILENAME for the initial value in initval
void initval_file(string *filename); void initval_file(string *filename);
//! Declares an endogenous variable //! Declares an endogenous variable
void declare_endogenous(string *name, string *tex_name = new string); void declare_endogenous(string *name, string *tex_name = NULL);
//! Declares an exogenous variable //! Declares an exogenous variable
void declare_exogenous(string *name, string *tex_name = new string); void declare_exogenous(string *name, string *tex_name = NULL);
//! Declares an exogenous deterministic variable //! Declares an exogenous deterministic variable
void declare_exogenous_det(string *name, string *tex_name = new string); void declare_exogenous_det(string *name, string *tex_name = NULL);
//! Declares a parameter //! Declares a parameter
void declare_parameter(string *name, string *tex_name = new string); void declare_parameter(string *name, string *tex_name = NULL);
//! Declares and initializes a local parameter //! Declares and initializes a local parameter
void declare_and_init_model_local_variable(string *name, NodeID rhs); void declare_and_init_model_local_variable(string *name, NodeID rhs);
//! Changes type of a symbol //! Changes type of a symbol
@ -338,6 +338,10 @@ public:
void end_planner_objective(NodeID expr); void end_planner_objective(NodeID expr);
//! ramsey policy statement //! ramsey policy statement
void ramsey_policy(); void ramsey_policy();
//! Adds a write_latex_dynamic_model statement
void write_latex_dynamic_model();
//! Adds a write_latex_static_model statement
void write_latex_static_model();
//! BVAR marginal density //! BVAR marginal density
void bvar_density(string *maxnlags); void bvar_density(string *maxnlags);
//! BVAR forecast //! BVAR forecast

View File

@ -415,3 +415,9 @@ StaticModel::computeNormalizedEquations(multimap<int, int> &endo_to_eqs) const
cout << "Endogenous " << symbol_table.getName(symb_id) << " normalized in equation " << (i+1) << endl; cout << "Endogenous " << symbol_table.getName(symb_id) << " normalized in equation " << (i+1) << endl;
} }
} }
void
StaticModel::writeLatexFile(const string &basename) const
{
writeLatexModelFile(basename + "_static.tex", oLatexStaticModel);
}

View File

@ -55,6 +55,9 @@ public:
//! Writes static model file //! Writes static model file
void writeStaticFile(const string &basename) const; void writeStaticFile(const string &basename) const;
//! Writes LaTeX file with the equations of the static model
void writeLatexFile(const string &basename) const;
virtual int getDerivID(int symb_id, int lag) const throw (UnknownDerivIDException); virtual int getDerivID(int symb_id, int lag) const throw (UnknownDerivIDException);
}; };

View File

@ -48,6 +48,20 @@ SymbolTable::addSymbol(const string &name, SymbolType type, const string &tex_na
tex_name_table.push_back(tex_name); tex_name_table.push_back(tex_name);
} }
void
SymbolTable::addSymbol(const string &name, SymbolType type) throw (AlreadyDeclaredException, FrozenException)
{
// Construct "tex_name" by prepending an antislash to all underscores in "name"
string tex_name = name;
size_t pos = 0;
while((pos = tex_name.find('_', pos)) != string::npos)
{
tex_name.insert(pos, "\\");
pos += 2;
}
addSymbol(name, type, tex_name);
}
void void
SymbolTable::freeze() throw (FrozenException) SymbolTable::freeze() throw (FrozenException)
{ {

View File

@ -115,7 +115,9 @@ public:
{ {
}; };
//! Add a symbol //! Add a symbol
void addSymbol(const string &name, SymbolType type, const string &tex_name = "") throw (AlreadyDeclaredException, FrozenException); void addSymbol(const string &name, SymbolType type, const string &tex_name) throw (AlreadyDeclaredException, FrozenException);
//! Add a symbol without its TeX name (will be equal to its name)
void addSymbol(const string &name, SymbolType type) throw (AlreadyDeclaredException, FrozenException);
//! Tests if symbol already exists //! Tests if symbol already exists
inline bool exists(const string &name) const; inline bool exists(const string &name) const;
//! Get symbol name (by ID) //! Get symbol name (by ID)