2008-02-03 11:28:36 +01:00
/*
2019-04-16 11:35:31 +02:00
* Copyright © 2006 - 2019 Dynare Team
2008-02-03 11:28:36 +01:00
*
* This file is part of Dynare .
*
* Dynare is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* Dynare is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with Dynare . If not , see < http : //www.gnu.org/licenses/>.
*/
2008-06-28 13:20:45 +02:00
# include <cstdlib>
2008-02-03 11:28:36 +01:00
# include <iostream>
# include <fstream>
2008-12-19 11:24:31 +01:00
# include <typeinfo>
2011-03-21 18:40:57 +01:00
# include <cassert>
2019-04-04 17:01:37 +02:00
# include <random>
2018-06-27 15:01:31 +02:00
2019-04-04 17:01:37 +02:00
# include <filesystem>
2012-05-08 16:02:22 +02:00
2008-02-03 11:28:36 +01:00
# include "ModFile.hh"
2010-10-25 18:20:58 +02:00
# include "ConfigFile.hh"
2011-03-21 18:40:57 +01:00
# include "ComputingTasks.hh"
2018-11-07 15:24:57 +01:00
# include "Shocks.hh"
2008-02-03 11:28:36 +01:00
2013-02-26 16:50:05 +01:00
ModFile : : ModFile ( WarningConsolidation & warnings_arg )
2018-10-04 17:18:27 +02:00
: var_model_table { symbol_table } ,
trend_component_model_table { symbol_table } ,
expressions_tree { symbol_table , num_constants , external_functions_table } ,
original_model { symbol_table , num_constants , external_functions_table ,
trend_component_model_table , var_model_table } ,
dynamic_model { symbol_table , num_constants , external_functions_table ,
trend_component_model_table , var_model_table } ,
trend_dynamic_model { symbol_table , num_constants , external_functions_table ,
trend_component_model_table , var_model_table } ,
ramsey_FOC_equations_dynamic_model { symbol_table , num_constants , external_functions_table ,
trend_component_model_table , var_model_table } ,
orig_ramsey_dynamic_model { symbol_table , num_constants , external_functions_table ,
trend_component_model_table , var_model_table } ,
non_linear_equations_dynamic_model { symbol_table , num_constants , external_functions_table ,
trend_component_model_table , var_model_table } ,
epilogue { symbol_table , num_constants , external_functions_table ,
trend_component_model_table , var_model_table } ,
static_model { symbol_table , num_constants , external_functions_table } ,
steady_state_model { symbol_table , num_constants , external_functions_table , static_model } ,
diff_static_model { symbol_table , num_constants , external_functions_table } ,
warnings { warnings_arg }
2008-02-03 11:28:36 +01:00
{
}
2008-12-19 11:24:31 +01:00
void
2018-12-20 17:04:28 +01:00
ModFile : : evalAllExpressions ( bool warn_uninit )
2008-12-19 11:24:31 +01:00
{
2018-12-20 17:04:28 +01:00
cout < < " Evaluating expressions... " ;
2008-12-31 20:29:17 +01:00
2009-02-27 13:19:25 +01:00
// Loop over all statements, and fill global eval context if relevant
2018-09-05 15:17:21 +02:00
for ( auto & st : statements )
2008-12-19 11:24:31 +01:00
{
2018-09-05 15:17:21 +02:00
auto ips = dynamic_cast < InitParamStatement * > ( st . get ( ) ) ;
2009-02-27 13:19:25 +01:00
if ( ips )
ips - > fillEvalContext ( global_eval_context ) ;
2018-09-05 15:17:21 +02:00
auto ies = dynamic_cast < InitOrEndValStatement * > ( st . get ( ) ) ;
2009-02-27 13:19:25 +01:00
if ( ies )
ies - > fillEvalContext ( global_eval_context ) ;
2018-09-05 15:17:21 +02:00
auto lpass = dynamic_cast < LoadParamsAndSteadyStateStatement * > ( st . get ( ) ) ;
2009-02-27 13:19:25 +01:00
if ( lpass )
lpass - > fillEvalContext ( global_eval_context ) ;
2008-12-19 11:24:31 +01:00
}
2009-02-27 13:19:25 +01:00
// Evaluate model local variables
2009-04-14 16:39:53 +02:00
dynamic_model . fillEvalContext ( global_eval_context ) ;
2009-02-27 13:19:25 +01:00
2018-12-20 17:04:28 +01:00
cout < < " done " < < endl ;
2009-02-27 13:19:25 +01:00
// Check if some symbols are not initialized, and give them a zero value then
2009-12-16 18:13:23 +01:00
for ( int id = 0 ; id < = symbol_table . maxID ( ) ; id + + )
2008-12-19 11:24:31 +01:00
{
2009-02-27 13:19:25 +01:00
SymbolType type = symbol_table . getType ( id ) ;
2018-07-17 18:34:07 +02:00
if ( ( type = = SymbolType : : endogenous | | type = = SymbolType : : exogenous | | type = = SymbolType : : exogenousDet
| | type = = SymbolType : : parameter | | type = = SymbolType : : modelLocalVariable )
2009-02-27 13:19:25 +01:00
& & global_eval_context . find ( id ) = = global_eval_context . end ( ) )
2008-12-19 11:24:31 +01:00
{
2009-11-06 19:31:03 +01:00
if ( warn_uninit )
2012-01-23 16:52:27 +01:00
warnings < < " WARNING: Can't find a numeric initial value for "
< < symbol_table . getName ( id ) < < " , using zero " < < endl ;
2009-02-27 13:19:25 +01:00
global_eval_context [ id ] = 0 ;
2008-12-19 11:24:31 +01:00
}
}
}
2008-02-03 11:28:36 +01:00
void
2018-09-05 15:17:21 +02:00
ModFile : : addStatement ( unique_ptr < Statement > st )
2008-02-03 11:28:36 +01:00
{
2018-09-05 15:17:21 +02:00
statements . push_back ( move ( st ) ) ;
2008-02-03 11:28:36 +01:00
}
2010-06-24 15:07:15 +02:00
void
2018-09-05 15:17:21 +02:00
ModFile : : addStatementAtFront ( unique_ptr < Statement > st )
2010-06-24 15:07:15 +02:00
{
2018-09-05 15:17:21 +02:00
statements . insert ( statements . begin ( ) , move ( st ) ) ;
2010-06-24 15:07:15 +02:00
}
2008-02-03 11:28:36 +01:00
void
2017-08-31 10:19:43 +02:00
ModFile : : checkPass ( bool nostrict , bool stochastic )
2008-02-03 11:28:36 +01:00
{
2018-06-04 12:26:16 +02:00
for ( auto & statement : statements )
statement - > checkPass ( mod_file_struct , warnings ) ;
2008-02-03 11:28:36 +01:00
2010-05-31 17:43:17 +02:00
// Check the steady state block
2017-08-30 15:46:17 +02:00
steady_state_model . checkPass ( mod_file_struct , warnings ) ;
2018-09-03 17:16:28 +02:00
// Check epilogue block
epilogue . checkPass ( warnings ) ;
2017-08-30 15:46:17 +02:00
if ( mod_file_struct . write_latex_steady_state_model_present & &
! mod_file_struct . steady_state_model_present )
{
cerr < < " ERROR: You cannot have a write_latex_steady_state_model statement without a steady_state_model block. " < < endl ;
exit ( EXIT_FAILURE ) ;
}
2010-05-31 17:43:17 +02:00
2008-04-24 12:55:26 +02:00
// If order option has not been set, default to 2
if ( ! mod_file_struct . order_option )
mod_file_struct . order_option = 2 ;
2015-07-30 14:40:03 +02:00
param_used_with_lead_lag = dynamic_model . ParamUsedWithLeadLag ( ) ;
if ( param_used_with_lead_lag )
warnings < < " WARNING: A parameter was used with a lead or a lag in the model block " < < endl ;
2008-09-29 12:16:13 +02:00
bool stochastic_statement_present = mod_file_struct . stoch_simul_present
| | mod_file_struct . estimation_present
| | mod_file_struct . osr_present
2011-03-17 15:15:13 +01:00
| | mod_file_struct . ramsey_policy_present
2013-10-28 14:22:23 +01:00
| | mod_file_struct . discretionary_policy_present
2017-08-31 10:19:43 +02:00
| | mod_file_struct . calib_smoother_present
2019-01-09 14:48:25 +01:00
| | mod_file_struct . identification_present
| | mod_file_struct . sensitivity_present
2017-08-31 10:19:43 +02:00
| | stochastic ;
2008-09-29 12:16:13 +02:00
2008-02-03 11:28:36 +01:00
// Allow empty model only when doing a standalone BVAR estimation
2009-04-14 16:39:53 +02:00
if ( dynamic_model . equation_number ( ) = = 0
2008-02-03 11:28:36 +01:00
& & ( mod_file_struct . check_present
2014-04-09 17:57:17 +02:00
| | mod_file_struct . perfect_foresight_solver_present
2008-09-29 12:16:13 +02:00
| | stochastic_statement_present ) )
{
cerr < < " ERROR: At least one model equation must be declared! " < < endl ;
2008-10-29 16:33:16 +01:00
exit ( EXIT_FAILURE ) ;
2008-09-29 12:16:13 +02:00
}
2015-09-03 17:04:34 +02:00
if ( ( mod_file_struct . ramsey_model_present | | mod_file_struct . ramsey_policy_present )
& & mod_file_struct . discretionary_policy_present )
{
2017-04-06 08:41:12 +02:00
cerr < < " ERROR: You cannot use the discretionary_policy command when you use either ramsey_model or ramsey_policy and vice versa " < < endl ;
2015-09-03 17:04:34 +02:00
exit ( EXIT_FAILURE ) ;
}
2017-06-01 19:58:32 +02:00
if ( ( ( mod_file_struct . ramsey_model_present | | mod_file_struct . discretionary_policy_present )
2011-03-17 15:15:13 +01:00
& & ! mod_file_struct . planner_objective_present )
2014-03-09 09:52:44 +01:00
| | ( ! ( mod_file_struct . ramsey_model_present | | mod_file_struct . discretionary_policy_present )
2017-06-01 19:58:32 +02:00
& & mod_file_struct . planner_objective_present ) )
2011-03-03 16:03:21 +01:00
{
2014-03-09 09:52:44 +01:00
cerr < < " ERROR: A planner_objective statement must be used with a ramsey_model, a ramsey_policy or a discretionary_policy statement and vice versa. " < < endl ;
2011-03-03 16:03:21 +01:00
exit ( EXIT_FAILURE ) ;
}
2011-03-03 16:30:53 +01:00
if ( ( mod_file_struct . osr_present & & ( ! mod_file_struct . osr_params_present | | ! mod_file_struct . optim_weights_present ) )
| | ( ( ! mod_file_struct . osr_present | | ! mod_file_struct . osr_params_present ) & & mod_file_struct . optim_weights_present )
| | ( ( ! mod_file_struct . osr_present | | ! mod_file_struct . optim_weights_present ) & & mod_file_struct . osr_params_present ) )
{
cerr < < " ERROR: The osr statement must be used with osr_params and optim_weights. " < < endl ;
exit ( EXIT_FAILURE ) ;
}
2014-04-09 17:57:17 +02:00
if ( mod_file_struct . perfect_foresight_solver_present & & stochastic_statement_present )
2008-02-03 11:28:36 +01:00
{
2014-04-09 17:57:17 +02:00
cerr < < " ERROR: A .mod file cannot contain both one of {perfect_foresight_solver,simul} and one of {stoch_simul, estimation, osr, ramsey_policy, discretionary_policy}. This is not possible: one cannot mix perfect foresight context with stochastic context in the same file. " < < endl ;
2008-10-29 16:33:16 +01:00
exit ( EXIT_FAILURE ) ;
2008-02-03 11:28:36 +01:00
}
2010-12-17 18:34:23 +01:00
if ( mod_file_struct . k_order_solver & & byte_code )
2009-12-09 12:50:58 +01:00
{
2010-12-17 18:34:23 +01:00
cerr < < " ERROR: 'k_order_solver' (which is implicit if order >= 3), is not yet compatible with 'bytecode'. " < < endl ;
2009-12-09 12:50:58 +01:00
exit ( EXIT_FAILURE ) ;
}
2018-09-21 17:13:19 +02:00
if ( use_dll & & ( block | | byte_code | | linear_decomposition ) )
{
cerr < < " ERROR: In 'model' block, 'use_dll' option is not compatible with 'block', 'bytecode' or 'linear_decomposition' " < < endl ;
exit ( EXIT_FAILURE ) ;
}
if ( block & & linear_decomposition )
{
cerr < < " ERROR: In 'model' block, 'block' option is not compatible with 'linear_decomposition' " < < endl ;
exit ( EXIT_FAILURE ) ;
}
if ( ! byte_code & & linear_decomposition )
2009-09-02 15:36:56 +02:00
{
2018-09-21 17:13:19 +02:00
cerr < < " ERROR: For the moment in 'model' block, 'linear_decomposition' option is compatible only with 'bytecode' option " < < endl ;
2009-09-02 15:36:56 +02:00
exit ( EXIT_FAILURE ) ;
}
2011-10-14 14:35:32 +02:00
if ( block | | byte_code )
if ( dynamic_model . isModelLocalVariableUsed ( ) )
{
cerr < < " ERROR: In 'model' block, 'block' or 'bytecode' options are not yet compatible with pound expressions " < < endl ;
exit ( EXIT_FAILURE ) ;
}
2011-02-04 16:25:38 +01:00
if ( ( stochastic_statement_present | | mod_file_struct . check_present | | mod_file_struct . steady_present ) & & no_static )
2010-01-08 12:06:25 +01:00
{
2011-03-17 15:15:13 +01:00
cerr < < " ERROR: no_static option is incompatible with stoch_simul, estimation, osr, ramsey_policy, discretionary_policy, steady and check commands " < < endl ;
2010-01-08 12:06:25 +01:00
exit ( EXIT_FAILURE ) ;
}
2010-02-22 17:33:38 +01:00
2010-06-11 21:19:30 +02:00
if ( mod_file_struct . dsge_var_estimated )
if ( ! mod_file_struct . dsge_prior_weight_in_estimated_params )
{
cerr < < " ERROR: When estimating a DSGE-VAR model and estimating the weight of the prior, dsge_prior_weight must "
< < " be referenced in the estimated_params block. " < < endl ;
exit ( EXIT_FAILURE ) ;
}
2010-06-21 18:40:36 +02:00
if ( symbol_table . exists ( " dsge_prior_weight " ) )
{
2018-07-17 18:34:07 +02:00
if ( symbol_table . getType ( " dsge_prior_weight " ) ! = SymbolType : : parameter )
2010-06-21 18:40:36 +02:00
{
cerr < < " ERROR: dsge_prior_weight may only be used as a parameter. " < < endl ;
exit ( EXIT_FAILURE ) ;
}
else
2012-01-23 16:52:27 +01:00
warnings < < " WARNING: When estimating a DSGE-Var, declaring dsge_prior_weight as a "
< < " parameter is deprecated. The preferred method is to do this via "
< < " the dsge_var option in the estimation statement. " < < endl ;
2010-06-21 18:40:36 +02:00
if ( mod_file_struct . dsge_var_estimated | | ! mod_file_struct . dsge_var_calibrated . empty ( ) )
{
cerr < < " ERROR: dsge_prior_weight can either be declared as a parameter (deprecated) or via the dsge_var option "
< < " to the estimation statement (preferred), but not both. " < < endl ;
exit ( EXIT_FAILURE ) ;
}
if ( ! mod_file_struct . dsge_prior_weight_initialized & & ! mod_file_struct . dsge_prior_weight_in_estimated_params )
{
cerr < < " ERROR: If dsge_prior_weight is declared as a parameter, it must either be initialized or placed in the "
< < " estimated_params block. " < < endl ;
exit ( EXIT_FAILURE ) ;
}
if ( mod_file_struct . dsge_prior_weight_initialized & & mod_file_struct . dsge_prior_weight_in_estimated_params )
{
2017-06-28 15:06:54 +02:00
cerr < < " ERROR: dsge_prior_weight cannot be both initialized and estimated. " < < endl ;
2010-06-21 18:40:36 +02:00
exit ( EXIT_FAILURE ) ;
}
}
2010-06-11 21:19:30 +02:00
if ( mod_file_struct . dsge_prior_weight_in_estimated_params )
2010-06-21 18:40:36 +02:00
if ( ! mod_file_struct . dsge_var_estimated & & ! mod_file_struct . dsge_var_calibrated . empty ( ) )
2010-06-11 21:19:30 +02:00
{
2010-06-21 18:40:36 +02:00
cerr < < " ERROR: If dsge_prior_weight is in the estimated_params block, the prior weight cannot be calibrated "
2010-06-11 21:19:30 +02:00
< < " via the dsge_var option in the estimation statement. " < < endl ;
exit ( EXIT_FAILURE ) ;
}
2010-06-21 18:40:36 +02:00
else if ( ! mod_file_struct . dsge_var_estimated & & ! symbol_table . exists ( " dsge_prior_weight " ) )
{
cerr < < " ERROR: If dsge_prior_weight is in the estimated_params block, it must either be declared as a parameter "
< < " (deprecated) or the dsge_var option must be passed to the estimation statement (preferred). " < < endl ;
exit ( EXIT_FAILURE ) ;
}
2013-04-11 17:07:39 +02:00
if ( dynamic_model . staticOnlyEquationsNbr ( ) ! = dynamic_model . dynamicOnlyEquationsNbr ( ) )
{
cerr < < " ERROR: the number of equations marked [static] must be equal to the number of equations marked [dynamic] " < < endl ;
exit ( EXIT_FAILURE ) ;
}
2017-06-01 19:58:32 +02:00
if ( dynamic_model . staticOnlyEquationsNbr ( ) > 0
& & ( mod_file_struct . ramsey_model_present | | mod_file_struct . discretionary_policy_present ) )
2013-04-11 17:07:39 +02:00
{
2014-03-09 09:52:44 +01:00
cerr < < " ERROR: marking equations as [static] or [dynamic] is not possible with ramsey_model, ramsey_policy or discretionary_policy " < < endl ;
2013-04-11 17:07:39 +02:00
exit ( EXIT_FAILURE ) ;
}
2013-05-17 14:14:15 +02:00
2017-06-01 19:58:32 +02:00
if ( stochastic_statement_present
2018-07-18 16:18:26 +02:00
& & ( dynamic_model . isUnaryOpUsed ( UnaryOpcode : : sign )
| | dynamic_model . isUnaryOpUsed ( UnaryOpcode : : abs )
| | dynamic_model . isBinaryOpUsed ( BinaryOpcode : : max )
| | dynamic_model . isBinaryOpUsed ( BinaryOpcode : : min )
| | dynamic_model . isBinaryOpUsed ( BinaryOpcode : : greater )
| | dynamic_model . isBinaryOpUsed ( BinaryOpcode : : less )
| | dynamic_model . isBinaryOpUsed ( BinaryOpcode : : greaterEqual )
| | dynamic_model . isBinaryOpUsed ( BinaryOpcode : : lessEqual )
| | dynamic_model . isBinaryOpUsed ( BinaryOpcode : : equalEqual )
| | dynamic_model . isBinaryOpUsed ( BinaryOpcode : : different ) ) )
2019-04-03 16:32:52 +02:00
warnings < < R " (WARNING: you are using a function (max, min, abs, sign) or an operator (<, >, <=, >=, ==, !=) which is unsuitable for a stochastic context; see the reference manual, section about " Expressions " , for more details.) " < < endl ;
2013-11-29 14:50:58 +01:00
2017-06-01 19:58:32 +02:00
if ( linear
2019-09-10 12:37:11 +02:00
& & ( dynamic_model . isUnaryOpUsedOnType ( SymbolType : : endogenous , UnaryOpcode : : sign )
| | dynamic_model . isUnaryOpUsedOnType ( SymbolType : : endogenous , UnaryOpcode : : abs )
| | dynamic_model . isBinaryOpUsedOnType ( SymbolType : : endogenous , BinaryOpcode : : max )
| | dynamic_model . isBinaryOpUsedOnType ( SymbolType : : endogenous , BinaryOpcode : : min )
| | dynamic_model . isBinaryOpUsedOnType ( SymbolType : : endogenous , BinaryOpcode : : greater )
| | dynamic_model . isBinaryOpUsedOnType ( SymbolType : : endogenous , BinaryOpcode : : less )
| | dynamic_model . isBinaryOpUsedOnType ( SymbolType : : endogenous , BinaryOpcode : : greaterEqual )
| | dynamic_model . isBinaryOpUsedOnType ( SymbolType : : endogenous , BinaryOpcode : : lessEqual )
| | dynamic_model . isBinaryOpUsedOnType ( SymbolType : : endogenous , BinaryOpcode : : equalEqual )
| | dynamic_model . isBinaryOpUsedOnType ( SymbolType : : endogenous , BinaryOpcode : : different ) ) )
{
cerr < < " ERROR: you have declared your model 'linear' but you are using a function "
< < " (max, min, abs, sign) or an operator (<, >, <=, >=, ==, !=) on an "
< < " endogenous variable. " < < endl ;
exit ( EXIT_FAILURE ) ;
}
if ( linear
& & ! mod_file_struct . perfect_foresight_solver_present
& & ( dynamic_model . isUnaryOpUsedOnType ( SymbolType : : exogenous , UnaryOpcode : : sign )
| | dynamic_model . isUnaryOpUsedOnType ( SymbolType : : exogenous , UnaryOpcode : : abs )
| | dynamic_model . isBinaryOpUsedOnType ( SymbolType : : exogenous , BinaryOpcode : : max )
| | dynamic_model . isBinaryOpUsedOnType ( SymbolType : : exogenous , BinaryOpcode : : min )
| | dynamic_model . isBinaryOpUsedOnType ( SymbolType : : exogenous , BinaryOpcode : : greater )
| | dynamic_model . isBinaryOpUsedOnType ( SymbolType : : exogenous , BinaryOpcode : : less )
| | dynamic_model . isBinaryOpUsedOnType ( SymbolType : : exogenous , BinaryOpcode : : greaterEqual )
| | dynamic_model . isBinaryOpUsedOnType ( SymbolType : : exogenous , BinaryOpcode : : lessEqual )
| | dynamic_model . isBinaryOpUsedOnType ( SymbolType : : exogenous , BinaryOpcode : : equalEqual )
| | dynamic_model . isBinaryOpUsedOnType ( SymbolType : : exogenous , BinaryOpcode : : different ) ) )
{
cerr < < " ERROR: you have declared your model 'linear' but you are using a function "
< < " (max, min, abs, sign) or an operator (<, >, <=, >=, ==, !=) on an "
< < " exogenous variable in a non-perfect-foresight context. " < < endl ;
exit ( EXIT_FAILURE ) ;
}
2017-04-05 11:07:34 +02:00
2013-11-29 14:50:58 +01:00
// Test if some estimated parameters are used within the values of shocks
// statements (see issue #469)
set < int > parameters_intersect ;
set_intersection ( mod_file_struct . parameters_within_shocks_values . begin ( ) ,
mod_file_struct . parameters_within_shocks_values . end ( ) ,
mod_file_struct . estimated_parameters . begin ( ) ,
mod_file_struct . estimated_parameters . end ( ) ,
inserter ( parameters_intersect , parameters_intersect . begin ( ) ) ) ;
if ( parameters_intersect . size ( ) > 0 )
{
cerr < < " ERROR: some estimated parameters ( " ;
2018-06-04 15:03:26 +02:00
for ( auto it = parameters_intersect . begin ( ) ;
2017-06-01 19:58:32 +02:00
it ! = parameters_intersect . end ( ) ; )
2013-11-29 14:50:58 +01:00
{
cerr < < symbol_table . getName ( * it ) ;
if ( + + it ! = parameters_intersect . end ( ) )
cerr < < " , " ;
}
cerr < < " ) also appear in the expressions defining the variance/covariance matrix of shocks; this is not allowed. " < < endl ;
exit ( EXIT_FAILURE ) ;
}
2013-11-29 16:03:15 +01:00
2015-08-24 12:54:05 +02:00
// Check if some exogenous is not used in the model block, Issue #841
2018-03-28 18:46:15 +02:00
set < int > unusedExo0 = dynamic_model . findUnusedExogenous ( ) ;
set < int > unusedExo ;
set_difference ( unusedExo0 . begin ( ) , unusedExo0 . end ( ) ,
mod_file_struct . pac_params . begin ( ) , mod_file_struct . pac_params . end ( ) ,
inserter ( unusedExo , unusedExo . begin ( ) ) ) ;
2015-03-06 09:49:11 +01:00
if ( unusedExo . size ( ) > 0 )
2013-11-29 16:03:15 +01:00
{
2015-08-24 12:54:05 +02:00
ostringstream unused_exos ;
2018-06-04 12:26:16 +02:00
for ( int it : unusedExo )
unused_exos < < symbol_table . getName ( it ) < < " " ;
2015-08-24 12:54:05 +02:00
if ( nostrict )
warnings < < " WARNING: " < < unused_exos . str ( )
< < " not used in model block, removed by nostrict command-line option " < < endl ;
else
2013-11-29 16:03:15 +01:00
{
2015-08-24 12:54:05 +02:00
cerr < < " ERROR: " < < unused_exos . str ( ) < < " not used in model block. To bypass this error, use the `nostrict` option. This may lead to crashes or unexpected behavior. " < < endl ;
exit ( EXIT_FAILURE ) ;
2013-11-29 16:03:15 +01:00
}
}
2009-09-30 17:10:31 +02:00
}
void
2018-12-20 17:04:28 +01:00
ModFile : : transformPass ( bool nostrict , bool stochastic , bool compute_xrefs , const bool transform_unary_ops )
2009-09-30 17:10:31 +02:00
{
2019-08-20 12:50:41 +02:00
/* Save the original model (must be done before any model transformations by preprocessor)
— except substituting out variables which we know are constant ( they
appear in an equation of the form : X = constant )
— except adl operators which we always want expanded
— except diff operators with a lead which have been expanded by
DataTree : AddDiff ( )
*/
2019-01-28 17:53:04 +01:00
dynamic_model . simplifyEquations ( ) ;
2019-02-25 15:29:46 +01:00
for ( auto & statement : statements )
{
auto pms = dynamic_cast < PacModelStatement * > ( statement . get ( ) ) ;
2019-02-28 19:22:34 +01:00
if ( pms ! = nullptr )
{
if ( pms - > growth ! = nullptr )
pac_growth . push_back ( pms - > growth ) ;
if ( pms - > aux_model_name = = " " )
dynamic_model . declarePacModelConsistentExpectationEndogs ( pms - > name ) ;
}
2019-02-25 15:29:46 +01:00
}
2018-01-30 10:06:56 +01:00
dynamic_model . substituteAdl ( ) ;
2017-07-27 23:14:50 +02:00
dynamic_model . setLeadsLagsOrig ( ) ;
2018-10-09 18:27:19 +02:00
original_model = dynamic_model ;
2015-02-16 08:31:30 +01:00
2019-09-05 11:24:36 +02:00
set < int > unusedEndogs = dynamic_model . findUnusedEndogenous ( ) ;
bool unusedEndogsIsErr = ! nostrict & & ! mod_file_struct . bvar_present & & unusedEndogs . size ( ) ;
for ( int unusedEndog : unusedEndogs )
if ( nostrict )
{
symbol_table . changeType ( unusedEndog , SymbolType : : unusedEndogenous ) ;
warnings < < " WARNING: ' " < < symbol_table . getName ( unusedEndog )
< < " ' not used in model block, removed by nostrict command-line option " < < endl ;
}
else if ( unusedEndogsIsErr )
cerr < < " Error: " < < symbol_table . getName ( unusedEndog ) < < " not used in the model block " < < endl ;
if ( unusedEndogsIsErr )
exit ( EXIT_FAILURE ) ;
2013-09-13 20:37:31 +02:00
2019-02-19 12:51:05 +01:00
// Get all equation tags associated with VARs and Trend Component Models
2018-06-05 16:38:37 +02:00
set < string > eqtags ;
2018-08-22 15:12:17 +02:00
for ( auto const & it : trend_component_model_table . getEqTags ( ) )
for ( auto & it1 : it . second )
2018-08-14 14:23:21 +02:00
eqtags . insert ( it1 ) ;
2018-06-05 16:38:37 +02:00
2018-08-22 15:12:17 +02:00
for ( auto const & it : var_model_table . getEqTags ( ) )
for ( auto & it1 : it . second )
2018-08-21 11:46:59 +02:00
eqtags . insert ( it1 ) ;
2018-11-29 16:01:49 +01:00
diff_table_t unary_ops_nodes ;
ExprNode : : subst_table_t unary_ops_subst_table ;
2018-05-30 16:48:08 +02:00
if ( transform_unary_ops )
2019-08-19 14:51:21 +02:00
tie ( unary_ops_nodes , unary_ops_subst_table ) = dynamic_model . substituteUnaryOps ( diff_static_model ) ;
2018-06-07 12:53:00 +02:00
else
2018-08-21 11:46:59 +02:00
// substitute only those unary ops that appear in auxiliary model equations
2019-08-19 14:51:21 +02:00
tie ( unary_ops_nodes , unary_ops_subst_table ) = dynamic_model . substituteUnaryOps ( diff_static_model , eqtags ) ;
2018-05-30 16:48:08 +02:00
2019-02-19 16:36:10 +01:00
// Create auxiliary variable and equations for Diff operators
2019-09-11 15:59:23 +02:00
auto [ diff_table , diff_subst_table ] = dynamic_model . substituteDiff ( diff_static_model , pac_growth ) ;
2018-02-08 13:07:15 +01:00
2018-08-14 14:23:21 +02:00
// Fill Trend Component Model Table
dynamic_model . fillTrendComponentModelTable ( ) ;
original_model . fillTrendComponentModelTableFromOrigModel ( diff_static_model ) ;
2018-09-12 17:56:30 +02:00
dynamic_model . fillTrendComponentmodelTableAREC ( diff_subst_table ) ;
2018-08-21 11:46:59 +02:00
dynamic_model . fillVarModelTable ( ) ;
original_model . fillVarModelTableFromOrigModel ( diff_static_model ) ;
2018-08-14 14:23:21 +02:00
2018-08-21 11:46:59 +02:00
// Pac Model
2019-02-28 19:22:34 +01:00
int i = 0 ;
2018-06-05 17:44:41 +02:00
for ( auto & statement : statements )
2016-11-25 17:15:13 +01:00
{
2018-09-05 15:17:21 +02:00
auto pms = dynamic_cast < PacModelStatement * > ( statement . get ( ) ) ;
2018-06-04 12:52:14 +02:00
if ( pms ! = nullptr )
2018-03-28 18:46:15 +02:00
{
2019-02-28 19:22:34 +01:00
if ( pms - > growth ! = nullptr )
pms - > overwriteGrowth ( pac_growth . at ( i + + ) ) ;
2019-02-15 12:52:46 +01:00
int max_lag ;
2018-08-14 14:23:21 +02:00
vector < int > lhs ;
vector < bool > nonstationary ;
2019-02-21 10:53:11 +01:00
string aux_model_type ;
2019-02-15 12:52:46 +01:00
if ( trend_component_model_table . isExistingTrendComponentModelName ( pms - > aux_model_name ) )
2018-08-14 14:23:21 +02:00
{
2019-02-20 16:42:22 +01:00
aux_model_type = " trend_component " ;
2019-02-15 12:52:46 +01:00
max_lag = trend_component_model_table . getMaxLag ( pms - > aux_model_name ) + 1 ;
lhs = dynamic_model . getUndiffLHSForPac ( pms - > aux_model_name , diff_subst_table ) ;
2018-10-24 15:57:07 +02:00
// All lhs variables in a trend component model are nonstationary
2019-02-15 12:52:46 +01:00
nonstationary . insert ( nonstationary . end ( ) , trend_component_model_table . getDiff ( pms - > aux_model_name ) . size ( ) , true ) ;
2018-08-14 14:23:21 +02:00
}
2019-02-15 12:52:46 +01:00
else if ( var_model_table . isExistingVarModelName ( pms - > aux_model_name ) )
2018-08-21 11:46:59 +02:00
{
2019-02-20 16:42:22 +01:00
aux_model_type = " var " ;
2019-02-15 12:52:46 +01:00
max_lag = var_model_table . getMaxLag ( pms - > aux_model_name ) ;
lhs = var_model_table . getLhs ( pms - > aux_model_name ) ;
2018-10-24 15:57:07 +02:00
// nonstationary variables in a VAR are those that are in diff
2019-02-15 12:52:46 +01:00
nonstationary = var_model_table . getDiff ( pms - > aux_model_name ) ;
2018-08-21 11:46:59 +02:00
}
2019-02-15 12:52:46 +01:00
else if ( pms - > aux_model_name = = " " )
max_lag = 0 ;
2018-08-14 14:23:21 +02:00
else
2018-03-28 18:46:15 +02:00
{
2019-02-15 12:52:46 +01:00
cerr < < " Error: aux_model_name not recognized as VAR model or Trend Component model " < < endl ;
2018-08-14 14:23:21 +02:00
exit ( EXIT_FAILURE ) ;
2018-03-28 18:46:15 +02:00
}
2019-08-19 14:51:21 +02:00
auto eqtag_and_lag = dynamic_model . walkPacParameters ( pms - > name ) ;
2019-02-19 16:36:10 +01:00
original_model . getPacMaxLag ( pms - > name , eqtag_and_lag ) ;
2019-02-15 12:52:46 +01:00
if ( pms - > aux_model_name = = " " )
2019-02-20 12:59:55 +01:00
dynamic_model . addPacModelConsistentExpectationEquation ( pms - > name , symbol_table . getID ( pms - > discount ) ,
eqtag_and_lag , diff_subst_table ) ;
2019-02-15 12:52:46 +01:00
else
2019-02-20 16:42:22 +01:00
dynamic_model . fillPacModelInfo ( pms - > name , lhs , max_lag , aux_model_type ,
2019-05-13 17:43:16 +02:00
eqtag_and_lag , nonstationary , pms - > growth ) ;
2019-02-19 16:36:10 +01:00
dynamic_model . substitutePacExpectation ( pms - > name ) ;
2018-03-28 18:46:15 +02:00
}
}
2018-08-21 11:46:59 +02:00
dynamic_model . addEquationsForVar ( ) ;
2018-01-30 16:33:16 +01:00
if ( symbol_table . predeterminedNbr ( ) > 0 )
dynamic_model . transformPredeterminedVariables ( ) ;
2011-03-21 18:36:38 +01:00
// Create auxiliary vars for Expectation operator
2018-12-20 17:04:28 +01:00
dynamic_model . substituteExpectation ( mod_file_struct . partial_information ) ;
2011-03-21 18:36:38 +01:00
2010-10-15 19:05:16 +02:00
if ( nonstationary_variables )
{
dynamic_model . detrendEquations ( ) ;
2018-10-09 18:27:19 +02:00
trend_dynamic_model = dynamic_model ;
2010-10-15 19:05:16 +02:00
dynamic_model . removeTrendVariableFromEquations ( ) ;
}
2016-03-14 07:56:16 +01:00
mod_file_struct . orig_eq_nbr = dynamic_model . equation_number ( ) ;
2014-03-09 09:52:44 +01:00
if ( mod_file_struct . ramsey_model_present )
2011-03-21 18:40:57 +01:00
{
2018-07-31 12:42:08 +02:00
PlannerObjectiveStatement * pos = nullptr ;
2018-06-04 12:26:16 +02:00
for ( auto & statement : statements )
2011-03-21 18:40:57 +01:00
{
2018-09-05 15:17:21 +02:00
auto pos2 = dynamic_cast < PlannerObjectiveStatement * > ( statement . get ( ) ) ;
2018-07-31 12:42:08 +02:00
if ( pos2 ! = nullptr )
if ( pos ! = nullptr )
{
cerr < < " ERROR: there can only be one planner_objective statement " < < endl ;
exit ( EXIT_FAILURE ) ;
}
else
pos = pos2 ;
2011-03-21 18:40:57 +01:00
}
2018-07-31 12:42:08 +02:00
assert ( pos ! = nullptr ) ;
const StaticModel & planner_objective = pos - > getPlannerObjective ( ) ;
2011-03-21 18:40:57 +01:00
/*
clone the model then clone the new equations back to the original because
we have to call computeDerivIDs ( in computeRamseyPolicyFOCs and computingPass )
2017-06-01 19:58:32 +02:00
*/
2016-11-29 14:20:53 +01:00
if ( linear )
2018-10-09 18:27:19 +02:00
orig_ramsey_dynamic_model = dynamic_model ;
ramsey_FOC_equations_dynamic_model = dynamic_model ;
2018-12-20 17:04:28 +01:00
ramsey_FOC_equations_dynamic_model . computeRamseyPolicyFOCs ( planner_objective ) ;
2011-03-21 18:40:57 +01:00
ramsey_FOC_equations_dynamic_model . replaceMyEquations ( dynamic_model ) ;
2016-03-14 07:56:16 +01:00
mod_file_struct . ramsey_eq_nbr = dynamic_model . equation_number ( ) - mod_file_struct . orig_eq_nbr ;
2011-03-21 18:40:57 +01:00
}
2018-08-01 19:41:44 +02:00
/* Handle var_expectation_model statements: collect information about them,
create the new corresponding parameters , and the expressions to replace
the var_expectation statements .
TODO : move information collection to checkPass ( ) , within a new
VarModelTable class * /
map < string , expr_t > var_expectation_subst_table ;
for ( auto & statement : statements )
{
2018-09-05 15:17:21 +02:00
auto vems = dynamic_cast < VarExpectationModelStatement * > ( statement . get ( ) ) ;
2018-08-01 19:41:44 +02:00
if ( ! vems )
continue ;
2018-08-22 16:50:01 +02:00
int max_lag ;
vector < int > lhs ;
2018-08-01 19:41:44 +02:00
auto & model_name = vems - > model_name ;
2018-08-22 16:57:36 +02:00
if ( var_model_table . isExistingVarModelName ( vems - > aux_model_name ) )
2018-08-22 16:50:01 +02:00
{
2018-08-22 16:57:36 +02:00
max_lag = var_model_table . getMaxLag ( vems - > aux_model_name ) ;
lhs = var_model_table . getLhs ( vems - > aux_model_name ) ;
2018-08-22 16:50:01 +02:00
}
2018-08-22 16:57:36 +02:00
else if ( trend_component_model_table . isExistingTrendComponentModelName ( vems - > aux_model_name ) )
2018-08-22 16:50:01 +02:00
{
2018-08-27 14:51:54 +02:00
max_lag = trend_component_model_table . getMaxLag ( vems - > aux_model_name ) + 1 ;
2018-10-12 15:19:36 +02:00
lhs = dynamic_model . getUndiffLHSForPac ( vems - > aux_model_name , diff_subst_table ) ;
2018-08-22 16:50:01 +02:00
}
else
2018-08-01 19:41:44 +02:00
{
2018-08-21 11:46:59 +02:00
cerr < < " ERROR: var_expectation_model " < < model_name
2018-08-22 16:57:36 +02:00
< < " refers to nonexistent auxiliary model " < < vems - > aux_model_name < < endl ;
2018-08-01 19:41:44 +02:00
exit ( EXIT_FAILURE ) ;
}
2018-11-29 16:01:49 +01:00
/* Substitute unary and diff operators in the 'expression' option, then
match the linear combination in the expression option */
vems - > substituteUnaryOpNodes ( diff_static_model , unary_ops_nodes , unary_ops_subst_table ) ;
vems - > substituteDiff ( diff_static_model , diff_table , diff_subst_table ) ;
vems - > matchExpression ( ) ;
2018-08-22 16:50:01 +02:00
/* Create auxiliary parameters and the expression to be substituted into
2018-08-01 19:41:44 +02:00
the var_expectations statement */
auto subst_expr = dynamic_model . Zero ;
2018-08-06 21:36:52 +02:00
for ( int lag = 0 ; lag < max_lag ; lag + + )
2018-08-01 19:41:44 +02:00
for ( auto variable : lhs )
{
string param_name = " var_expectation_model_ " + model_name + ' _ ' + symbol_table . getName ( variable ) + ' _ ' + to_string ( lag ) ;
int new_param_id = symbol_table . addSymbol ( param_name , SymbolType : : parameter ) ;
vems - > aux_params_ids . push_back ( new_param_id ) ;
subst_expr = dynamic_model . AddPlus ( subst_expr ,
dynamic_model . AddTimes ( dynamic_model . AddVariable ( new_param_id ) ,
dynamic_model . AddVariable ( variable , - lag ) ) ) ;
}
if ( var_expectation_subst_table . find ( model_name ) ! = var_expectation_subst_table . end ( ) )
{
cerr < < " ERROR: model name ' " < < model_name < < " ' is used by several var_expectation_model statements " < < endl ;
exit ( EXIT_FAILURE ) ;
}
var_expectation_subst_table [ model_name ] = subst_expr ;
}
// And finally perform the substitutions
dynamic_model . substituteVarExpectation ( var_expectation_subst_table ) ;
2009-09-30 17:10:31 +02:00
if ( mod_file_struct . stoch_simul_present
| | mod_file_struct . estimation_present
| | mod_file_struct . osr_present
2011-03-17 15:15:13 +01:00
| | mod_file_struct . ramsey_policy_present
2013-10-28 14:22:23 +01:00
| | mod_file_struct . discretionary_policy_present
2017-08-31 10:19:43 +02:00
| | mod_file_struct . calib_smoother_present
2019-01-09 14:48:25 +01:00
| | mod_file_struct . identification_present
| | mod_file_struct . sensitivity_present
2017-08-31 10:19:43 +02:00
| | stochastic )
2009-09-30 17:10:31 +02:00
{
2010-08-18 13:45:07 +02:00
// In stochastic models, create auxiliary vars for leads and lags greater than 2, on both endos and exos
2018-12-20 17:04:28 +01:00
dynamic_model . substituteEndoLeadGreaterThanTwo ( false ) ;
dynamic_model . substituteExoLead ( false ) ;
dynamic_model . substituteEndoLagGreaterThanTwo ( false ) ;
dynamic_model . substituteExoLag ( false ) ;
2010-08-18 13:45:07 +02:00
}
else
{
// In deterministic models, create auxiliary vars for leads and lags endogenous greater than 2, only on endos (useless on exos)
2018-12-20 17:04:28 +01:00
dynamic_model . substituteEndoLeadGreaterThanTwo ( true ) ;
dynamic_model . substituteEndoLagGreaterThanTwo ( true ) ;
2009-09-30 17:10:31 +02:00
}
2009-09-02 15:36:56 +02:00
2018-09-03 15:05:30 +02:00
dynamic_model . updateVarAndTrendModel ( ) ;
2018-08-21 11:46:59 +02:00
2013-04-25 18:09:31 +02:00
if ( differentiate_forward_vars )
2018-12-20 17:04:28 +01:00
dynamic_model . differentiateForwardVars ( differentiate_forward_vars_subset ) ;
2013-04-25 18:09:31 +02:00
2010-06-21 18:40:36 +02:00
if ( mod_file_struct . dsge_var_estimated | | ! mod_file_struct . dsge_var_calibrated . empty ( ) )
2010-06-11 21:19:30 +02:00
try
{
2018-07-17 18:34:07 +02:00
int sid = symbol_table . addSymbol ( " dsge_prior_weight " , SymbolType : : parameter ) ;
2010-06-21 18:40:36 +02:00
if ( ! mod_file_struct . dsge_var_calibrated . empty ( ) )
2018-09-05 15:17:21 +02:00
addStatementAtFront ( make_unique < InitParamStatement > ( sid ,
expressions_tree . AddNonNegativeConstant ( mod_file_struct . dsge_var_calibrated ) ,
symbol_table ) ) ;
2010-06-11 21:19:30 +02:00
}
catch ( SymbolTable : : AlreadyDeclaredException & e )
{
cerr < < " ERROR: dsge_prior_weight should not be declared as a model variable / parameter "
< < " when the dsge_var option is passed to the estimation statement. " < < endl ;
exit ( EXIT_FAILURE ) ;
}
2009-02-27 13:19:25 +01:00
// Freeze the symbol table
symbol_table . freeze ( ) ;
2017-03-06 16:34:08 +01:00
if ( compute_xrefs )
dynamic_model . computeXrefs ( ) ;
2008-10-17 14:52:08 +02:00
/*
2013-09-13 20:37:31 +02:00
Enforce the same number of equations and endogenous , except in three cases :
2014-03-09 09:52:44 +01:00
- ramsey_model , ramsey_policy or discretionary_policy is used
2008-10-17 14:52:08 +02:00
- a BVAR command is used and there is no equation ( standalone BVAR estimation )
2013-09-13 20:37:31 +02:00
- nostrict option is passed and there are more endogs than equations ( dealt with before freeze )
2008-10-17 14:52:08 +02:00
*/
2014-03-09 09:52:44 +01:00
if ( ! ( mod_file_struct . ramsey_model_present | | mod_file_struct . discretionary_policy_present )
2009-11-26 18:25:04 +01:00
& & ! ( mod_file_struct . bvar_present & & dynamic_model . equation_number ( ) = = 0 )
2015-06-04 14:16:52 +02:00
& & ! ( mod_file_struct . occbin_option )
2009-04-14 16:39:53 +02:00
& & ( dynamic_model . equation_number ( ) ! = symbol_table . endo_nbr ( ) ) )
2008-02-03 11:28:36 +01:00
{
2009-04-14 16:39:53 +02:00
cerr < < " ERROR: There are " < < dynamic_model . equation_number ( ) < < " equations but " < < symbol_table . endo_nbr ( ) < < " endogenous variables! " < < endl ;
2008-10-29 16:33:16 +01:00
exit ( EXIT_FAILURE ) ;
2008-02-03 11:28:36 +01:00
}
2011-03-21 18:40:57 +01:00
2014-04-09 17:57:17 +02:00
if ( symbol_table . exo_det_nbr ( ) > 0 & & mod_file_struct . perfect_foresight_solver_present )
2011-03-18 12:47:06 +01:00
{
2017-01-31 17:10:39 +01:00
cerr < < " ERROR: A .mod file cannot contain both one of {perfect_foresight_solver, simul} and varexo_det declaration (all exogenous variables are deterministic in this case) " < < endl ;
2011-03-18 12:47:06 +01:00
exit ( EXIT_FAILURE ) ;
}
2011-03-21 18:40:57 +01:00
2013-02-07 11:52:59 +01:00
if ( mod_file_struct . ramsey_policy_present & & symbol_table . exo_det_nbr ( ) > 0 )
{
cerr < < " ERROR: ramsey_policy is incompatible with deterministic exogenous variables " < < endl ;
exit ( EXIT_FAILURE ) ;
}
2016-12-27 13:46:01 +01:00
if ( mod_file_struct . ramsey_policy_present )
2018-06-04 12:26:16 +02:00
for ( auto & statement : statements )
2016-12-27 13:46:01 +01:00
{
2018-09-05 15:17:21 +02:00
auto * rps = dynamic_cast < RamseyPolicyStatement * > ( statement . get ( ) ) ;
2018-06-04 12:52:14 +02:00
if ( rps ! = nullptr )
2016-12-27 13:46:01 +01:00
rps - > checkRamseyPolicyList ( ) ;
}
2014-07-30 17:28:45 +02:00
if ( mod_file_struct . identification_present & & symbol_table . exo_det_nbr ( ) > 0 )
{
cerr < < " ERROR: identification is incompatible with deterministic exogenous variables " < < endl ;
exit ( EXIT_FAILURE ) ;
}
2018-12-20 17:04:28 +01:00
if ( ! mod_file_struct . ramsey_model_present )
cout < < " Found " < < dynamic_model . equation_number ( ) < < " equation(s). " < < endl ;
else
{
cout < < " Found " < < mod_file_struct . orig_eq_nbr < < " equation(s). " < < endl ;
cout < < " Found " < < dynamic_model . equation_number ( ) < < " FOC equation(s) for Ramsey Problem. " < < endl ;
}
2010-06-11 21:19:30 +02:00
2010-06-21 18:40:36 +02:00
if ( symbol_table . exists ( " dsge_prior_weight " ) )
2010-06-11 21:19:30 +02:00
if ( mod_file_struct . bayesian_irf_present )
{
if ( symbol_table . exo_nbr ( ) ! = symbol_table . observedVariablesNbr ( ) )
{
2010-06-21 18:40:36 +02:00
cerr < < " ERROR: When estimating a DSGE-Var and the bayesian_irf option is passed to the estimation "
< < " statement, the number of shocks must equal the number of observed variables. " < < endl ;
2010-06-11 21:19:30 +02:00
exit ( EXIT_FAILURE ) ;
}
}
else
if ( symbol_table . exo_nbr ( ) < symbol_table . observedVariablesNbr ( ) )
{
2010-06-21 18:40:36 +02:00
cerr < < " ERROR: When estimating a DSGE-Var, the number of shocks must be "
< < " greater than or equal to the number of observed variables. " < < endl ;
2010-06-11 21:19:30 +02:00
exit ( EXIT_FAILURE ) ;
}
2008-02-03 11:28:36 +01:00
}
void
2018-12-20 17:04:28 +01:00
ModFile : : computingPass ( bool no_tmp_terms , FileOutputType output , int params_derivs_order )
2008-02-03 11:28:36 +01:00
{
// Mod file may have no equation (for example in a standalone BVAR estimation)
2009-04-14 16:39:53 +02:00
if ( dynamic_model . equation_number ( ) > 0 )
2008-02-03 11:28:36 +01:00
{
2013-10-29 11:46:54 +01:00
if ( nonstationary_variables )
trend_dynamic_model . runTrendTest ( global_eval_context ) ;
2010-10-15 19:05:16 +02:00
2009-04-14 16:39:53 +02:00
// Compute static model and its derivatives
2018-10-10 17:08:54 +02:00
static_model = static_cast < StaticModel > ( dynamic_model ) ;
2018-09-21 17:13:19 +02:00
if ( linear_decomposition )
{
2018-10-09 18:27:19 +02:00
non_linear_equations_dynamic_model = dynamic_model ;
2018-09-21 17:13:19 +02:00
non_linear_equations_dynamic_model . set_cutoff_to_zero ( ) ;
2018-12-20 17:04:28 +01:00
non_linear_equations_dynamic_model . computingPass ( true , 1 , 0 , global_eval_context , no_tmp_terms , block , use_dll , byte_code , linear_decomposition ) ;
2018-09-21 17:13:19 +02:00
}
2011-02-04 16:25:38 +01:00
if ( ! no_static )
2017-06-01 19:58:32 +02:00
{
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 ( ) ;
2018-11-22 14:32:40 +01:00
int derivsOrder = 1 ;
2016-05-18 12:26:19 +02:00
int paramsDerivsOrder = 0 ;
if ( mod_file_struct . identification_present | | mod_file_struct . estimation_analytic_derivation )
2018-11-22 14:32:40 +01:00
{
derivsOrder = 2 ;
paramsDerivsOrder = params_derivs_order ;
}
2018-12-20 17:04:28 +01:00
static_model . computingPass ( derivsOrder , paramsDerivsOrder , global_eval_context , no_tmp_terms , block , byte_code ) ;
2017-06-01 19:58:32 +02:00
}
2009-04-14 16:39:53 +02:00
// Set things to compute for dynamic model
2014-04-09 17:57:17 +02:00
if ( mod_file_struct . perfect_foresight_solver_present | | mod_file_struct . check_present
2017-06-01 19:58:32 +02:00
| | 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 )
2018-12-20 17:04:28 +01:00
dynamic_model . computingPass ( true , 1 , 0 , global_eval_context , no_tmp_terms , block , use_dll , byte_code , linear_decomposition ) ;
2017-06-01 19:58:32 +02:00
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 ( ) ;
2019-04-12 15:41:52 +02:00
if ( mod_file_struct . order_option < 1 )
2017-06-01 19:58:32 +02:00
{
cerr < < " ERROR: Incorrect order option... " < < endl ;
exit ( EXIT_FAILURE ) ;
}
2019-07-05 17:44:10 +02:00
int derivsOrder = max ( mod_file_struct . order_option ,
mod_file_struct . identification_order + 1 ) ;
if ( mod_file_struct . sensitivity_present | | linear | | output = = FileOutputType : : second )
2018-11-22 14:32:40 +01:00
derivsOrder = max ( derivsOrder , 2 ) ;
if ( mod_file_struct . estimation_analytic_derivation | | output = = FileOutputType : : third )
derivsOrder = max ( derivsOrder , 3 ) ;
2017-06-01 19:58:32 +02:00
int paramsDerivsOrder = 0 ;
if ( mod_file_struct . identification_present | | mod_file_struct . estimation_analytic_derivation )
paramsDerivsOrder = params_derivs_order ;
2018-12-20 17:04:28 +01:00
dynamic_model . computingPass ( true , derivsOrder , paramsDerivsOrder , global_eval_context , no_tmp_terms , block , use_dll , byte_code , linear_decomposition ) ;
2017-06-01 19:58:32 +02:00
if ( linear & & mod_file_struct . ramsey_model_present )
2018-12-20 17:04:28 +01:00
orig_ramsey_dynamic_model . computingPass ( true , 2 , paramsDerivsOrder , global_eval_context , no_tmp_terms , block , use_dll , byte_code , linear_decomposition ) ;
2017-06-01 19:58:32 +02:00
}
}
else // No computing task requested, compute derivatives up to 2nd order by default
2018-12-20 17:04:28 +01:00
dynamic_model . computingPass ( true , 2 , 0 , global_eval_context , no_tmp_terms , block , use_dll , byte_code , linear_decomposition ) ;
2017-06-01 19:58:32 +02:00
2018-01-11 12:55:36 +01:00
map < int , string > eqs ;
if ( mod_file_struct . ramsey_model_present )
orig_ramsey_dynamic_model . setNonZeroHessianEquations ( eqs ) ;
else
dynamic_model . setNonZeroHessianEquations ( eqs ) ;
2016-11-29 14:20:53 +01:00
2018-01-11 12:55:36 +01:00
if ( linear & & ! eqs . empty ( ) )
{
2016-07-27 21:01:54 +02:00
cerr < < " ERROR: If the model is declared linear the second derivatives must be equal to zero. " < < endl
< < " The following equations had non-zero second derivatives: " < < endl ;
for ( map < int , string > : : const_iterator it = eqs . begin ( ) ; it ! = eqs . end ( ) ; it + + )
{
cerr < < " * Eq # " < < it - > first + 1 ;
if ( ! it - > second . empty ( ) )
cerr < < " [ " < < it - > second < < " ] " ;
cerr < < endl ;
}
2016-07-25 19:43:34 +02:00
exit ( EXIT_FAILURE ) ;
}
2008-02-03 11:28:36 +01:00
}
2009-04-20 12:48:54 +02:00
2018-06-04 12:26:16 +02:00
for ( auto & statement : statements )
statement - > computingPass ( ) ;
2018-09-03 17:16:28 +02:00
2018-12-20 17:04:28 +01:00
// Compute epilogue derivatives (but silence standard output)
streambuf * oldcout = cout . rdbuf ( ) ;
cout . rdbuf ( nullptr ) ;
epilogue . computingPass ( true , 2 , 0 , global_eval_context , true , false , false , false , false ) ;
cout . rdbuf ( oldcout ) ;
2008-02-03 11:28:36 +01:00
}
void
2015-05-28 11:42:12 +02:00
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 ,
2018-10-26 11:44:26 +02:00
bool check_model_changes , bool minimal_workspace , bool compute_xrefs ,
2018-12-20 17:04:28 +01:00
const string & mexext ,
2019-04-04 17:01:37 +02:00
const filesystem : : path & matlabroot ,
const filesystem : : path & dynareroot , bool onlymodel ) const
2008-02-03 11:28:36 +01:00
{
2018-09-25 19:15:22 +02:00
bool hasModelChanged = ! dynamic_model . isChecksumMatching ( basename , block ) ;
2018-06-27 15:01:31 +02:00
if ( ! check_model_changes )
hasModelChanged = true ;
if ( hasModelChanged )
{
// Erase possible remnants of previous runs
2018-07-09 18:18:26 +02:00
/* Under MATLAB+Windows (but not under Octave nor under GNU/Linux or
macOS ) , if we directly remove the " + " subdirectory , then the
preprocessor is not able to recreate it afterwards ( presumably because
MATLAB maintains some sort of lock on it ) . The workaround is to rename
2019-09-11 17:03:37 +02:00
it before deleting it ( the renaming must occur in the same directory ,
otherwise it may file if the destination is not on the same
filesystem ) . */
2019-04-04 17:01:37 +02:00
if ( filesystem : : exists ( " + " + basename ) )
2018-07-09 18:18:26 +02:00
{
2019-04-04 17:01:37 +02:00
auto tmp = unique_path ( ) ;
filesystem : : rename ( " + " + basename , tmp ) ;
filesystem : : remove_all ( tmp ) ;
2018-07-09 18:18:26 +02:00
}
2019-04-04 17:01:37 +02:00
filesystem : : remove_all ( basename + " /model/src " ) ;
filesystem : : remove_all ( basename + " /model/bytecode " ) ;
2018-06-27 15:01:31 +02:00
}
2008-02-03 11:28:36 +01:00
ofstream mOutputFile ;
2009-10-06 10:56:02 +02:00
2008-02-03 11:28:36 +01:00
if ( basename . size ( ) )
{
2019-04-04 17:01:37 +02:00
filesystem : : create_directory ( " + " + basename ) ;
2018-06-27 15:01:31 +02:00
string fname = " + " + basename + " /driver.m " ;
2018-06-27 15:12:12 +02:00
mOutputFile . open ( fname , ios : : out | ios : : binary ) ;
2008-02-03 11:28:36 +01:00
if ( ! mOutputFile . is_open ( ) )
{
2015-06-30 12:12:49 +02:00
cerr < < " ERROR: Can't open file " < < fname < < " for writing " < < endl ;
2008-10-29 16:33:16 +01:00
exit ( EXIT_FAILURE ) ;
2008-02-03 11:28:36 +01:00
}
}
else
{
2008-09-29 12:16:13 +02:00
cerr < < " ERROR: Missing file name " < < endl ;
2008-10-29 16:33:16 +01:00
exit ( EXIT_FAILURE ) ;
2008-02-03 11:28:36 +01:00
}
2008-06-16 18:33:28 +02:00
mOutputFile < < " % " < < endl
2015-06-30 12:12:49 +02:00
< < " % Status : main Dynare file " < < endl
2008-06-16 18:33:28 +02:00
< < " % " < < endl
< < " % Warning : this file is generated automatically by Dynare " < < endl
< < " % from model file (.mod) " < < endl < < endl ;
2008-02-03 11:28:36 +01:00
2013-02-26 16:50:05 +01:00
if ( no_warn )
mOutputFile < < " warning off " < < endl ; // This will be executed *after* function warning_config()
2008-02-03 11:28:36 +01:00
if ( clear_all )
2015-09-30 22:52:48 +02:00
mOutputFile < < " if isoctave || matlab_ver_less_than('8.6') " < < endl
< < " clear all " < < endl
2017-06-01 19:58:32 +02:00
< < " else " < < endl
< < " clearvars -global " < < endl
< < " clear_persistent_variables(fileparts(which('dynare')), false) " < < endl
< < " end " < < endl ;
2014-12-30 21:51:33 +01:00
else if ( clear_global )
2015-04-04 19:22:49 +02:00
mOutputFile < < " clear M_ options_ oo_ estim_params_ bayestopt_ dataset_ dataset_info estimation_info ys0_ ex0_; " < < endl ;
2009-04-30 15:05:21 +02:00
2015-10-10 11:13:13 +02:00
mOutputFile < < " tic0 = tic; " < < endl
2017-06-01 19:58:32 +02:00
< < " % Define global variables. " < < endl
2015-04-04 19:22:49 +02:00
< < " global M_ options_ oo_ estim_params_ bayestopt_ dataset_ dataset_info estimation_info ys0_ ex0_ " < < endl
2009-04-30 15:05:21 +02:00
< < " options_ = []; " < < endl
< < " M_.fname = ' " < < basename < < " '; " < < endl
2015-04-30 12:35:33 +02:00
< < " M_.dynare_version = ' " < < PACKAGE_VERSION < < " '; " < < endl
< < " oo_.dynare_version = ' " < < PACKAGE_VERSION < < " '; " < < endl
< < " options_.dynare_version = ' " < < PACKAGE_VERSION < < " '; " < < endl
2009-04-30 15:05:21 +02:00
< < " % " < < endl
< < " % Some global variables initialization " < < endl
2012-06-06 16:07:59 +02:00
< < " % " < < endl ;
2018-11-07 15:24:57 +01:00
if ( ! onlymodel )
config_file . writeHooks ( mOutputFile ) ;
2012-06-06 16:07:59 +02:00
mOutputFile < < " global_initialization; " < < endl
2012-04-20 18:15:02 +02:00
< < " diary off; " < < endl ;
if ( ! no_log )
2013-03-18 13:44:04 +01:00
mOutputFile < < " diary(' " < < basename < < " .log'); " < < endl ;
2009-04-30 15:05:21 +02:00
2015-05-28 11:42:12 +02:00
if ( minimal_workspace )
2019-03-19 14:05:41 +01:00
mOutputFile < < " options_.minimal_workspace = true; " < < endl ;
2015-05-28 11:42:12 +02:00
2010-10-28 11:19:11 +02:00
if ( console )
2019-03-19 14:05:41 +01:00
mOutputFile < < " options_.console_mode = true; " < < endl
< < " options_.nodisplay = true; " < < endl ;
2013-07-10 11:03:48 +02:00
if ( nograph )
2019-03-19 14:05:41 +01:00
mOutputFile < < " options_.nograph = true; " < < endl ;
2013-07-10 12:02:12 +02:00
if ( nointeractive )
2019-03-19 14:05:41 +01:00
mOutputFile < < " options_.nointeractive = true; " < < endl ;
2015-07-30 14:40:03 +02:00
if ( param_used_with_lead_lag )
mOutputFile < < " M_.parameter_used_with_lead_lag = true; " < < endl ;
2018-12-20 17:04:28 +01:00
cout < < " Processing outputs ... " < < endl ;
2008-02-03 11:28:36 +01:00
symbol_table . writeOutput ( mOutputFile ) ;
2018-09-06 17:53:07 +02:00
var_model_table . writeOutput ( basename , mOutputFile ) ;
2018-09-07 10:56:40 +02:00
trend_component_model_table . writeOutput ( basename , mOutputFile ) ;
2018-08-14 14:23:21 +02:00
2013-10-28 15:29:41 +01:00
// Initialize M_.Sigma_e, M_.Correlation_matrix, M_.H, and M_.Correlation_matrix_ME
2010-04-14 15:03:41 +02:00
mOutputFile < < " M_.Sigma_e = zeros( " < < symbol_table . exo_nbr ( ) < < " , "
2013-10-28 15:29:41 +01:00
< < symbol_table . exo_nbr ( ) < < " ); " < < endl
< < " M_.Correlation_matrix = eye( " < < symbol_table . exo_nbr ( ) < < " , "
2010-04-14 15:03:41 +02:00
< < symbol_table . exo_nbr ( ) < < " ); " < < endl ;
if ( mod_file_struct . calibrated_measurement_errors )
mOutputFile < < " M_.H = zeros( " < < symbol_table . observedVariablesNbr ( ) < < " , "
2013-10-28 15:29:41 +01:00
< < symbol_table . observedVariablesNbr ( ) < < " ); " < < endl
< < " M_.Correlation_matrix_ME = eye( " < < symbol_table . observedVariablesNbr ( ) < < " , "
2010-04-14 15:03:41 +02:00
< < symbol_table . observedVariablesNbr ( ) < < " ); " < < endl ;
else
2013-10-28 15:29:41 +01:00
mOutputFile < < " M_.H = 0; " < < endl
< < " M_.Correlation_matrix_ME = 1; " < < endl ;
2010-04-14 15:03:41 +02:00
2014-04-10 11:43:26 +02:00
// May be later modified by a shocks block
2019-03-19 14:05:41 +01:00
mOutputFile < < " M_.sigma_e_is_diagonal = true; " < < endl ;
2014-04-10 11:43:26 +02:00
2014-04-09 18:33:24 +02:00
// Initialize M_.det_shocks
mOutputFile < < " M_.det_shocks = []; " < < endl ;
2019-03-19 14:05:41 +01:00
auto to_matlab_logical = [ ] ( bool m ) { return m ? " true " : " false " ; } ;
2008-02-03 11:28:36 +01:00
2019-03-19 14:05:41 +01:00
mOutputFile < < " options_.linear = " < < to_matlab_logical ( linear ) < < " ; " < < endl
< < " options_.block = " < < to_matlab_logical ( block ) < < " ; " < < endl
< < " options_.bytecode = " < < to_matlab_logical ( byte_code ) < < " ; " < < endl
< < " options_.use_dll = " < < to_matlab_logical ( use_dll ) < < " ; " < < endl
< < " options_.linear_decomposition = " < < to_matlab_logical ( linear_decomposition ) < < " ; " < < endl ;
2009-09-02 15:36:56 +02:00
2013-05-31 14:47:28 +02:00
if ( parallel_local_files . size ( ) > 0 )
{
mOutputFile < < " options_.parallel_info.local_files = { " < < endl ;
2018-06-04 12:26:16 +02:00
for ( const auto & parallel_local_file : parallel_local_files )
2013-05-31 14:47:28 +02:00
{
2019-04-03 16:32:52 +02:00
size_t j = parallel_local_file . find_last_of ( R " (/ \ ) " ) ;
2013-05-31 14:47:28 +02:00
if ( j = = string : : npos )
2018-06-04 12:26:16 +02:00
mOutputFile < < " '', ' " < < parallel_local_file < < " '; " < < endl ;
2013-05-31 14:47:28 +02:00
else
2018-06-04 12:26:16 +02:00
mOutputFile < < " ' " < < parallel_local_file . substr ( 0 , j + 1 ) < < " ', ' "
< < parallel_local_file . substr ( j + 1 , string : : npos ) < < " '; " < < endl ;
2013-05-31 14:47:28 +02:00
}
mOutputFile < < " }; " < < endl ;
}
2018-01-11 12:55:36 +01:00
mOutputFile < < " M_.nonzero_hessian_eqs = " ;
if ( mod_file_struct . ramsey_model_present )
orig_ramsey_dynamic_model . printNonZeroHessianEquations ( mOutputFile ) ;
else
dynamic_model . printNonZeroHessianEquations ( mOutputFile ) ;
mOutputFile < < " ; " < < endl
< < " M_.hessian_eq_zero = isempty(M_.nonzero_hessian_eqs); " < < endl ;
2016-11-14 12:30:52 +01:00
2018-11-07 15:24:57 +01:00
if ( ! onlymodel )
config_file . writeCluster ( mOutputFile ) ;
2010-10-25 18:20:58 +02:00
2009-09-03 18:34:15 +02:00
if ( byte_code )
mOutputFile < < " if exist('bytecode') ~= 3 " < < endl
< < " error('DYNARE: Can''t find bytecode DLL. Please compile it or remove the ''bytecode'' option.') " < < endl
< < " end " < < endl ;
2016-03-14 07:56:16 +01:00
mOutputFile < < " M_.orig_eq_nbr = " < < mod_file_struct . orig_eq_nbr < < " ; " < < endl
2014-10-13 17:25:08 +02:00
< < " M_.eq_nbr = " < < dynamic_model . equation_number ( ) < < " ; " < < endl
2017-08-29 10:58:39 +02:00
< < " M_.ramsey_eq_nbr = " < < mod_file_struct . ramsey_eq_nbr < < " ; " < < endl
2018-06-27 15:01:31 +02:00
< < " M_.set_auxiliary_variables = exist(['./+' M_.fname '/set_auxiliary_variables.m'], 'file') == 2; " < < endl ;
2011-03-21 18:40:57 +01:00
2009-04-14 16:39:53 +02:00
if ( dynamic_model . equation_number ( ) > 0 )
2008-02-03 11:28:36 +01:00
{
2018-09-21 17:13:19 +02:00
if ( linear_decomposition )
non_linear_equations_dynamic_model . writeOutput ( mOutputFile , basename , block , true , byte_code , use_dll , mod_file_struct . order_option , mod_file_struct . estimation_present , compute_xrefs , false ) ;
dynamic_model . writeOutput ( mOutputFile , basename , block , false , byte_code , use_dll , mod_file_struct . order_option , mod_file_struct . estimation_present , compute_xrefs , false ) ;
2010-09-17 11:23:00 +02:00
if ( ! no_static )
2011-03-28 11:19:10 +02:00
static_model . writeOutput ( mOutputFile , block ) ;
2008-02-03 11:28:36 +01:00
}
2018-11-07 15:24:57 +01:00
if ( onlymodel )
for ( auto & statement : statements )
{
2018-12-27 12:06:39 +01:00
/* Special treatment for initval block: insert initial values for the
auxiliary variables and initialize exo det */
auto * ivs = dynamic_cast < InitValStatement * > ( statement . get ( ) ) ;
if ( ivs ! = nullptr )
{
ivs - > writeOutput ( mOutputFile , basename , minimal_workspace ) ;
static_model . writeAuxVarInitval ( mOutputFile , ExprNodeOutputType : : matlabOutsideModel ) ;
ivs - > writeOutputPostInit ( mOutputFile ) ;
}
// Special treatment for endval block: insert initial values for the auxiliary variables
auto * evs = dynamic_cast < EndValStatement * > ( statement . get ( ) ) ;
if ( evs ! = nullptr )
{
evs - > writeOutput ( mOutputFile , basename , minimal_workspace ) ;
static_model . writeAuxVarInitval ( mOutputFile , ExprNodeOutputType : : matlabOutsideModel ) ;
}
2018-11-07 15:24:57 +01:00
auto * ips = dynamic_cast < InitParamStatement * > ( statement . get ( ) ) ;
if ( ips ! = nullptr )
ips - > writeOutput ( mOutputFile , basename , minimal_workspace ) ;
2009-09-30 17:10:31 +02:00
2018-11-07 15:24:57 +01:00
auto * ss = dynamic_cast < ShocksStatement * > ( statement . get ( ) ) ;
if ( ss ! = nullptr )
ss - > writeOutput ( mOutputFile , basename , minimal_workspace ) ;
2018-12-27 19:07:51 +01:00
auto * eps = dynamic_cast < EstimatedParamsStatement * > ( statement . get ( ) ) ;
if ( eps ! = nullptr )
eps - > writeOutput ( mOutputFile , basename , minimal_workspace ) ;
2019-07-22 23:18:01 +02:00
auto * sgs = dynamic_cast < ShockGroupsStatement * > ( statement . get ( ) ) ;
if ( sgs ! = nullptr )
sgs - > writeOutput ( mOutputFile , basename , minimal_workspace ) ;
2018-11-07 15:24:57 +01:00
}
else
{
for ( auto & statement : statements )
2009-09-30 17:10:31 +02:00
{
2018-11-07 15:24:57 +01:00
statement - > writeOutput ( mOutputFile , basename , minimal_workspace ) ;
/* Special treatment for initval block: insert initial values for the
auxiliary variables and initialize exo det */
auto ivs = dynamic_cast < InitValStatement * > ( statement . get ( ) ) ;
if ( ivs ! = nullptr )
{
static_model . writeAuxVarInitval ( mOutputFile , ExprNodeOutputType : : matlabOutsideModel ) ;
ivs - > writeOutputPostInit ( mOutputFile ) ;
}
2009-09-30 17:10:31 +02:00
2018-11-07 15:24:57 +01:00
// Special treatment for endval block: insert initial values for the auxiliary variables
auto evs = dynamic_cast < EndValStatement * > ( statement . get ( ) ) ;
if ( evs ! = nullptr )
static_model . writeAuxVarInitval ( mOutputFile , ExprNodeOutputType : : matlabOutsideModel ) ;
2013-04-22 17:29:59 +02:00
2018-11-07 15:24:57 +01:00
// Special treatment for load params and steady state statement: insert initial values for the auxiliary variables
auto lpass = dynamic_cast < LoadParamsAndSteadyStateStatement * > ( statement . get ( ) ) ;
if ( lpass & & ! no_static )
static_model . writeAuxVarInitval ( mOutputFile , ExprNodeOutputType : : matlabOutsideModel ) ;
}
2008-02-03 11:28:36 +01:00
2018-11-07 15:24:57 +01:00
mOutputFile < < " save(' " < < basename < < " _results.mat', 'oo_', 'M_', 'options_'); " < < endl
< < " if exist('estim_params_', 'var') == 1 " < < endl
< < " save(' " < < basename < < " _results.mat', 'estim_params_', '-append'); " < < endl < < " end " < < endl
< < " if exist('bayestopt_', 'var') == 1 " < < endl
< < " save(' " < < basename < < " _results.mat', 'bayestopt_', '-append'); " < < endl < < " end " < < endl
< < " if exist('dataset_', 'var') == 1 " < < endl
< < " save(' " < < basename < < " _results.mat', 'dataset_', '-append'); " < < endl < < " end " < < endl
< < " if exist('estimation_info', 'var') == 1 " < < endl
< < " save(' " < < basename < < " _results.mat', 'estimation_info', '-append'); " < < endl < < " end " < < endl
< < " if exist('dataset_info', 'var') == 1 " < < endl
< < " save(' " < < basename < < " _results.mat', 'dataset_info', '-append'); " < < endl < < " end " < < endl
< < " if exist('oo_recursive_', 'var') == 1 " < < endl
< < " save(' " < < basename < < " _results.mat', 'oo_recursive_', '-append'); " < < endl < < " end " < < endl ;
config_file . writeEndParallel ( mOutputFile ) ;
mOutputFile < < endl < < endl
< < " disp(['Total computing time : ' dynsec2hms(toc(tic0)) ]); " < < endl ;
if ( ! no_warn )
{
if ( warnings . countWarnings ( ) > 0 )
mOutputFile < < " disp('Note: " < < warnings . countWarnings ( ) < < " warning(s) encountered in the preprocessor') " < < endl ;
2013-03-05 12:53:37 +01:00
2018-11-07 15:24:57 +01:00
mOutputFile < < " if ~isempty(lastwarn) " < < endl
< < " disp('Note: warning(s) encountered in MATLAB/Octave code') " < < endl
< < " end " < < endl ;
}
2013-02-26 16:50:05 +01:00
}
2012-01-23 16:52:27 +01:00
2012-04-20 18:15:02 +02:00
if ( ! no_log )
mOutputFile < < " diary off " < < endl ;
2008-02-03 11:28:36 +01:00
mOutputFile . close ( ) ;
2009-04-30 15:05:21 +02:00
2015-05-10 18:16:11 +02:00
if ( hasModelChanged )
2009-07-07 16:20:48 +02:00
{
2015-05-10 18:16:11 +02:00
// Create static and dynamic files
if ( dynamic_model . equation_number ( ) > 0 )
2017-06-01 19:58:32 +02:00
{
if ( ! no_static )
{
2018-10-26 11:44:26 +02:00
static_model . writeStaticFile ( basename , block , byte_code , use_dll , mexext , matlabroot , dynareroot , false ) ;
2017-06-01 19:58:32 +02:00
static_model . writeParamsDerivativesFile ( basename , false ) ;
}
2009-12-16 14:21:31 +01:00
2018-09-21 17:13:19 +02:00
if ( linear_decomposition )
{
2018-10-26 11:44:26 +02:00
non_linear_equations_dynamic_model . writeDynamicFile ( basename , block , linear_decomposition , byte_code , use_dll , mexext , matlabroot , dynareroot , mod_file_struct . order_option , false ) ;
2018-09-21 17:13:19 +02:00
non_linear_equations_dynamic_model . writeParamsDerivativesFile ( basename , false ) ;
}
2018-10-26 11:44:26 +02:00
dynamic_model . writeDynamicFile ( basename , block , false , byte_code , use_dll , mexext , matlabroot , dynareroot , mod_file_struct . order_option , false ) ;
2018-09-21 17:13:19 +02:00
2017-06-01 19:58:32 +02:00
dynamic_model . writeParamsDerivativesFile ( basename , false ) ;
2019-05-03 19:24:55 +02:00
dynamic_model . writeDynamicJacobianNonZeroElts ( basename ) ;
2017-06-01 19:58:32 +02:00
}
2010-04-23 18:39:07 +02:00
2015-05-10 18:16:11 +02:00
// Create steady state file
2015-07-28 17:27:56 +02:00
steady_state_model . writeSteadyStateFile ( basename , mod_file_struct . ramsey_model_present , false ) ;
2018-09-03 17:16:28 +02:00
// Create epilogue file
epilogue . writeEpilogueFile ( basename ) ;
2015-05-10 18:16:11 +02:00
}
2015-07-21 17:47:56 +02:00
2018-12-20 17:04:28 +01:00
cout < < " done " < < endl ;
2008-02-03 11:28:36 +01:00
}
2015-07-21 17:26:08 +02:00
void
2018-12-20 17:04:28 +01:00
ModFile : : writeExternalFiles ( const string & basename , FileOutputType output , LanguageOutputType language ) const
2015-07-21 17:26:08 +02:00
{
2017-06-01 19:58:32 +02:00
switch ( language )
2015-07-21 17:26:08 +02:00
{
2018-07-18 17:28:05 +02:00
case LanguageOutputType : : julia :
2018-12-20 17:04:28 +01:00
writeExternalFilesJulia ( basename , output ) ;
2015-07-21 17:47:56 +02:00
break ;
2019-08-22 17:43:34 +02:00
case LanguageOutputType : : matlab :
cerr < < " The 'output' option cannot be used when language=matlab " < < endl ;
2015-07-21 17:26:08 +02:00
exit ( EXIT_FAILURE ) ;
}
}
2015-07-21 17:47:56 +02:00
void
2018-12-20 17:04:28 +01:00
ModFile : : writeExternalFilesJulia ( const string & basename , FileOutputType output ) const
2015-07-21 17:47:56 +02:00
{
ofstream jlOutputFile ;
if ( basename . size ( ) )
{
string fname ( basename ) ;
fname + = " .jl " ;
2018-06-27 15:12:12 +02:00
jlOutputFile . open ( fname , ios : : out | ios : : binary ) ;
2015-07-21 17:47:56 +02:00
if ( ! jlOutputFile . is_open ( ) )
{
cerr < < " ERROR: Can't open file " < < fname
< < " for writing " < < endl ;
exit ( EXIT_FAILURE ) ;
}
}
else
{
cerr < < " ERROR: Missing file name " < < endl ;
exit ( EXIT_FAILURE ) ;
}
jlOutputFile < < " module " < < basename < < endl
2015-08-21 12:00:47 +02:00
< < " # " < < endl
< < " # NB: this file was automatically generated by Dynare " < < endl
< < " # from " < < basename < < " .mod " < < endl
2016-06-13 11:58:43 +02:00
< < " # " < < endl < < endl
2015-07-23 17:32:09 +02:00
< < " using DynareModel " < < endl
2015-07-29 11:07:36 +02:00
< < " using DynareOptions " < < endl
2016-06-13 11:58:43 +02:00
< < " using DynareOutput " < < endl < < endl
2015-07-23 17:32:09 +02:00
< < " using Utils " < < endl
2016-06-13 11:58:43 +02:00
< < " using SteadyState " < < endl < < endl
2015-07-27 15:59:13 +02:00
< < " using " < < basename < < " Static " < < endl
2015-08-19 10:59:30 +02:00
< < " using " < < basename < < " Dynamic " < < endl
2019-04-03 16:32:52 +02:00
< < R " (if isfile( " ) " << basename << R " ( SteadyState . jl " )) " < < endl
2016-05-19 14:44:49 +02:00
< < " using " < < basename < < " SteadyState " < < endl
< < " end " < < endl
2019-04-03 16:32:52 +02:00
< < R " (if isfile( " ) " << basename << R " ( SteadyState2 . jl " )) " < < endl
2016-05-19 12:51:59 +02:00
< < " using " < < basename < < " SteadyState2 " < < endl
< < " end " < < endl < < endl
2017-06-01 19:58:32 +02:00
< < " export model_, options_, oo_ " < < endl ;
2015-07-29 13:31:42 +02:00
2015-07-29 14:59:09 +02:00
// Write Output
jlOutputFile < < endl
2016-05-19 18:32:48 +02:00
< < " oo_ = dynare_output() " < < endl
2019-04-03 16:32:52 +02:00
< < R " (oo_.dynare_version = " ) " << PACKAGE_VERSION << R " ( " ) " < < endl ;
2015-07-29 14:59:09 +02:00
2015-07-29 13:31:42 +02:00
// Write Options
jlOutputFile < < endl
2016-05-19 18:32:48 +02:00
< < " options_ = dynare_options() " < < endl
2019-04-03 16:32:52 +02:00
< < R " (options_.dynare_version = " ) " << PACKAGE_VERSION << R " ( " ) " < < endl ;
2019-09-10 12:37:11 +02:00
if ( linear )
2016-05-19 18:32:48 +02:00
jlOutputFile < < " options_.linear = true " < < endl ;
2015-07-29 13:31:42 +02:00
// Write Model
jlOutputFile < < endl
2016-05-19 18:32:48 +02:00
< < " model_ = dynare_model() " < < endl
2019-04-03 16:32:52 +02:00
< < R " (model_.fname = " ) " << basename << R " ( " ) " < < endl
< < R " (model_.dynare_version = " ) " << PACKAGE_VERSION << R " ( " ) " < < endl
2016-05-19 18:32:48 +02:00
< < " model_.sigma_e = zeros(Float64, " < < symbol_table . exo_nbr ( ) < < " , "
2015-07-24 12:33:28 +02:00
< < symbol_table . exo_nbr ( ) < < " ) " < < endl
2016-05-19 18:32:48 +02:00
< < " model_.correlation_matrix = ones(Float64, " < < symbol_table . exo_nbr ( ) < < " , "
2015-07-24 12:33:28 +02:00
< < symbol_table . exo_nbr ( ) < < " ) " < < endl
2016-05-19 18:32:48 +02:00
< < " model_.orig_eq_nbr = " < < mod_file_struct . orig_eq_nbr < < endl
< < " model_.eq_nbr = " < < dynamic_model . equation_number ( ) < < endl
< < " model_.ramsey_eq_nbr = " < < mod_file_struct . ramsey_eq_nbr < < endl ;
2015-07-21 17:47:56 +02:00
2015-07-24 12:33:28 +02:00
if ( mod_file_struct . calibrated_measurement_errors )
2016-05-19 18:32:48 +02:00
jlOutputFile < < " model_.h = zeros(Float64, "
2015-07-24 12:33:28 +02:00
< < symbol_table . observedVariablesNbr ( ) < < " , "
< < symbol_table . observedVariablesNbr ( ) < < " ); " < < endl
2016-05-19 18:32:48 +02:00
< < " model_.correlation_matrix_me = ones(Float64, "
2015-07-24 12:33:28 +02:00
< < symbol_table . observedVariablesNbr ( ) < < " , "
< < symbol_table . observedVariablesNbr ( ) < < " ); " < < endl ;
else
2016-05-19 18:32:48 +02:00
jlOutputFile < < " model_.h = zeros(Float64, 1, 1) " < < endl
< < " model_.correlation_matrix_me = ones(Float64, 1, 1) " < < endl ;
2015-07-24 12:33:28 +02:00
2018-12-20 17:04:28 +01:00
cout < < " Processing outputs ... " < < endl ;
2015-07-21 17:47:56 +02:00
symbol_table . writeJuliaOutput ( jlOutputFile ) ;
2015-07-27 15:33:38 +02:00
if ( dynamic_model . equation_number ( ) > 0 )
2015-07-27 17:02:51 +02:00
{
2018-09-21 17:13:19 +02:00
dynamic_model . writeOutput ( jlOutputFile , basename , false , false , false , false ,
2015-07-29 14:59:09 +02:00
mod_file_struct . order_option ,
2016-02-23 13:55:02 +01:00
mod_file_struct . estimation_present , false , true ) ;
2015-07-27 17:02:51 +02:00
if ( ! no_static )
2015-07-28 12:29:42 +02:00
{
2018-10-26 11:44:26 +02:00
static_model . writeStaticFile ( basename , false , false , false , " " , { } , { } , true ) ;
2015-07-28 12:29:42 +02:00
static_model . writeParamsDerivativesFile ( basename , true ) ;
}
2018-09-21 17:13:19 +02:00
dynamic_model . writeDynamicFile ( basename , block , linear_decomposition , byte_code , use_dll ,
2018-10-26 11:44:26 +02:00
" " , { } , { } , mod_file_struct . order_option , true ) ;
2015-07-28 14:59:55 +02:00
dynamic_model . writeParamsDerivativesFile ( basename , true ) ;
2015-07-27 17:02:51 +02:00
}
2015-07-28 17:27:56 +02:00
steady_state_model . writeSteadyStateFile ( basename , mod_file_struct . ramsey_model_present , true ) ;
2015-07-27 15:33:38 +02:00
2016-05-19 22:41:26 +02:00
// Print statements (includes parameter values)
2018-09-05 15:17:21 +02:00
for ( auto & statement : statements )
2018-06-04 12:26:16 +02:00
statement - > writeJuliaOutput ( jlOutputFile , basename ) ;
2016-05-19 22:41:26 +02:00
2016-05-19 18:32:48 +02:00
jlOutputFile < < " model_.static = " < < basename < < " Static.static! " < < endl
< < " model_.dynamic = " < < basename < < " Dynamic.dynamic! " < < endl
2018-03-29 14:10:34 +02:00
< < " model_.temporaries.static = " < < basename < < " Static.tmp_nbr " < < endl
< < " model_.temporaries.dynamic = " < < basename < < " Dynamic.tmp_nbr " < < endl
2019-04-03 16:32:52 +02:00
< < R " (if isfile( " ) " << basename << R " ( SteadyState . jl " )) " < < endl
2016-05-19 18:32:48 +02:00
< < " model_.user_written_analytical_steady_state = true " < < endl
2016-05-20 14:51:35 +02:00
< < " model_.steady_state = " < < basename < < " SteadyState.steady_state! " < < endl
2016-05-19 14:44:49 +02:00
< < " end " < < endl
2019-04-03 16:32:52 +02:00
< < R " (if isfile( " ) " << basename << R " ( SteadyState2 . jl " )) " < < endl
2016-05-19 18:32:48 +02:00
< < " model_.analytical_steady_state = true " < < endl
< < " model_.steady_state = " < < basename < < " SteadyState2.steady_state! " < < endl
2016-05-19 12:51:59 +02:00
< < " end " < < endl
2019-04-03 16:32:52 +02:00
< < R " (if isfile( " ) " << basename << R " ( StaticParamsDerivs . jl " )) " < < endl
2015-07-28 17:32:34 +02:00
< < " using " < < basename < < " StaticParamsDerivs " < < endl
2016-05-19 18:32:48 +02:00
< < " model_.static_params_derivs = " < < basename < < " StaticParamsDerivs.params_derivs " < < endl
2015-07-28 17:32:34 +02:00
< < " end " < < endl
2019-04-03 16:32:52 +02:00
< < R " (if isfile( " ) " << basename << R " ( DynamicParamsDerivs . jl " )) " < < endl
2015-07-28 17:32:34 +02:00
< < " using " < < basename < < " DynamicParamsDerivs " < < endl
2016-05-19 18:32:48 +02:00
< < " model_.dynamic_params_derivs = " < < basename < < " DynamicParamsDerivs.params_derivs " < < endl
2015-07-28 17:32:34 +02:00
< < " end " < < endl
2017-06-01 19:58:32 +02:00
< < " end " < < endl ;
2015-07-21 17:47:56 +02:00
jlOutputFile . close ( ) ;
2018-12-20 17:04:28 +01:00
cout < < " done " < < endl ;
2015-07-21 17:47:56 +02:00
}
2017-02-02 15:09:43 +01:00
void
2018-12-20 17:04:28 +01:00
ModFile : : writeJsonOutput ( const string & basename , JsonOutputPointType json , JsonFileOutputType json_output_mode , bool onlyjson , bool jsonderivsimple )
2017-02-20 12:18:11 +01:00
{
2018-07-18 17:28:05 +02:00
if ( json = = JsonOutputPointType : : nojson )
2017-02-20 12:18:11 +01:00
return ;
2018-07-18 17:28:05 +02:00
if ( json = = JsonOutputPointType : : parsing | | json = = JsonOutputPointType : : checkpass )
2017-02-20 12:18:11 +01:00
symbol_table . freeze ( ) ;
2018-07-18 17:28:05 +02:00
if ( json_output_mode = = JsonFileOutputType : : standardout )
2017-06-29 13:18:59 +02:00
cout < < " //-- BEGIN JSON --// " < < endl
< < " { " < < endl ;
2017-06-29 13:15:32 +02:00
2018-07-18 17:28:05 +02:00
writeJsonOutputParsingCheck ( basename , json_output_mode , json = = JsonOutputPointType : : transformpass , json = = JsonOutputPointType : : computingpass ) ;
2017-02-20 12:18:11 +01:00
2018-07-18 17:28:05 +02:00
if ( json = = JsonOutputPointType : : parsing | | json = = JsonOutputPointType : : checkpass )
2017-02-20 12:18:11 +01:00
symbol_table . unfreeze ( ) ;
2018-07-18 17:28:05 +02:00
if ( json = = JsonOutputPointType : : computingpass )
2017-06-29 12:42:28 +02:00
writeJsonComputingPassOutput ( basename , json_output_mode , jsonderivsimple ) ;
2017-02-20 12:18:11 +01:00
2018-07-18 17:28:05 +02:00
if ( json_output_mode = = JsonFileOutputType : : standardout )
2017-06-29 13:18:59 +02:00
cout < < " } " < < endl
< < " //-- END JSON --// " < < endl ;
2017-02-20 12:18:11 +01:00
2018-12-20 17:04:28 +01:00
switch ( json )
{
case JsonOutputPointType : : parsing :
cout < < " JSON written after Parsing step. " < < endl ;
break ;
case JsonOutputPointType : : checkpass :
cout < < " JSON written after Check step. " < < endl ;
break ;
case JsonOutputPointType : : transformpass :
cout < < " JSON written after Transform step. " < < endl ;
break ;
case JsonOutputPointType : : computingpass :
cout < < " JSON written after Computing step. " < < endl ;
break ;
case JsonOutputPointType : : nojson :
cerr < < " ModFile::writeJsonOutput: should not arrive here. " < < endl ;
exit ( EXIT_FAILURE ) ;
}
2017-02-28 14:34:22 +01:00
if ( onlyjson )
exit ( EXIT_SUCCESS ) ;
2017-02-20 12:18:11 +01:00
}
void
2017-06-28 17:11:24 +02:00
ModFile : : writeJsonOutputParsingCheck ( const string & basename , JsonFileOutputType json_output_mode , bool transformpass , bool computingpass ) const
2017-02-02 15:09:43 +01:00
{
ostringstream output ;
output < < " { " < < endl ;
symbol_table . writeJsonOutput ( output ) ;
2017-02-27 15:40:34 +01:00
output < < " , " ;
2017-02-02 15:09:43 +01:00
dynamic_model . writeJsonOutput ( output ) ;
2018-08-22 09:15:00 +02:00
if ( ! statements . empty ( )
2018-08-21 11:46:59 +02:00
| | ! var_model_table . empty ( )
2018-08-22 09:15:00 +02:00
| | ! trend_component_model_table . empty ( ) )
2017-02-02 15:09:43 +01:00
{
2019-04-03 16:32:52 +02:00
output < < R " (, " statements " : [) " ;
2018-08-21 11:46:59 +02:00
if ( ! var_model_table . empty ( ) )
{
var_model_table . writeJsonOutput ( output ) ;
output < < " , " ;
}
2018-08-22 09:15:00 +02:00
if ( ! trend_component_model_table . empty ( ) )
{
trend_component_model_table . writeJsonOutput ( output ) ;
output < < " , " ;
}
2018-06-04 15:03:26 +02:00
for ( auto it = statements . begin ( ) ;
2017-02-08 18:29:57 +01:00
it ! = statements . end ( ) ; it + + )
2017-02-02 15:09:43 +01:00
{
2017-02-08 18:29:57 +01:00
if ( it ! = statements . begin ( ) )
output < < " , " < < endl ;
2017-02-02 15:09:43 +01:00
( * it ) - > writeJsonOutput ( output ) ;
}
output < < " ] " < < endl ;
}
2017-06-28 17:11:24 +02:00
if ( computingpass )
{
output < < " , " ;
dynamic_model . writeJsonDynamicModelInfo ( output ) ;
}
2017-02-02 15:09:43 +01:00
output < < " } " < < endl ;
2017-06-28 12:04:04 +02:00
ostringstream original_model_output ;
original_model_output < < " " ;
2017-06-29 13:15:32 +02:00
if ( transformpass | | computingpass )
2017-06-28 12:04:04 +02:00
{
original_model_output < < " { " ;
original_model . writeJsonOriginalModelOutput ( original_model_output ) ;
2019-03-06 11:43:23 +01:00
if ( ! statements . empty ( ) | | ! var_model_table . empty ( ) | | ! trend_component_model_table . empty ( ) )
{
2019-04-03 16:32:52 +02:00
original_model_output < < endl < < R " (, " statements " : [) " ;
2019-03-06 11:43:23 +01:00
if ( ! var_model_table . empty ( ) )
{
var_model_table . writeJsonOutput ( original_model_output ) ;
original_model_output < < " , " ;
}
if ( ! trend_component_model_table . empty ( ) )
{
trend_component_model_table . writeJsonOutput ( original_model_output ) ;
original_model_output < < " , " ;
}
int i = 0 ;
for ( const auto & it : statements )
{
original_model_output < < ( i + + > 0 ? " , " : " " ) < < endl ;
it - > writeJsonOutput ( original_model_output ) ;
}
original_model_output < < " ] " < < endl ;
}
2017-06-28 12:04:04 +02:00
original_model_output < < " } " < < endl ;
}
2017-10-16 17:24:55 +02:00
ostringstream steady_state_model_output ;
steady_state_model_output < < " " ;
if ( dynamic_model . equation_number ( ) > 0 )
steady_state_model . writeJsonSteadyStateFile ( steady_state_model_output ,
transformpass | | computingpass ) ;
2018-07-18 17:28:05 +02:00
if ( json_output_mode = = JsonFileOutputType : : standardout )
2017-06-28 12:04:04 +02:00
{
2017-06-29 13:15:32 +02:00
if ( transformpass | | computingpass )
2019-04-03 16:32:52 +02:00
cout < < R " ( " transformed_modfile " : ) " ;
2017-06-29 13:15:32 +02:00
else
2019-04-03 16:32:52 +02:00
cout < < R " ( " modfile " : ) " ;
2017-06-28 12:04:04 +02:00
cout < < output . str ( ) ;
if ( ! original_model_output . str ( ) . empty ( ) )
2019-04-03 16:32:52 +02:00
cout < < R " (, " original_model " : ) " < < original_model_output . str ( ) ;
2017-10-16 17:24:55 +02:00
if ( ! steady_state_model_output . str ( ) . empty ( ) )
2019-04-03 16:32:52 +02:00
cout < < R " (, " steady_state_model " : ) " < < steady_state_model_output . str ( ) ;
2017-06-28 12:04:04 +02:00
}
2017-02-02 15:09:43 +01:00
else
{
ofstream jsonOutputFile ;
if ( basename . size ( ) )
{
2019-04-04 17:01:37 +02:00
filesystem : : create_directories ( basename + " /model/json " ) ;
2018-06-27 16:08:31 +02:00
string fname { basename + " /model/json/modfile.json " } ;
2018-06-27 15:12:12 +02:00
jsonOutputFile . open ( fname , ios : : out | ios : : binary ) ;
2017-02-02 15:09:43 +01:00
if ( ! jsonOutputFile . is_open ( ) )
{
cerr < < " ERROR: Can't open file " < < fname < < " for writing " < < endl ;
exit ( EXIT_FAILURE ) ;
}
}
2017-06-14 07:01:31 +02:00
else
{
cerr < < " ERROR: Missing file name " < < endl ;
exit ( EXIT_FAILURE ) ;
}
2017-02-02 15:09:43 +01:00
jsonOutputFile < < output . str ( ) ;
jsonOutputFile . close ( ) ;
2017-06-28 12:04:04 +02:00
if ( ! original_model_output . str ( ) . empty ( ) )
{
if ( basename . size ( ) )
{
2018-06-27 16:08:31 +02:00
string fname { basename + " /model/json/modfile-original.json " } ;
2018-06-27 15:12:12 +02:00
jsonOutputFile . open ( fname , ios : : out | ios : : binary ) ;
2017-06-28 12:04:04 +02:00
if ( ! jsonOutputFile . is_open ( ) )
{
cerr < < " ERROR: Can't open file " < < fname < < " for writing " < < endl ;
exit ( EXIT_FAILURE ) ;
}
}
else
{
cerr < < " ERROR: Missing file name " < < endl ;
exit ( EXIT_FAILURE ) ;
}
jsonOutputFile < < original_model_output . str ( ) ;
jsonOutputFile . close ( ) ;
}
2017-10-16 17:24:55 +02:00
if ( ! steady_state_model_output . str ( ) . empty ( ) )
{
if ( basename . size ( ) )
{
2018-06-27 16:08:31 +02:00
string fname { basename + " /model/json/steady_state_model.json " } ;
2018-06-27 15:12:12 +02:00
jsonOutputFile . open ( fname , ios : : out | ios : : binary ) ;
2017-10-16 17:24:55 +02:00
if ( ! jsonOutputFile . is_open ( ) )
{
cerr < < " ERROR: Can't open file " < < fname < < " for writing " < < endl ;
exit ( EXIT_FAILURE ) ;
}
}
else
{
cerr < < " ERROR: Missing file name " < < endl ;
exit ( EXIT_FAILURE ) ;
}
jsonOutputFile < < steady_state_model_output . str ( ) ;
jsonOutputFile . close ( ) ;
}
2017-02-02 15:09:43 +01:00
}
}
2017-02-20 12:18:11 +01:00
void
2017-06-29 12:42:28 +02:00
ModFile : : writeJsonComputingPassOutput ( const string & basename , JsonFileOutputType json_output_mode , bool jsonderivsimple ) const
2017-02-20 12:18:11 +01:00
{
2018-07-18 17:28:05 +02:00
if ( basename . empty ( ) & & json_output_mode ! = JsonFileOutputType : : standardout )
2017-06-29 15:03:31 +02:00
{
cerr < < " ERROR: Missing file name " < < endl ;
exit ( EXIT_FAILURE ) ;
}
ostringstream tmp_out , static_output , dynamic_output , static_paramsd_output , dynamic_paramsd_output ;
2017-02-20 12:18:11 +01:00
static_output < < " { " ;
2017-06-29 15:03:31 +02:00
static_model . writeJsonComputingPassOutput ( static_output , ! jsonderivsimple ) ;
static_output < < " } " ;
2017-02-20 12:18:11 +01:00
dynamic_output < < " { " ;
2017-06-29 15:03:31 +02:00
dynamic_model . writeJsonComputingPassOutput ( dynamic_output , ! jsonderivsimple ) ;
dynamic_output < < " } " ;
2017-02-20 12:18:11 +01:00
tmp_out < < " " ;
static_paramsd_output < < " " ;
2017-06-29 15:03:31 +02:00
static_model . writeJsonParamsDerivativesFile ( tmp_out , ! jsonderivsimple ) ;
2017-02-20 12:18:11 +01:00
if ( ! tmp_out . str ( ) . empty ( ) )
static_paramsd_output < < " { " < < tmp_out . str ( ) < < " } " < < endl ;
2017-06-29 15:03:31 +02:00
tmp_out . str ( " " ) ;
2017-02-20 12:18:11 +01:00
dynamic_paramsd_output < < " " ;
2017-06-29 15:03:31 +02:00
dynamic_model . writeJsonParamsDerivativesFile ( tmp_out , ! jsonderivsimple ) ;
if ( ! tmp_out . str ( ) . empty ( ) )
dynamic_paramsd_output < < " { " < < tmp_out . str ( ) < < " } " < < endl ;
2017-03-02 18:34:18 +01:00
2018-07-18 17:28:05 +02:00
if ( json_output_mode = = JsonFileOutputType : : standardout )
2017-02-20 12:18:11 +01:00
{
2019-04-03 16:32:52 +02:00
cout < < R " (, " static_model " : ) " < < static_output . str ( ) < < endl
< < R " (, " dynamic_model " : ) " < < dynamic_output . str ( ) < < endl ;
2017-03-02 18:34:18 +01:00
2017-02-20 12:18:11 +01:00
if ( ! static_paramsd_output . str ( ) . empty ( ) )
2019-04-03 16:32:52 +02:00
cout < < R " (, " static_params_deriv " : ) " < < static_paramsd_output . str ( ) < < endl ;
2017-03-02 18:34:18 +01:00
if ( ! dynamic_paramsd_output . str ( ) . empty ( ) )
2019-04-03 16:32:52 +02:00
cout < < R " (, " dynamic_params_deriv " : ) " < < dynamic_paramsd_output . str ( ) < < endl ;
2017-02-20 12:18:11 +01:00
}
else
{
2019-04-04 17:01:37 +02:00
filesystem : : create_directories ( basename + " /model/json " ) ;
2017-02-20 12:18:11 +01:00
2018-06-27 16:08:31 +02:00
writeJsonFileHelper ( basename + " /model/json/static.json " , static_output ) ;
writeJsonFileHelper ( basename + " /model/json/dynamic.json " , dynamic_output ) ;
2017-02-20 12:18:11 +01:00
if ( ! static_paramsd_output . str ( ) . empty ( ) )
2018-06-27 16:08:31 +02:00
writeJsonFileHelper ( basename + " /model/json/static_params_derivs.json " , static_paramsd_output ) ;
2017-02-20 12:18:11 +01:00
if ( ! dynamic_paramsd_output . str ( ) . empty ( ) )
2018-06-27 16:08:31 +02:00
writeJsonFileHelper ( basename + " /model/json/params_derivs.json " , dynamic_paramsd_output ) ;
2017-02-20 12:18:11 +01:00
}
}
2017-03-02 18:34:18 +01:00
void
2018-06-27 16:08:31 +02:00
ModFile : : writeJsonFileHelper ( const string & fname , ostringstream & output ) const
2017-03-02 18:34:18 +01:00
{
ofstream jsonOutput ;
2018-06-27 15:12:12 +02:00
jsonOutput . open ( fname , ios : : out | ios : : binary ) ;
2017-03-02 18:34:18 +01:00
if ( ! jsonOutput . is_open ( ) )
{
cerr < < " ERROR: Can't open file " < < fname < < " for writing " < < endl ;
exit ( EXIT_FAILURE ) ;
}
jsonOutput < < output . str ( ) ;
jsonOutput . close ( ) ;
}
2019-04-04 17:01:37 +02:00
filesystem : : path
ModFile : : unique_path ( )
{
filesystem : : path path ;
string possible_characters = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz " ;
random_device rd ;
mt19937 generator ( rd ( ) ) ;
uniform_int_distribution < int > distribution { 0 , static_cast < int > ( possible_characters . size ( ) ) - 1 } ;
do
{
constexpr int rand_length = 10 ;
string rand_str ( rand_length , ' \0 ' ) ;
for ( auto & dis : rand_str )
dis = possible_characters [ distribution ( generator ) ] ;
2019-09-11 17:03:37 +02:00
path = rand_str ;
2019-04-04 17:01:37 +02:00
}
while ( filesystem : : exists ( path ) ) ;
return path ;
}