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-bf33cf982152time-shift
parent
e96420b3a7
commit
44c864f9f7
|
@ -965,3 +965,25 @@ void
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "SymbolTable.hh"
|
||||
#include "Statement.hh"
|
||||
#include "StaticModel.hh"
|
||||
#include "DynamicModel.hh"
|
||||
|
||||
class SteadyStatement : public Statement
|
||||
{
|
||||
|
@ -438,4 +439,22 @@ public:
|
|||
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
|
||||
|
|
|
@ -2500,3 +2500,9 @@ DynamicModel::writeParamsDerivativesFile(const string &basename) const
|
|||
|
||||
paramsDerivsFile.close();
|
||||
}
|
||||
|
||||
void
|
||||
DynamicModel::writeLatexFile(const string &basename) const
|
||||
{
|
||||
writeLatexModelFile(basename + "_dynamic.tex", oLatexDynamicModel);
|
||||
}
|
||||
|
|
|
@ -146,6 +146,10 @@ public:
|
|||
//! Converts to static model (only the equations)
|
||||
/*! It assumes that the static model given in argument has just been allocated */
|
||||
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 getDynJacobianCol(int deriv_id) const throw (UnknownDerivIDException);
|
||||
};
|
||||
|
|
|
@ -99,7 +99,7 @@ class ParsingDriver;
|
|||
%token <string_val> FLOAT_NUMBER
|
||||
%token FORECAST
|
||||
%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 <string_val> INT_NUMBER
|
||||
%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 NOGRAPH NOMOMENTS NOPRINT NORMAL_PDF
|
||||
%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 <string_val> QUOTED_STRING
|
||||
%token QZ_CRITERIUM
|
||||
|
@ -124,9 +124,8 @@ class ParsingDriver;
|
|||
%token <string_val> TEX_NAME
|
||||
%token UNIFORM_PDF UNIT_ROOT_VARS USE_DLL
|
||||
%token VALUES VAR VAREXO VAREXO_DET VAROBS
|
||||
%token XLS_SHEET XLS_RANGE PLOT_PRIORS
|
||||
%token NORMCDF
|
||||
%token HOMOTOPY_SETUP HOMOTOPY_MODE HOMOTOPY_STEPS
|
||||
%token WRITE_LATEX_DYNAMIC_MODEL WRITE_LATEX_STATIC_MODEL
|
||||
%token XLS_SHEET XLS_RANGE
|
||||
%left COMMA
|
||||
%left EQUAL_EQUAL EXCLAMATION_EQUAL
|
||||
%left LESS GREATER LESS_EQUAL GREATER_EQUAL
|
||||
|
@ -134,7 +133,7 @@ class ParsingDriver;
|
|||
%left TIMES DIVIDE
|
||||
%left UMINUS UPLUS
|
||||
%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 */
|
||||
%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
|
||||
|
@ -211,6 +210,8 @@ statement : parameters
|
|||
| load_params_and_steady_state
|
||||
| save_params_and_steady_state
|
||||
| identification
|
||||
| write_latex_dynamic_model
|
||||
| write_latex_static_model
|
||||
;
|
||||
|
||||
dsample : DSAMPLE INT_NUMBER ';'
|
||||
|
@ -1159,6 +1160,14 @@ ramsey_policy_options : stoch_simul_options
|
|||
| 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
|
||||
| o_bvar_prior_decay
|
||||
| o_bvar_prior_lambda
|
||||
|
|
|
@ -116,6 +116,8 @@ int sigma_e = 0;
|
|||
<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>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>check {BEGIN DYNARE_STATEMENT; return token::CHECK;}
|
||||
|
|
|
@ -263,6 +263,23 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
|||
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 tsid = datatree.symbol_table.getTypeSpecificID(symb_id);
|
||||
switch(type)
|
||||
|
@ -271,7 +288,7 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
|||
if (output_type == oMatlabOutsideModel)
|
||||
output << "M_.params" << "(" << tsid + 1 << ")";
|
||||
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;
|
||||
|
||||
case eModelLocalVariable:
|
||||
|
@ -291,32 +308,34 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
|||
{
|
||||
case oMatlabDynamicModel:
|
||||
case oCDynamicModel:
|
||||
i = datatree.getDynJacobianCol(deriv_id) + OFFSET(output_type);
|
||||
output << "y" << LPAR(output_type) << i << RPAR(output_type);
|
||||
i = datatree.getDynJacobianCol(deriv_id) + ARRAY_SUBSCRIPT_OFFSET(output_type);
|
||||
output << "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type);
|
||||
break;
|
||||
case oMatlabStaticModel:
|
||||
case oMatlabStaticModelSparse:
|
||||
case oCStaticModel:
|
||||
i = tsid + OFFSET(output_type);
|
||||
output << "y" << LPAR(output_type) << i << RPAR(output_type);
|
||||
i = tsid + ARRAY_SUBSCRIPT_OFFSET(output_type);
|
||||
output << "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type);
|
||||
break;
|
||||
case oMatlabDynamicModelSparse:
|
||||
i = tsid + OFFSET(output_type);
|
||||
i = tsid + ARRAY_SUBSCRIPT_OFFSET(output_type);
|
||||
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)
|
||||
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
|
||||
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;
|
||||
case oMatlabOutsideModel:
|
||||
output << "oo_.steady_state" << "(" << tsid + 1 << ")";
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
break;
|
||||
|
||||
case eExogenous:
|
||||
i = tsid + OFFSET(output_type);
|
||||
i = tsid + ARRAY_SUBSCRIPT_OFFSET(output_type);
|
||||
switch(output_type)
|
||||
{
|
||||
case oMatlabDynamicModel:
|
||||
|
@ -339,17 +358,19 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
|||
case oMatlabStaticModel:
|
||||
case oMatlabStaticModelSparse:
|
||||
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;
|
||||
case oMatlabOutsideModel:
|
||||
assert(lag == 0);
|
||||
output << "oo_.exo_steady_state" << "(" << i << ")";
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
break;
|
||||
|
||||
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)
|
||||
{
|
||||
case oMatlabDynamicModel:
|
||||
|
@ -372,12 +393,14 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
|||
case oMatlabStaticModel:
|
||||
case oMatlabStaticModelSparse:
|
||||
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;
|
||||
case oMatlabOutsideModel:
|
||||
assert(lag == 0);
|
||||
output << "oo_.exo_det_steady_state" << "(" << tsid + 1 << ")";
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -729,7 +752,7 @@ UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
|||
|
||||
// Always put parenthesis around uminus nodes
|
||||
if (op_code == oUminus)
|
||||
output << "(";
|
||||
output << LEFT_PAR(output_type);
|
||||
|
||||
switch(op_code)
|
||||
{
|
||||
|
@ -743,7 +766,10 @@ UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
|||
output << "log";
|
||||
break;
|
||||
case oLog10:
|
||||
output << "log10";
|
||||
if (IS_LATEX(output_type))
|
||||
output << "log_{10}";
|
||||
else
|
||||
output << "log10";
|
||||
break;
|
||||
case oCos:
|
||||
output << "cos";
|
||||
|
@ -796,7 +822,7 @@ UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
|||
|| (op_code == oUminus
|
||||
&& arg->precedence(output_type, temporary_terms) < precedence(output_type, temporary_terms)))
|
||||
{
|
||||
output << "(";
|
||||
output << LEFT_PAR(output_type);
|
||||
close_parenthesis = true;
|
||||
}
|
||||
|
||||
|
@ -804,11 +830,11 @@ UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
|||
arg->writeOutput(output, output_type, temporary_terms);
|
||||
|
||||
if (close_parenthesis)
|
||||
output << ")";
|
||||
output << RIGHT_PAR(output_type);
|
||||
|
||||
// Close parenthesis for uminus
|
||||
if (op_code == oUminus)
|
||||
output << ")";
|
||||
output << RIGHT_PAR(output_type);
|
||||
}
|
||||
|
||||
double
|
||||
|
@ -1055,7 +1081,7 @@ BinaryOpNode::precedence(ExprNodeOutputType output_type, const temporary_terms_t
|
|||
case oDivide:
|
||||
return 4;
|
||||
case oPower:
|
||||
if (!OFFSET(output_type))
|
||||
if (IS_C(output_type))
|
||||
// In C, power operator is of the form pow(a, b)
|
||||
return 100;
|
||||
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
|
||||
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)
|
||||
{
|
||||
|
@ -1316,20 +1342,29 @@ BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
|||
|
||||
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
|
||||
BinaryOpNode *barg1 = dynamic_cast<BinaryOpNode *>(arg1);
|
||||
if (arg1->precedence(output_type, temporary_terms) < prec
|
||||
|| (op_code == oPower && barg1 != NULL && barg1->op_code == oPower))
|
||||
if (IS_LATEX(output_type) && op_code == oDivide)
|
||||
output << "\\frac{";
|
||||
else
|
||||
{
|
||||
output << "(";
|
||||
close_parenthesis = true;
|
||||
// If left argument has a lower precedence, or if current and left argument are both power operators, add parenthesis around left argument
|
||||
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
|
||||
arg1->writeOutput(output, output_type, temporary_terms);
|
||||
|
||||
if (close_parenthesis)
|
||||
output << ")";
|
||||
output << RIGHT_PAR(output_type);
|
||||
|
||||
if (IS_LATEX(output_type) && op_code == oDivide)
|
||||
output << "}";
|
||||
|
||||
|
||||
// Write current operator symbol
|
||||
switch(op_code)
|
||||
|
@ -1341,10 +1376,14 @@ BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
|||
output << "-";
|
||||
break;
|
||||
case oTimes:
|
||||
output << "*";
|
||||
if (IS_LATEX(output_type))
|
||||
output << "\\cdot ";
|
||||
else
|
||||
output << "*";
|
||||
break;
|
||||
case oDivide:
|
||||
output << "/";
|
||||
if (!IS_LATEX(output_type))
|
||||
output << "/";
|
||||
break;
|
||||
case oPower:
|
||||
output << "^";
|
||||
|
@ -1356,19 +1395,30 @@ BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
|||
output << ">";
|
||||
break;
|
||||
case oLessEqual:
|
||||
output << "<=";
|
||||
if (IS_LATEX(output_type))
|
||||
output << "\\leq ";
|
||||
else
|
||||
output << "<=";
|
||||
break;
|
||||
case oGreaterEqual:
|
||||
output << ">=";
|
||||
if (IS_LATEX(output_type))
|
||||
output << "\\geq ";
|
||||
else
|
||||
output << ">=";
|
||||
break;
|
||||
case oEqualEqual:
|
||||
output << "==";
|
||||
break;
|
||||
case oDifferent:
|
||||
if (OFFSET(output_type))
|
||||
if (IS_MATLAB(output_type))
|
||||
output << "~=";
|
||||
else
|
||||
output << "!=";
|
||||
{
|
||||
if (IS_C(output_type))
|
||||
output << "!=";
|
||||
else
|
||||
output << "\\neq ";
|
||||
}
|
||||
break;
|
||||
case oEqual:
|
||||
output << "=";
|
||||
|
@ -1379,27 +1429,35 @@ BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
|||
|
||||
close_parenthesis = false;
|
||||
|
||||
/* Add parenthesis around right argument if:
|
||||
- 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)
|
||||
|| (op_code == oMinus && arg2_prec == prec)
|
||||
|| (op_code == oDivide && arg2_prec == prec))
|
||||
if (IS_LATEX(output_type) && (op_code == oPower || op_code == oDivide))
|
||||
output << "{";
|
||||
else
|
||||
{
|
||||
output << "(";
|
||||
close_parenthesis = true;
|
||||
/* Add parenthesis around right argument if:
|
||||
- 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
|
||||
arg2->writeOutput(output, output_type, temporary_terms);
|
||||
|
||||
if (IS_LATEX(output_type) && (op_code == oPower || op_code == oDivide))
|
||||
output << "}";
|
||||
|
||||
if (close_parenthesis)
|
||||
output << ")";
|
||||
output << RIGHT_PAR(output_type);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1698,7 +1756,7 @@ TrinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
|||
const temporary_terms_type &temporary_terms) const
|
||||
{
|
||||
// TrinaryOpNode not implemented for C output
|
||||
assert(OFFSET(output_type));
|
||||
assert(!IS_C(output_type));
|
||||
|
||||
// If current node is a temporary term
|
||||
temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<TrinaryOpNode *>(this));
|
||||
|
|
|
@ -46,6 +46,10 @@ typedef set<NodeID, ExprNodeLess> temporary_terms_type;
|
|||
typedef map<int,int> map_idx_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)
|
||||
enum ExprNodeOutputType
|
||||
{
|
||||
|
@ -55,26 +59,34 @@ enum ExprNodeOutputType
|
|||
oMatlabDynamicModelSparse,//!< Matlab code, dynamic block decomposed mode declaration
|
||||
oCStaticModel, //!< C code, static 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
|
||||
/*! The key is a symbol id. Lags are assumed to be null */
|
||||
typedef map<int, double> eval_context_type;
|
||||
#define IS_MATLAB(output_type) ((output_type) == oMatlabStaticModel \
|
||||
|| (output_type) == oMatlabDynamicModel \
|
||||
|| (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 */
|
||||
#define OFFSET(output_type) ((output_type == oMatlabStaticModel) \
|
||||
|| (output_type == oMatlabDynamicModel) \
|
||||
|| (output_type == oMatlabOutsideModel) \
|
||||
|| (output_type == oMatlabStaticModelSparse) \
|
||||
|| (output_type == oMatlabDynamicModelSparse))
|
||||
#define ARRAY_SUBSCRIPT_OFFSET(output_type) ((int) IS_MATLAB(output_type))
|
||||
|
||||
// Left parenthesis: '(' for Matlab, '[' for C
|
||||
#define LPAR(output_type) (OFFSET(output_type) ? '(' : '[')
|
||||
// Left and right array subscript delimiters: '(' and ')' for Matlab, '[' and ']' for C
|
||||
#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
|
||||
#define RPAR(output_type) (OFFSET(output_type) ? ')' : ']')
|
||||
// Left and right parentheses
|
||||
#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
|
||||
#define MIN_COST_MATLAB (40*90)
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
* along with Dynare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#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
|
||||
temporary_terms_type tt2;
|
||||
|
||||
if (tt.size() > 0 && (!OFFSET(output_type)))
|
||||
if (tt.size() > 0 && (IS_C(output_type)))
|
||||
output << "double" << endl;
|
||||
|
||||
for (temporary_terms_type::const_iterator it = tt.begin();
|
||||
it != tt.end(); it++)
|
||||
{
|
||||
if (!OFFSET(output_type) && it != tt.begin())
|
||||
if (IS_C(output_type) && it != tt.begin())
|
||||
output << "," << endl;
|
||||
|
||||
(*it)->writeOutput(output, output_type, tt);
|
||||
|
@ -166,10 +167,10 @@ ModelTree::writeTemporaryTerms(const temporary_terms_type &tt, ostream &output,
|
|||
// Insert current node into tt2
|
||||
tt2.insert(*it);
|
||||
|
||||
if (OFFSET(output_type))
|
||||
if (IS_MATLAB(output_type))
|
||||
output << ";" << endl;
|
||||
}
|
||||
if (!OFFSET(output_type))
|
||||
if (IS_C(output_type))
|
||||
output << ";" << endl;
|
||||
}
|
||||
|
||||
|
@ -182,7 +183,7 @@ ModelTree::writeModelLocalVariables(ostream &output, ExprNodeOutputType output_t
|
|||
int id = it->first;
|
||||
NodeID value = it->second;
|
||||
|
||||
if (!OFFSET(output_type))
|
||||
if (IS_C(output_type))
|
||||
output << "double ";
|
||||
|
||||
output << symbol_table.getName(id) << " = ";
|
||||
|
@ -209,10 +210,54 @@ ModelTree::writeModelEquations(ostream &output, ExprNodeOutputType output_type)
|
|||
rhs->writeOutput(output, output_type, temporary_terms);
|
||||
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
|
||||
ModelTree::addEquation(NodeID eq)
|
||||
{
|
||||
|
@ -225,10 +270,10 @@ ModelTree::addEquation(NodeID eq)
|
|||
void
|
||||
ModelTree::matrixHelper(ostream &output, int eq_nb, int col_nb, ExprNodeOutputType output_type) const
|
||||
{
|
||||
output << LPAR(output_type);
|
||||
if (OFFSET(output_type))
|
||||
output << LEFT_ARRAY_SUBSCRIPT(output_type);
|
||||
if (IS_MATLAB(output_type))
|
||||
output << eq_nb + 1 << ", " << col_nb + 1;
|
||||
else
|
||||
output << eq_nb + col_nb * equations.size();
|
||||
output << RPAR(output_type);
|
||||
output << RIGHT_ARRAY_SUBSCRIPT(output_type);
|
||||
}
|
||||
|
|
|
@ -99,6 +99,9 @@ protected:
|
|||
//! 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;
|
||||
|
||||
//! Writes LaTeX model file
|
||||
void writeLatexModelFile(const string &filename, ExprNodeOutputType output_type) const;
|
||||
|
||||
public:
|
||||
ModelTree(SymbolTable &symbol_table_arg, NumericalConstants &num_constants);
|
||||
//! Mode in which the ModelTree is supposed to work (Matlab, DLL or SparseDLL)
|
||||
|
|
|
@ -101,7 +101,10 @@ ParsingDriver::declare_symbol(string *name, SymbolType type, string *tex_name)
|
|||
{
|
||||
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)
|
||||
{
|
||||
|
@ -112,7 +115,8 @@ ParsingDriver::declare_symbol(string *name, SymbolType type, string *tex_name)
|
|||
}
|
||||
|
||||
delete name;
|
||||
delete tex_name;
|
||||
if (tex_name != NULL)
|
||||
delete tex_name;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1042,6 +1046,18 @@ ParsingDriver::ramsey_policy()
|
|||
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
|
||||
ParsingDriver::bvar_density(string *maxnlags)
|
||||
{
|
||||
|
|
|
@ -178,13 +178,13 @@ public:
|
|||
//! Sets the FILENAME for the initial value in initval
|
||||
void initval_file(string *filename);
|
||||
//! 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
|
||||
void declare_exogenous(string *name, string *tex_name = new string);
|
||||
void declare_exogenous(string *name, string *tex_name = NULL);
|
||||
//! 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
|
||||
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
|
||||
void declare_and_init_model_local_variable(string *name, NodeID rhs);
|
||||
//! Changes type of a symbol
|
||||
|
@ -338,6 +338,10 @@ public:
|
|||
void end_planner_objective(NodeID expr);
|
||||
//! ramsey policy statement
|
||||
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
|
||||
void bvar_density(string *maxnlags);
|
||||
//! BVAR forecast
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StaticModel::writeLatexFile(const string &basename) const
|
||||
{
|
||||
writeLatexModelFile(basename + "_static.tex", oLatexStaticModel);
|
||||
}
|
||||
|
|
|
@ -55,6 +55,9 @@ public:
|
|||
//! Writes static model file
|
||||
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);
|
||||
};
|
||||
|
||||
|
|
|
@ -48,6 +48,20 @@ SymbolTable::addSymbol(const string &name, SymbolType type, const string &tex_na
|
|||
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
|
||||
SymbolTable::freeze() throw (FrozenException)
|
||||
{
|
||||
|
|
|
@ -115,7 +115,9 @@ public:
|
|||
{
|
||||
};
|
||||
//! 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
|
||||
inline bool exists(const string &name) const;
|
||||
//! Get symbol name (by ID)
|
||||
|
|
Loading…
Reference in New Issue