2009-12-16 14:21:31 +01:00
/*
2023-01-09 15:19:36 +01:00
* Copyright © 2007 - 2023 Dynare Team
2008-01-11 14:42:14 +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
2021-06-09 17:33:48 +02:00
* along with Dynare . If not , see < https : //www.gnu.org/licenses/>.
2008-01-11 14:42:14 +01:00
*/
2021-02-09 15:55:36 +01:00
2013-03-22 15:44:34 +01:00
# include <ctime>
2021-02-01 12:28:50 +01:00
# include <cmath>
2021-02-09 15:55:36 +01:00
# include <cstring>
2023-01-24 12:21:08 +01:00
# include <type_traits>
2015-11-06 15:06:17 +01:00
2021-02-09 15:55:36 +01:00
# include "Interpreter.hh"
# include "ErrorHandling.hh"
2013-03-22 15:44:34 +01:00
2009-09-11 19:06:54 +02:00
string
Get_Argument ( const mxArray * prhs )
{
const mxArray * mxa = prhs ;
2021-02-01 12:39:34 +01:00
auto buflen = mwSize ( mxGetM ( mxa ) * mxGetN ( mxa ) + 1 ) ;
2009-09-11 19:06:54 +02:00
char * first_argument ;
2019-04-23 12:58:38 +02:00
first_argument = static_cast < char * > ( mxCalloc ( buflen , sizeof ( char ) ) ) ;
2013-03-22 15:44:34 +01:00
size_t status = mxGetString ( mxa , first_argument , buflen ) ;
2009-09-11 19:06:54 +02:00
if ( status ! = 0 )
mexWarnMsgTxt ( " Not enough space. The first argument is truncated. " ) ;
string f ( first_argument ) ;
mxFree ( first_argument ) ;
return f ;
}
2009-12-16 14:21:31 +01:00
2013-03-22 15:44:34 +01:00
string
deblank ( string x )
{
2019-04-23 12:58:38 +02:00
for ( int i = 0 ; i < static_cast < int > ( x . length ( ) ) ; i + + )
2013-03-22 15:44:34 +01:00
if ( x [ i ] = = ' ' )
x . erase ( i - - , 1 ) ;
return x ;
}
2009-12-16 18:18:38 +01:00
void
2010-10-11 19:21:32 +02:00
Get_Arguments_and_global_variables ( int nrhs ,
const mxArray * prhs [ ] ,
int & count_array_argument ,
2013-03-22 15:44:34 +01:00
double * yd [ ] , size_t & row_y , size_t & col_y ,
double * xd [ ] , size_t & row_x , size_t & col_x ,
double * params [ ] ,
double * steady_yd [ ] , size_t & steady_row_y , size_t & steady_col_y ,
2011-03-14 17:46:00 +01:00
unsigned int & periods ,
2010-10-11 19:21:32 +02:00
mxArray * block_structur [ ] ,
2023-01-09 15:19:36 +01:00
bool & steady_state , bool & block_decomposed ,
bool & evaluate , int & block ,
2010-12-31 16:41:50 +01:00
mxArray * M_ [ ] , mxArray * oo_ [ ] , mxArray * options_ [ ] , bool & global_temporary_terms ,
2011-01-14 19:22:29 +01:00
bool & print ,
2011-06-17 16:37:36 +02:00
bool & print_error ,
2013-03-22 15:44:34 +01:00
mxArray * GlobalTemporaryTerms [ ] ,
2015-09-22 12:45:27 +02:00
string * plan_struct_name , string * pfplan_struct_name , bool * extended_path , mxArray * ep_struct [ ] )
2010-10-11 19:21:32 +02:00
{
2013-03-22 15:44:34 +01:00
size_t pos ;
2015-09-22 12:45:27 +02:00
* extended_path = false ;
2021-02-01 14:43:52 +01:00
for ( int i = 0 ; i < nrhs ; i + + )
{
2022-02-17 17:41:10 +01:00
# ifdef DEBUG
if ( mxIsChar ( prhs [ i ] ) )
mexPrintf ( " Arg %d: %s \n " , i , Get_Argument ( prhs [ i ] ) . c_str ( ) ) ;
# endif
2021-02-01 14:43:52 +01:00
if ( ! mxIsChar ( prhs [ i ] ) )
{
switch ( count_array_argument )
{
case 0 :
* yd = mxGetPr ( prhs [ i ] ) ;
row_y = mxGetM ( prhs [ i ] ) ;
col_y = mxGetN ( prhs [ i ] ) ;
break ;
case 1 :
* xd = mxGetPr ( prhs [ i ] ) ;
row_x = mxGetM ( prhs [ i ] ) ;
col_x = mxGetN ( prhs [ i ] ) ;
break ;
case 2 :
* params = mxGetPr ( prhs [ i ] ) ;
break ;
case 3 :
* steady_yd = mxGetPr ( prhs [ i ] ) ;
steady_row_y = mxGetM ( prhs [ i ] ) ;
steady_col_y = mxGetN ( prhs [ i ] ) ;
break ;
case 4 :
2021-02-03 18:10:01 +01:00
periods = static_cast < int > ( mxGetScalar ( prhs [ i ] ) ) ;
2021-02-01 14:43:52 +01:00
break ;
case 5 :
* block_structur = mxDuplicateArray ( prhs [ i ] ) ;
break ;
case 6 :
global_temporary_terms = true ;
* GlobalTemporaryTerms = mxDuplicateArray ( prhs [ i ] ) ;
break ;
default :
mexPrintf ( " Unknown argument count_array_argument=%d \n " , count_array_argument ) ;
break ;
}
count_array_argument + + ;
}
else
if ( Get_Argument ( prhs [ i ] ) = = " static " )
steady_state = true ;
else if ( Get_Argument ( prhs [ i ] ) = = " dynamic " )
steady_state = false ;
2023-01-09 15:19:36 +01:00
else if ( Get_Argument ( prhs [ i ] ) = = " block_decomposed " )
block_decomposed = true ;
2021-02-01 14:43:52 +01:00
else if ( Get_Argument ( prhs [ i ] ) = = " evaluate " )
evaluate = true ;
else if ( Get_Argument ( prhs [ i ] ) = = " global_temporary_terms " )
global_temporary_terms = true ;
else if ( Get_Argument ( prhs [ i ] ) = = " print " )
print = true ;
else if ( Get_Argument ( prhs [ i ] ) = = " no_print_error " )
print_error = false ;
else
2011-02-04 16:53:12 +01:00
{
2021-02-01 14:43:52 +01:00
pos = 0 ;
if ( Get_Argument ( prhs [ i ] ) . substr ( 0 , 5 ) = = " block " )
{
size_t pos1 = Get_Argument ( prhs [ i ] ) . find ( " = " , pos + 5 ) ;
if ( pos1 ! = string : : npos )
pos = pos1 + 1 ;
else
pos + = 5 ;
block = atoi ( Get_Argument ( prhs [ i ] ) . substr ( pos , string : : npos ) . c_str ( ) ) - 1 ;
}
else if ( Get_Argument ( prhs [ i ] ) . substr ( 0 , 13 ) = = " extended_path " )
{
* extended_path = true ;
if ( ( i + 1 ) > = nrhs )
* ep_struct = nullptr ;
else
{
* ep_struct = mxDuplicateArray ( prhs [ i + 1 ] ) ;
i + + ;
}
}
else if ( Get_Argument ( prhs [ i ] ) . substr ( 0 , 6 ) = = " pfplan " )
{
size_t pos1 = Get_Argument ( prhs [ i ] ) . find ( " = " , pos + 6 ) ;
if ( pos1 ! = string : : npos )
pos = pos1 + 1 ;
else
pos + = 6 ;
* pfplan_struct_name = deblank ( Get_Argument ( prhs [ i ] ) . substr ( pos , string : : npos ) ) ;
}
else if ( Get_Argument ( prhs [ i ] ) . substr ( 0 , 4 ) = = " plan " )
2011-02-04 16:53:12 +01:00
{
2021-02-01 14:43:52 +01:00
size_t pos1 = Get_Argument ( prhs [ i ] ) . find ( " = " , pos + 4 ) ;
if ( pos1 ! = string : : npos )
pos = pos1 + 1 ;
else
pos + = 4 ;
* plan_struct_name = deblank ( Get_Argument ( prhs [ i ] ) . substr ( pos , string : : npos ) ) ;
}
else
2022-07-29 12:42:50 +02:00
throw FatalException { " In main, unknown argument : " + Get_Argument ( prhs [ i ] ) } ;
2011-02-04 16:53:12 +01:00
}
2021-02-01 14:43:52 +01:00
}
2011-03-14 17:46:00 +01:00
if ( count_array_argument > 0 & & count_array_argument < 5 )
2010-07-23 11:20:24 +02:00
{
2010-10-11 19:21:32 +02:00
if ( count_array_argument = = 3 & & steady_state )
periods = 1 ;
else
2022-07-29 12:42:50 +02:00
throw FatalException { " In main, missing arguments. All the following arguments have to be indicated y, x, params, it_, ys " } ;
2010-07-23 11:20:24 +02:00
}
2010-10-11 19:21:32 +02:00
* M_ = mexGetVariable ( " global " , " M_ " ) ;
2021-02-03 18:10:01 +01:00
if ( ! * M_ )
2022-07-29 12:42:50 +02:00
throw FatalException { " In main, global variable not found: M_ " } ;
2021-02-03 18:10:01 +01:00
2007-10-04 00:01:08 +02:00
/* Gets variables and parameters from global workspace of Matlab */
2010-10-11 19:21:32 +02:00
* oo_ = mexGetVariable ( " global " , " oo_ " ) ;
2021-02-03 18:10:01 +01:00
if ( ! * oo_ )
2022-07-29 12:42:50 +02:00
throw FatalException { " In main, global variable not found: oo_ " } ;
2021-02-03 18:10:01 +01:00
2010-10-11 19:21:32 +02:00
* options_ = mexGetVariable ( " global " , " options_ " ) ;
2021-02-03 18:10:01 +01:00
if ( ! * options_ )
2022-07-29 12:42:50 +02:00
throw FatalException { " In main, global variable not found: options_ " } ;
2010-10-11 19:21:32 +02:00
}
/* The gateway routine */
2021-02-01 14:43:52 +01:00
void
mexFunction ( int nlhs , mxArray * plhs [ ] , int nrhs , const mxArray * prhs [ ] )
2010-10-11 19:21:32 +02:00
{
mxArray * M_ , * oo_ , * options_ ;
2011-02-04 16:53:12 +01:00
mxArray * GlobalTemporaryTerms ;
2021-02-01 13:49:27 +01:00
mxArray * block_structur = nullptr ;
mxArray * pfplan_struct = nullptr ;
2022-07-05 13:02:17 +02:00
size_t i , row_y = 0 , col_y = 0 , row_x = 0 , col_x = 0 ;
2013-03-22 15:44:34 +01:00
size_t steady_row_y , steady_col_y ;
2010-10-11 19:21:32 +02:00
int y_kmin = 0 , y_kmax = 0 , y_decal = 0 ;
unsigned int periods = 1 ;
double * direction ;
bool steady_state = false ;
2023-01-09 15:19:36 +01:00
bool block_decomposed { false } ;
2010-10-11 19:21:32 +02:00
bool evaluate = false ;
int block = - 1 ;
2021-02-01 13:49:27 +01:00
double * params = nullptr ;
double * yd = nullptr , * xd = nullptr ;
2010-10-11 19:21:32 +02:00
int count_array_argument = 0 ;
2010-12-31 16:41:50 +01:00
bool global_temporary_terms = false ;
2011-12-12 12:40:46 +01:00
bool print = false , print_error = true , print_it = false ;
2023-02-17 19:46:41 +01:00
double * steady_yd = nullptr ;
2013-03-22 15:44:34 +01:00
string plan , pfplan ;
2015-09-22 12:45:27 +02:00
bool extended_path ;
2017-05-16 16:30:27 +02:00
mxArray * extended_path_struct ;
2013-03-22 15:44:34 +01:00
2015-09-22 12:45:27 +02:00
table_conditional_local_type conditional_local ;
vector < s_plan > splan , spfplan , sextended_path , sconditional_extended_path ;
vector_table_conditional_local_type vector_conditional_local ;
table_conditional_global_type table_conditional_global ;
int max_periods = 0 ;
2013-03-22 15:44:34 +01:00
2022-02-17 17:41:10 +01:00
# ifdef DEBUG
mexPrintf ( " ************************************** \n " ) ;
mexPrintf ( " ENTERING BYTECODE: nargin=%d, nargout=%d \n " , nrhs , nlhs ) ;
# endif
2010-10-11 19:21:32 +02:00
try
{
Get_Arguments_and_global_variables ( nrhs , prhs , count_array_argument ,
2011-02-04 16:53:12 +01:00
& yd , row_y , col_y ,
& xd , row_x , col_x ,
2013-03-22 15:44:34 +01:00
& params ,
2011-03-14 17:46:00 +01:00
& steady_yd , steady_row_y , steady_col_y ,
periods ,
2011-02-04 16:53:12 +01:00
& block_structur ,
2023-01-09 15:19:36 +01:00
steady_state , block_decomposed , evaluate , block ,
2011-02-04 16:53:12 +01:00
& M_ , & oo_ , & options_ , global_temporary_terms ,
2013-03-22 15:44:34 +01:00
print , print_error , & GlobalTemporaryTerms ,
2015-09-22 12:45:27 +02:00
& plan , & pfplan , & extended_path , & extended_path_struct ) ;
2010-10-11 19:21:32 +02:00
}
2022-07-29 12:42:50 +02:00
catch ( GeneralException & feh )
2010-10-11 19:21:32 +02:00
{
2022-07-29 12:42:50 +02:00
mexErrMsgTxt ( feh . message . c_str ( ) ) ;
2010-10-11 19:21:32 +02:00
}
2022-02-17 17:41:10 +01:00
# ifdef DEBUG
mexPrintf ( " ************************************** \n " ) ;
# endif
2010-07-23 11:20:24 +02:00
if ( ! count_array_argument )
2013-03-22 15:44:34 +01:00
{
int field = mxGetFieldNumber ( M_ , " params " ) ;
if ( field < 0 )
2020-01-10 17:55:57 +01:00
mexErrMsgTxt ( " params is not a field of M_ " ) ;
2013-03-22 15:44:34 +01:00
params = mxGetPr ( mxGetFieldByNumber ( M_ , 0 , field ) ) ;
}
2010-09-24 12:52:58 +02:00
2022-07-28 16:56:40 +02:00
BasicSymbolTable symbol_table ;
2015-09-22 12:45:27 +02:00
vector < string > dates ;
2013-03-22 15:44:34 +01:00
2015-09-22 12:45:27 +02:00
if ( extended_path )
{
2021-02-09 15:55:36 +01:00
if ( ! extended_path_struct )
mexErrMsgTxt ( " The 'extended_path' option must be followed by the extended_path descriptor " ) ;
2017-05-16 16:30:27 +02:00
mxArray * date_str = mxGetField ( extended_path_struct , 0 , " date_str " ) ;
2021-02-09 15:55:36 +01:00
if ( ! date_str )
mexErrMsgTxt ( " The extended_path description structure does not contain the member: date_str " ) ;
2015-09-22 12:45:27 +02:00
int nb_periods = mxGetM ( date_str ) * mxGetN ( date_str ) ;
2017-03-24 23:15:25 +01:00
2017-05-16 16:30:27 +02:00
mxArray * constrained_vars_ = mxGetField ( extended_path_struct , 0 , " constrained_vars_ " ) ;
2021-02-09 15:55:36 +01:00
if ( ! constrained_vars_ )
mexErrMsgTxt ( " The extended_path description structure does not contain the member: constrained_vars_ " ) ;
2017-05-16 16:30:27 +02:00
mxArray * constrained_paths_ = mxGetField ( extended_path_struct , 0 , " constrained_paths_ " ) ;
2021-02-09 15:55:36 +01:00
if ( ! constrained_paths_ )
mexErrMsgTxt ( " The extended_path description structure does not contain the member: constrained_paths_ " ) ;
2017-05-16 16:30:27 +02:00
mxArray * constrained_int_date_ = mxGetField ( extended_path_struct , 0 , " constrained_int_date_ " ) ;
2021-02-09 15:55:36 +01:00
if ( ! constrained_int_date_ )
mexErrMsgTxt ( " The extended_path description structure does not contain the member: constrained_int_date_ " ) ;
2017-05-16 16:30:27 +02:00
mxArray * constrained_perfect_foresight_ = mxGetField ( extended_path_struct , 0 , " constrained_perfect_foresight_ " ) ;
2021-02-09 15:55:36 +01:00
if ( ! constrained_perfect_foresight_ )
mexErrMsgTxt ( " The extended_path description structure does not contain the member: constrained_perfect_foresight_ " ) ;
2017-05-16 16:30:27 +02:00
mxArray * shock_var_ = mxGetField ( extended_path_struct , 0 , " shock_vars_ " ) ;
2021-02-09 15:55:36 +01:00
if ( ! shock_var_ )
mexErrMsgTxt ( " The extended_path description structure does not contain the member: shock_vars_ " ) ;
2017-05-16 16:30:27 +02:00
mxArray * shock_paths_ = mxGetField ( extended_path_struct , 0 , " shock_paths_ " ) ;
2021-02-09 15:55:36 +01:00
if ( ! shock_paths_ )
mexErrMsgTxt ( " The extended_path description structure does not contain the member: shock_paths_ " ) ;
2017-05-16 16:30:27 +02:00
mxArray * shock_int_date_ = mxGetField ( extended_path_struct , 0 , " shock_int_date_ " ) ;
2021-02-09 15:55:36 +01:00
if ( ! shock_int_date_ )
mexErrMsgTxt ( " The extended_path description structure does not contain the member: shock_int_date_ " ) ;
2017-05-16 16:30:27 +02:00
mxArray * shock_str_date_ = mxGetField ( extended_path_struct , 0 , " shock_str_date_ " ) ;
2021-02-09 15:55:36 +01:00
if ( ! shock_str_date_ )
mexErrMsgTxt ( " The extended_path description structure does not contain the member: shock_str_date_ " ) ;
2015-09-22 12:45:27 +02:00
int nb_constrained = mxGetM ( constrained_vars_ ) * mxGetN ( constrained_vars_ ) ;
int nb_controlled = 0 ;
2017-05-16 16:30:27 +02:00
mxArray * options_cond_fcst_ = mxGetField ( extended_path_struct , 0 , " options_cond_fcst_ " ) ;
2021-02-01 13:49:27 +01:00
mxArray * controlled_varexo = nullptr ;
2021-02-09 15:55:36 +01:00
if ( options_cond_fcst_ )
2015-09-22 12:45:27 +02:00
{
controlled_varexo = mxGetField ( options_cond_fcst_ , 0 , " controlled_varexo " ) ;
nb_controlled = mxGetM ( controlled_varexo ) * mxGetN ( controlled_varexo ) ;
if ( nb_controlled ! = nb_constrained )
2021-02-03 18:10:01 +01:00
mexErrMsgTxt ( " The number of exogenized variables and the number of exogenous controlled variables should be equal. " ) ;
2015-09-22 12:45:27 +02:00
}
2021-02-01 13:49:27 +01:00
double * controlled_varexo_value = nullptr ;
2021-02-09 15:55:36 +01:00
if ( controlled_varexo )
2015-09-22 12:45:27 +02:00
controlled_varexo_value = mxGetPr ( controlled_varexo ) ;
2017-05-16 16:30:27 +02:00
double * constrained_var_value = mxGetPr ( constrained_vars_ ) ;
2015-09-22 12:45:27 +02:00
sconditional_extended_path . resize ( nb_constrained ) ;
max_periods = 0 ;
2017-05-16 16:30:27 +02:00
if ( nb_constrained )
2015-09-22 12:45:27 +02:00
{
conditional_local . is_cond = false ;
conditional_local . var_exo = 0 ;
conditional_local . var_endo = 0 ;
conditional_local . constrained_value = 0 ;
for ( int i = 0 ; i < nb_periods ; i + + )
{
vector_conditional_local . clear ( ) ;
for ( unsigned int j = 0 ; j < row_y ; j + + )
{
conditional_local . var_endo = j ;
vector_conditional_local . push_back ( conditional_local ) ;
}
table_conditional_global [ i ] = vector_conditional_local ;
}
}
2017-03-24 23:15:25 +01:00
2015-09-22 12:45:27 +02:00
vector_table_conditional_local_type vv3 = table_conditional_global [ 0 ] ;
for ( int i = 0 ; i < nb_constrained ; i + + )
{
sconditional_extended_path [ i ] . exo_num = ceil ( constrained_var_value [ i ] ) ;
sconditional_extended_path [ i ] . var_num = ceil ( controlled_varexo_value [ i ] ) ;
2017-05-16 16:30:27 +02:00
mxArray * Array_constrained_paths_ = mxGetCell ( constrained_paths_ , i ) ;
2015-09-22 12:45:27 +02:00
double * specific_constrained_paths_ = mxGetPr ( Array_constrained_paths_ ) ;
double * specific_constrained_int_date_ = mxGetPr ( mxGetCell ( constrained_int_date_ , i ) ) ;
int nb_local_periods = mxGetM ( Array_constrained_paths_ ) * mxGetN ( Array_constrained_paths_ ) ;
2019-04-23 12:58:38 +02:00
int * constrained_int_date = static_cast < int * > ( mxMalloc ( nb_local_periods * sizeof ( int ) ) ) ;
2022-07-29 12:58:10 +02:00
test_mxMalloc ( constrained_int_date , __LINE__ , __FILE__ , __func__ , nb_local_periods * sizeof ( int ) ) ;
2015-09-22 12:45:27 +02:00
if ( nb_periods < nb_local_periods )
2021-02-09 15:55:36 +01:00
mexErrMsgTxt ( ( " The total number of simulation periods ( " + to_string ( nb_periods )
2021-02-03 18:10:01 +01:00
+ " ) is lesser than the number of periods in the shock definitions ( "
+ to_string ( nb_local_periods ) ) . c_str ( ) ) ;
sconditional_extended_path [ i ] . per_value . resize ( nb_local_periods ) ;
sconditional_extended_path [ i ] . value . resize ( nb_periods ) ;
2015-09-22 12:45:27 +02:00
for ( int j = 0 ; j < nb_periods ; j + + )
sconditional_extended_path [ i ] . value [ j ] = 0 ;
for ( int j = 0 ; j < nb_local_periods ; j + + )
{
2021-02-03 18:10:01 +01:00
constrained_int_date [ j ] = static_cast < int > ( specific_constrained_int_date_ [ j ] ) - 1 ;
2015-09-22 12:45:27 +02:00
conditional_local . is_cond = true ;
conditional_local . var_exo = sconditional_extended_path [ i ] . var_num - 1 ;
conditional_local . var_endo = sconditional_extended_path [ i ] . exo_num - 1 ;
conditional_local . constrained_value = specific_constrained_paths_ [ j ] ;
table_conditional_global [ constrained_int_date [ j ] ] [ sconditional_extended_path [ i ] . exo_num - 1 ] = conditional_local ;
2021-02-03 18:10:01 +01:00
sconditional_extended_path [ i ] . per_value [ j ] = { constrained_int_date [ j ] , specific_constrained_paths_ [ j ] } ;
2017-05-16 16:30:27 +02:00
sconditional_extended_path [ i ] . value [ constrained_int_date [ j ] ] = specific_constrained_paths_ [ j ] ;
2021-02-03 18:10:01 +01:00
max_periods = max ( max_periods , constrained_int_date [ j ] + 1 ) ;
2015-09-22 12:45:27 +02:00
}
mxFree ( constrained_int_date ) ;
}
vector_table_conditional_local_type vv = table_conditional_global [ 0 ] ;
2017-05-16 16:30:27 +02:00
double * shock_var_value = mxGetPr ( shock_var_ ) ;
2015-09-22 12:45:27 +02:00
int nb_shocks = mxGetM ( shock_var_ ) * mxGetN ( shock_var_ ) ;
sextended_path . resize ( nb_shocks ) ;
for ( int i = 0 ; i < nb_shocks ; i + + )
{
sextended_path [ i ] . exo_num = ceil ( shock_var_value [ i ] ) ;
2017-05-16 16:30:27 +02:00
mxArray * Array_shock_paths_ = mxGetCell ( shock_paths_ , i ) ;
2015-09-22 12:45:27 +02:00
double * specific_shock_paths_ = mxGetPr ( Array_shock_paths_ ) ;
double * specific_shock_int_date_ = mxGetPr ( mxGetCell ( shock_int_date_ , i ) ) ;
int nb_local_periods = mxGetM ( Array_shock_paths_ ) * mxGetN ( Array_shock_paths_ ) ;
if ( nb_periods < nb_local_periods )
2022-06-22 12:51:08 +02:00
mexErrMsgTxt ( ( " The total number of simulation periods ( " + to_string ( nb_periods )
2021-02-03 18:10:01 +01:00
+ " ) is lesser than the number of periods in the shock definitions ( "
+ to_string ( nb_local_periods ) ) . c_str ( ) ) ;
sextended_path [ i ] . per_value . resize ( nb_local_periods ) ;
sextended_path [ i ] . value . resize ( nb_periods ) ;
2015-09-22 12:45:27 +02:00
for ( int j = 0 ; j < nb_periods ; j + + )
sextended_path [ i ] . value [ j ] = 0 ;
for ( int j = 0 ; j < nb_local_periods ; j + + )
{
2021-02-03 18:10:01 +01:00
sextended_path [ i ] . per_value [ j ] = { static_cast < int > ( specific_shock_int_date_ [ j ] ) , specific_shock_paths_ [ j ] } ;
sextended_path [ i ] . value [ static_cast < int > ( specific_shock_int_date_ [ j ] - 1 ) ] = specific_shock_paths_ [ j ] ;
max_periods = max ( max_periods , static_cast < int > ( specific_shock_int_date_ [ j ] ) ) ;
2015-09-22 12:45:27 +02:00
}
}
2017-05-16 16:30:27 +02:00
for ( int i = 0 ; i < nb_periods ; i + + )
2015-09-22 12:45:27 +02:00
{
int buflen = mxGetNumberOfElements ( mxGetCell ( date_str , i ) ) + 1 ;
2019-04-23 12:58:38 +02:00
char * buf = static_cast < char * > ( mxCalloc ( buflen , sizeof ( char ) ) ) ;
2015-09-22 12:45:27 +02:00
int info = mxGetString ( mxGetCell ( date_str , i ) , buf , buflen ) ;
if ( info )
2021-02-09 15:55:36 +01:00
mexErrMsgTxt ( " Can not allocated memory to store the date_str in the extended path descriptor " ) ;
2021-02-01 12:46:02 +01:00
dates . emplace_back ( buf ) ; //string(Dates[i]);
2015-09-22 12:45:27 +02:00
mxFree ( buf ) ;
}
2017-05-16 16:30:27 +02:00
}
if ( plan . length ( ) > 0 )
2013-03-22 15:44:34 +01:00
{
2017-05-16 16:30:27 +02:00
mxArray * plan_struct = mexGetVariable ( " base " , plan . c_str ( ) ) ;
2021-02-09 15:55:36 +01:00
if ( ! plan_struct )
mexErrMsgTxt ( ( " Can't find the plan: " + plan ) . c_str ( ) ) ;
2013-03-22 15:44:34 +01:00
size_t n_plan = mxGetN ( plan_struct ) ;
splan . resize ( n_plan ) ;
2019-04-23 12:58:38 +02:00
for ( int i = 0 ; i < static_cast < int > ( n_plan ) ; i + + )
2013-03-22 15:44:34 +01:00
{
splan [ i ] . var = " " ;
splan [ i ] . exo = " " ;
2017-05-16 16:30:27 +02:00
mxArray * tmp = mxGetField ( plan_struct , i , " exo " ) ;
2013-03-22 15:44:34 +01:00
if ( tmp )
{
2019-12-20 14:50:19 +01:00
char name [ 100 ] ;
2013-03-22 15:44:34 +01:00
mxGetString ( tmp , name , 100 ) ;
splan [ i ] . var = name ;
2022-07-28 16:56:40 +02:00
auto [ variable_type , exo_num ] = symbol_table . getIDAndType ( name ) ;
2022-07-05 13:02:17 +02:00
if ( variable_type = = SymbolType : : exogenous )
2013-03-22 15:44:34 +01:00
splan [ i ] . var_num = exo_num ;
else
2022-07-29 12:42:50 +02:00
mexErrMsgTxt ( ( " The variable ' " s + name + " ' defined as var in plan is not an exogenous " ) . c_str ( ) ) ;
2013-03-22 15:44:34 +01:00
}
tmp = mxGetField ( plan_struct , i , " var " ) ;
if ( tmp )
{
2019-12-20 14:50:19 +01:00
char name [ 100 ] ;
2013-03-22 15:44:34 +01:00
mxGetString ( tmp , name , 100 ) ;
splan [ i ] . exo = name ;
2022-07-28 16:56:40 +02:00
auto [ variable_type , exo_num ] = symbol_table . getIDAndType ( name ) ;
2018-07-18 17:51:59 +02:00
if ( variable_type = = SymbolType : : endogenous )
2013-03-22 15:44:34 +01:00
splan [ i ] . exo_num = exo_num ;
else
2022-07-29 12:42:50 +02:00
mexErrMsgTxt ( ( " The variable ' " s + name + " ' defined as exo in plan is not an endogenous variable " ) . c_str ( ) ) ;
2013-03-22 15:44:34 +01:00
}
tmp = mxGetField ( plan_struct , i , " per_value " ) ;
if ( tmp )
{
size_t num_shocks = mxGetM ( tmp ) ;
2021-02-03 18:10:01 +01:00
splan [ i ] . per_value . resize ( num_shocks ) ;
2017-05-16 16:30:27 +02:00
double * per_value = mxGetPr ( tmp ) ;
2019-04-23 12:58:38 +02:00
for ( int j = 0 ; j < static_cast < int > ( num_shocks ) ; j + + )
2021-02-03 18:10:01 +01:00
splan [ i ] . per_value [ j ] = { ceil ( per_value [ j ] ) , per_value [ j + num_shocks ] } ;
2013-03-22 15:44:34 +01:00
}
}
2013-06-12 16:05:10 +02:00
int i = 0 ;
2021-02-01 12:32:17 +01:00
for ( auto & it : splan )
2013-03-22 15:44:34 +01:00
{
mexPrintf ( " ---------------------------------------------------------------------------------------------------- \n " ) ;
2017-06-28 15:06:54 +02:00
mexPrintf ( " surprise #%d \n " , i + 1 ) ;
2021-02-01 12:32:17 +01:00
if ( it . exo . length ( ) )
mexPrintf ( " plan fliping var=%s (%d) exo=%s (%d) for the following periods and with the following values: \n " , it . var . c_str ( ) , it . var_num , it . exo . c_str ( ) , it . exo_num ) ;
2013-03-22 15:44:34 +01:00
else
2021-02-01 12:32:17 +01:00
mexPrintf ( " plan shocks on var=%s for the following periods and with the following values: \n " , it . var . c_str ( ) ) ;
2021-02-03 18:10:01 +01:00
for ( auto & [ period , value ] : it . per_value )
mexPrintf ( " %3d %10.5f \n " , period , value ) ;
2013-03-22 15:44:34 +01:00
i + + ;
}
}
2017-05-16 16:30:27 +02:00
if ( pfplan . length ( ) > 0 )
2013-03-22 15:44:34 +01:00
{
pfplan_struct = mexGetVariable ( " base " , pfplan . c_str ( ) ) ;
if ( ! pfplan_struct )
2021-02-03 18:10:01 +01:00
mexErrMsgTxt ( ( " Can't find the pfplan: " + pfplan ) . c_str ( ) ) ;
2013-03-22 15:44:34 +01:00
size_t n_plan = mxGetN ( pfplan_struct ) ;
spfplan . resize ( n_plan ) ;
2019-04-23 12:58:38 +02:00
for ( int i = 0 ; i < static_cast < int > ( n_plan ) ; i + + )
2013-03-22 15:44:34 +01:00
{
spfplan [ i ] . var = " " ;
spfplan [ i ] . exo = " " ;
2017-05-16 16:30:27 +02:00
mxArray * tmp = mxGetField ( pfplan_struct , i , " var " ) ;
2013-03-22 15:44:34 +01:00
if ( tmp )
{
2019-12-20 14:50:19 +01:00
char name [ 100 ] ;
2013-03-22 15:44:34 +01:00
mxGetString ( tmp , name , 100 ) ;
spfplan [ i ] . var = name ;
2022-07-28 16:56:40 +02:00
auto [ variable_type , exo_num ] = symbol_table . getIDAndType ( name ) ;
2022-07-05 13:02:17 +02:00
if ( variable_type = = SymbolType : : exogenous )
2013-03-22 15:44:34 +01:00
splan [ i ] . var_num = exo_num ;
else
2022-07-29 12:42:50 +02:00
mexErrMsgTxt ( ( " The variable ' " s + name + " ' defined as var in pfplan is not an exogenous " ) . c_str ( ) ) ;
2013-03-22 15:44:34 +01:00
}
tmp = mxGetField ( pfplan_struct , i , " exo " ) ;
if ( tmp )
{
2019-12-20 14:50:19 +01:00
char name [ 100 ] ;
2013-03-22 15:44:34 +01:00
mxGetString ( tmp , name , 100 ) ;
spfplan [ i ] . exo = name ;
2022-07-28 16:56:40 +02:00
auto [ variable_type , exo_num ] = symbol_table . getIDAndType ( name ) ;
2018-07-18 17:51:59 +02:00
if ( variable_type = = SymbolType : : endogenous )
2013-03-22 15:44:34 +01:00
spfplan [ i ] . exo_num = exo_num ;
else
2022-07-29 12:42:50 +02:00
mexErrMsgTxt ( ( " The variable ' " s + name + " ' defined as exo in pfplan is not an endogenous variable " ) . c_str ( ) ) ;
2013-03-22 15:44:34 +01:00
}
tmp = mxGetField ( pfplan_struct , i , " per_value " ) ;
if ( tmp )
{
size_t num_shocks = mxGetM ( tmp ) ;
2017-05-16 16:30:27 +02:00
double * per_value = mxGetPr ( tmp ) ;
2021-02-03 18:10:01 +01:00
spfplan [ i ] . per_value . resize ( num_shocks ) ;
2019-04-23 12:58:38 +02:00
for ( int j = 0 ; j < static_cast < int > ( num_shocks ) ; j + + )
2021-02-03 18:10:01 +01:00
spfplan [ i ] . per_value [ j ] = { ceil ( per_value [ j ] ) , per_value [ j + num_shocks ] } ;
2013-03-22 15:44:34 +01:00
}
}
2013-06-12 16:05:10 +02:00
int i = 0 ;
2021-02-01 12:32:17 +01:00
for ( auto & it : spfplan )
2013-03-22 15:44:34 +01:00
{
mexPrintf ( " ---------------------------------------------------------------------------------------------------- \n " ) ;
2013-11-05 13:51:18 +01:00
mexPrintf ( " perfect foresight #%d \n " , i + 1 ) ;
2021-02-01 12:32:17 +01:00
if ( it . exo . length ( ) )
mexPrintf ( " plan flipping var=%s (%d) exo=%s (%d) for the following periods and with the following values: \n " , it . var . c_str ( ) , it . var_num , it . exo . c_str ( ) , it . exo_num ) ;
2013-03-22 15:44:34 +01:00
else
2021-02-01 12:32:17 +01:00
mexPrintf ( " plan shocks on var=%s (%d) for the following periods and with the following values: \n " , it . var . c_str ( ) , it . var_num ) ;
2021-02-03 18:10:01 +01:00
for ( auto & [ period , value ] : it . per_value )
mexPrintf ( " %3d %10.5f \n " , period , value ) ;
2013-03-22 15:44:34 +01:00
i + + ;
}
}
int field_steady_state = mxGetFieldNumber ( oo_ , " steady_state " ) ;
if ( field_steady_state < 0 )
2020-01-10 17:55:57 +01:00
mexErrMsgTxt ( " steady_state is not a field of oo_ " ) ;
2013-03-22 15:44:34 +01:00
int field_exo_steady_state = mxGetFieldNumber ( oo_ , " exo_steady_state " ) ;
if ( field_exo_steady_state < 0 )
2020-01-10 17:55:57 +01:00
mexErrMsgTxt ( " exo_steady_state is not a field of oo_ " ) ;
2013-03-22 15:44:34 +01:00
2009-12-16 18:18:38 +01:00
if ( ! steady_state )
2009-08-25 11:43:01 +02:00
{
2013-03-22 15:44:34 +01:00
int field_endo_simul = mxGetFieldNumber ( oo_ , " endo_simul " ) ;
if ( field_endo_simul < 0 )
2020-01-10 17:55:57 +01:00
mexErrMsgTxt ( " endo_simul is not a field of oo_ " ) ;
2013-03-22 15:44:34 +01:00
int field_exo_simul = mxGetFieldNumber ( oo_ , " exo_simul " ) ;
if ( field_exo_simul < 0 )
2020-01-10 17:55:57 +01:00
mexErrMsgTxt ( " exo_simul is not a field of oo_ " ) ;
2013-03-22 15:44:34 +01:00
2010-07-23 11:20:24 +02:00
if ( ! count_array_argument )
{
2017-05-16 16:30:27 +02:00
mxArray * endo_sim_arr = mxGetFieldByNumber ( oo_ , 0 , field_endo_simul ) ;
2013-03-22 15:44:34 +01:00
yd = mxGetPr ( endo_sim_arr ) ;
row_y = mxGetM ( endo_sim_arr ) ;
col_y = mxGetN ( endo_sim_arr ) ;
2017-05-16 16:30:27 +02:00
mxArray * exo_sim_arr = mxGetFieldByNumber ( oo_ , 0 , field_exo_simul ) ;
2013-03-22 15:44:34 +01:00
xd = mxGetPr ( exo_sim_arr ) ;
row_x = mxGetM ( exo_sim_arr ) ;
col_x = mxGetN ( exo_sim_arr ) ;
2010-07-23 11:20:24 +02:00
}
2013-03-22 15:44:34 +01:00
int field = mxGetFieldNumber ( M_ , " maximum_lag " ) ;
if ( field > = 0 )
2021-02-03 18:10:01 +01:00
y_kmin = static_cast < int > ( floor ( * ( mxGetPr ( mxGetFieldByNumber ( M_ , 0 , field ) ) ) ) ) ;
2013-03-22 15:44:34 +01:00
else
2020-01-10 17:55:57 +01:00
mexErrMsgTxt ( " maximum_lag is not a field of M_ " ) ;
2013-03-22 15:44:34 +01:00
field = mxGetFieldNumber ( M_ , " maximum_lead " ) ;
if ( field > = 0 )
2021-02-03 18:10:01 +01:00
y_kmax = static_cast < int > ( floor ( * ( mxGetPr ( mxGetFieldByNumber ( M_ , 0 , field ) ) ) ) ) ;
2013-03-22 15:44:34 +01:00
else
2020-01-10 17:55:57 +01:00
mexErrMsgTxt ( " maximum_lead is not a field of M_ " ) ;
2013-03-22 15:44:34 +01:00
field = mxGetFieldNumber ( M_ , " maximum_endo_lag " ) ;
if ( field > = 0 )
2021-02-03 18:10:01 +01:00
y_decal = max ( 0 , y_kmin - static_cast < int > ( floor ( * ( mxGetPr ( mxGetFieldByNumber ( M_ , 0 , field ) ) ) ) ) ) ;
2013-03-22 15:44:34 +01:00
else
2020-01-10 17:55:57 +01:00
mexErrMsgTxt ( " maximum_endo_lag is not a field of M_ " ) ;
2009-08-25 11:43:01 +02:00
2010-07-23 11:20:24 +02:00
if ( ! count_array_argument )
2013-03-22 15:44:34 +01:00
{
int field = mxGetFieldNumber ( options_ , " periods " ) ;
if ( field > = 0 )
2021-02-03 18:10:01 +01:00
periods = static_cast < int > ( floor ( * ( mxGetPr ( mxGetFieldByNumber ( options_ , 0 , field ) ) ) ) ) ;
2013-03-22 15:44:34 +01:00
else
2020-01-10 17:55:57 +01:00
mexErrMsgTxt ( " options_ is not a field of options_ " ) ;
2013-03-22 15:44:34 +01:00
}
2017-05-16 16:30:27 +02:00
if ( ! steady_yd )
2011-03-14 17:46:00 +01:00
{
2017-05-16 16:30:27 +02:00
mxArray * steady_state_arr = mxGetFieldByNumber ( oo_ , 0 , field_steady_state ) ;
2013-03-22 15:44:34 +01:00
steady_yd = mxGetPr ( steady_state_arr ) ;
steady_row_y = mxGetM ( steady_state_arr ) ;
steady_col_y = mxGetN ( steady_state_arr ) ;
2011-03-14 17:46:00 +01:00
}
2009-12-16 18:18:38 +01:00
}
else
{
2010-07-23 11:20:24 +02:00
if ( ! count_array_argument )
{
2017-05-16 16:30:27 +02:00
mxArray * steady_state_arr = mxGetFieldByNumber ( oo_ , 0 , field_steady_state ) ;
2013-03-22 15:44:34 +01:00
yd = mxGetPr ( steady_state_arr ) ;
row_y = mxGetM ( steady_state_arr ) ;
col_y = mxGetN ( steady_state_arr ) ;
2010-08-18 13:51:57 +02:00
2017-05-16 16:30:27 +02:00
mxArray * exo_steady_state_arr = mxGetFieldByNumber ( oo_ , 0 , field_exo_steady_state ) ;
2013-03-22 15:44:34 +01:00
xd = mxGetPr ( exo_steady_state_arr ) ;
row_x = mxGetM ( exo_steady_state_arr ) ;
col_x = mxGetN ( exo_steady_state_arr ) ;
2010-07-23 11:20:24 +02:00
}
2009-08-25 11:43:01 +02:00
}
2013-03-22 15:44:34 +01:00
int field = mxGetFieldNumber ( options_ , " verbosity " ) ;
int verbose = 0 ;
if ( field > = 0 )
2021-02-03 18:10:01 +01:00
verbose = static_cast < int > ( * mxGetPr ( ( mxGetFieldByNumber ( options_ , 0 , field ) ) ) ) ;
2013-03-22 15:44:34 +01:00
else
2020-01-10 17:55:57 +01:00
mexErrMsgTxt ( " verbosity is not a field of options_ " ) ;
2011-12-12 12:40:46 +01:00
if ( verbose )
print_it = true ;
2013-10-09 16:55:46 +02:00
if ( ! steady_state )
field = mxGetFieldNumber ( options_ , " simul " ) ;
else
field = mxGetFieldNumber ( options_ , " steady " ) ;
mxArray * temporaryfield ;
2013-10-09 16:26:29 +02:00
if ( field > = 0 )
2013-10-09 16:55:46 +02:00
temporaryfield = mxGetFieldByNumber ( options_ , 0 , field ) ;
2013-10-09 16:26:29 +02:00
else
2015-11-06 15:06:17 +01:00
{
if ( ! steady_state )
2020-01-10 17:55:57 +01:00
mexErrMsgTxt ( " simul is not a field of options_ " ) ;
2015-11-06 15:06:17 +01:00
else
2020-01-10 17:55:57 +01:00
mexErrMsgTxt ( " steady is not a field of options_ " ) ;
2015-11-06 15:06:17 +01:00
}
2013-10-09 16:55:46 +02:00
field = mxGetFieldNumber ( temporaryfield , " maxit " ) ;
2017-05-16 16:30:27 +02:00
if ( field < 0 )
2015-11-06 15:06:17 +01:00
{
if ( ! steady_state )
2020-01-10 17:55:57 +01:00
mexErrMsgTxt ( " maxit is not a field of options_.simul " ) ;
2015-11-06 15:06:17 +01:00
else
2020-01-10 17:55:57 +01:00
mexErrMsgTxt ( " maxit is not a field of options_.steady " ) ;
2015-11-06 15:06:17 +01:00
}
2021-02-03 18:10:01 +01:00
int maxit_ = static_cast < int > ( floor ( * mxGetPr ( mxGetFieldByNumber ( temporaryfield , 0 , field ) ) ) ) ;
2013-03-22 15:44:34 +01:00
field = mxGetFieldNumber ( options_ , " markowitz " ) ;
if ( field < 0 )
2020-01-10 17:55:57 +01:00
mexErrMsgTxt ( " markowitz is not a field of options_ " ) ;
2021-02-03 18:10:01 +01:00
auto markowitz_c = static_cast < double > ( * mxGetPr ( mxGetFieldByNumber ( options_ , 0 , field ) ) ) ;
2013-03-22 15:44:34 +01:00
field = mxGetFieldNumber ( options_ , " minimal_solving_periods " ) ;
if ( field < 0 )
2020-01-10 17:55:57 +01:00
mexErrMsgTxt ( " minimal_solving_periods is not a field of options_ " ) ;
2021-02-03 18:10:01 +01:00
int minimal_solving_periods = static_cast < int > ( * mxGetPr ( mxGetFieldByNumber ( options_ , 0 , field ) ) ) ;
2013-03-22 15:44:34 +01:00
field = mxGetFieldNumber ( options_ , " stack_solve_algo " ) ;
if ( field < 0 )
2020-01-10 17:55:57 +01:00
mexErrMsgTxt ( " stack_solve_algo is not a field of options_ " ) ;
2021-02-03 18:10:01 +01:00
int stack_solve_algo = static_cast < int > ( * mxGetPr ( mxGetFieldByNumber ( options_ , 0 , field ) ) ) ;
2010-08-18 13:51:57 +02:00
int solve_algo ;
2009-08-25 11:43:01 +02:00
double solve_tolf ;
2013-03-22 15:44:34 +01:00
2009-12-16 18:18:38 +01:00
if ( steady_state )
2011-02-04 16:53:12 +01:00
{
2013-03-22 15:44:34 +01:00
int field = mxGetFieldNumber ( options_ , " solve_algo " ) ;
if ( field > = 0 )
2021-02-03 18:10:01 +01:00
solve_algo = static_cast < int > ( * mxGetPr ( mxGetFieldByNumber ( options_ , 0 , field ) ) ) ;
2013-03-22 15:44:34 +01:00
else
2020-01-10 17:55:57 +01:00
mexErrMsgTxt ( " solve_algo is not a field of options_ " ) ;
2013-03-22 15:44:34 +01:00
field = mxGetFieldNumber ( options_ , " solve_tolf " ) ;
if ( field > = 0 )
2021-02-03 18:10:01 +01:00
solve_tolf = * mxGetPr ( mxGetFieldByNumber ( options_ , 0 , field ) ) ;
2013-03-22 15:44:34 +01:00
else
2020-01-10 17:55:57 +01:00
mexErrMsgTxt ( " solve_tolf is not a field of options_ " ) ;
2011-02-04 16:53:12 +01:00
}
2009-12-16 18:18:38 +01:00
else
2010-08-18 13:51:57 +02:00
{
solve_algo = stack_solve_algo ;
2013-03-22 15:44:34 +01:00
int field = mxGetFieldNumber ( options_ , " dynatol " ) ;
mxArray * dynatol ;
if ( field > = 0 )
dynatol = mxGetFieldByNumber ( options_ , 0 , field ) ;
else
2020-01-10 17:55:57 +01:00
mexErrMsgTxt ( " dynatol is not a field of options_ " ) ;
2013-03-22 15:44:34 +01:00
field = mxGetFieldNumber ( dynatol , " f " ) ;
if ( field > = 0 )
2021-02-03 18:10:01 +01:00
solve_tolf = * mxGetPr ( mxGetFieldByNumber ( dynatol , 0 , field ) ) ;
2013-03-22 15:44:34 +01:00
else
2020-01-10 17:55:57 +01:00
mexErrMsgTxt ( " f is not a field of options_.dynatol " ) ;
2010-08-18 13:51:57 +02:00
}
2013-03-22 15:44:34 +01:00
field = mxGetFieldNumber ( M_ , " fname " ) ;
mxArray * mxa ;
if ( field > = 0 )
mxa = mxGetFieldByNumber ( M_ , 0 , field ) ;
else
2020-01-10 17:55:57 +01:00
mexErrMsgTxt ( " fname is not a field of M_ " ) ;
2013-03-22 15:44:34 +01:00
size_t buflen = mxGetM ( mxa ) * mxGetN ( mxa ) + 1 ;
2021-02-03 18:10:01 +01:00
char * fname = static_cast < char * > ( mxCalloc ( buflen + 1 , sizeof ( char ) ) ) ;
size_t status = mxGetString ( mxa , fname , static_cast < int > ( buflen ) ) ;
2010-08-18 13:51:57 +02:00
fname [ buflen ] = ' ' ;
2007-10-04 00:01:08 +02:00
if ( status ! = 0 )
mexWarnMsgTxt ( " Not enough space. Filename is truncated. " ) ;
2010-08-18 13:51:57 +02:00
string file_name = fname ;
2023-02-21 22:20:46 +01:00
mxFree ( fname ) ;
2009-08-25 11:43:01 +02:00
2013-03-22 15:44:34 +01:00
if ( stack_solve_algo = = 7 & & ! steady_state )
2022-07-29 12:42:50 +02:00
mexErrMsgTxt ( " Bytecode: Can't use option stack_solve_algo=7 " ) ;
2021-02-01 14:03:57 +01:00
2022-02-17 17:00:53 +01:00
if ( steady_state & & ! evaluate & & ( solve_algo < 5 | | solve_algo > 8 ) )
2022-07-29 12:42:50 +02:00
mexErrMsgTxt ( " Bytecode: solve_algo must be between 5 and 8 when using the internal steady state solver " ) ;
2022-02-17 17:00:53 +01:00
2013-03-22 15:44:34 +01:00
size_t size_of_direction = col_y * row_y * sizeof ( double ) ;
2021-02-01 12:39:34 +01:00
auto * y = static_cast < double * > ( mxMalloc ( size_of_direction ) ) ;
2022-07-29 12:58:10 +02:00
test_mxMalloc ( y , __LINE__ , __FILE__ , __func__ , size_of_direction ) ;
2021-02-01 12:39:34 +01:00
auto * ya = static_cast < double * > ( mxMalloc ( size_of_direction ) ) ;
2022-07-29 12:58:10 +02:00
test_mxMalloc ( ya , __LINE__ , __FILE__ , __func__ , size_of_direction ) ;
2019-04-23 12:58:38 +02:00
direction = static_cast < double * > ( mxMalloc ( size_of_direction ) ) ;
2022-07-29 12:58:10 +02:00
test_mxMalloc ( direction , __LINE__ , __FILE__ , __func__ , size_of_direction ) ;
2017-05-16 16:30:27 +02:00
memset ( direction , 0 , size_of_direction ) ;
2021-02-01 12:39:34 +01:00
auto * x = static_cast < double * > ( mxMalloc ( col_x * row_x * sizeof ( double ) ) ) ;
2022-07-29 12:58:10 +02:00
test_mxMalloc ( x , __LINE__ , __FILE__ , __func__ , col_x * row_x * sizeof ( double ) ) ;
2009-12-16 18:18:38 +01:00
for ( i = 0 ; i < row_x * col_x ; i + + )
2021-02-03 18:10:01 +01:00
x [ i ] = static_cast < double > ( xd [ i ] ) ;
2009-12-16 18:18:38 +01:00
for ( i = 0 ; i < row_y * col_y ; i + + )
2009-09-11 19:06:54 +02:00
{
2021-02-03 18:10:01 +01:00
y [ i ] = static_cast < double > ( yd [ i ] ) ;
ya [ i ] = static_cast < double > ( yd [ i ] ) ;
2017-05-16 16:30:27 +02:00
}
size_t y_size = row_y ;
size_t nb_row_x = row_x ;
2009-12-16 18:18:38 +01:00
clock_t t0 = clock ( ) ;
2023-04-18 17:53:27 +02:00
const filesystem : : path codfile { file_name + " /model/bytecode/ " + ( block_decomposed ? " block/ " : " " )
+ ( steady_state ? " static " : " dynamic " ) + " .cod " } ;
Evaluate evaluator { codfile , steady_state , symbol_table } ;
Interpreter interprete { evaluator , params , y , ya , x , steady_yd , direction , y_size , nb_row_x ,
2022-07-28 16:56:40 +02:00
periods , y_kmin , y_kmax , maxit_ , solve_tolf , size_of_direction , y_decal ,
markowitz_c , file_name , minimal_solving_periods , stack_solve_algo ,
solve_algo , global_temporary_terms , print , print_error , GlobalTemporaryTerms ,
2023-01-09 15:19:36 +01:00
steady_state , block_decomposed , print_it , col_x , col_y , symbol_table } ;
2010-09-24 12:52:58 +02:00
double * pind ;
2023-02-23 23:37:08 +01:00
bool r ;
vector < int > blocks ;
2017-05-16 16:30:27 +02:00
2015-09-22 12:45:27 +02:00
if ( extended_path )
2017-05-16 16:30:27 +02:00
{
try
{
2023-02-23 23:37:08 +01:00
tie ( r , blocks ) = interprete . extended_path ( file_name , evaluate , block , max_periods , sextended_path , sconditional_extended_path , dates , table_conditional_global ) ;
2017-05-16 16:30:27 +02:00
}
2022-07-29 12:42:50 +02:00
catch ( GeneralException & feh )
2017-05-16 16:30:27 +02:00
{
2021-09-20 17:28:43 +02:00
// Release the lock on dynamic.bin for MATLAB+Windows, see #1815
interprete . Close_SaveCode ( ) ;
2022-07-29 12:42:50 +02:00
mexErrMsgTxt ( feh . message . c_str ( ) ) ;
2017-05-16 16:30:27 +02:00
}
2010-09-24 12:52:58 +02:00
}
2015-09-22 12:45:27 +02:00
else
2010-09-24 12:52:58 +02:00
{
2017-05-16 16:30:27 +02:00
try
{
2023-02-23 23:37:08 +01:00
tie ( r , blocks ) = interprete . compute_blocks ( file_name , evaluate , block ) ;
2017-05-16 16:30:27 +02:00
}
2022-07-29 12:42:50 +02:00
catch ( GeneralException & feh )
2017-05-16 16:30:27 +02:00
{
2021-09-20 17:28:43 +02:00
// Release the lock on dynamic.bin for MATLAB+Windows, see #1815
interprete . Close_SaveCode ( ) ;
2022-07-29 12:42:50 +02:00
mexErrMsgTxt ( feh . message . c_str ( ) ) ;
2017-05-16 16:30:27 +02:00
}
2010-09-24 12:52:58 +02:00
}
2009-12-16 18:18:38 +01:00
clock_t t1 = clock ( ) ;
2020-01-10 17:55:57 +01:00
if ( ! steady_state & & ! evaluate & & print )
2021-02-03 18:10:01 +01:00
mexPrintf ( " Simulation Time=%f milliseconds \n " ,
1000.0 * ( static_cast < double > ( t1 ) - static_cast < double > ( t0 ) ) / static_cast < double > ( CLOCKS_PER_SEC ) ) ;
2010-10-11 19:21:32 +02:00
bool dont_store_a_structure = false ;
2009-12-16 18:18:38 +01:00
if ( nlhs > 0 )
2007-10-04 00:01:08 +02:00
{
2020-01-10 17:55:57 +01:00
if ( block > = 0 )
2009-12-16 18:18:38 +01:00
{
2020-01-10 17:55:57 +01:00
if ( evaluate )
2010-10-11 19:21:32 +02:00
{
2020-01-10 17:55:57 +01:00
vector < double > residual = interprete . get_residual ( ) ;
2021-02-03 18:10:01 +01:00
plhs [ 0 ] = mxCreateDoubleMatrix ( static_cast < int > ( residual . size ( ) / static_cast < double > ( col_y ) ) ,
static_cast < int > ( col_y ) , mxREAL ) ;
2020-01-10 17:55:57 +01:00
pind = mxGetPr ( plhs [ 0 ] ) ;
for ( i = 0 ; i < residual . size ( ) ; i + + )
pind [ i ] = residual [ i ] ;
2010-10-11 19:21:32 +02:00
}
2009-12-16 18:18:38 +01:00
else
2017-05-16 16:30:27 +02:00
{
2021-02-09 15:55:36 +01:00
int out_periods = extended_path ? max_periods + y_kmin : row_y ;
2021-02-03 18:10:01 +01:00
plhs [ 0 ] = mxCreateDoubleMatrix ( out_periods , static_cast < int > ( col_y ) , mxREAL ) ;
2020-01-10 17:55:57 +01:00
pind = mxGetPr ( plhs [ 0 ] ) ;
for ( i = 0 ; i < out_periods * col_y ; i + + )
pind [ i ] = y [ i ] ;
}
}
else
{
2021-02-09 15:55:36 +01:00
int out_periods = extended_path ? max_periods + y_kmin : col_y ;
2021-02-03 18:10:01 +01:00
plhs [ 0 ] = mxCreateDoubleMatrix ( static_cast < int > ( row_y ) , out_periods , mxREAL ) ;
2020-01-10 17:55:57 +01:00
pind = mxGetPr ( plhs [ 0 ] ) ;
if ( evaluate )
{
vector < double > residual = interprete . get_residual ( ) ;
for ( i = 0 ; i < residual . size ( ) ; i + + )
pind [ i ] = residual [ i ] ;
}
else
for ( i = 0 ; i < row_y * out_periods ; i + + )
pind [ i ] = y [ i ] ;
}
if ( nlhs > 1 )
{
if ( evaluate )
{
2021-02-09 15:55:36 +01:00
int jacob_field_number = 0 , jacob_exo_field_number = 0 ,
2023-01-17 13:50:16 +01:00
jacob_exo_det_field_number = 0 ;
2020-01-10 17:55:57 +01:00
if ( ! block_structur )
{
2023-01-17 13:50:16 +01:00
const char * field_names [ ] = { " g1 " , " g1_x " , " g1_xd " } ;
2020-01-10 17:55:57 +01:00
jacob_field_number = 0 ;
jacob_exo_field_number = 1 ;
jacob_exo_det_field_number = 2 ;
2023-02-23 23:37:08 +01:00
mwSize dims [ 1 ] = { static_cast < mwSize > ( blocks . size ( ) ) } ;
2023-01-24 12:21:08 +01:00
plhs [ 1 ] = mxCreateStructArray ( 1 , dims , std : : extent_v < decltype ( field_names ) > , field_names ) ;
2020-01-10 17:55:57 +01:00
}
else if ( ! mxIsStruct ( block_structur ) )
2011-01-31 12:30:16 +01:00
{
2023-02-23 23:37:08 +01:00
plhs [ 1 ] = interprete . get_jacob ( blocks [ 0 ] ) ;
2020-01-10 17:55:57 +01:00
dont_store_a_structure = true ;
2011-01-31 12:30:16 +01:00
}
2010-10-11 19:21:32 +02:00
else
2010-07-23 11:20:24 +02:00
{
2020-01-10 17:55:57 +01:00
plhs [ 1 ] = block_structur ;
jacob_field_number = mxAddField ( plhs [ 1 ] , " g1 " ) ;
if ( jacob_field_number = = - 1 )
2022-07-29 12:42:50 +02:00
mexErrMsgTxt ( " Fatal error in bytecode: in main, cannot add extra field jacob to the structArray " ) ;
2020-01-10 17:55:57 +01:00
jacob_exo_field_number = mxAddField ( plhs [ 1 ] , " g1_x " ) ;
if ( jacob_exo_field_number = = - 1 )
2022-07-29 12:42:50 +02:00
mexErrMsgTxt ( " Fatal error in bytecode: in main, cannot add extra field jacob_exo to the structArray " ) ;
2020-01-10 17:55:57 +01:00
jacob_exo_det_field_number = mxAddField ( plhs [ 1 ] , " g1_xd " ) ;
if ( jacob_exo_det_field_number = = - 1 )
2022-07-29 12:42:50 +02:00
mexErrMsgTxt ( " Fatal error in bytecode: in main, cannot add extra field jacob_exo_det to the structArray " ) ;
2020-01-10 17:55:57 +01:00
}
if ( ! dont_store_a_structure )
2023-02-23 23:37:08 +01:00
for ( size_t i { 0 } ; i < blocks . size ( ) ; i + + )
2021-02-09 15:55:36 +01:00
{
2023-02-23 23:37:08 +01:00
mxSetFieldByNumber ( plhs [ 1 ] , i , jacob_field_number , interprete . get_jacob ( blocks [ i ] ) ) ;
2021-02-09 15:55:36 +01:00
if ( ! steady_state )
{
2023-02-23 23:37:08 +01:00
mxSetFieldByNumber ( plhs [ 1 ] , i , jacob_exo_field_number , interprete . get_jacob_exo ( blocks [ i ] ) ) ;
mxSetFieldByNumber ( plhs [ 1 ] , i , jacob_exo_det_field_number , interprete . get_jacob_exo_det ( blocks [ i ] ) ) ;
2021-02-09 15:55:36 +01:00
}
}
2020-01-10 17:55:57 +01:00
}
else
{
2021-02-03 18:10:01 +01:00
plhs [ 1 ] = mxCreateDoubleMatrix ( static_cast < int > ( row_x ) , static_cast < int > ( col_x ) , mxREAL ) ;
2020-01-10 17:55:57 +01:00
pind = mxGetPr ( plhs [ 1 ] ) ;
for ( i = 0 ; i < row_x * col_x ; i + + )
2021-02-03 18:10:01 +01:00
pind [ i ] = x [ i ] ;
2020-01-10 17:55:57 +01:00
}
if ( nlhs > 2 )
{
2021-02-03 18:10:01 +01:00
plhs [ 2 ] = mxCreateDoubleMatrix ( static_cast < int > ( row_y ) , static_cast < int > ( col_y ) , mxREAL ) ;
2020-01-10 17:55:57 +01:00
pind = mxGetPr ( plhs [ 2 ] ) ;
for ( i = 0 ; i < row_y * col_y ; i + + )
pind [ i ] = y [ i ] ;
2010-10-11 19:21:32 +02:00
if ( nlhs > 3 )
2010-07-23 11:20:24 +02:00
{
2020-01-10 17:55:57 +01:00
mxArray * GlobalTemporaryTerms = interprete . get_Temporary_Terms ( ) ;
size_t nb_temp_terms = mxGetM ( GlobalTemporaryTerms ) ;
2021-02-03 18:10:01 +01:00
plhs [ 3 ] = mxCreateDoubleMatrix ( static_cast < int > ( nb_temp_terms ) , 1 , mxREAL ) ;
2010-10-11 19:21:32 +02:00
pind = mxGetPr ( plhs [ 3 ] ) ;
2020-01-10 17:55:57 +01:00
double * tt = mxGetPr ( GlobalTemporaryTerms ) ;
for ( i = 0 ; i < nb_temp_terms ; i + + )
pind [ i ] = tt [ i ] ;
2010-07-23 11:20:24 +02:00
}
}
2020-01-10 17:55:57 +01:00
2009-12-16 18:18:38 +01:00
}
2007-10-04 00:01:08 +02:00
}
2009-12-16 18:18:38 +01:00
if ( x )
2017-05-16 16:30:27 +02:00
mxFree ( x ) ;
2009-12-16 18:18:38 +01:00
if ( y )
2017-05-16 16:30:27 +02:00
mxFree ( y ) ;
2009-12-16 18:18:38 +01:00
if ( ya )
2017-05-16 16:30:27 +02:00
mxFree ( ya ) ;
2009-12-16 18:18:38 +01:00
if ( direction )
2017-05-16 16:30:27 +02:00
mxFree ( direction ) ;
2007-10-04 00:01:08 +02:00
}