Merge branch 'master' into new_ep

issue#70
Michel Juillard 2015-05-23 18:26:07 +02:00
commit f1c95edc31
17 changed files with 968 additions and 601 deletions

View File

@ -518,17 +518,14 @@ DynareSensitivityStatement::writeOutput(ostream &output, const string &basename)
output << "dynare_sensitivity(options_gsa);" << endl;
}
RplotStatement::RplotStatement(const SymbolList &symbol_list_arg,
const OptionsList &options_list_arg) :
symbol_list(symbol_list_arg),
options_list(options_list_arg)
RplotStatement::RplotStatement(const SymbolList &symbol_list_arg) :
symbol_list(symbol_list_arg)
{
}
void
RplotStatement::writeOutput(ostream &output, const string &basename) const
{
options_list.writeOutput(output);
symbol_list.writeOutput("var_list_", output);
output << "rplot(var_list_);" << endl;
}
@ -1943,8 +1940,6 @@ void
EstimationDataStatement::writeOutput(ostream &output, const string &basename) const
{
options_list.writeOutput(output, "options_.dataset");
//if (options_list.date_options.find("first_obs") == options_list.date_options.end())
// output << "options_.dataset.first_obs = options_.initial_period;" << endl;
}
SubsamplesStatement::SubsamplesStatement(const string &name1_arg,
@ -2082,6 +2077,113 @@ SubsamplesEqualStatement::writeOutput(ostream &output, const string &basename) c
<< endl;
}
JointPriorStatement::JointPriorStatement(const vector<string> joint_parameters_arg,
const PriorDistributions &prior_shape_arg,
const OptionsList &options_list_arg) :
joint_parameters(joint_parameters_arg),
prior_shape(prior_shape_arg),
options_list(options_list_arg)
{
}
void
JointPriorStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings)
{
if (joint_parameters.size() < 2)
{
cerr << "ERROR: you must pass at least two parameters to the joint prior statement" << endl;
exit(EXIT_FAILURE);
}
if (prior_shape == eNoShape)
{
cerr << "ERROR: You must pass the shape option to the prior statement." << endl;
exit(EXIT_FAILURE);
}
if (options_list.num_options.find("mean") == options_list.num_options.end() &&
options_list.num_options.find("mode") == options_list.num_options.end())
{
cerr << "ERROR: You must pass at least one of mean and mode to the prior statement." << endl;
exit(EXIT_FAILURE);
}
OptionsList::num_options_t::const_iterator it_num = options_list.num_options.find("domain");
if (it_num != options_list.num_options.end())
{
using namespace boost;
vector<string> tokenizedDomain;
split(tokenizedDomain, it_num->second, is_any_of("[ ]"), token_compress_on);
if (tokenizedDomain.size() != 4)
{
cerr << "ERROR: You must pass exactly two values to the domain option." << endl;
exit(EXIT_FAILURE);
}
}
}
void
JointPriorStatement::writeOutput(ostream &output, const string &basename) const
{
for (vector<string>::const_iterator it = joint_parameters.begin() ; it != joint_parameters.end(); it++)
output << "eifind = get_new_or_existing_ei_index('joint_parameter_prior_index', '"
<< *it << "', '');" << endl
<< "estimation_info.joint_parameter_prior_index(eifind) = {'" << *it << "'};" << endl;
output << "key = {[";
for (vector<string>::const_iterator it = joint_parameters.begin() ; it != joint_parameters.end(); it++)
output << "get_new_or_existing_ei_index('joint_parameter_prior_index', '" << *it << "', '') ..."
<< endl << " ";
output << "]};" << endl;
string lhs_field("estimation_info.joint_parameter_tmp");
writeOutputHelper(output, "domain", lhs_field);
writeOutputHelper(output, "interval", lhs_field);
writeOutputHelper(output, "mean", lhs_field);
writeOutputHelper(output, "median", lhs_field);
writeOutputHelper(output, "mode", lhs_field);
assert(prior_shape != eNoShape);
output << lhs_field << ".shape = " << prior_shape << ";" << endl;
writeOutputHelper(output, "shift", lhs_field);
writeOutputHelper(output, "stdev", lhs_field);
writeOutputHelper(output, "truncate", lhs_field);
writeOutputHelper(output, "variance", lhs_field);
output << "estimation_info.joint_parameter_tmp = [key, ..." << endl
<< " " << lhs_field << ".domain , ..." << endl
<< " " << lhs_field << ".interval , ..." << endl
<< " " << lhs_field << ".mean , ..." << endl
<< " " << lhs_field << ".median , ..." << endl
<< " " << lhs_field << ".mode , ..." << endl
<< " " << lhs_field << ".shape , ..." << endl
<< " " << lhs_field << ".shift , ..." << endl
<< " " << lhs_field << ".stdev , ..." << endl
<< " " << lhs_field << ".truncate , ..." << endl
<< " " << lhs_field << ".variance];" << endl
<< "estimation_info.joint_parameter = [estimation_info.joint_parameter; estimation_info.joint_parameter_tmp];" << endl
<< "estimation_info=rmfield(estimation_info, 'joint_parameter_tmp');" << endl;
}
void
JointPriorStatement::writeOutputHelper(ostream &output, const string &field, const string &lhs_field) const
{
OptionsList::num_options_t::const_iterator itn = options_list.num_options.find(field);
output << lhs_field << "." << field << " = {";
if (field=="variance")
output << "{";
if (itn != options_list.num_options.end())
output << itn->second;
else
output << "{}";
if (field=="variance")
output << "}";
output << "};" << endl;
}
BasicPriorStatement::~BasicPriorStatement()
{
}
@ -2399,27 +2501,6 @@ CorrPriorStatement::writeOutput(ostream &output, const string &basename) const
writePriorOutput(output, lhs_field, name1);
}
PriorEqualStatement::PriorEqualStatement(const string &to_declaration_type_arg,
const string &to_name1_arg,
const string &to_name2_arg,
const string &to_subsample_name_arg,
const string &from_declaration_type_arg,
const string &from_name1_arg,
const string &from_name2_arg,
const string &from_subsample_name_arg,
const SymbolTable &symbol_table_arg) :
to_declaration_type(to_declaration_type_arg),
to_name1(to_name1_arg),
to_name2(to_name2_arg),
to_subsample_name(to_subsample_name_arg),
from_declaration_type(from_declaration_type_arg),
from_name1(from_name1_arg),
from_name2(from_name2_arg),
from_subsample_name(from_subsample_name_arg),
symbol_table(symbol_table_arg)
{
}
void
CorrPriorStatement::writeCOutput(ostream &output, const string &basename)
{
@ -2452,6 +2533,27 @@ CorrPriorStatement::writeCOutput(ostream &output, const string &basename)
output << endl <<" index, index1, shape, mean, mode, stdev, variance, domain));" << endl;
}
PriorEqualStatement::PriorEqualStatement(const string &to_declaration_type_arg,
const string &to_name1_arg,
const string &to_name2_arg,
const string &to_subsample_name_arg,
const string &from_declaration_type_arg,
const string &from_name1_arg,
const string &from_name2_arg,
const string &from_subsample_name_arg,
const SymbolTable &symbol_table_arg) :
to_declaration_type(to_declaration_type_arg),
to_name1(to_name1_arg),
to_name2(to_name2_arg),
to_subsample_name(to_subsample_name_arg),
from_declaration_type(from_declaration_type_arg),
from_name1(from_name1_arg),
from_name2(from_name2_arg),
from_subsample_name(from_subsample_name_arg),
symbol_table(symbol_table_arg)
{
}
void
PriorEqualStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings)
{
@ -2716,6 +2818,33 @@ CorrOptionsStatement::writeOutput(ostream &output, const string &basename) const
writeOptionsOutput(output, lhs_field, name1);
}
void
CorrOptionsStatement::writeCOutput(ostream &output, const string &basename)
{
output << endl
<< "index = ";
if (is_structural_innovation(symbol_table.getType(name)))
output << "exo_names";
else
output << "endo_names";
output << "[\""<< name << "\"];" << endl;
output << "index1 = ";
if (is_structural_innovation(symbol_table.getType(name1)))
output << "exo_names";
else
output << "endo_names";
output << "[\""<< name1 << "\"];" << endl;
writeCOutputHelper(output, "init");
if (is_structural_innovation(symbol_table.getType(name)))
output << "msdsgeinfo->addStructuralInnovationCorrOption(new ModFileStructuralInnovationCorrOption(";
else
output << "msdsgeinfo->addMeasurementErrorCorrOption(new ModFileMeasurementErrorCorrOption(";
output << "index, index1, init));" << endl;
}
OptionsEqualStatement::OptionsEqualStatement(const string &to_declaration_type_arg,
const string &to_name1_arg,
const string &to_name2_arg,
@ -2883,33 +3012,6 @@ ModelDiagnosticsStatement::writeOutput(ostream &output, const string &basename)
output << "model_diagnostics(M_,options_,oo_);" << endl;
}
void
CorrOptionsStatement::writeCOutput(ostream &output, const string &basename)
{
output << endl
<< "index = ";
if (is_structural_innovation(symbol_table.getType(name)))
output << "exo_names";
else
output << "endo_names";
output << "[\""<< name << "\"];" << endl;
output << "index1 = ";
if (is_structural_innovation(symbol_table.getType(name1)))
output << "exo_names";
else
output << "endo_names";
output << "[\""<< name1 << "\"];" << endl;
writeCOutputHelper(output, "init");
if (is_structural_innovation(symbol_table.getType(name)))
output << "msdsgeinfo->addStructuralInnovationCorrOption(new ModFileStructuralInnovationCorrOption(";
else
output << "msdsgeinfo->addMeasurementErrorCorrOption(new ModFileMeasurementErrorCorrOption(";
output << "index, index1, init));" << endl;
}
Smoother2histvalStatement::Smoother2histvalStatement(const OptionsList &options_list_arg) :
options_list(options_list_arg)
{

View File

@ -150,10 +150,8 @@ class RplotStatement : public Statement
{
private:
const SymbolList symbol_list;
const OptionsList options_list;
public:
RplotStatement(const SymbolList &symbol_list_arg,
const OptionsList &options_list_arg);
RplotStatement(const SymbolList &symbol_list_arg);
virtual void writeOutput(ostream &output, const string &basename) const;
};
@ -679,6 +677,22 @@ public:
virtual void writeOutput(ostream &output, const string &basename) const;
};
class JointPriorStatement : public Statement
{
private:
const vector<string> joint_parameters;
const PriorDistributions prior_shape;
const OptionsList options_list;
public:
JointPriorStatement(const vector<string> joint_parameters_arg,
const PriorDistributions &prior_shape_arg,
const OptionsList &options_list_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
virtual void writeOutput(ostream &output, const string &basename) const;
void writeOutputHelper(ostream &output, const string &field, const string &lhs_field) const;
};
class BasicPriorStatement : public Statement
{
public:

View File

@ -261,8 +261,6 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const
{
int lag = it->first.first;
unsigned int var = it->first.second.first;
//int eqr = getBlockInitialEquationID(block, eq);
//int varr = getBlockInitialVariableID(block, var);
if (var != prev_var || lag != prev_lag)
{
prev_var = var;
@ -280,8 +278,6 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const
{
int lag = it->first.first;
unsigned int var = it->first.second.first;
//int eqr = getBlockInitialEquationID(block, eq);
//int varr = getBlockInitialVariableID(block, var);
if (var != prev_var || lag != prev_lag)
{
prev_var = var;
@ -299,8 +295,6 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const
{
int lag = it->first.first;
unsigned int var = it->first.second.first;
//int eqr = getBlockInitialEquationID(block, eq);
//int varr = getBlockInitialVariableID(block, var);
if (var != prev_var || lag != prev_lag)
{
prev_var = var;
@ -318,8 +312,6 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const
{
int lag = it->first.first;
unsigned int var = it->first.second.first;
//int eqr = getBlockInitialEquationID(block, eq);
//int varr = getBlockInitialVariableID(block, var);
if (var != prev_var || lag != prev_lag)
{
prev_var = var;
@ -2801,89 +2793,6 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de
typedef pair<int, pair<int, int > > index_KF;
vector<index_KF> v_index_KF;
/* DO 170, J = 1, N
TEMP1 = ALPHA*A( J, J )
DO 110, I = 1, M
C( I, J ) = TEMP1*B( I, J )
11 110 CONTINUE
DO 140, K = 1, J - 1
TEMP1 = ALPHA*A( K, J )
DO 130, I = 1, M
C( I, J ) = C( I, J ) + TEMP1*B( I, K )
13 130 CONTINUE
14 140 CONTINUE
DO 160, K = J + 1, N
TEMP1 = ALPHA*A( J, K )
DO 150, I = 1, M
C( I, J ) = C( I, J ) + TEMP1*B( I, K )
15 150 CONTINUE
16 160 CONTINUE
17 170 CONTINUE
for(int j = 0; j < n; j++)
{
double temp1 = P_t_t1[j + j * n];
for (int i = 0; i < n; i++)
tmp[i + j * n] = tmp1 * T[i + j * n];
for (int k = 0; k < j - 1; k++)
{
temp1 = P_t_t1[k + j * n];
for (int i = 0; i < n; i++)
tmp[i + j * n] += temp1 * T[i + k * n];
}
for (int k = j + 1; k < n; k++)
{
temp1 = P_t_t1[j + k * n];
for (int i = 0; i < n; i++)
tmp[i + j * n] += temp1 * T[i + k * n];
}
}
for(int j = n_obs; j < n; j++)
{
int j1 = j - n_obs;
double temp1 = P_t_t1[j1 + j1 * n_state];
for (int i = 0; i < n; i++)
tmp[i + j1 * n] = tmp1 * T[i + j * n];
for (int k = n_obs; k < j - 1; k++)
{
int k1 = k - n_obs;
temp1 = P_t_t1[k1 + j1 * n_state];
for (int i = 0; i < n; i++)
tmp[i + j1 * n] += temp1 * T[i + k * n];
}
for (int k = max(j + 1, n_obs); k < n; k++)
{
int k1 = k - n_obs;
temp1 = P_t_t1[j1 + k1 * n_state];
for (int i = 0; i < n; i++)
tmp[i + j1 * n] += temp1 * T[i + k * n];
}
}
for(int j = n_obs; j < n; j++)
{
int j1 = j - n_obs;
double temp1 = P_t_t1[j1 + j1 * n_state];
for (int i = 0; i < n; i++)
tmp[i + j1 * n] = tmp1 * T[i + j * n];
for (int k = n_obs; k < j - 1; k++)
{
int k1 = k - n_obs;
temp1 = P_t_t1[k1 + j1 * n_state];
for (int i = 0; i < n; i++)
if ((i < n_obs) || (i >= nb_diag + n_obs) || (j1 >= nb_diag))
tmp[i + j1 * n] += temp1 * T[i + k * n];
}
for (int k = max(j + 1, n_obs); k < n; k++)
{
int k1 = k - n_obs;
temp1 = P_t_t1[j1 + k1 * n_state];
for (int i = 0; i < n; i++)
if ((i < n_obs) || (i >= nb_diag + n_obs) || (j1 >= nb_diag))
tmp[i + j1 * n] += temp1 * T[i + k * n];
}
}*/
for (int i = 0; i < n; i++)
//int i = 0;
for (int j = n_obs; j < n; j++)
@ -2902,7 +2811,6 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de
for (vector<index_KF>::iterator it = v_index_KF.begin(); it != v_index_KF.end(); it++)
KF_index_file.write(reinterpret_cast<char *>(&(*it)), sizeof(index_KF));
//typedef pair<pair<int, int>, pair<int, int > > index_KF_2;
vector<index_KF> v_index_KF_2;
int n_n_obs = n * n_obs;
for (int i = 0; i < n; i++)
@ -4313,5 +4221,117 @@ DynamicModel::dynamicOnlyEquationsNbr() const
return eqs.size();
}
#ifndef PRIVATE_BUFFER_SIZE
#define PRIVATE_BUFFER_SIZE 1024
#endif
bool
DynamicModel::isChecksumMatching(const string &basename) const
{
boost::crc_32_type result;
std::stringstream buffer;
// Write equation tags
for (size_t i = 0; i < equation_tags.size(); i++)
buffer << " " << equation_tags[i].first + 1
<< equation_tags[i].second.first
<< equation_tags[i].second.second;
ExprNodeOutputType buffer_type = oCDynamicModel;
for (int eq = 0; eq < (int) equations.size(); eq++)
{
BinaryOpNode *eq_node = equations[eq];
expr_t lhs = eq_node->get_arg1();
expr_t rhs = eq_node->get_arg2();
// Test if the right hand side of the equation is empty.
double vrhs = 1.0;
try
{
vrhs = rhs->eval(eval_context_t());
}
catch (ExprNode::EvalException &e)
{
}
if (vrhs != 0) // The right hand side of the equation is not empty ==> residual=lhs-rhs;
{
buffer << "lhs =";
lhs->writeOutput(buffer, buffer_type, temporary_terms);
buffer << ";" << endl;
buffer << "rhs =";
rhs->writeOutput(buffer, buffer_type, temporary_terms);
buffer << ";" << endl;
buffer << "residual" << LEFT_ARRAY_SUBSCRIPT(buffer_type)
<< eq + ARRAY_SUBSCRIPT_OFFSET(buffer_type)
<< RIGHT_ARRAY_SUBSCRIPT(buffer_type)
<< "= lhs-rhs;" << endl;
}
else // The right hand side of the equation is empty ==> residual=lhs;
{
buffer << "residual" << LEFT_ARRAY_SUBSCRIPT(buffer_type)
<< eq + ARRAY_SUBSCRIPT_OFFSET(buffer_type)
<< RIGHT_ARRAY_SUBSCRIPT(buffer_type)
<< " = ";
lhs->writeOutput(buffer, buffer_type, temporary_terms);
buffer << ";" << endl;
}
}
char private_buffer[PRIVATE_BUFFER_SIZE];
while(buffer)
{
buffer.get(private_buffer,PRIVATE_BUFFER_SIZE);
result.process_bytes(private_buffer,strlen(private_buffer));
}
bool basename_dir_exists = false;
#ifdef _WIN32
int r = mkdir(basename.c_str());
#else
int r = mkdir(basename.c_str(), 0777);
#endif
if (r < 0)
if (errno != EEXIST)
{
perror("ERROR");
exit(EXIT_FAILURE);
}
else
basename_dir_exists = true;
// check whether basename directory exist. If not, create it.
// If it does, read old checksum if it exist
fstream checksum_file;
string filename = basename + "/checksum";
unsigned int old_checksum = 0;
// read old checksum if it exists
if (basename_dir_exists)
{
checksum_file.open(filename.c_str(), ios::in | ios::binary);
if (checksum_file.is_open())
{
checksum_file >> old_checksum;
checksum_file.close();
}
}
// write new checksum file if none or different from old checksum
if (old_checksum != result.checksum())
{
checksum_file.open(filename.c_str(), ios::out | ios::binary);
if (!checksum_file.is_open())
{
cerr << "ERROR: Can't open file " << filename << endl;
exit(EXIT_FAILURE);
}
checksum_file << result.checksum();
checksum_file.close();
return false;
}
return true;
}

View File

@ -24,6 +24,7 @@ using namespace std;
#define ZERO_BAND 1e-8
#include <fstream>
#include <boost/crc.hpp>
#include "StaticModel.hh"
@ -479,6 +480,8 @@ public:
void writeSecondDerivativesC_csr(const string &basename, bool cuda) const;
//! Writes C file containing third order derivatives of model evaluated at steady state (compressed sparse column)
void writeThirdDerivativesC_csr(const string &basename, bool cuda) const;
bool isChecksumMatching(const string &basename) const;
};
//! Classes to re-order derivatives for various sparse storage formats

View File

@ -82,17 +82,17 @@ class ParsingDriver;
#define yylex driver.lexer->lex
}
%token AIM_SOLVER ANALYTIC_DERIVATION AR AUTOCORR
%token BAYESIAN_IRF BETA_PDF BLOCK USE_CALIBRATION
%token BVAR_DENSITY BVAR_FORECAST NODECOMPOSITION
%token BVAR_PRIOR_DECAY BVAR_PRIOR_FLAT BVAR_PRIOR_LAMBDA
%token AIM_SOLVER ANALYTIC_DERIVATION AR AUTOCORR TARB_MODE_COMPUTE
%token BAYESIAN_IRF BETA_PDF BLOCK USE_CALIBRATION USE_TARB TARB_NEW_BLOCK_PROBABILITY
%token BVAR_DENSITY BVAR_FORECAST NODECOMPOSITION DR_DISPLAY_TOL HUGE_NUMBER
%token BVAR_PRIOR_DECAY BVAR_PRIOR_FLAT BVAR_PRIOR_LAMBDA TARB_OPTIM
%token BVAR_PRIOR_MU BVAR_PRIOR_OMEGA BVAR_PRIOR_TAU BVAR_PRIOR_TRAIN
%token BVAR_REPLIC BYTECODE ALL_VALUES_REQUIRED
%token CALIB_SMOOTHER CHANGE_TYPE CHECK CONDITIONAL_FORECAST CONDITIONAL_FORECAST_PATHS CONF_SIG CONSTANT CONTROLLED_VAREXO CORR COVAR CUTOFF CYCLE_REDUCTION LOGARITHMIC_REDUCTION
%token CONSIDER_ALL_ENDOGENOUS CONSIDER_ONLY_OBSERVED
%token DATAFILE FILE SERIES DOUBLING DR_CYCLE_REDUCTION_TOL DR_LOGARITHMIC_REDUCTION_TOL DR_LOGARITHMIC_REDUCTION_MAXITER DR_ALGO DROP DSAMPLE DYNASAVE DYNATYPE CALIBRATION DIFFERENTIATE_FORWARD_VARS
%token END ENDVAL EQUAL ESTIMATION ESTIMATED_PARAMS ESTIMATED_PARAMS_BOUNDS ESTIMATED_PARAMS_INIT EXTENDED_PATH ENDOGENOUS_PRIOR
%token FILENAME FILTER_STEP_AHEAD FILTERED_VARS FIRST_OBS LAST_OBS SET_TIME
%token FILENAME DIRNAME FILTER_STEP_AHEAD FILTERED_VARS FIRST_OBS LAST_OBS SET_TIME
%token <string_val> FLOAT_NUMBER DATES
%token DEFAULT FIXED_POINT OPT_ALGO
%token FORECAST K_ORDER_SOLVER INSTRUMENTS SHIFT MEAN STDEV VARIANCE MODE INTERVAL SHAPE DOMAINN
@ -101,7 +101,7 @@ class ParsingDriver;
%token IDENTIFICATION INF_CONSTANT INITVAL INITVAL_FILE BOUNDS JSCALE INIT INFILE INVARS
%token <string_val> INT_NUMBER
%token INV_GAMMA_PDF INV_GAMMA1_PDF INV_GAMMA2_PDF IRF IRF_SHOCKS IRF_PLOT_THRESHOLD IRF_CALIBRATION
%token KALMAN_ALGO KALMAN_TOL SUBSAMPLES OPTIONS TOLF
%token KALMAN_ALGO KALMAN_TOL DIFFUSE_KALMAN_TOL SUBSAMPLES OPTIONS TOLF
%token LAPLACE LIK_ALGO LIK_INIT LINEAR LOAD_IDENT_FILES LOAD_MH_FILE LOAD_PARAMS_AND_STEADY_STATE LOGLINEAR LOGDATA LYAPUNOV
%token LYAPUNOV_FIXED_POINT_TOL LYAPUNOV_DOUBLING_TOL LYAPUNOV_SQUARE_ROOT_SOLVER_TOL LOG_DEFLATOR LOG_TREND_VAR LOG_GROWTH_FACTOR MARKOWITZ MARGINAL_DENSITY MAX MAXIT
%token MFS MH_CONF_SIG MH_DROP MH_INIT_SCALE MH_JSCALE MH_MODE MH_NBLOCKS MH_REPLIC MH_RECOVER POSTERIOR_MAX_SUBSAMPLE_DRAWS MIN MINIMAL_SOLVING_PERIODS
@ -171,6 +171,7 @@ class ParsingDriver;
%token PARAMETER_CONVERGENCE_CRITERION NUMBER_OF_LARGE_PERTURBATIONS NUMBER_OF_SMALL_PERTURBATIONS
%token NUMBER_OF_POSTERIOR_DRAWS_AFTER_PERTURBATION MAX_NUMBER_OF_STAGES
%token RANDOM_FUNCTION_CONVERGENCE_CRITERION RANDOM_PARAMETER_CONVERGENCE_CRITERION
%token <vector_string_val> SYMBOL_VEC
%type <node_val> expression expression_or_empty
%type <node_val> equation hand_side
@ -1093,6 +1094,7 @@ stoch_simul_primary_options : o_dr_algo
| o_dr_logarithmic_reduction_tol
| o_dr_logarithmic_reduction_maxiter
| o_irf_plot_threshold
| o_dr_display_tol
;
stoch_simul_options : stoch_simul_primary_options
@ -1422,6 +1424,8 @@ prior : symbol '.' PRIOR { driver.set_prior_variance(); driver.prior_shape = eNo
{ driver.set_prior($1, new string ("")); }
| symbol '.' symbol '.' PRIOR { driver.set_prior_variance(); driver.prior_shape = eNoShape; } '(' prior_options_list ')' ';'
{ driver.set_prior($1, $3); }
| SYMBOL_VEC '.' PRIOR { driver.set_prior_variance(); driver.prior_shape = eNoShape; } '(' joint_prior_options_list ')' ';'
{ driver.set_joint_prior($1); }
| STD '(' symbol ')' '.' PRIOR { driver.set_prior_variance(); driver.prior_shape = eNoShape; } '(' prior_options_list ')' ';'
{ driver.set_std_prior($3, new string ("")); }
| STD '(' symbol ')' '.' symbol '.' PRIOR { driver.set_prior_variance(); driver.prior_shape = eNoShape; } '(' prior_options_list ')' ';'
@ -1448,6 +1452,22 @@ prior_options : o_shift
| o_domain
;
joint_prior_options_list : joint_prior_options_list COMMA joint_prior_options
| joint_prior_options
;
joint_prior_options : o_shift
| o_mean_vec
| o_median
| o_stdev
| o_truncate
| o_variance_mat
| o_mode
| o_interval
| o_shape
| o_domain
;
prior_eq : prior_eq_opt EQUAL prior_eq_opt ';'
{
driver.copy_prior($1->at(0), $1->at(1), $1->at(2), $1->at(3),
@ -1645,6 +1665,7 @@ estimation_options : o_datafile
| o_filtered_vars
| o_kalman_algo
| o_kalman_tol
| o_diffuse_kalman_tol
| o_xls_sheet
| o_xls_range
| o_filter_step_ahead
@ -1692,6 +1713,12 @@ estimation_options : o_datafile
| o_filter_algorithm
| o_proposal_approximation
| o_distribution_approximation
| o_dirname
| o_huge_number
| o_use_tarb
| o_tarb_mode_compute
| o_tarb_new_block_probability
| o_tarb_optim
;
list_optim_option : QUOTED_STRING COMMA QUOTED_STRING
@ -1704,6 +1731,16 @@ optim_options : list_optim_option
| optim_options COMMA list_optim_option;
;
list_tarb_optim_option : QUOTED_STRING COMMA QUOTED_STRING
{ driver.tarb_optim_options_string($1, $3); }
| QUOTED_STRING COMMA signed_number
{ driver.tarb_optim_options_num($1, $3); }
;
tarb_optim_options : list_tarb_optim_option
| tarb_optim_options COMMA list_tarb_optim_option;
;
varobs : VAROBS { driver.check_varobs(); } varobs_list ';';
varobs_list : varobs_list symbol
@ -1748,6 +1785,7 @@ osr_options : stoch_simul_primary_options
| o_osr_tolf
| o_opt_algo
| o_optim
| o_huge_number
;
osr : OSR ';'
@ -2526,6 +2564,8 @@ o_qz_zero_threshold : QZ_ZERO_THRESHOLD EQUAL non_negative_number { driver.optio
o_file : FILE EQUAL filename { driver.option_str("file", $3); };
o_series : SERIES EQUAL symbol { driver.option_str("series", $3); };
o_datafile : DATAFILE EQUAL filename { driver.option_str("datafile", $3); };
o_dirname : DIRNAME EQUAL filename { driver.option_str("dirname", $3); };
o_huge_number : HUGE_NUMBER EQUAL non_negative_number { driver.option_num("huge_number", $3); };
o_nobs : NOBS EQUAL vec_int
{ driver.option_vec_int("nobs", $3); }
| NOBS EQUAL vec_int_number
@ -2544,6 +2584,7 @@ o_shift : SHIFT EQUAL signed_number { driver.option_num("shift", $3); };
o_shape : SHAPE EQUAL prior_distribution { driver.prior_shape = $3; };
o_mode : MODE EQUAL signed_number { driver.option_num("mode", $3); };
o_mean : MEAN EQUAL signed_number { driver.option_num("mean", $3); };
o_mean_vec : MEAN EQUAL vec_value { driver.option_num("mean", $3); };
o_truncate : TRUNCATE EQUAL vec_value { driver.option_num("truncate", $3); };
o_stdev : STDEV EQUAL non_negative_number { driver.option_num("stdev", $3); };
o_jscale : JSCALE EQUAL non_negative_number { driver.option_num("jscale", $3); };
@ -2552,6 +2593,7 @@ o_bounds : BOUNDS EQUAL vec_value_w_inf { driver.option_num("bounds", $3); };
o_domain : DOMAINN EQUAL vec_value { driver.option_num("domain", $3); };
o_interval : INTERVAL EQUAL vec_value { driver.option_num("interval", $3); };
o_variance : VARIANCE EQUAL expression { driver.set_prior_variance($3); }
o_variance_mat : VARIANCE EQUAL vec_of_vec_value { driver.option_num("variance",$3); }
o_prefilter : PREFILTER EQUAL INT_NUMBER { driver.option_num("prefilter", $3); };
o_presample : PRESAMPLE EQUAL INT_NUMBER { driver.option_num("presample", $3); };
o_lik_algo : LIK_ALGO EQUAL INT_NUMBER { driver.option_num("lik_algo", $3); };
@ -2590,6 +2632,7 @@ o_posterior_max_subsample_draws : POSTERIOR_MAX_SUBSAMPLE_DRAWS EQUAL INT_NUMBER
o_mh_drop : MH_DROP EQUAL non_negative_number { driver.option_num("mh_drop", $3); };
o_mh_jscale : MH_JSCALE EQUAL non_negative_number { driver.option_num("mh_jscale", $3); };
o_optim : OPTIM EQUAL '(' optim_options ')';
o_tarb_optim : TARB_OPTIM EQUAL '(' tarb_optim_options ')';
o_mh_init_scale : MH_INIT_SCALE EQUAL non_negative_number { driver.option_num("mh_init_scale", $3); };
o_mode_file : MODE_FILE EQUAL filename { driver.option_str("mode_file", $3); };
o_mode_compute : MODE_COMPUTE EQUAL INT_NUMBER { driver.option_num("mode_compute", $3); };
@ -2622,6 +2665,7 @@ o_filtered_vars : FILTERED_VARS { driver.option_num("filtered_vars", "1"); };
o_relative_irf : RELATIVE_IRF { driver.option_num("relative_irf", "1"); };
o_kalman_algo : KALMAN_ALGO EQUAL INT_NUMBER { driver.option_num("kalman_algo", $3); };
o_kalman_tol : KALMAN_TOL EQUAL non_negative_number { driver.option_num("kalman_tol", $3); };
o_diffuse_kalman_tol : DIFFUSE_KALMAN_TOL EQUAL non_negative_number { driver.option_num("diffuse_kalman_tol", $3); };
o_marginal_density : MARGINAL_DENSITY EQUAL LAPLACE
{ driver.option_str("mc_marginal_density", "laplace"); }
| MARGINAL_DENSITY EQUAL MODIFIEDHARMONICMEAN
@ -2843,7 +2887,9 @@ o_equations : EQUATIONS EQUAL vec_int
| EQUATIONS EQUAL vec_int_number
{ driver.option_vec_int("ms.equations",$3); }
;
o_use_tarb : USE_TARB { driver.option_num("TaRB.use_TaRB", "1"); };
o_tarb_mode_compute : TARB_MODE_COMPUTE EQUAL INT_NUMBER { driver.option_num("TaRB.mode_compute", $3); };
o_tarb_new_block_probability : TARB_NEW_BLOCK_PROBABILITY EQUAL non_negative_number {driver.option_num("TaRB.new_block_probability",$3); };
o_instruments : INSTRUMENTS EQUAL '(' symbol_list ')' {driver.option_symbol_list("instruments"); };
o_ext_func_name : EXT_FUNC_NAME EQUAL filename { driver.external_function_option("name", $3); };
@ -2941,6 +2987,7 @@ o_mcmc_jumping_covariance : MCMC_JUMPING_COVARIANCE EQUAL HESSIAN
{ driver.option_str("MCMC_jumping_covariance", $3); }
;
o_irf_plot_threshold : IRF_PLOT_THRESHOLD EQUAL non_negative_number { driver.option_num("impulse_responses.plot_threshold", $3); };
o_dr_display_tol : DR_DISPLAY_TOL EQUAL non_negative_number { driver.option_num("dr_display_tol", $3); };
o_consider_all_endogenous : CONSIDER_ALL_ENDOGENOUS { driver.option_str("endo_vars_for_moment_computations_in_estimation", "all_endogenous_variables"); };
o_consider_only_observed : CONSIDER_ONLY_OBSERVED { driver.option_str("endo_vars_for_moment_computations_in_estimation", "only_observed_variables"); };
o_no_homotopy : NO_HOMOTOPY { driver.option_num("no_homotopy", "1"); };

View File

@ -236,6 +236,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>dates {dates_parens_nb=0; BEGIN DATES_STATEMENT; yylval->string_val = new string("dates");}
<DYNARE_STATEMENT>file {return token::FILE;}
<DYNARE_STATEMENT>datafile {return token::DATAFILE;}
<DYNARE_STATEMENT>dirname {return token::DIRNAME;}
<DYNARE_STATEMENT>nobs {return token::NOBS;}
<DYNARE_STATEMENT>last_obs {return token::LAST_OBS;}
<DYNARE_STATEMENT>first_obs {return token::FIRST_OBS;}
@ -288,6 +289,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>nodiagnostic {return token::NODIAGNOSTIC;}
<DYNARE_STATEMENT>kalman_algo {return token::KALMAN_ALGO;}
<DYNARE_STATEMENT>kalman_tol {return token::KALMAN_TOL;}
<DYNARE_STATEMENT>diffuse_kalman_tol {return token::DIFFUSE_KALMAN_TOL;}
<DYNARE_STATEMENT>forecast {return token::FORECAST;}
<DYNARE_STATEMENT>smoother {return token::SMOOTHER;}
<DYNARE_STATEMENT>bayesian_irf {return token::BAYESIAN_IRF;}
@ -565,6 +567,12 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>period {return token::PERIOD;}
<DYNARE_STATEMENT>outfile {return token::OUTFILE;}
<DYNARE_STATEMENT>outvars {return token::OUTVARS;}
<DYNARE_STATEMENT>huge_number {return token::HUGE_NUMBER;}
<DYNARE_STATEMENT>dr_display_tol {return token::DR_DISPLAY_TOL;}
<DYNARE_STATEMENT>use_tarb {return token::USE_TARB;}
<DYNARE_STATEMENT>tarb_mode_compute {return token::TARB_MODE_COMPUTE;}
<DYNARE_STATEMENT>tarb_new_block_probability {return token::TARB_NEW_BLOCK_PROBABILITY;}
<DYNARE_STATEMENT>tarb_optim {return token::TARB_OPTIM;}
<DYNARE_STATEMENT>[\$][^$]*[\$] {
strtok(yytext+1, "$");
@ -839,6 +847,41 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
}
}
/* For joint prior statement, match [symbol, symbol, ...]
If no match, begin native and push everything back on stack
*/
<INITIAL>\[([[:space:]]*[A-Za-z_][A-Za-z0-9_]*[[:space:]]*,{1}[[:space:]]*)*([[:space:]]*[A-Za-z_][A-Za-z0-9_]*[[:space:]]*){1}\] {
string yytextcpy = string(yytext);
yytextcpy.erase(remove(yytextcpy.begin(), yytextcpy.end(), '['), yytextcpy.end());
yytextcpy.erase(remove(yytextcpy.begin(), yytextcpy.end(), ']'), yytextcpy.end());
yytextcpy.erase(remove(yytextcpy.begin(), yytextcpy.end(), ' '), yytextcpy.end());
istringstream ss(yytextcpy);
string token;
yylval->vector_string_val = new vector<string *>;
bool dynare_statement = true;
while(getline(ss, token, ','))
if (driver.symbol_exists_and_is_not_modfile_local_or_external_function(token.c_str()))
yylval->vector_string_val->push_back(new string(token));
else
{
for (vector<string *>::iterator it=yylval->vector_string_val->begin();
it != yylval->vector_string_val->end(); it++)
delete *it;
delete yylval->vector_string_val;
BEGIN NATIVE;
yyless(0);
dynare_statement = false;
break;
}
if (dynare_statement)
{
BEGIN DYNARE_STATEMENT;
return token::SYMBOL_VEC;
}
}
/* Enter a native block */
<INITIAL>. { BEGIN NATIVE; yyless(0); }

View File

@ -38,7 +38,7 @@
void main2(stringstream &in, string &basename, bool debug, bool clear_all, bool clear_global, bool no_tmp_terms, bool no_log, bool no_warn,
bool warn_uninit, bool console, bool nograph, bool nointeractive,
bool parallel, const string &parallel_config_file, const string &cluster_name, bool parallel_slave_open_mode,
bool parallel_test, bool nostrict, FileOutputType output_mode, LanguageOutputType lang
bool parallel_test, bool nostrict, bool check_model_changes, FileOutputType output_mode, LanguageOutputType lang
#if defined(_WIN32) || defined(__CYGWIN32__)
, bool cygwin, bool msvc
#endif
@ -49,7 +49,7 @@ usage()
{
cerr << "Dynare usage: dynare mod_file [debug] [noclearall] [onlyclearglobals] [savemacro[=macro_file]] [onlymacro] [nolinemacro] [notmpterms] [nolog] [warn_uninit]"
<< " [console] [nograph] [nointeractive] [parallel[=cluster_name]] [conffile=parallel_config_path_and_filename] [parallel_slave_open_mode] [parallel_test] "
<< " [-D<variable>[=<value>]] [nostrict] [output=dynamic|first|second|third] [language=C|C++]"
<< " [-D<variable>[=<value>]] [nostrict] [fast] [output=dynamic|first|second|third] [language=C|C++]"
#if defined(_WIN32) || defined(__CYGWIN32__)
<< " [cygwin] [msvc]"
#endif
@ -97,6 +97,7 @@ main(int argc, char **argv)
bool parallel_slave_open_mode = false;
bool parallel_test = false;
bool nostrict = false;
bool check_model_changes = false;
map<string, string> defines;
FileOutputType output_mode = none;
LanguageOutputType language = matlab;
@ -165,6 +166,8 @@ main(int argc, char **argv)
parallel_test = true;
else if (!strcmp(argv[arg], "nostrict"))
nostrict = true;
else if (!strcmp(argv[arg], "fast"))
check_model_changes = true;
else if (strlen(argv[arg]) >= 8 && !strncmp(argv[arg], "parallel", 8))
{
parallel = true;
@ -285,7 +288,7 @@ main(int argc, char **argv)
// Do the rest
main2(macro_output, basename, debug, clear_all, clear_global, no_tmp_terms, no_log, no_warn, warn_uninit, console, nograph, nointeractive,
parallel, parallel_config_file, cluster_name, parallel_slave_open_mode, parallel_test, nostrict, output_mode, language
parallel, parallel_config_file, cluster_name, parallel_slave_open_mode, parallel_test, nostrict, check_model_changes, output_mode, language
#if defined(_WIN32) || defined(__CYGWIN32__)
, cygwin, msvc
#endif

View File

@ -27,7 +27,7 @@
void
main2(stringstream &in, string &basename, bool debug, bool clear_all, bool clear_global, bool no_tmp_terms, bool no_log, bool no_warn, bool warn_uninit, bool console, bool nograph, bool nointeractive,
bool parallel, const string &parallel_config_file, const string &cluster_name, bool parallel_slave_open_mode,
bool parallel_test, bool nostrict, FileOutputType output_mode, LanguageOutputType language
bool parallel_test, bool nostrict, bool check_model_changes, FileOutputType output_mode, LanguageOutputType language
#if defined(_WIN32) || defined(__CYGWIN32__)
, bool cygwin, bool msvc
#endif
@ -60,11 +60,12 @@ main2(stringstream &in, string &basename, bool debug, bool clear_all, bool clear
if (output_mode != none)
mod_file->writeExternalFiles(basename, output_mode, language);
else
mod_file->writeOutputFiles(basename, clear_all, clear_global, no_log, no_warn, console, nograph, nointeractive, config_file
mod_file->writeOutputFiles(basename, clear_all, clear_global, no_log, no_warn, console, nograph,
nointeractive, config_file, check_model_changes
#if defined(_WIN32) || defined(__CYGWIN32__)
, cygwin, msvc
, cygwin, msvc
#endif
);
);
delete mod_file;

View File

@ -308,6 +308,12 @@ NumConstNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
output << datatree.num_constants.get(id);
}
bool
NumConstNode::containsExternalFunction() const
{
return false;
}
double
NumConstNode::eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException)
{
@ -571,6 +577,12 @@ VariableNode::collectTemporary_terms(const temporary_terms_t &temporary_terms, t
datatree.local_variables_table[symb_id]->collectTemporary_terms(temporary_terms, temporary_terms_inuse, Curr_Block);
}
bool
VariableNode::containsExternalFunction() const
{
return false;
}
void
VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
@ -1714,6 +1726,12 @@ UnaryOpNode::collectTemporary_terms(const temporary_terms_t &temporary_terms, te
arg->collectTemporary_terms(temporary_terms, temporary_terms_inuse, Curr_Block);
}
bool
UnaryOpNode::containsExternalFunction() const
{
return arg->containsExternalFunction();
}
void
UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
@ -2885,6 +2903,13 @@ BinaryOpNode::collectTemporary_terms(const temporary_terms_t &temporary_terms, t
}
}
bool
BinaryOpNode::containsExternalFunction() const
{
return arg1->containsExternalFunction()
|| arg2->containsExternalFunction();
}
void
BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
@ -3963,6 +3988,14 @@ TrinaryOpNode::collectTemporary_terms(const temporary_terms_t &temporary_terms,
}
}
bool
TrinaryOpNode::containsExternalFunction() const
{
return arg1->containsExternalFunction()
|| arg2->containsExternalFunction()
|| arg3->containsExternalFunction();
}
void
TrinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
@ -4297,15 +4330,6 @@ AbstractExternalFunctionNode::AbstractExternalFunctionNode(DataTree &datatree_ar
{
}
ExternalFunctionNode::ExternalFunctionNode(DataTree &datatree_arg,
int symb_id_arg,
const vector<expr_t> &arguments_arg) :
AbstractExternalFunctionNode(datatree_arg, symb_id_arg, arguments_arg)
{
// Add myself to the external function map
datatree.external_function_node_map[make_pair(arguments, symb_id)] = this;
}
void
AbstractExternalFunctionNode::prepareForDerivation()
{
@ -4336,20 +4360,6 @@ AbstractExternalFunctionNode::computeDerivative(int deriv_id)
return composeDerivatives(dargs);
}
expr_t
ExternalFunctionNode::composeDerivatives(const vector<expr_t> &dargs)
{
vector<expr_t> dNodes;
for (int i = 0; i < (int) dargs.size(); i++)
dNodes.push_back(datatree.AddTimes(dargs.at(i),
datatree.AddFirstDerivExternalFunction(symb_id, arguments, i+1)));
expr_t theDeriv = datatree.Zero;
for (vector<expr_t>::const_iterator it = dNodes.begin(); it != dNodes.end(); it++)
theDeriv = datatree.AddPlus(theDeriv, *it);
return theDeriv;
}
expr_t
AbstractExternalFunctionNode::getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recursive_variables)
{
@ -4361,76 +4371,6 @@ AbstractExternalFunctionNode::getChainRuleDerivative(int deriv_id, const map<int
return composeDerivatives(dargs);
}
void
ExternalFunctionNode::computeTemporaryTerms(map<expr_t, int> &reference_count,
temporary_terms_t &temporary_terms,
bool is_matlab) const
{
temporary_terms.insert(const_cast<ExternalFunctionNode *>(this));
}
void
AbstractExternalFunctionNode::writeExternalFunctionArguments(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const
{
for (vector<expr_t>::const_iterator it = arguments.begin();
it != arguments.end(); it++)
{
if (it != arguments.begin())
output << ",";
(*it)->writeOutput(output, output_type, temporary_terms, tef_terms);
}
}
void
AbstractExternalFunctionNode::writePrhs(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms, const string &ending) const
{
output << "mxArray *prhs"<< ending << "[nrhs"<< ending << "];" << endl;
int i = 0;
for (vector<expr_t>::const_iterator it = arguments.begin();
it != arguments.end(); it++)
{
output << "prhs" << ending << "[" << i++ << "] = mxCreateDoubleScalar("; // All external_function arguments are scalars
(*it)->writeOutput(output, output_type, temporary_terms, tef_terms);
output << ");" << endl;
}
}
void
ExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const
{
if (output_type == oMatlabOutsideModel || output_type == oSteadyStateFile
|| output_type == oCSteadyStateFile || IS_LATEX(output_type))
{
string name = IS_LATEX(output_type) ? datatree.symbol_table.getTeXName(symb_id)
: datatree.symbol_table.getName(symb_id);
output << name << "(";
writeExternalFunctionArguments(output, output_type, temporary_terms, tef_terms);
output << ")";
return;
}
temporary_terms_t::const_iterator it = temporary_terms.find(const_cast<ExternalFunctionNode *>(this));
if (it != temporary_terms.end())
{
if (output_type == oMatlabDynamicModelSparse)
output << "T" << idx << "(it_)";
else
output << "T" << idx;
return;
}
if (IS_C(output_type))
output << "*";
output << "TEF_" << getIndxInTefTerms(symb_id, tef_terms);
}
unsigned int
AbstractExternalFunctionNode::compileExternalFunctionArguments(ostream &CompileCode, unsigned int &instruction_number,
bool lhs_rhs, const temporary_terms_t &temporary_terms,
@ -4444,184 +4384,6 @@ AbstractExternalFunctionNode::compileExternalFunctionArguments(ostream &CompileC
return (arguments.size());
}
void
ExternalFunctionNode::compile(ostream &CompileCode, unsigned int &instruction_number,
bool lhs_rhs, const temporary_terms_t &temporary_terms,
const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
deriv_node_temp_terms_t &tef_terms) const
{
temporary_terms_t::const_iterator it = temporary_terms.find(const_cast<ExternalFunctionNode *>(this));
if (it != temporary_terms.end())
{
if (dynamic)
{
map_idx_t::const_iterator ii = map_idx.find(idx);
FLDT_ fldt(ii->second);
fldt.write(CompileCode, instruction_number);
}
else
{
map_idx_t::const_iterator ii = map_idx.find(idx);
FLDST_ fldst(ii->second);
fldst.write(CompileCode, instruction_number);
}
return;
}
if (!lhs_rhs)
{
FLDTEF_ fldtef(getIndxInTefTerms(symb_id, tef_terms));
fldtef.write(CompileCode, instruction_number);
}
else
{
FSTPTEF_ fstptef(getIndxInTefTerms(symb_id, tef_terms));
fstptef.write(CompileCode, instruction_number);
}
}
void
ExternalFunctionNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const
{
int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id);
assert(first_deriv_symb_id != eExtFunSetButNoNameProvided);
for (vector<expr_t>::const_iterator it = arguments.begin();
it != arguments.end(); it++)
(*it)->writeExternalFunctionOutput(output, output_type, temporary_terms, tef_terms);
if (!alreadyWrittenAsTefTerm(symb_id, tef_terms))
{
tef_terms[make_pair(symb_id, arguments)] = (int) tef_terms.size();
int indx = getIndxInTefTerms(symb_id, tef_terms);
int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id);
assert(second_deriv_symb_id != eExtFunSetButNoNameProvided);
if (IS_C(output_type))
{
stringstream ending;
ending << "_tef_" << getIndxInTefTerms(symb_id, tef_terms);
if (symb_id == first_deriv_symb_id
&& symb_id == second_deriv_symb_id)
output << "int nlhs" << ending.str() << " = 3;" << endl
<< "double *TEF_" << indx << ", "
<< "*TEFD_" << indx << ", "
<< "*TEFDD_" << indx << ";" << endl;
else if (symb_id == first_deriv_symb_id)
output << "int nlhs" << ending.str() << " = 2;" << endl
<< "double *TEF_" << indx << ", "
<< "*TEFD_" << indx << "; " << endl;
else
output << "int nlhs" << ending.str() << " = 1;" << endl
<< "double *TEF_" << indx << ";" << endl;
output << "mxArray *plhs" << ending.str()<< "[nlhs"<< ending.str() << "];" << endl;
output << "int nrhs" << ending.str()<< " = " << arguments.size() << ";" << endl;
writePrhs(output, output_type, temporary_terms, tef_terms, ending.str());
output << "mexCallMATLAB("
<< "nlhs" << ending.str() << ", "
<< "plhs" << ending.str() << ", "
<< "nrhs" << ending.str() << ", "
<< "prhs" << ending.str() << ", \""
<< datatree.symbol_table.getName(symb_id) << "\");" << endl;
if (symb_id == first_deriv_symb_id
&& symb_id == second_deriv_symb_id)
output << "TEF_" << indx << " = mxGetPr(plhs" << ending.str() << "[0]);" << endl
<< "TEFD_" << indx << " = mxGetPr(plhs" << ending.str() << "[1]);" << endl
<< "TEFDD_" << indx << " = mxGetPr(plhs" << ending.str() << "[2]);" << endl
<< "int TEFDD_" << indx << "_nrows = (int)mxGetM(plhs" << ending.str()<< "[2]);" << endl;
else if (symb_id == first_deriv_symb_id)
output << "TEF_" << indx << " = mxGetPr(plhs" << ending.str() << "[0]);" << endl
<< "TEFD_" << indx << " = mxGetPr(plhs" << ending.str() << "[1]);" << endl;
else
output << "TEF_" << indx << " = mxGetPr(plhs" << ending.str() << "[0]);" << endl;
}
else
{
if (symb_id == first_deriv_symb_id
&& symb_id == second_deriv_symb_id)
output << "[TEF_" << indx << " TEFD_"<< indx << " TEFDD_"<< indx << "] = ";
else if (symb_id == first_deriv_symb_id)
output << "[TEF_" << indx << " TEFD_"<< indx << "] = ";
else
output << "TEF_" << indx << " = ";
output << datatree.symbol_table.getName(symb_id) << "(";
writeExternalFunctionArguments(output, output_type, temporary_terms, tef_terms);
output << ");" << endl;
}
}
}
void
ExternalFunctionNode::compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
bool lhs_rhs, const temporary_terms_t &temporary_terms,
const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
deriv_node_temp_terms_t &tef_terms) const
{
int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id);
assert(first_deriv_symb_id != eExtFunSetButNoNameProvided);
for (vector<expr_t>::const_iterator it = arguments.begin();
it != arguments.end(); it++)
(*it)->compileExternalFunctionOutput(CompileCode, instruction_number, lhs_rhs, temporary_terms,
map_idx, dynamic, steady_dynamic, tef_terms);
if (!alreadyWrittenAsTefTerm(symb_id, tef_terms))
{
tef_terms[make_pair(symb_id, arguments)] = (int) tef_terms.size();
int indx = getIndxInTefTerms(symb_id, tef_terms);
int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id);
assert(second_deriv_symb_id != eExtFunSetButNoNameProvided);
unsigned int nb_output_arguments = 0;
if (symb_id == first_deriv_symb_id
&& symb_id == second_deriv_symb_id)
nb_output_arguments = 3;
else if (symb_id == first_deriv_symb_id)
nb_output_arguments = 2;
else
nb_output_arguments = 1;
unsigned int nb_input_arguments = compileExternalFunctionArguments(CompileCode, instruction_number, lhs_rhs, temporary_terms,
map_idx, dynamic, steady_dynamic, tef_terms);
FCALL_ fcall(nb_output_arguments, nb_input_arguments, datatree.symbol_table.getName(symb_id), indx);
switch (nb_output_arguments)
{
case 1:
fcall.set_function_type(ExternalFunctionWithoutDerivative);
break;
case 2:
fcall.set_function_type(ExternalFunctionWithFirstDerivative);
break;
case 3:
fcall.set_function_type(ExternalFunctionWithFirstandSecondDerivative);
break;
}
fcall.write(CompileCode, instruction_number);
FSTPTEF_ fstptef(indx);
fstptef.write(CompileCode, instruction_number);
}
}
void
ExternalFunctionNode::computeTemporaryTerms(map<expr_t, int> &reference_count,
temporary_terms_t &temporary_terms,
map<expr_t, pair<int, int> > &first_occurence,
int Curr_block,
vector< vector<temporary_terms_t> > &v_temporary_terms,
int equation) const
{
expr_t this2 = const_cast<ExternalFunctionNode *>(this);
temporary_terms.insert(this2);
first_occurence[this2] = make_pair(Curr_block, equation);
v_temporary_terms[Curr_block][equation].insert(this2);
}
void
AbstractExternalFunctionNode::collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const
{
@ -4650,45 +4412,6 @@ AbstractExternalFunctionNode::eval(const eval_context_t &eval_context) const thr
throw EvalExternalFunctionException();
}
pair<int, expr_t>
AbstractExternalFunctionNode::normalizeEquation(int var_endo, vector<pair<int, pair<expr_t, expr_t> > > &List_of_Op_RHS) const
{
vector<pair<bool, expr_t> > V_arguments;
vector<expr_t> V_expr_t;
bool present = false;
for (vector<expr_t>::const_iterator it = arguments.begin();
it != arguments.end(); it++)
{
V_arguments.push_back((*it)->normalizeEquation(var_endo, List_of_Op_RHS));
present = present || V_arguments[V_arguments.size()-1].first;
V_expr_t.push_back(V_arguments[V_arguments.size()-1].second);
}
if (!present)
return (make_pair(0, datatree.AddExternalFunction(symb_id, V_expr_t)));
else
return (make_pair(1, (expr_t) NULL));
}
expr_t
ExternalFunctionNode::toStatic(DataTree &static_datatree) const
{
vector<expr_t> static_arguments;
for (vector<expr_t>::const_iterator it = arguments.begin();
it != arguments.end(); it++)
static_arguments.push_back((*it)->toStatic(static_datatree));
return static_datatree.AddExternalFunction(symb_id, static_arguments);
}
expr_t
ExternalFunctionNode::cloneDynamic(DataTree &dynamic_datatree) const
{
vector<expr_t> dynamic_arguments;
for (vector<expr_t>::const_iterator it = arguments.begin();
it != arguments.end(); it++)
dynamic_arguments.push_back((*it)->cloneDynamic(dynamic_datatree));
return dynamic_datatree.AddExternalFunction(symb_id, dynamic_arguments);
}
int
AbstractExternalFunctionNode::maxEndoLead() const
{
@ -4811,12 +4534,6 @@ AbstractExternalFunctionNode::differentiateForwardVars(const vector<string> &sub
return buildSimilarExternalFunctionNode(arguments_subst, datatree);
}
expr_t
ExternalFunctionNode::buildSimilarExternalFunctionNode(vector<expr_t> &alt_args, DataTree &alt_datatree) const
{
return alt_datatree.AddExternalFunction(symb_id, alt_args);
}
bool
AbstractExternalFunctionNode::alreadyWrittenAsTefTerm(int the_symb_id, deriv_node_temp_terms_t &tef_terms) const
{
@ -4889,10 +4606,331 @@ AbstractExternalFunctionNode::isInStaticForm() const
for (vector<expr_t>::const_iterator it = arguments.begin(); it != arguments.end(); ++it)
if (!(*it)->isInStaticForm())
return false;
return true;
}
pair<int, expr_t>
AbstractExternalFunctionNode::normalizeEquation(int var_endo, vector<pair<int, pair<expr_t, expr_t> > > &List_of_Op_RHS) const
{
vector<pair<bool, expr_t> > V_arguments;
vector<expr_t> V_expr_t;
bool present = false;
for (vector<expr_t>::const_iterator it = arguments.begin();
it != arguments.end(); it++)
{
V_arguments.push_back((*it)->normalizeEquation(var_endo, List_of_Op_RHS));
present = present || V_arguments[V_arguments.size()-1].first;
V_expr_t.push_back(V_arguments[V_arguments.size()-1].second);
}
if (!present)
return (make_pair(0, datatree.AddExternalFunction(symb_id, V_expr_t)));
else
return (make_pair(1, (expr_t) NULL));
}
void
AbstractExternalFunctionNode::writeExternalFunctionArguments(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const
{
for (vector<expr_t>::const_iterator it = arguments.begin();
it != arguments.end(); it++)
{
if (it != arguments.begin())
output << ",";
(*it)->writeOutput(output, output_type, temporary_terms, tef_terms);
}
}
void
AbstractExternalFunctionNode::writePrhs(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms, const string &ending) const
{
output << "mxArray *prhs"<< ending << "[nrhs"<< ending << "];" << endl;
int i = 0;
for (vector<expr_t>::const_iterator it = arguments.begin();
it != arguments.end(); it++)
{
output << "prhs" << ending << "[" << i++ << "] = mxCreateDoubleScalar("; // All external_function arguments are scalars
(*it)->writeOutput(output, output_type, temporary_terms, tef_terms);
output << ");" << endl;
}
}
bool
AbstractExternalFunctionNode::containsExternalFunction() const
{
return true;
}
ExternalFunctionNode::ExternalFunctionNode(DataTree &datatree_arg,
int symb_id_arg,
const vector<expr_t> &arguments_arg) :
AbstractExternalFunctionNode(datatree_arg, symb_id_arg, arguments_arg)
{
// Add myself to the external function map
datatree.external_function_node_map[make_pair(arguments, symb_id)] = this;
}
expr_t
ExternalFunctionNode::composeDerivatives(const vector<expr_t> &dargs)
{
vector<expr_t> dNodes;
for (int i = 0; i < (int) dargs.size(); i++)
dNodes.push_back(datatree.AddTimes(dargs.at(i),
datatree.AddFirstDerivExternalFunction(symb_id, arguments, i+1)));
expr_t theDeriv = datatree.Zero;
for (vector<expr_t>::const_iterator it = dNodes.begin(); it != dNodes.end(); it++)
theDeriv = datatree.AddPlus(theDeriv, *it);
return theDeriv;
}
void
ExternalFunctionNode::computeTemporaryTerms(map<expr_t, int> &reference_count,
temporary_terms_t &temporary_terms,
bool is_matlab) const
{
temporary_terms.insert(const_cast<ExternalFunctionNode *>(this));
}
void
ExternalFunctionNode::computeTemporaryTerms(map<expr_t, int> &reference_count,
temporary_terms_t &temporary_terms,
map<expr_t, pair<int, int> > &first_occurence,
int Curr_block,
vector< vector<temporary_terms_t> > &v_temporary_terms,
int equation) const
{
expr_t this2 = const_cast<ExternalFunctionNode *>(this);
temporary_terms.insert(this2);
first_occurence[this2] = make_pair(Curr_block, equation);
v_temporary_terms[Curr_block][equation].insert(this2);
}
void
ExternalFunctionNode::compile(ostream &CompileCode, unsigned int &instruction_number,
bool lhs_rhs, const temporary_terms_t &temporary_terms,
const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
deriv_node_temp_terms_t &tef_terms) const
{
temporary_terms_t::const_iterator it = temporary_terms.find(const_cast<ExternalFunctionNode *>(this));
if (it != temporary_terms.end())
{
if (dynamic)
{
map_idx_t::const_iterator ii = map_idx.find(idx);
FLDT_ fldt(ii->second);
fldt.write(CompileCode, instruction_number);
}
else
{
map_idx_t::const_iterator ii = map_idx.find(idx);
FLDST_ fldst(ii->second);
fldst.write(CompileCode, instruction_number);
}
return;
}
if (!lhs_rhs)
{
FLDTEF_ fldtef(getIndxInTefTerms(symb_id, tef_terms));
fldtef.write(CompileCode, instruction_number);
}
else
{
FSTPTEF_ fstptef(getIndxInTefTerms(symb_id, tef_terms));
fstptef.write(CompileCode, instruction_number);
}
}
void
ExternalFunctionNode::compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
bool lhs_rhs, const temporary_terms_t &temporary_terms,
const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
deriv_node_temp_terms_t &tef_terms) const
{
int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id);
assert(first_deriv_symb_id != eExtFunSetButNoNameProvided);
for (vector<expr_t>::const_iterator it = arguments.begin();
it != arguments.end(); it++)
(*it)->compileExternalFunctionOutput(CompileCode, instruction_number, lhs_rhs, temporary_terms,
map_idx, dynamic, steady_dynamic, tef_terms);
if (!alreadyWrittenAsTefTerm(symb_id, tef_terms))
{
tef_terms[make_pair(symb_id, arguments)] = (int) tef_terms.size();
int indx = getIndxInTefTerms(symb_id, tef_terms);
int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id);
assert(second_deriv_symb_id != eExtFunSetButNoNameProvided);
unsigned int nb_output_arguments = 0;
if (symb_id == first_deriv_symb_id
&& symb_id == second_deriv_symb_id)
nb_output_arguments = 3;
else if (symb_id == first_deriv_symb_id)
nb_output_arguments = 2;
else
nb_output_arguments = 1;
unsigned int nb_input_arguments = compileExternalFunctionArguments(CompileCode, instruction_number, lhs_rhs, temporary_terms,
map_idx, dynamic, steady_dynamic, tef_terms);
FCALL_ fcall(nb_output_arguments, nb_input_arguments, datatree.symbol_table.getName(symb_id), indx);
switch (nb_output_arguments)
{
case 1:
fcall.set_function_type(ExternalFunctionWithoutDerivative);
break;
case 2:
fcall.set_function_type(ExternalFunctionWithFirstDerivative);
break;
case 3:
fcall.set_function_type(ExternalFunctionWithFirstandSecondDerivative);
break;
}
fcall.write(CompileCode, instruction_number);
FSTPTEF_ fstptef(indx);
fstptef.write(CompileCode, instruction_number);
}
}
void
ExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const
{
if (output_type == oMatlabOutsideModel || output_type == oSteadyStateFile
|| output_type == oCSteadyStateFile || IS_LATEX(output_type))
{
string name = IS_LATEX(output_type) ? datatree.symbol_table.getTeXName(symb_id)
: datatree.symbol_table.getName(symb_id);
output << name << "(";
writeExternalFunctionArguments(output, output_type, temporary_terms, tef_terms);
output << ")";
return;
}
temporary_terms_t::const_iterator it = temporary_terms.find(const_cast<ExternalFunctionNode *>(this));
if (it != temporary_terms.end())
{
if (output_type == oMatlabDynamicModelSparse)
output << "T" << idx << "(it_)";
else
output << "T" << idx;
return;
}
if (IS_C(output_type))
output << "*";
output << "TEF_" << getIndxInTefTerms(symb_id, tef_terms);
}
void
ExternalFunctionNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const
{
int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id);
assert(first_deriv_symb_id != eExtFunSetButNoNameProvided);
for (vector<expr_t>::const_iterator it = arguments.begin();
it != arguments.end(); it++)
(*it)->writeExternalFunctionOutput(output, output_type, temporary_terms, tef_terms);
if (!alreadyWrittenAsTefTerm(symb_id, tef_terms))
{
tef_terms[make_pair(symb_id, arguments)] = (int) tef_terms.size();
int indx = getIndxInTefTerms(symb_id, tef_terms);
int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id);
assert(second_deriv_symb_id != eExtFunSetButNoNameProvided);
if (IS_C(output_type))
{
stringstream ending;
ending << "_tef_" << getIndxInTefTerms(symb_id, tef_terms);
if (symb_id == first_deriv_symb_id
&& symb_id == second_deriv_symb_id)
output << "int nlhs" << ending.str() << " = 3;" << endl
<< "double *TEF_" << indx << ", "
<< "*TEFD_" << indx << ", "
<< "*TEFDD_" << indx << ";" << endl;
else if (symb_id == first_deriv_symb_id)
output << "int nlhs" << ending.str() << " = 2;" << endl
<< "double *TEF_" << indx << ", "
<< "*TEFD_" << indx << "; " << endl;
else
output << "int nlhs" << ending.str() << " = 1;" << endl
<< "double *TEF_" << indx << ";" << endl;
output << "mxArray *plhs" << ending.str()<< "[nlhs"<< ending.str() << "];" << endl;
output << "int nrhs" << ending.str()<< " = " << arguments.size() << ";" << endl;
writePrhs(output, output_type, temporary_terms, tef_terms, ending.str());
output << "mexCallMATLAB("
<< "nlhs" << ending.str() << ", "
<< "plhs" << ending.str() << ", "
<< "nrhs" << ending.str() << ", "
<< "prhs" << ending.str() << ", \""
<< datatree.symbol_table.getName(symb_id) << "\");" << endl;
if (symb_id == first_deriv_symb_id
&& symb_id == second_deriv_symb_id)
output << "TEF_" << indx << " = mxGetPr(plhs" << ending.str() << "[0]);" << endl
<< "TEFD_" << indx << " = mxGetPr(plhs" << ending.str() << "[1]);" << endl
<< "TEFDD_" << indx << " = mxGetPr(plhs" << ending.str() << "[2]);" << endl
<< "int TEFDD_" << indx << "_nrows = (int)mxGetM(plhs" << ending.str()<< "[2]);" << endl;
else if (symb_id == first_deriv_symb_id)
output << "TEF_" << indx << " = mxGetPr(plhs" << ending.str() << "[0]);" << endl
<< "TEFD_" << indx << " = mxGetPr(plhs" << ending.str() << "[1]);" << endl;
else
output << "TEF_" << indx << " = mxGetPr(plhs" << ending.str() << "[0]);" << endl;
}
else
{
if (symb_id == first_deriv_symb_id
&& symb_id == second_deriv_symb_id)
output << "[TEF_" << indx << " TEFD_"<< indx << " TEFDD_"<< indx << "] = ";
else if (symb_id == first_deriv_symb_id)
output << "[TEF_" << indx << " TEFD_"<< indx << "] = ";
else
output << "TEF_" << indx << " = ";
output << datatree.symbol_table.getName(symb_id) << "(";
writeExternalFunctionArguments(output, output_type, temporary_terms, tef_terms);
output << ");" << endl;
}
}
}
expr_t
ExternalFunctionNode::toStatic(DataTree &static_datatree) const
{
vector<expr_t> static_arguments;
for (vector<expr_t>::const_iterator it = arguments.begin();
it != arguments.end(); it++)
static_arguments.push_back((*it)->toStatic(static_datatree));
return static_datatree.AddExternalFunction(symb_id, static_arguments);
}
expr_t
ExternalFunctionNode::cloneDynamic(DataTree &dynamic_datatree) const
{
vector<expr_t> dynamic_arguments;
for (vector<expr_t>::const_iterator it = arguments.begin();
it != arguments.end(); it++)
dynamic_arguments.push_back((*it)->cloneDynamic(dynamic_datatree));
return dynamic_datatree.AddExternalFunction(symb_id, dynamic_arguments);
}
expr_t
ExternalFunctionNode::buildSimilarExternalFunctionNode(vector<expr_t> &alt_args, DataTree &alt_datatree) const
{
return alt_datatree.AddExternalFunction(symb_id, alt_args);
}
FirstDerivExternalFunctionNode::FirstDerivExternalFunctionNode(DataTree &datatree_arg,
int top_level_symb_id_arg,
const vector<expr_t> &arguments_arg,

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2014 Dynare Team
* Copyright (C) 2007-2015 Dynare Team
*
* This file is part of Dynare.
*
@ -187,6 +187,9 @@ public:
*/
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const = 0;
//! returns true if the expr node contains an external function
virtual bool containsExternalFunction() const = 0;
//! Writes output of node (with no temporary terms and with "outside model" output type)
void writeOutput(ostream &output) const;
@ -441,6 +444,7 @@ public:
};
virtual void prepareForDerivation();
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual bool containsExternalFunction() const;
virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const;
virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException);
@ -486,6 +490,7 @@ public:
VariableNode(DataTree &datatree_arg, int symb_id_arg, int lag_arg);
virtual void prepareForDerivation();
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual bool containsExternalFunction() const;
virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
virtual void computeTemporaryTerms(map<expr_t, int> &reference_count,
temporary_terms_t &temporary_terms,
@ -552,6 +557,7 @@ public:
virtual void prepareForDerivation();
virtual void computeTemporaryTerms(map<expr_t, int> &reference_count, temporary_terms_t &temporary_terms, bool is_matlab) const;
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual bool containsExternalFunction() const;
virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const;
@ -630,6 +636,7 @@ public:
virtual int precedence(ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const;
virtual void computeTemporaryTerms(map<expr_t, int> &reference_count, temporary_terms_t &temporary_terms, bool is_matlab) const;
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual bool containsExternalFunction() const;
virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const;
@ -724,6 +731,7 @@ public:
virtual int precedence(ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const;
virtual void computeTemporaryTerms(map<expr_t, int> &reference_count, temporary_terms_t &temporary_terms, bool is_matlab) const;
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual bool containsExternalFunction() const;
virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const;
@ -795,6 +803,7 @@ public:
virtual void prepareForDerivation();
virtual void computeTemporaryTerms(map<expr_t, int> &reference_count, temporary_terms_t &temporary_terms, bool is_matlab) const = 0;
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const = 0;
virtual bool containsExternalFunction() const;
virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const = 0;

View File

@ -68,8 +68,14 @@ DynareFlex.cc FlexLexer.h: DynareFlex.ll
DynareBison.cc DynareBison.hh location.hh stack.hh position.hh: DynareBison.yy
$(YACC) -o DynareBison.cc DynareBison.yy
all-local:
cd ../matlab && $(LN_S) -f $(abs_srcdir)/$(PROGRAMS) $(PROGRAMS)
all-local: $(PROGRAMS)
if [ -z "`file $(PROGRAMS) | grep x86.64`" ]; then \
ARCH="32"; \
else \
ARCH="64"; \
fi; \
mkdir -p ../matlab/preprocessor$$ARCH ; \
cd ../matlab/preprocessor$$ARCH && $(LN_S) -f $(abs_srcdir)/$(PROGRAMS) $(PROGRAMS)
if HAVE_DOXYGEN
html-local:
@ -77,7 +83,7 @@ html-local:
endif
clean-local:
cd ../matlab && rm -f $(PROGRAMS)
rm -rf ../matlab/preprocessor*
rm -rf doc/html/
EXTRA_DIST = $(BUILT_SOURCES) Doxyfile

View File

@ -290,7 +290,7 @@ ModFile::checkPass()
// Check if some exogenous is not used in the model block
set<int> unusedExo = dynamic_model.findUnusedExogenous();
if (unusedExo.size() > 1)
if (unusedExo.size() > 0)
{
warnings << "WARNING: some exogenous (";
for (set<int>::const_iterator it = unusedExo.begin();
@ -469,55 +469,55 @@ ModFile::computingPass(bool no_tmp_terms, FileOutputType output)
// Compute static model and its derivatives
dynamic_model.toStatic(static_model);
if (!no_static)
{
if (mod_file_struct.stoch_simul_present
|| mod_file_struct.estimation_present || mod_file_struct.osr_present
|| mod_file_struct.ramsey_model_present || mod_file_struct.identification_present
|| mod_file_struct.calib_smoother_present)
static_model.set_cutoff_to_zero();
{
if (mod_file_struct.stoch_simul_present
|| mod_file_struct.estimation_present || mod_file_struct.osr_present
|| mod_file_struct.ramsey_model_present || mod_file_struct.identification_present
|| mod_file_struct.calib_smoother_present)
static_model.set_cutoff_to_zero();
const bool static_hessian = mod_file_struct.identification_present
|| mod_file_struct.estimation_analytic_derivation;
const bool paramsDerivatives = mod_file_struct.identification_present
|| mod_file_struct.estimation_analytic_derivation;
static_model.computingPass(global_eval_context, no_tmp_terms, static_hessian,
false, paramsDerivatives, block, byte_code);
}
const bool static_hessian = mod_file_struct.identification_present
|| mod_file_struct.estimation_analytic_derivation;
const bool paramsDerivatives = mod_file_struct.identification_present
|| mod_file_struct.estimation_analytic_derivation;
static_model.computingPass(global_eval_context, no_tmp_terms, static_hessian,
false, paramsDerivatives, block, byte_code);
}
// Set things to compute for dynamic model
if (mod_file_struct.perfect_foresight_solver_present || mod_file_struct.check_present
|| mod_file_struct.stoch_simul_present
|| mod_file_struct.estimation_present || mod_file_struct.osr_present
|| mod_file_struct.ramsey_model_present || mod_file_struct.identification_present
|| mod_file_struct.calib_smoother_present)
{
if (mod_file_struct.perfect_foresight_solver_present)
dynamic_model.computingPass(true, false, false, false, global_eval_context, no_tmp_terms, block, use_dll, byte_code);
else
{
if (mod_file_struct.stoch_simul_present
|| mod_file_struct.estimation_present || mod_file_struct.osr_present
|| mod_file_struct.ramsey_model_present || mod_file_struct.identification_present
|| mod_file_struct.calib_smoother_present)
dynamic_model.set_cutoff_to_zero();
if (mod_file_struct.order_option < 1 || mod_file_struct.order_option > 3)
{
cerr << "ERROR: Incorrect order option..." << endl;
exit(EXIT_FAILURE);
}
bool hessian = mod_file_struct.order_option >= 2
|| mod_file_struct.identification_present
|| mod_file_struct.estimation_analytic_derivation
|| output == second
|| output == third;
bool thirdDerivatives = mod_file_struct.order_option == 3
|| mod_file_struct.estimation_analytic_derivation
|| output == third;
bool paramsDerivatives = mod_file_struct.identification_present || mod_file_struct.estimation_analytic_derivation;
dynamic_model.computingPass(true, hessian, thirdDerivatives, paramsDerivatives, global_eval_context, no_tmp_terms, block, use_dll, byte_code);
}
}
else // No computing task requested, compute derivatives up to 2nd order by default
dynamic_model.computingPass(true, true, false, false, global_eval_context, no_tmp_terms, block, use_dll, byte_code);
|| mod_file_struct.stoch_simul_present
|| mod_file_struct.estimation_present || mod_file_struct.osr_present
|| mod_file_struct.ramsey_model_present || mod_file_struct.identification_present
|| mod_file_struct.calib_smoother_present)
{
if (mod_file_struct.perfect_foresight_solver_present)
dynamic_model.computingPass(true, false, false, false, global_eval_context, no_tmp_terms, block, use_dll, byte_code);
else
{
if (mod_file_struct.stoch_simul_present
|| mod_file_struct.estimation_present || mod_file_struct.osr_present
|| mod_file_struct.ramsey_model_present || mod_file_struct.identification_present
|| mod_file_struct.calib_smoother_present)
dynamic_model.set_cutoff_to_zero();
if (mod_file_struct.order_option < 1 || mod_file_struct.order_option > 3)
{
cerr << "ERROR: Incorrect order option..." << endl;
exit(EXIT_FAILURE);
}
bool hessian = mod_file_struct.order_option >= 2
|| mod_file_struct.identification_present
|| mod_file_struct.estimation_analytic_derivation
|| output == second
|| output == third;
bool thirdDerivatives = mod_file_struct.order_option == 3
|| mod_file_struct.estimation_analytic_derivation
|| output == third;
bool paramsDerivatives = mod_file_struct.identification_present || mod_file_struct.estimation_analytic_derivation;
dynamic_model.computingPass(true, hessian, thirdDerivatives, paramsDerivatives, global_eval_context, no_tmp_terms, block, use_dll, byte_code);
}
}
else // No computing task requested, compute derivatives up to 2nd order by default
dynamic_model.computingPass(true, true, false, false, global_eval_context, no_tmp_terms, block, use_dll, byte_code);
}
for (vector<Statement *>::iterator it = statements.begin();
@ -526,7 +526,8 @@ ModFile::computingPass(bool no_tmp_terms, FileOutputType output)
}
void
ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_global, bool no_log, bool no_warn, bool console, bool nograph, bool nointeractive, const ConfigFile &config_file
ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_global, bool no_log, bool no_warn, bool console, bool nograph,
bool nointeractive, const ConfigFile &config_file, bool check_model_changes
#if defined(_WIN32) || defined(__CYGWIN32__)
, bool cygwin, bool msvc
#endif
@ -574,6 +575,9 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
<< "global M_ oo_ options_ ys0_ ex0_ estimation_info" << endl
<< "options_ = [];" << endl
<< "M_.fname = '" << basename << "';" << endl
<< "M_.dynare_version = '" << PACKAGE_VERSION << "';" << endl
<< "oo_.dynare_version = '" << PACKAGE_VERSION << "';" << endl
<< "options_.dynare_version = '" << PACKAGE_VERSION << "';" << endl
<< "%" << endl
<< "% Some global variables initialization" << endl
<< "%" << endl;
@ -592,7 +596,7 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
if (nointeractive)
mOutputFile << "options_.nointeractive = 1;" << endl;
cout << "Processing outputs ...";
cout << "Processing outputs ..." << endl;
symbol_table.writeOutput(mOutputFile);
@ -646,18 +650,25 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
<< " error('DYNARE: Can''t find bytecode DLL. Please compile it or remove the ''bytecode'' option.')" << endl
<< "end" << endl;
// Erase possible remnants of previous runs
unlink((basename + "_dynamic.m").c_str());
unlink((basename + "_dynamic.cod").c_str());
unlink((basename + "_dynamic.bin").c_str());
bool hasModelChanged = !dynamic_model.isChecksumMatching(basename);
if (!check_model_changes)
hasModelChanged = true;
if (hasModelChanged)
{
// Erase possible remnants of previous runs
unlink((basename + "_dynamic.m").c_str());
unlink((basename + "_dynamic.cod").c_str());
unlink((basename + "_dynamic.bin").c_str());
unlink((basename + "_static.m").c_str());
unlink((basename + "_static.cod").c_str());
unlink((basename + "_static.bin").c_str());
unlink((basename + "_steadystate2.m").c_str());
unlink((basename + "_set_auxiliary_variables.m").c_str());
unlink((basename + "_static.m").c_str());
unlink((basename + "_static.cod").c_str());
unlink((basename + "_static.bin").c_str());
unlink((basename + "_steadystate2.m").c_str());
unlink((basename + "_set_auxiliary_variables.m").c_str());
}
if (!use_dll)
{
mOutputFile << "erase_compiled_function('" + basename + "_static');" << endl;
@ -692,55 +703,22 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
#endif
// Compile the dynamic MEX file for use_dll option
// When check_model_changes is true, don't force compile if MEX is fresher than source
if (use_dll)
{
mOutputFile << "if ~exist('OCTAVE_VERSION')" << endl;
// Some mex commands are enclosed in an eval(), because otherwise it will make Octave fail
#if defined(_WIN32) || defined(__CYGWIN32__)
if (msvc)
// MATLAB/Windows + Microsoft Visual C++
mOutputFile << " eval('mex -O LINKFLAGS=\"$LINKFLAGS /export:Dynamic\" " << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl
<< " eval('mex -O LINKFLAGS=\"$LINKFLAGS /export:Static\" " << basename << "_static.c "<< basename << "_static_mex.c')" << endl;
mOutputFile << "dyn_mex('msvc', '" << basename << "', " << !check_model_changes << ")" << endl;
else if (cygwin)
// MATLAB/Windows + Cygwin g++
mOutputFile << " eval('mex -O PRELINK_CMDS1=\"echo EXPORTS > mex.def & echo mexFunction >> mex.def & echo Dynamic >> mex.def\" " << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl
<< " eval('mex -O PRELINK_CMDS1=\"echo EXPORTS > mex.def & echo mexFunction >> mex.def & echo Static >> mex.def\" " << basename << "_static.c "<< basename << "_static_mex.c')" << endl;
mOutputFile << "dyn_mex('cygwin', '" << basename << "', " << !check_model_changes << ")" << endl;
else
mOutputFile << " error('When using the USE_DLL option, you must give either ''cygwin'' or ''msvc'' option to the ''dynare'' command')" << endl;
#else
# ifdef __linux__
// MATLAB/Linux
mOutputFile << " if matlab_ver_less_than('8.3')" << endl
<< " eval('mex -O LDFLAGS=''-pthread -shared -Wl,--no-undefined'' " << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl
<< " eval('mex -O LDFLAGS=''-pthread -shared -Wl,--no-undefined'' " << basename << "_static.c "<< basename << "_static_mex.c')" << endl
<< " else" << endl
<< " eval('mex -O LINKEXPORT='''' " << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl
<< " eval('mex -O LINKEXPORT='''' " << basename << "_static.c "<< basename << "_static_mex.c')" << endl
<< " end" << endl;
# else // MacOS
// MATLAB/MacOS
mOutputFile << " if matlab_ver_less_than('8.3')" << endl
<< " if matlab_ver_less_than('8.1')" << endl
<< " eval('mex -O LDFLAGS=''-Wl,-twolevel_namespace -undefined error -arch \\$ARCHS -Wl,-syslibroot,\\$SDKROOT -mmacosx-version-min=\\$MACOSX_DEPLOYMENT_TARGET -bundle'' "
<< basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl
<< " eval('mex -O LDFLAGS=''-Wl,-twolevel_namespace -undefined error -arch \\$ARCHS -Wl,-syslibroot,\\$SDKROOT -mmacosx-version-min=\\$MACOSX_DEPLOYMENT_TARGET -bundle'' "
<< basename << "_static.c " << basename << "_static_mex.c')" << endl
<< " else" << endl
<< " eval('mex -O LDFLAGS=''-Wl,-twolevel_namespace -undefined error -arch \\$ARCHS -Wl,-syslibroot,\\$MW_SDKROOT -mmacosx-version-min=\\$MACOSX_DEPLOYMENT_TARGET -bundle'' "
<< basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl
<< " eval('mex -O LDFLAGS=''-Wl,-twolevel_namespace -undefined error -arch \\$ARCHS -Wl,-syslibroot,\\$MW_SDKROOT -mmacosx-version-min=\\$MACOSX_DEPLOYMENT_TARGET -bundle'' "
<< basename << "_static.c " << basename << "_static_mex.c')" << endl
<< " end" << endl
<< " else" << endl
<< " eval('mex -O LINKEXPORT='''' " << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl
<< " eval('mex -O LINKEXPORT='''' " << basename << "_static.c "<< basename << "_static_mex.c')" << endl
<< " end" << endl;
# endif
// other configurations
mOutputFile << "dyn_mex('', '" << basename << "', " << !check_model_changes << ")" << endl;
#endif
mOutputFile << "else" << endl // Octave
<< " mex " << basename << "_dynamic.c " << basename << "_dynamic_mex.c" << endl
<< " mex " << basename << "_static.c " << basename << "_static_mex.c" << endl
<< "end" << endl;
}
// Add path for block option with M-files
@ -821,22 +799,24 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
mOutputFile.close();
// Create static and dynamic files
if (dynamic_model.equation_number() > 0)
if (hasModelChanged)
{
if (!no_static)
{
static_model.writeStaticFile(basename, block, byte_code, use_dll);
static_model.writeParamsDerivativesFile(basename);
}
// Create static and dynamic files
if (dynamic_model.equation_number() > 0)
{
if (!no_static)
{
static_model.writeStaticFile(basename, block, byte_code, use_dll);
static_model.writeParamsDerivativesFile(basename);
}
dynamic_model.writeDynamicFile(basename, block, byte_code, use_dll, mod_file_struct.order_option);
dynamic_model.writeParamsDerivativesFile(basename);
dynamic_model.writeDynamicFile(basename, block, byte_code, use_dll, mod_file_struct.order_option);
dynamic_model.writeParamsDerivativesFile(basename);
}
// Create steady state file
steady_state_model.writeSteadyStateFile(basename, mod_file_struct.ramsey_model_present);
}
// Create steady state file
steady_state_model.writeSteadyStateFile(basename, mod_file_struct.ramsey_model_present);
cout << "done" << endl;
}

View File

@ -24,6 +24,8 @@ using namespace std;
#include <ostream>
#include <ctime>
#include <iostream>
#include <sstream>
#include "SymbolTable.hh"
#include "NumericalConstants.hh"
@ -37,6 +39,11 @@ using namespace std;
#include "WarningConsolidation.hh"
#include "ExtendedPreprocessorTypes.hh"
// for checksum computation
#ifndef PRIVATE_BUFFER_SIZE
#define PRIVATE_BUFFER_SIZE 1024
#endif
//! The abstract representation of a "mod" file
class ModFile
{
@ -138,7 +145,8 @@ public:
\param cygwin Should the MEX command of use_dll be adapted for Cygwin?
\param msvc Should the MEX command of use_dll be adapted for MSVC?
*/
void writeOutputFiles(const string &basename, bool clear_all, bool clear_global, bool no_log, bool no_warn, bool console, bool nograph, bool nointeractive, const ConfigFile &config_file
void writeOutputFiles(const string &basename, bool clear_all, bool clear_global, bool no_log, bool no_warn,
bool console, bool nograph, bool nointeractive, const ConfigFile &config_file, bool check_model_changes
#if defined(_WIN32) || defined(__CYGWIN32__)
, bool cygwin, bool msvc
#endif
@ -153,6 +161,8 @@ public:
//! Writes Cpp output files only => No further Matlab processing
void writeCCOutputFiles(const string &basename) const;
void writeModelCC(const string &basename) const;
void computeChecksum();
};
#endif // ! MOD_FILE_HH

View File

@ -1186,8 +1186,7 @@ ParsingDriver::add_in_symbol_list(string *tmp_var)
void
ParsingDriver::rplot()
{
mod_file->addStatement(new RplotStatement(symbol_list, options_list));
options_list.clear();
mod_file->addStatement(new RplotStatement(symbol_list));
symbol_list.clear();
}
@ -1410,6 +1409,26 @@ ParsingDriver::set_prior(string *name, string *subsample_name)
delete subsample_name;
}
void
ParsingDriver::set_joint_prior(vector<string *>*symbol_vec)
{
for (vector<string *>::const_iterator it=symbol_vec->begin(); it != symbol_vec->end(); it++)
add_joint_parameter(*it);
mod_file->addStatement(new JointPriorStatement(joint_parameters, prior_shape, options_list));
joint_parameters.clear();
options_list.clear();
prior_shape = eNoShape;
delete symbol_vec;
}
void
ParsingDriver::add_joint_parameter(string *name)
{
check_symbol_is_parameter(name);
joint_parameters.push_back(*name);
delete name;
}
void
ParsingDriver::set_prior_variance(expr_t variance)
{
@ -1611,6 +1630,34 @@ ParsingDriver::optim_options_num(string *name, string *value)
delete value;
}
void
ParsingDriver::tarb_optim_options_helper(const string &name)
{
if (options_list.string_options.find("TaRB.optim_opt") == options_list.string_options.end())
options_list.string_options["TaRB.optim_opt"] = "";
else
options_list.string_options["TaRB.optim_opt"] += ",";
options_list.string_options["TaRB.optim_opt"] += "''" + name + "'',";
}
void
ParsingDriver::tarb_optim_options_string(string *name, string *value)
{
tarb_optim_options_helper(*name);
options_list.string_options["TaRB.optim_opt"] += "''" + *value + "''";
delete name;
delete value;
}
void
ParsingDriver::tarb_optim_options_num(string *name, string *value)
{
tarb_optim_options_helper(*name);
options_list.string_options["TaRB.optim_opt"] += *value;
delete name;
delete value;
}
void
ParsingDriver::check_varobs()
{

View File

@ -98,6 +98,7 @@ private:
//! Creates option "optim_opt" in OptionsList if it doesn't exist, else add a comma, and adds the option name
void optim_options_helper(const string &name);
void tarb_optim_options_helper(const string &name);
//! Stores temporary symbol table
SymbolList symbol_list;
@ -186,6 +187,8 @@ private:
//! Temporary storage for argument list of external function
stack<vector<expr_t> > stack_external_function_args;
//! Temporary storage for parameters in joint prior statement
vector<string> joint_parameters;
//! Temporary storage for the symb_id associated with the "name" symbol of the current external_function statement
int current_external_function_id;
//! Temporary storage for option list provided to external_function()
@ -411,6 +414,10 @@ public:
void estimation_data();
//! Sets the prior for a parameter
void set_prior(string *arg1, string *arg2);
//! Sets the joint prior for a set of parameters
void set_joint_prior(vector<string *>*symbol_vec);
//! Adds a parameters to the list of joint parameters
void add_joint_parameter(string *name);
//! Adds the variance option to its temporary holding place
void set_prior_variance(expr_t variance=NULL);
//! Copies the prior from_name to_name
@ -437,6 +444,10 @@ public:
void optim_options_string(string *name, string *value);
//! Adds an optimization option (numeric value)
void optim_options_num(string *name, string *value);
//! Adds a TaRB optimization option (string value)
void tarb_optim_options_string(string *name, string *value);
//! Adds a TaRB optimization option (numeric value)
void tarb_optim_options_num(string *name, string *value);
//! Check that no observed variable has yet be defined
void check_varobs();
//! Add a new observed variable

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 Dynare Team
* Copyright (C) 2003-2015 Dynare Team
*
* This file is part of Dynare.
*
@ -1927,9 +1927,16 @@ void StaticModel::writeAuxVarRecursiveDefinitions(const string &basename) const
<< "% from model file (.mod)" << endl
<< endl;
deriv_node_temp_terms_t tef_terms;
temporary_terms_t temporary_terms;
for (int i = 0; i < (int) aux_equations.size(); i++)
if (dynamic_cast<ExprNode *>(aux_equations[i])->containsExternalFunction())
dynamic_cast<ExprNode *>(aux_equations[i])->writeExternalFunctionOutput(output, oMatlabStaticModel,
temporary_terms, tef_terms);
for (int i = 0; i < (int) aux_equations.size(); i++)
{
dynamic_cast<ExprNode *>(aux_equations[i])->writeOutput(output, oMatlabStaticModel);
dynamic_cast<ExprNode *>(aux_equations[i])->writeOutput(output, oMatlabStaticModel, temporary_terms, tef_terms);
output << ";" << endl;
}
}

View File

@ -84,6 +84,32 @@ CONT \\\\
BEGIN(INITIAL);
}
<INITIAL>^{SPC}*@#{SPC}*include{SPC}+[^\"\r\n]*{SPC}*{EOL} {
yylloc->lines(1);
yylloc->step();
// Get variable name
string modvarname = string(yytext);
int dblq_idx1 = modvarname.find("include");
modvarname.erase(0, dblq_idx1 + 7);
modvarname.erase(0, modvarname.find_first_not_of(" \t"));
size_t p = modvarname.find_last_not_of(" \t\n\r");
if (string::npos != p)
modvarname.erase(p+1);
string *filename = NULL;
try
{
filename = new string(driver.get_variable(modvarname)->toString());
}
catch(MacroDriver::UnknownVariable(&e))
{
driver.error(*yylloc, "Unknown variable: " + modvarname);
}
create_include_context(filename, yylloc, driver);
BEGIN(INITIAL);
}
<INITIAL>^{SPC}*@# { yylloc->step(); BEGIN(STMT); }
<INITIAL>@\{ { yylloc->step(); BEGIN(EXPR); }