2008-01-11 14:42:14 +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
*/
2010-06-09 18:35:03 +02:00
2009-08-25 11:43:01 +02:00
# include <sstream>
2015-09-22 12:45:27 +02:00
# include <algorithm>
2023-01-09 15:19:36 +01:00
# include <filesystem>
2023-02-23 23:37:08 +01:00
# include <numeric>
2023-04-06 18:44:22 +02:00
# include <cfenv>
2021-02-09 15:55:36 +01:00
2009-12-16 18:18:38 +01:00
# include "Interpreter.hh"
2007-11-21 00:27:30 +01:00
2021-02-03 18:10:01 +01:00
constexpr double BIG = 1.0e+8 , SMALL = 1.0e-5 ;
2010-02-05 12:05:21 +01:00
2023-04-18 17:53:27 +02:00
Interpreter : : Interpreter ( Evaluate & evaluator_arg , double * params_arg , double * y_arg , double * ya_arg , double * x_arg , double * steady_y_arg ,
2013-03-22 15:44:34 +01:00
double * direction_arg , size_t y_size_arg ,
2022-07-05 13:02:17 +02:00
size_t nb_row_x_arg , int periods_arg , int y_kmin_arg , int y_kmax_arg ,
2023-04-18 21:50:55 +02:00
int maxit_arg_ , double solve_tolf_arg , int y_decal_arg , double markowitz_c_arg ,
2010-12-31 16:37:34 +01:00
string & filename_arg , int minimal_solving_periods_arg , int stack_solve_algo_arg , int solve_algo_arg ,
2023-06-13 16:34:22 +02:00
bool global_temporary_terms_arg , bool print_arg , mxArray * GlobalTemporaryTerms_arg ,
bool steady_state_arg , bool block_decomposed_arg , int col_x_arg , int col_y_arg , const BasicSymbolTable & symbol_table_arg , int verbosity_arg )
: dynSparseMatrix { evaluator_arg , y_size_arg , y_kmin_arg , y_kmax_arg , steady_state_arg , block_decomposed_arg , periods_arg , minimal_solving_periods_arg , symbol_table_arg , verbosity_arg }
2007-11-21 00:27:30 +01:00
{
2009-12-16 18:18:38 +01:00
params = params_arg ;
y = y_arg ;
ya = ya_arg ;
x = x_arg ;
2009-09-18 18:34:11 +02:00
steady_y = steady_y_arg ;
2009-12-16 18:18:38 +01:00
direction = direction_arg ;
nb_row_x = nb_row_x_arg ;
periods = periods_arg ;
maxit_ = maxit_arg_ ;
solve_tolf = solve_tolf_arg ;
2022-03-31 17:39:43 +02:00
slowc = 1 ;
slowc_save = 1 ;
2009-12-16 18:18:38 +01:00
y_decal = y_decal_arg ;
markowitz_c = markowitz_c_arg ;
filename = filename_arg ;
2021-02-01 13:49:27 +01:00
T = nullptr ;
2009-10-18 17:18:16 +02:00
minimal_solving_periods = minimal_solving_periods_arg ;
2010-07-23 11:20:24 +02:00
stack_solve_algo = stack_solve_algo_arg ;
solve_algo = solve_algo_arg ;
2010-12-31 16:37:34 +01:00
global_temporary_terms = global_temporary_terms_arg ;
print = print_arg ;
2017-05-16 16:30:27 +02:00
col_x = col_x_arg ;
2017-05-05 14:22:38 +02:00
col_y = col_y_arg ;
2011-01-14 19:22:29 +01:00
GlobalTemporaryTerms = GlobalTemporaryTerms_arg ;
2009-08-25 11:43:01 +02:00
}
2023-02-24 21:12:07 +01:00
void
Interpreter : : evaluate_over_periods ( bool forward )
{
if ( steady_state )
compute_block_time ( 0 , false , false ) ;
else
{
if ( forward )
{
for ( it_ = y_kmin ; it_ < periods + y_kmin ; it_ + + )
compute_block_time ( 0 , false , false ) ;
it_ = periods + y_kmin - 1 ; // Do not leave it_ in inconsistent state
}
else
{
for ( it_ = periods + y_kmin - 1 ; it_ > = y_kmin ; it_ - - )
compute_block_time ( 0 , false , false ) ;
it_ = y_kmin ; // Do not leave it_ in inconsistent state (see #1727)
}
}
}
void
Interpreter : : solve_simple_one_periods ( )
{
bool cvg = false ;
int iter = 0 ;
double ya ;
double slowc = 1 ;
res1 = 0 ;
2023-06-13 16:37:16 +02:00
while ( ! ( cvg | | iter > = maxit_ ) )
2023-02-24 21:12:07 +01:00
{
Per_y_ = it_ * y_size ;
ya = y [ Block_Contain [ 0 ] . Variable + Per_y_ ] ;
compute_block_time ( 0 , false , false ) ;
if ( ! isfinite ( res1 ) )
{
res1 = std : : numeric_limits < double > : : quiet_NaN ( ) ;
while ( ( isinf ( res1 ) | | isnan ( res1 ) ) & & ( slowc > 1e-9 ) )
{
compute_block_time ( 0 , false , false ) ;
if ( ! isfinite ( res1 ) )
{
slowc / = 1.5 ;
2023-06-13 16:34:22 +02:00
if ( verbosity > = 2 )
mexPrintf ( " Reducing the path length in Newton step slowc=%f \n " , slowc ) ;
2023-04-06 18:44:22 +02:00
feclearexcept ( FE_ALL_EXCEPT ) ;
y [ Block_Contain [ 0 ] . Variable + Per_y_ ] = ya - slowc * ( r [ 0 ] / g1 [ 0 ] ) ;
if ( fetestexcept ( FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW ) )
{
res1 = numeric_limits < double > : : quiet_NaN ( ) ;
2023-06-13 16:34:22 +02:00
if ( verbosity > = 1 )
2023-04-06 18:44:22 +02:00
mexPrintf ( " Singularity in block %d " , block_num + 1 ) ;
}
2023-02-24 21:12:07 +01:00
}
}
}
double rr ;
rr = r [ 0 ] ;
cvg = ( fabs ( rr ) < solve_tolf ) ;
if ( cvg )
continue ;
2023-04-06 18:44:22 +02:00
feclearexcept ( FE_ALL_EXCEPT ) ;
y [ Block_Contain [ 0 ] . Variable + Per_y_ ] + = - slowc * ( rr / g1 [ 0 ] ) ;
if ( fetestexcept ( FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW ) )
2023-02-24 21:12:07 +01:00
{
2023-04-06 18:44:22 +02:00
res1 = numeric_limits < double > : : quiet_NaN ( ) ;
2023-06-13 16:34:22 +02:00
if ( verbosity > = 1 )
2023-04-06 18:44:22 +02:00
mexPrintf ( " Singularity in block %d " , block_num + 1 ) ;
2023-02-24 21:12:07 +01:00
}
iter + + ;
}
if ( ! cvg )
throw FatalException { " In Solve Forward simple, convergence not achieved in block "
+ to_string ( block_num + 1 ) + " , after " + to_string ( iter ) + " iterations " } ;
}
void
Interpreter : : solve_simple_over_periods ( bool forward )
{
g1 = static_cast < double * > ( mxMalloc ( sizeof ( double ) ) ) ;
test_mxMalloc ( g1 , __LINE__ , __FILE__ , __func__ , sizeof ( double ) ) ;
r = static_cast < double * > ( mxMalloc ( sizeof ( double ) ) ) ;
test_mxMalloc ( r , __LINE__ , __FILE__ , __func__ , sizeof ( double ) ) ;
if ( steady_state )
{
it_ = 0 ;
solve_simple_one_periods ( ) ;
}
else
{
if ( forward )
{
for ( it_ = y_kmin ; it_ < periods + y_kmin ; it_ + + )
solve_simple_one_periods ( ) ;
it_ = periods + y_kmin - 1 ; // Do not leave it_ in inconsistent state
}
else
{
for ( it_ = periods + y_kmin - 1 ; it_ > = y_kmin ; it_ - - )
solve_simple_one_periods ( ) ;
it_ = y_kmin ; // Do not leave it_ in inconsistent state (see #1727)
}
}
mxFree ( g1 ) ;
mxFree ( r ) ;
}
void
Interpreter : : compute_complete_2b ( bool no_derivatives , double * _res1 , double * _res2 , double * _max_res , int * _max_res_idx )
{
res1 = 0 ;
* _res1 = 0 ;
* _res2 = 0 ;
* _max_res = 0 ;
for ( it_ = y_kmin ; it_ < periods + y_kmin ; it_ + + )
{
Per_u_ = ( it_ - y_kmin ) * u_count_int ;
Per_y_ = it_ * y_size ;
int shift = ( it_ - y_kmin ) * size ;
compute_block_time ( Per_u_ , false , no_derivatives ) ;
if ( ! ( isnan ( res1 ) | | isinf ( res1 ) ) )
for ( int i = 0 ; i < size ; i + + )
{
double rr ;
rr = r [ i ] ;
res [ i + shift ] = rr ;
if ( max_res < fabs ( rr ) )
{
* _max_res = fabs ( rr ) ;
* _max_res_idx = i ;
}
* _res2 + = rr * rr ;
* _res1 + = fabs ( rr ) ;
}
else
return ;
}
it_ = periods + y_kmin - 1 ; // Do not leave it_ in inconsistent state
return ;
}
2007-11-21 00:27:30 +01:00
void
2023-02-23 23:37:08 +01:00
Interpreter : : evaluate_a_block ( bool initialization , bool single_block , const string & bin_base_name )
2009-09-11 19:06:54 +02:00
{
2022-06-20 16:26:58 +02:00
switch ( type )
2009-09-11 19:06:54 +02:00
{
2020-03-20 18:51:37 +01:00
case BlockSimulationType : : evaluateForward :
2009-12-16 18:18:38 +01:00
if ( steady_state )
2010-10-11 19:21:32 +02:00
{
2021-02-03 18:10:01 +01:00
compute_block_time ( 0 , true , false ) ;
2023-02-23 23:37:08 +01:00
if ( single_block )
2010-10-11 19:21:32 +02:00
for ( int j = 0 ; j < size ; j + + )
residual [ j ] = y [ Block_Contain [ j ] . Variable ] - ya [ Block_Contain [ j ] . Variable ] ;
2011-01-31 12:30:16 +01:00
else
for ( int j = 0 ; j < size ; j + + )
2013-03-22 15:44:34 +01:00
residual [ Block_Contain [ j ] . Equation ] = y [ Block_Contain [ j ] . Variable ] - ya [ Block_Contain [ j ] . Variable ] ;
2011-02-04 16:53:12 +01:00
}
2009-12-16 18:18:38 +01:00
else
{
for ( it_ = y_kmin ; it_ < periods + y_kmin ; it_ + + )
{
Per_y_ = it_ * y_size ;
2021-02-03 18:10:01 +01:00
compute_block_time ( 0 , true , false ) ;
2023-02-23 23:37:08 +01:00
if ( single_block )
2010-10-11 19:21:32 +02:00
for ( int j = 0 ; j < size ; j + + )
2023-06-12 19:12:12 +02:00
residual [ ( it_ - y_kmin ) * size + j ] = y [ it_ * y_size + Block_Contain [ j ] . Variable ] - ya [ it_ * y_size + Block_Contain [ j ] . Variable ] ;
2011-01-31 12:30:16 +01:00
else
for ( int j = 0 ; j < size ; j + + )
2023-06-12 19:12:12 +02:00
residual [ ( it_ - y_kmin ) * y_size + Block_Contain [ j ] . Equation ] = y [ it_ * y_size + Block_Contain [ j ] . Variable ] - ya [ it_ * y_size + Block_Contain [ j ] . Variable ] ;
2009-12-16 18:18:38 +01:00
}
}
break ;
2020-03-20 18:51:37 +01:00
case BlockSimulationType : : solveForwardSimple :
2019-04-23 12:58:38 +02:00
g1 = static_cast < double * > ( mxMalloc ( size * size * sizeof ( double ) ) ) ;
2017-03-24 23:15:25 +01:00
test_mxMalloc ( g1 , __LINE__ , __FILE__ , __func__ , size * size * sizeof ( double ) ) ;
2019-04-23 12:58:38 +02:00
r = static_cast < double * > ( mxMalloc ( size * sizeof ( double ) ) ) ;
2017-03-24 23:15:25 +01:00
test_mxMalloc ( r , __LINE__ , __FILE__ , __func__ , size * sizeof ( double ) ) ;
2013-03-22 15:44:34 +01:00
if ( steady_state )
{
2021-02-03 18:10:01 +01:00
compute_block_time ( 0 , true , false ) ;
2023-02-23 23:37:08 +01:00
if ( ! single_block )
2013-03-22 15:44:34 +01:00
for ( int j = 0 ; j < size ; j + + )
residual [ Block_Contain [ j ] . Equation ] = r [ j ] ;
2010-10-11 19:21:32 +02:00
else
2013-03-22 15:44:34 +01:00
for ( int j = 0 ; j < size ; j + + )
residual [ j ] = r [ j ] ;
2009-12-16 18:18:38 +01:00
}
else
{
for ( it_ = y_kmin ; it_ < periods + y_kmin ; it_ + + )
{
Per_y_ = it_ * y_size ;
2021-02-03 18:10:01 +01:00
compute_block_time ( 0 , true , false ) ;
2023-02-23 23:37:08 +01:00
if ( ! single_block )
2013-03-22 15:44:34 +01:00
for ( int j = 0 ; j < size ; j + + )
2023-06-12 19:12:12 +02:00
residual [ ( it_ - y_kmin ) * y_size + Block_Contain [ j ] . Equation ] = r [ j ] ;
2010-10-11 19:21:32 +02:00
else
2013-03-22 15:44:34 +01:00
for ( int j = 0 ; j < size ; j + + )
2023-06-12 19:12:12 +02:00
residual [ ( it_ - y_kmin ) * size + j ] = r [ j ] ;
2009-12-16 18:18:38 +01:00
}
2017-05-16 16:30:27 +02:00
}
mxFree ( g1 ) ;
2009-12-16 18:18:38 +01:00
mxFree ( r ) ;
break ;
2020-03-20 18:51:37 +01:00
case BlockSimulationType : : solveForwardComplete :
2015-09-22 12:45:27 +02:00
if ( initialization )
2017-05-16 16:30:27 +02:00
{
fixe_u ( & u , u_count_int , u_count_int ) ;
Read_SparseMatrix ( bin_base_name , size , 1 , 0 , 0 , false , stack_solve_algo , solve_algo ) ;
}
2010-11-20 15:45:15 +01:00
# ifdef DEBUG
2020-03-20 18:51:37 +01:00
mexPrintf ( " in SOLVE FORWARD COMPLETE r = mxMalloc(%d*sizeof(double)) \n " , size ) ;
2010-11-20 15:45:15 +01:00
# endif
2019-04-23 12:58:38 +02:00
r = static_cast < double * > ( mxMalloc ( size * sizeof ( double ) ) ) ;
2017-03-24 23:15:25 +01:00
test_mxMalloc ( r , __LINE__ , __FILE__ , __func__ , size * sizeof ( double ) ) ;
2009-12-16 18:18:38 +01:00
if ( steady_state )
{
2021-02-03 18:10:01 +01:00
compute_block_time ( 0 , true , false ) ;
2023-02-23 23:37:08 +01:00
if ( ! single_block )
2010-10-11 19:21:32 +02:00
for ( int j = 0 ; j < size ; j + + )
2013-03-22 15:44:34 +01:00
residual [ Block_Contain [ j ] . Equation ] = r [ j ] ;
2010-10-11 19:21:32 +02:00
else
for ( int j = 0 ; j < size ; j + + )
residual [ j ] = r [ j ] ;
2009-12-16 18:18:38 +01:00
}
else
{
for ( it_ = y_kmin ; it_ < periods + y_kmin ; it_ + + )
{
Per_y_ = it_ * y_size ;
2021-02-03 18:10:01 +01:00
compute_block_time ( 0 , true , false ) ;
2023-02-23 23:37:08 +01:00
if ( ! single_block )
2010-10-11 19:21:32 +02:00
for ( int j = 0 ; j < size ; j + + )
2023-06-12 19:12:12 +02:00
residual [ ( it_ - y_kmin ) * y_size + Block_Contain [ j ] . Equation ] = r [ j ] ;
2010-10-11 19:21:32 +02:00
else
for ( int j = 0 ; j < size ; j + + )
2023-06-12 19:12:12 +02:00
residual [ ( it_ - y_kmin ) * size + j ] = r [ j ] ;
2009-12-16 18:18:38 +01:00
}
}
mxFree ( r ) ;
break ;
2020-03-20 18:51:37 +01:00
case BlockSimulationType : : evaluateBackward :
2009-12-16 18:18:38 +01:00
if ( steady_state )
2011-01-31 12:30:16 +01:00
{
2021-02-03 18:10:01 +01:00
compute_block_time ( 0 , true , false ) ;
2023-02-23 23:37:08 +01:00
if ( single_block )
2010-10-11 19:21:32 +02:00
for ( int j = 0 ; j < size ; j + + )
residual [ j ] = y [ Block_Contain [ j ] . Variable ] - ya [ Block_Contain [ j ] . Variable ] ;
2011-01-31 12:30:16 +01:00
else
for ( int j = 0 ; j < size ; j + + )
2013-03-22 15:44:34 +01:00
residual [ Block_Contain [ j ] . Equation ] = y [ Block_Contain [ j ] . Variable ] - ya [ Block_Contain [ j ] . Variable ] ;
2011-02-04 16:53:12 +01:00
}
2009-12-16 18:18:38 +01:00
else
{
for ( it_ = periods + y_kmin - 1 ; it_ > = y_kmin ; it_ - - )
{
Per_y_ = it_ * y_size ;
2021-02-03 18:10:01 +01:00
compute_block_time ( 0 , true , false ) ;
2023-02-23 23:37:08 +01:00
if ( single_block )
2010-10-11 19:21:32 +02:00
for ( int j = 0 ; j < size ; j + + )
2023-06-12 19:12:12 +02:00
residual [ ( it_ - y_kmin ) * size + j ] = y [ it_ * y_size + Block_Contain [ j ] . Variable ] - ya [ it_ * y_size + Block_Contain [ j ] . Variable ] ;
2011-01-31 12:30:16 +01:00
else
for ( int j = 0 ; j < size ; j + + )
2023-06-12 19:12:12 +02:00
residual [ ( it_ - y_kmin ) * y_size + Block_Contain [ j ] . Equation ] = y [ it_ * y_size + Block_Contain [ j ] . Variable ] - ya [ it_ * y_size + Block_Contain [ j ] . Variable ] ;
2009-12-16 18:18:38 +01:00
}
}
break ;
2020-03-20 18:51:37 +01:00
case BlockSimulationType : : solveBackwardSimple :
2019-04-23 12:58:38 +02:00
g1 = static_cast < double * > ( mxMalloc ( size * size * sizeof ( double ) ) ) ;
2017-03-24 23:15:25 +01:00
test_mxMalloc ( g1 , __LINE__ , __FILE__ , __func__ , size * size * sizeof ( double ) ) ;
2019-04-23 12:58:38 +02:00
r = static_cast < double * > ( mxMalloc ( size * sizeof ( double ) ) ) ;
2017-03-24 23:15:25 +01:00
test_mxMalloc ( r , __LINE__ , __FILE__ , __func__ , size * sizeof ( double ) ) ;
2009-12-16 18:18:38 +01:00
if ( steady_state )
{
2021-02-03 18:10:01 +01:00
compute_block_time ( 0 , true , false ) ;
2023-02-23 23:37:08 +01:00
if ( ! single_block )
2013-03-22 15:44:34 +01:00
for ( int j = 0 ; j < size ; j + + )
residual [ Block_Contain [ j ] . Equation ] = r [ j ] ;
2010-10-11 19:21:32 +02:00
else
2013-03-22 15:44:34 +01:00
for ( int j = 0 ; j < size ; j + + )
residual [ j ] = r [ j ] ;
2009-12-16 18:18:38 +01:00
}
else
{
for ( it_ = periods + y_kmin - 1 ; it_ > = y_kmin ; it_ - - )
{
Per_y_ = it_ * y_size ;
2021-02-03 18:10:01 +01:00
compute_block_time ( 0 , true , false ) ;
2023-02-23 23:37:08 +01:00
if ( ! single_block )
2013-03-22 15:44:34 +01:00
for ( int j = 0 ; j < size ; j + + )
2023-06-12 19:12:12 +02:00
residual [ ( it_ - y_kmin ) * y_size + Block_Contain [ j ] . Equation ] = r [ j ] ;
2010-10-11 19:21:32 +02:00
else
2013-03-22 15:44:34 +01:00
for ( int j = 0 ; j < size ; j + + )
2023-06-12 19:12:12 +02:00
residual [ ( it_ - y_kmin ) * size + j ] = r [ j ] ;
2009-12-16 18:18:38 +01:00
}
}
mxFree ( g1 ) ;
mxFree ( r ) ;
break ;
2020-03-20 18:51:37 +01:00
case BlockSimulationType : : solveBackwardComplete :
2015-09-22 12:45:27 +02:00
if ( initialization )
{
fixe_u ( & u , u_count_int , u_count_int ) ;
Read_SparseMatrix ( bin_base_name , size , 1 , 0 , 0 , false , stack_solve_algo , solve_algo ) ;
}
2019-04-23 12:58:38 +02:00
r = static_cast < double * > ( mxMalloc ( size * sizeof ( double ) ) ) ;
2017-03-24 23:15:25 +01:00
test_mxMalloc ( r , __LINE__ , __FILE__ , __func__ , size * sizeof ( double ) ) ;
2009-12-16 18:18:38 +01:00
if ( steady_state )
{
2021-02-03 18:10:01 +01:00
compute_block_time ( 0 , true , false ) ;
2023-02-23 23:37:08 +01:00
if ( ! single_block )
2010-10-11 19:21:32 +02:00
for ( int j = 0 ; j < size ; j + + )
2013-03-22 15:44:34 +01:00
residual [ Block_Contain [ j ] . Equation ] = r [ j ] ;
2010-10-11 19:21:32 +02:00
else
for ( int j = 0 ; j < size ; j + + )
residual [ j ] = r [ j ] ;
2009-12-16 18:18:38 +01:00
}
else
{
for ( it_ = periods + y_kmin - 1 ; it_ > = y_kmin ; it_ - - )
{
Per_y_ = it_ * y_size ;
2021-02-03 18:10:01 +01:00
compute_block_time ( 0 , true , false ) ;
2023-02-23 23:37:08 +01:00
if ( ! single_block )
2010-10-11 19:21:32 +02:00
for ( int j = 0 ; j < size ; j + + )
2023-06-12 19:12:12 +02:00
residual [ ( it_ - y_kmin ) * y_size + Block_Contain [ j ] . Equation ] = r [ j ] ;
2010-10-11 19:21:32 +02:00
else
for ( int j = 0 ; j < size ; j + + )
2023-06-12 19:12:12 +02:00
residual [ ( it_ - y_kmin ) * size + j ] = r [ j ] ;
2009-12-16 18:18:38 +01:00
}
}
mxFree ( r ) ;
break ;
2020-03-20 18:51:37 +01:00
case BlockSimulationType : : solveTwoBoundariesSimple :
case BlockSimulationType : : solveTwoBoundariesComplete :
2015-09-22 12:45:27 +02:00
if ( initialization )
{
fixe_u ( & u , u_count_int , u_count_int ) ;
Read_SparseMatrix ( bin_base_name , size , periods , y_kmin , y_kmax , true , stack_solve_algo , solve_algo ) ;
}
2009-12-16 18:18:38 +01:00
u_count = u_count_int * ( periods + y_kmax + y_kmin ) ;
2019-04-23 12:58:38 +02:00
r = static_cast < double * > ( mxMalloc ( size * sizeof ( double ) ) ) ;
2017-03-24 23:15:25 +01:00
test_mxMalloc ( r , __LINE__ , __FILE__ , __func__ , size * sizeof ( double ) ) ;
2009-12-16 18:18:38 +01:00
for ( it_ = y_kmin ; it_ < periods + y_kmin ; it_ + + )
{
Per_u_ = ( it_ - y_kmin ) * u_count_int ;
Per_y_ = it_ * y_size ;
2021-02-03 18:10:01 +01:00
compute_block_time ( Per_u_ , true , false ) ;
2023-02-23 23:37:08 +01:00
if ( ! single_block )
2010-10-11 19:21:32 +02:00
for ( int j = 0 ; j < size ; j + + )
2023-06-12 19:12:12 +02:00
residual [ ( it_ - y_kmin ) * y_size + Block_Contain [ j ] . Equation ] = r [ j ] ;
2010-10-11 19:21:32 +02:00
else
for ( int j = 0 ; j < size ; j + + )
2023-06-12 19:12:12 +02:00
residual [ ( it_ - y_kmin ) * size + j ] = r [ j ] ;
2009-12-16 18:18:38 +01:00
}
mxFree ( r ) ;
break ;
2020-03-20 18:51:37 +01:00
case BlockSimulationType : : unknown :
2022-07-29 12:42:50 +02:00
throw FatalException { " UNKNOWN block simulation type: impossible case " } ;
2009-09-11 19:06:54 +02:00
}
}
2010-09-24 12:52:58 +02:00
int
2023-02-23 23:37:08 +01:00
Interpreter : : simulate_a_block ( const vector_table_conditional_local_type & vector_table_conditional_local , bool single_block , const string & bin_base_name )
2007-11-21 00:27:30 +01:00
{
2015-09-22 12:45:27 +02:00
max_res = 0 ;
max_res_idx = 0 ;
2009-10-16 18:34:27 +02:00
bool cvg ;
2007-11-21 00:27:30 +01:00
double * y_save ;
2010-07-23 11:20:24 +02:00
# ifdef DEBUG
2013-03-22 15:44:34 +01:00
mexPrintf ( " simulate_a_block type = %d, periods=%d, y_kmin=%d, y_kmax=%d \n " , type , periods , y_kmin , y_kmax ) ;
mexEvalString ( " drawnow; " ) ;
2010-07-23 11:20:24 +02:00
# endif
2022-06-20 16:26:58 +02:00
switch ( type )
2007-11-21 00:27:30 +01:00
{
2020-03-20 18:51:37 +01:00
case BlockSimulationType : : evaluateForward :
2010-07-23 11:20:24 +02:00
# ifdef DEBUG
2020-03-20 18:51:37 +01:00
mexPrintf ( " EVALUATE FORWARD \n " ) ;
2013-03-22 15:44:34 +01:00
mexEvalString ( " drawnow; " ) ;
2010-07-23 11:20:24 +02:00
# endif
2017-05-16 16:30:27 +02:00
evaluate_over_periods ( true ) ;
2009-12-16 18:18:38 +01:00
break ;
2020-03-20 18:51:37 +01:00
case BlockSimulationType : : evaluateBackward :
2010-07-23 11:20:24 +02:00
# ifdef DEBUG
2020-03-20 18:51:37 +01:00
mexPrintf ( " EVALUATE BACKWARD \n " ) ;
2013-03-22 15:44:34 +01:00
mexEvalString ( " drawnow; " ) ;
2010-07-23 11:20:24 +02:00
# endif
2017-05-16 16:30:27 +02:00
evaluate_over_periods ( false ) ;
2009-12-16 18:18:38 +01:00
break ;
2020-03-20 18:51:37 +01:00
case BlockSimulationType : : solveForwardSimple :
2010-07-23 11:20:24 +02:00
# ifdef DEBUG
2020-03-20 18:51:37 +01:00
mexPrintf ( " SOLVE FORWARD SIMPLE size=%d \n " , size ) ;
2013-03-22 15:44:34 +01:00
mexEvalString ( " drawnow; " ) ;
2010-07-23 11:20:24 +02:00
# endif
2013-03-22 15:44:34 +01:00
solve_simple_over_periods ( true ) ;
2009-12-16 18:18:38 +01:00
break ;
2020-03-20 18:51:37 +01:00
case BlockSimulationType : : solveBackwardSimple :
2010-07-23 11:20:24 +02:00
# ifdef DEBUG
2020-03-20 18:51:37 +01:00
mexPrintf ( " SOLVE BACKWARD SIMPLE \n " ) ;
2013-03-22 15:44:34 +01:00
mexEvalString ( " drawnow; " ) ;
2010-07-23 11:20:24 +02:00
# endif
2013-03-22 15:44:34 +01:00
solve_simple_over_periods ( false ) ;
2009-12-16 18:18:38 +01:00
break ;
2020-03-20 18:51:37 +01:00
case BlockSimulationType : : solveForwardComplete :
2010-07-23 11:20:24 +02:00
# ifdef DEBUG
2020-03-20 18:51:37 +01:00
mexPrintf ( " SOLVE FORWARD COMPLETE \n " ) ;
2013-03-22 15:44:34 +01:00
mexEvalString ( " drawnow; " ) ;
2010-07-23 11:20:24 +02:00
# endif
2015-09-22 12:45:27 +02:00
if ( vector_table_conditional_local . size ( ) )
2023-02-24 20:30:15 +01:00
evaluate_a_block ( true , single_block , bin_base_name ) ;
2015-09-22 12:45:27 +02:00
else
{
fixe_u ( & u , u_count_int , u_count_int ) ;
Read_SparseMatrix ( bin_base_name , size , 1 , 0 , 0 , false , stack_solve_algo , solve_algo ) ;
}
2009-12-16 18:18:38 +01:00
Per_u_ = 0 ;
2012-03-06 11:03:13 +01:00
2013-03-22 15:44:34 +01:00
Simulate_Newton_One_Boundary ( true ) ;
mxFree ( u ) ;
2009-12-16 18:18:38 +01:00
mxFree ( index_equa ) ;
mxFree ( index_vara ) ;
2023-04-18 21:50:55 +02:00
fill_n ( direction , y_size * col_y , 0 ) ;
2013-03-22 15:44:34 +01:00
End_Solver ( ) ;
2009-12-16 18:18:38 +01:00
break ;
2020-03-20 18:51:37 +01:00
case BlockSimulationType : : solveBackwardComplete :
2010-07-23 11:20:24 +02:00
# ifdef DEBUG
2020-03-20 18:51:37 +01:00
mexPrintf ( " SOLVE BACKWARD COMPLETE \n " ) ;
2013-03-22 15:44:34 +01:00
mexEvalString ( " drawnow; " ) ;
2010-07-23 11:20:24 +02:00
# endif
2015-09-22 12:45:27 +02:00
if ( vector_table_conditional_local . size ( ) )
2023-02-24 20:30:15 +01:00
evaluate_a_block ( true , single_block , bin_base_name ) ;
2015-09-22 12:45:27 +02:00
else
{
fixe_u ( & u , u_count_int , u_count_int ) ;
Read_SparseMatrix ( bin_base_name , size , 1 , 0 , 0 , false , stack_solve_algo , solve_algo ) ;
}
2013-03-22 15:44:34 +01:00
Per_u_ = 0 ;
Simulate_Newton_One_Boundary ( false ) ;
2009-12-16 18:18:38 +01:00
mxFree ( index_equa ) ;
mxFree ( index_vara ) ;
2023-04-18 21:50:55 +02:00
fill_n ( direction , y_size * col_y , 0 ) ;
2009-12-16 18:18:38 +01:00
mxFree ( u ) ;
2013-03-22 15:44:34 +01:00
End_Solver ( ) ;
2009-12-16 18:18:38 +01:00
break ;
2020-03-20 18:51:37 +01:00
case BlockSimulationType : : solveTwoBoundariesSimple :
case BlockSimulationType : : solveTwoBoundariesComplete :
2010-07-23 11:20:24 +02:00
# ifdef DEBUG
2020-03-20 18:51:37 +01:00
mexPrintf ( " SOLVE TWO BOUNDARIES \n " ) ;
2013-03-22 15:44:34 +01:00
mexEvalString ( " drawnow; " ) ;
2010-07-23 11:20:24 +02:00
# endif
2009-12-16 18:18:38 +01:00
if ( steady_state )
{
2023-06-13 16:34:22 +02:00
if ( verbosity > = 1 )
mexPrintf ( " SOLVE TWO BOUNDARIES in a steady state model: impossible case \n " ) ;
2010-09-24 12:52:58 +02:00
return ERROR_ON_EXIT ;
2009-12-16 18:18:38 +01:00
}
2015-09-22 12:45:27 +02:00
if ( vector_table_conditional_local . size ( ) )
2023-02-24 20:30:15 +01:00
evaluate_a_block ( true , single_block , bin_base_name ) ;
2015-09-22 12:45:27 +02:00
else
{
fixe_u ( & u , u_count_int , u_count_int ) ;
Read_SparseMatrix ( bin_base_name , size , periods , y_kmin , y_kmax , true , stack_solve_algo , solve_algo ) ;
}
2009-12-16 18:18:38 +01:00
u_count = u_count_int * ( periods + y_kmax + y_kmin ) ;
2019-04-23 12:58:38 +02:00
r = static_cast < double * > ( mxMalloc ( size * sizeof ( double ) ) ) ;
2017-03-24 23:15:25 +01:00
test_mxMalloc ( r , __LINE__ , __FILE__ , __func__ , size * sizeof ( double ) ) ;
2019-04-23 12:58:38 +02:00
res = static_cast < double * > ( mxMalloc ( size * periods * sizeof ( double ) ) ) ;
2017-03-24 23:15:25 +01:00
test_mxMalloc ( res , __LINE__ , __FILE__ , __func__ , size * periods * sizeof ( double ) ) ;
2019-04-23 12:58:38 +02:00
y_save = static_cast < double * > ( mxMalloc ( y_size * sizeof ( double ) * ( periods + y_kmax + y_kmin ) ) ) ;
2017-03-24 23:15:25 +01:00
test_mxMalloc ( y_save , __LINE__ , __FILE__ , __func__ , y_size * sizeof ( double ) * ( periods + y_kmax + y_kmin ) ) ;
2009-12-16 18:18:38 +01:00
iter = 0 ;
2022-03-01 11:27:56 +01:00
if ( ! is_linear
| | stack_solve_algo = = 4 ) // On linear blocks, stack_solve_algo=4 may
// need more than one iteration to find the
// optimal (unitary!) path length
2009-12-16 18:18:38 +01:00
{
cvg = false ;
2010-02-06 15:07:56 +01:00
glambda2 = g0 = very_big ;
try_at_iteration = 0 ;
2009-12-16 18:18:38 +01:00
int u_count_saved = u_count ;
2023-06-13 16:37:16 +02:00
while ( ! ( cvg | | ( iter > = maxit_ ) ) )
2009-12-16 18:18:38 +01:00
{
res2 = 0 ;
res1 = 0 ;
max_res = 0 ;
max_res_idx = 0 ;
2021-02-09 15:55:36 +01:00
copy_n ( y , y_size * ( periods + y_kmax + y_kmin ) , y_save ) ;
2015-09-22 12:45:27 +02:00
if ( vector_table_conditional_local . size ( ) )
2021-02-03 18:10:01 +01:00
for ( auto & it1 : vector_table_conditional_local )
if ( it1 . is_cond )
y [ it1 . var_endo + y_kmin * size ] = it1 . constrained_value ;
2013-03-22 15:44:34 +01:00
compute_complete_2b ( false , & res1 , & res2 , & max_res , & max_res_idx ) ;
if ( ! ( isnan ( res1 ) | | isinf ( res1 ) ) )
2009-12-16 18:18:38 +01:00
cvg = ( max_res < solve_tolf ) ;
2013-03-22 15:44:34 +01:00
if ( isnan ( res1 ) | | isinf ( res1 ) | | ( stack_solve_algo = = 4 & & iter > 0 ) )
2021-02-09 15:55:36 +01:00
copy_n ( y_save , y_size * ( periods + y_kmax + y_kmin ) , y ) ;
2009-12-16 18:18:38 +01:00
u_count = u_count_saved ;
2010-02-06 15:07:56 +01:00
int prev_iter = iter ;
2023-04-18 16:55:12 +02:00
Simulate_Newton_Two_Boundaries ( block_num , y_size , y_kmin , y_kmax , size , periods , cvg , minimal_solving_periods , stack_solve_algo , vector_table_conditional_local ) ;
2009-12-16 18:18:38 +01:00
iter + + ;
2010-02-06 15:07:56 +01:00
if ( iter > prev_iter )
{
g0 = res2 ;
gp0 = - res2 ;
try_at_iteration = 0 ;
2010-09-17 09:57:38 +02:00
slowc_save = slowc ;
2010-02-06 15:07:56 +01:00
}
2009-12-16 18:18:38 +01:00
}
if ( ! cvg )
2022-07-29 12:42:50 +02:00
throw FatalException { " In Solve two boundaries, convergence not achieved in block "
2023-02-23 23:37:08 +01:00
+ to_string ( block_num + 1 ) + " , after "
+ to_string ( iter ) + " iterations " } ;
2009-12-16 18:18:38 +01:00
}
else
{
2010-07-23 11:20:24 +02:00
res1 = 0 ;
res2 = 0 ;
max_res = 0 ; max_res_idx = 0 ;
2013-03-22 15:44:34 +01:00
compute_complete_2b ( false , & res1 , & res2 , & max_res , & max_res_idx ) ;
2009-12-16 18:18:38 +01:00
cvg = false ;
2023-04-18 16:55:12 +02:00
Simulate_Newton_Two_Boundaries ( block_num , y_size , y_kmin , y_kmax , size , periods , cvg , minimal_solving_periods , stack_solve_algo , vector_table_conditional_local ) ;
2015-09-22 12:45:27 +02:00
max_res = 0 ; max_res_idx = 0 ;
2009-12-16 18:18:38 +01:00
}
2022-03-31 17:39:43 +02:00
slowc = 1 ; // slowc is modified when stack_solve_algo=4, so restore it
2017-03-24 23:15:25 +01:00
if ( r )
2017-05-16 16:30:27 +02:00
mxFree ( r ) ;
2017-03-24 23:15:25 +01:00
if ( y_save )
2017-05-16 16:30:27 +02:00
mxFree ( y_save ) ;
2017-03-24 23:15:25 +01:00
if ( u )
2017-05-16 16:30:27 +02:00
mxFree ( u ) ;
2017-03-24 23:15:25 +01:00
if ( index_vara )
2017-05-16 16:30:27 +02:00
mxFree ( index_vara ) ;
2017-03-24 23:15:25 +01:00
if ( index_equa )
2017-05-16 16:30:27 +02:00
mxFree ( index_equa ) ;
2017-03-24 23:15:25 +01:00
if ( res )
mxFree ( res ) ;
2023-04-18 21:50:55 +02:00
fill_n ( direction , y_size * col_y , 0 ) ;
2013-03-22 15:44:34 +01:00
End_Solver ( ) ;
2009-12-16 18:18:38 +01:00
break ;
default :
2022-07-29 12:42:50 +02:00
throw FatalException { " In simulate_a_block, Unknown type = " + to_string ( static_cast < int > ( type ) ) } ;
2010-09-24 12:52:58 +02:00
return ERROR_ON_EXIT ;
2007-11-21 00:27:30 +01:00
}
2010-09-24 12:52:58 +02:00
return NO_ERROR_ON_EXIT ;
2007-11-21 00:27:30 +01:00
}
2015-09-22 12:45:27 +02:00
void
2023-02-23 23:37:08 +01:00
Interpreter : : check_for_controlled_exo_validity ( int current_block , const vector < s_plan > & sconstrained_extended_path )
2015-09-22 12:45:27 +02:00
{
2023-04-18 17:53:27 +02:00
vector < int > exogenous { evaluator . getCurrentBlockExogenous ( ) } ;
vector < int > endogenous { evaluator . getCurrentBlockEndogenous ( ) } ;
2021-02-01 12:32:17 +01:00
for ( auto & it : sconstrained_extended_path )
2015-09-22 12:45:27 +02:00
{
2021-02-03 18:10:01 +01:00
if ( find ( endogenous . begin ( ) , endogenous . end ( ) , it . exo_num ) ! = endogenous . end ( )
& & find ( exogenous . begin ( ) , exogenous . end ( ) , it . var_num ) = = exogenous . end ( ) )
2022-07-29 12:42:50 +02:00
throw FatalException { " \n The conditional forecast involving as constrained variable "
2023-02-23 23:37:08 +01:00
+ symbol_table . getName ( SymbolType : : endogenous , it . exo_num )
+ " and as endogenized exogenous " + symbol_table . getName ( SymbolType : : exogenous , it . var_num )
+ " that do not appear in block= " + to_string ( current_block + 1 )
+ " ) \n You should not use block in model options " } ;
2021-02-03 18:10:01 +01:00
else if ( find ( endogenous . begin ( ) , endogenous . end ( ) , it . exo_num ) ! = endogenous . end ( )
& & find ( exogenous . begin ( ) , exogenous . end ( ) , it . var_num ) ! = exogenous . end ( )
2023-02-23 23:37:08 +01:00
& & ( type = = BlockSimulationType : : evaluateForward
| | type = = BlockSimulationType : : evaluateBackward ) )
2022-07-29 12:42:50 +02:00
throw FatalException { " \n The conditional forecast cannot be implemented for the block= "
2023-02-23 23:37:08 +01:00
+ to_string ( current_block + 1 ) + " ) that has to be evaluated instead to be solved \n You should not use block in model options " } ;
2021-02-03 18:10:01 +01:00
else if ( find ( previous_block_exogenous . begin ( ) , previous_block_exogenous . end ( ) , it . var_num )
! = previous_block_exogenous . end ( ) )
2022-07-29 12:42:50 +02:00
throw FatalException { " \n The conditional forecast involves in the block "
2023-02-23 23:37:08 +01:00
+ to_string ( current_block + 1 ) + " the endogenized exogenous "
+ symbol_table . getName ( SymbolType : : exogenous , it . var_num )
+ " that appear also in a previous block \n You should not use block in model options " } ;
2015-09-22 12:45:27 +02:00
}
2020-05-06 18:17:25 +02:00
for ( auto it : exogenous )
previous_block_exogenous . push_back ( it ) ;
2015-09-22 12:45:27 +02:00
}
2023-02-23 23:37:08 +01:00
pair < bool , vector < int > >
2023-02-23 17:21:22 +01:00
Interpreter : : MainLoop ( const string & bin_basename , bool evaluate , int block , bool constrained , const vector < s_plan > & sconstrained_extended_path , const vector_table_conditional_local_type & vector_table_conditional_local )
2015-09-22 12:45:27 +02:00
{
2023-02-23 23:37:08 +01:00
initializeTemporaryTerms ( global_temporary_terms ) ;
2023-04-18 17:53:27 +02:00
int nb_blocks { evaluator . get_block_number ( ) } ;
if ( block > = nb_blocks )
2023-02-23 23:37:08 +01:00
throw FatalException { " Interpreter::MainLoop: Input argument block = " + to_string ( block + 1 )
+ " is greater than the number of blocks in the model ( "
2023-04-18 17:53:27 +02:00
+ to_string ( nb_blocks ) + " see M_.block_structure " + ( steady_state ? " _stat " : " " ) + " .block) " } ;
2023-02-23 23:37:08 +01:00
vector < int > blocks ;
if ( block < 0 )
{
2023-04-18 17:53:27 +02:00
blocks . resize ( nb_blocks ) ;
2023-02-23 23:37:08 +01:00
iota ( blocks . begin ( ) , blocks . end ( ) , 0 ) ;
}
else
blocks . push_back ( block ) ;
2023-04-18 17:53:27 +02:00
jacobian_block . resize ( nb_blocks ) ;
jacobian_exo_block . resize ( nb_blocks ) ;
jacobian_det_exo_block . resize ( nb_blocks ) ;
2023-02-23 23:37:08 +01:00
2015-09-22 12:45:27 +02:00
double max_res_local = 0 ;
int max_res_idx_local = 0 ;
2010-10-11 19:21:32 +02:00
2011-01-31 12:30:16 +01:00
if ( block < 0 )
{
if ( steady_state )
residual = vector < double > ( y_size ) ;
else
2023-06-12 19:12:12 +02:00
residual = vector < double > ( y_size * periods ) ;
2011-01-31 12:30:16 +01:00
}
2011-02-04 16:53:12 +01:00
2023-02-23 23:37:08 +01:00
for ( int current_block : blocks )
2007-11-21 00:27:30 +01:00
{
2023-04-18 17:53:27 +02:00
evaluator . gotoBlock ( current_block ) ;
2023-04-18 16:55:12 +02:00
block_num = current_block ;
2023-04-18 17:53:27 +02:00
size = evaluator . getCurrentBlockSize ( ) ;
type = evaluator . getCurrentBlockType ( ) ;
is_linear = evaluator . isCurrentBlockLinear ( ) ;
Block_Contain = evaluator . getCurrentBlockEquationsAndVariables ( ) ;
u_count_int = evaluator . getCurrentBlockUCount ( ) ;
2023-02-23 23:37:08 +01:00
if ( constrained )
check_for_controlled_exo_validity ( current_block , sconstrained_extended_path ) ;
if ( print )
2007-11-21 00:27:30 +01:00
{
2023-02-23 23:37:08 +01:00
if ( steady_state )
residual = vector < double > ( size ) ;
2010-10-11 19:21:32 +02:00
else
2023-06-12 19:12:12 +02:00
residual = vector < double > ( size * periods ) ;
2023-04-18 17:53:27 +02:00
evaluator . printCurrentBlock ( ) ;
2023-02-23 23:37:08 +01:00
}
else if ( evaluate )
{
2010-11-20 15:45:15 +01:00
# ifdef DEBUG
2023-02-23 23:37:08 +01:00
mexPrintf ( " jacobian_block=mxCreateDoubleMatrix(%d, %d, mxREAL) \n " , size , getCurrentBlockNbColJacob ( ) ) ;
2010-11-20 15:45:15 +01:00
# endif
2023-04-18 17:53:27 +02:00
jacobian_block [ current_block ] = mxCreateDoubleMatrix ( size , evaluator . getCurrentBlockNbColJacob ( ) , mxREAL ) ;
2023-02-23 23:37:08 +01:00
if ( ! steady_state )
{
2010-11-20 15:45:15 +01:00
# ifdef DEBUG
2023-04-18 17:53:27 +02:00
mexPrintf ( " allocates jacobian_exo_block( %d, %d, mxREAL) \n " , size , evaluator . getCurrentBlockExoSize ( ) ) ;
2023-02-23 23:37:08 +01:00
mexPrintf ( " (0) Allocating Jacobian \n " ) ;
2017-03-24 23:15:25 +01:00
# endif
2010-12-17 17:17:40 +01:00
2023-04-18 17:53:27 +02:00
jacobian_exo_block [ current_block ] = mxCreateDoubleMatrix ( size , evaluator . getCurrentBlockExoSize ( ) , mxREAL ) ;
jacobian_det_exo_block [ current_block ] = mxCreateDoubleMatrix ( size , evaluator . getCurrentBlockExoDetSize ( ) , mxREAL ) ;
2023-02-23 23:37:08 +01:00
}
2010-10-11 19:21:32 +02:00
if ( block > = 0 )
2023-02-23 23:37:08 +01:00
{
if ( steady_state )
residual = vector < double > ( size ) ;
else
2023-06-12 19:12:12 +02:00
residual = vector < double > ( size * periods ) ;
2023-02-23 23:37:08 +01:00
}
evaluate_a_block ( true , block > = 0 , bin_basename ) ;
}
else
{
2009-12-16 18:18:38 +01:00
# ifdef DEBUG
2023-06-13 16:34:22 +02:00
mexPrintf ( " endo in block %d, size=%d, type=%d, steady_state=%d, is_linear=%d, endo_nbr=%d, u_count_int=%d \n " ,
current_block + 1 , size , type , steady_state , is_linear , symbol_table_endo_nbr , u_count_int ) ;
2009-12-16 18:18:38 +01:00
# endif
2023-02-23 23:37:08 +01:00
bool result ;
if ( sconstrained_extended_path . size ( ) )
2010-12-31 16:37:34 +01:00
{
2023-04-18 17:53:27 +02:00
jacobian_block [ current_block ] = mxCreateDoubleMatrix ( size , evaluator . getCurrentBlockNbColJacob ( ) , mxREAL ) ;
jacobian_exo_block [ current_block ] = mxCreateDoubleMatrix ( size , evaluator . getCurrentBlockExoSize ( ) , mxREAL ) ;
jacobian_det_exo_block [ current_block ] = mxCreateDoubleMatrix ( size , evaluator . getCurrentBlockExoDetSize ( ) , mxREAL ) ;
2023-06-12 19:12:12 +02:00
residual = vector < double > ( size * periods ) ;
2023-02-23 23:37:08 +01:00
result = simulate_a_block ( vector_table_conditional_local , block > = 0 , bin_basename ) ;
2010-12-31 16:37:34 +01:00
}
2017-05-16 16:30:27 +02:00
else
2023-02-23 23:37:08 +01:00
result = simulate_a_block ( vector_table_conditional_local , block > = 0 , bin_basename ) ;
if ( max_res > max_res_local )
2017-05-16 16:30:27 +02:00
{
2023-02-23 23:37:08 +01:00
max_res_local = max_res ;
max_res_idx_local = max_res_idx ;
2017-03-24 23:15:25 +01:00
}
2023-02-23 23:37:08 +01:00
if ( result = = ERROR_ON_EXIT )
return { ERROR_ON_EXIT , { } } ;
2007-11-21 00:27:30 +01:00
}
}
2023-02-23 23:37:08 +01:00
2017-05-16 16:30:27 +02:00
max_res = max_res_local ;
2015-09-22 12:45:27 +02:00
max_res_idx = max_res_idx_local ;
Close_SaveCode ( ) ;
2023-02-23 23:37:08 +01:00
return { true , blocks } ;
2015-09-22 12:45:27 +02:00
}
string
Interpreter : : elastic ( string str , unsigned int len , bool left )
{
if ( str . length ( ) > len )
return str ;
else
{
int diff = len - str . length ( ) ;
if ( diff % 2 = = 0 )
{
if ( left )
{
//mexPrintf("(1) diff=%d\n",diff);
2017-05-16 16:30:27 +02:00
str . insert ( str . end ( ) , diff - 1 , ' ' ) ;
str . insert ( str . begin ( ) , 1 , ' ' ) ;
2015-09-22 12:45:27 +02:00
}
else
{
2017-05-16 16:30:27 +02:00
str . insert ( str . end ( ) , diff / 2 , ' ' ) ;
str . insert ( str . begin ( ) , diff / 2 , ' ' ) ;
2015-09-22 12:45:27 +02:00
}
}
else
{
if ( left )
{
//mexPrintf("(2) diff=%d\n",diff);
2017-05-16 16:30:27 +02:00
str . insert ( str . end ( ) , diff - 1 , ' ' ) ;
str . insert ( str . begin ( ) , 1 , ' ' ) ;
2015-09-22 12:45:27 +02:00
}
else
{
2017-05-16 16:30:27 +02:00
str . insert ( str . end ( ) , ceil ( diff / 2 ) , ' ' ) ;
str . insert ( str . begin ( ) , ceil ( diff / 2 + 1 ) , ' ' ) ;
2015-09-22 12:45:27 +02:00
}
}
return str ;
}
}
2023-02-23 23:37:08 +01:00
pair < bool , vector < int > >
Interpreter : : extended_path ( const string & file_name , bool evaluate , int block , int nb_periods , const vector < s_plan > & sextended_path , const vector < s_plan > & sconstrained_extended_path , const vector < string > & dates , const table_conditional_global_type & table_conditional_global )
2015-09-22 12:45:27 +02:00
{
2017-05-05 14:22:38 +02:00
size_t size_of_direction = y_size * col_y * sizeof ( double ) ;
2021-02-01 12:39:34 +01:00
auto * y_save = static_cast < double * > ( mxMalloc ( size_of_direction ) ) ;
2017-05-05 14:22:38 +02:00
test_mxMalloc ( y_save , __LINE__ , __FILE__ , __func__ , size_of_direction ) ;
2021-02-01 12:39:34 +01:00
auto * x_save = static_cast < double * > ( mxMalloc ( nb_row_x * col_x * sizeof ( double ) ) ) ;
2017-05-05 14:22:38 +02:00
test_mxMalloc ( x_save , __LINE__ , __FILE__ , __func__ , nb_row_x * col_x * sizeof ( double ) ) ;
2017-03-24 23:15:25 +01:00
2015-09-22 12:45:27 +02:00
vector_table_conditional_local_type vector_table_conditional_local ;
vector_table_conditional_local . clear ( ) ;
2022-07-28 16:56:40 +02:00
int endo_name_length_l = static_cast < int > ( symbol_table . maxEndoNameLength ( ) ) ;
2015-09-22 12:45:27 +02:00
for ( int j = 0 ; j < col_x * nb_row_x ; j + + )
2015-11-19 17:03:05 +01:00
{
x_save [ j ] = x [ j ] ;
x [ j ] = 0 ;
2017-05-05 14:22:38 +02:00
}
2015-11-19 17:03:05 +01:00
for ( int j = 0 ; j < col_x ; j + + )
2017-05-05 14:22:38 +02:00
x [ y_kmin + j * nb_row_x ] = x_save [ y_kmin + j * nb_row_x ] ;
for ( int i = 0 ; i < y_size * col_y ; i + + )
y_save [ i ] = y [ i ] ;
2015-09-22 12:45:27 +02:00
if ( endo_name_length_l < 8 )
endo_name_length_l = 8 ;
2023-06-13 16:34:22 +02:00
int old_verbosity { verbosity } ;
verbosity = 0 ;
2015-09-22 12:45:27 +02:00
ostringstream res1 ;
res1 < < std : : scientific < < 2.54656875434865131 ;
int real_max_length = res1 . str ( ) . length ( ) ;
int date_length = dates [ 0 ] . length ( ) ;
int table_length = 2 + date_length + 3 + endo_name_length_l + 3 + real_max_length + 3 + 3 + 2 + 6 + 2 ;
string line ;
2017-05-16 16:30:27 +02:00
line . insert ( line . begin ( ) , table_length , ' - ' ) ;
line . insert ( line . length ( ) , " \n " ) ;
2023-06-13 16:34:22 +02:00
if ( old_verbosity > = 1 )
2015-11-19 17:03:05 +01:00
{
2017-05-16 16:30:27 +02:00
mexPrintf ( " \n Extended Path simulation: \n " ) ;
mexPrintf ( " ------------------------- \n " ) ;
mexPrintf ( line . c_str ( ) ) ;
string title = " | " + elastic ( " date " , date_length + 2 , false ) + " | " + elastic ( " variable " , endo_name_length_l + 2 , false ) + " | " + elastic ( " max. value " , real_max_length + 2 , false ) + " | iter. | " + elastic ( " cvg " , 5 , false ) + " | \n " ;
mexPrintf ( title . c_str ( ) ) ;
mexPrintf ( line . c_str ( ) ) ;
2015-11-19 17:03:05 +01:00
}
2023-02-23 23:37:08 +01:00
bool r ;
vector < int > blocks ;
2015-09-22 12:45:27 +02:00
for ( int t = 0 ; t < nb_periods ; t + + )
{
previous_block_exogenous . clear ( ) ;
2023-06-13 16:34:22 +02:00
if ( old_verbosity > = 1 )
2015-11-19 17:03:05 +01:00
{
2017-05-16 16:30:27 +02:00
mexPrintf ( " |%s| " , elastic ( dates [ t ] , date_length + 2 , false ) . c_str ( ) ) ;
2015-11-19 17:03:05 +01:00
mexEvalString ( " drawnow; " ) ;
}
2021-02-01 12:32:17 +01:00
for ( const auto & it : sextended_path )
2021-02-03 18:10:01 +01:00
x [ y_kmin + ( it . exo_num - 1 ) * nb_row_x ] = it . value [ t ] ;
2017-04-28 18:25:47 +02:00
2015-09-22 12:45:27 +02:00
vector_table_conditional_local . clear ( ) ;
2021-02-03 19:51:56 +01:00
if ( auto it = table_conditional_global . find ( t ) ; it ! = table_conditional_global . end ( ) )
vector_table_conditional_local = it - > second ;
2023-02-23 23:37:08 +01:00
tie ( r , blocks ) = MainLoop ( file_name , evaluate , block , true , sconstrained_extended_path , vector_table_conditional_local ) ;
2015-09-22 12:45:27 +02:00
for ( int j = 0 ; j < y_size ; j + + )
{
2019-12-20 14:50:19 +01:00
y_save [ j + ( t + y_kmin ) * y_size ] = y [ j + y_kmin * y_size ] ;
2015-09-22 12:45:27 +02:00
if ( y_kmin > 0 )
2019-12-20 14:50:19 +01:00
y [ j ] = y [ j + y_kmin * y_size ] ;
2015-09-22 12:45:27 +02:00
}
for ( int j = 0 ; j < col_x ; j + + )
2017-05-16 16:30:27 +02:00
{
x_save [ t + y_kmin + j * nb_row_x ] = x [ y_kmin + j * nb_row_x ] ;
2017-04-28 18:25:47 +02:00
if ( t < nb_periods )
x [ y_kmin + j * nb_row_x ] = x_save [ t + 1 + y_kmin + j * nb_row_x ] ;
2015-09-22 12:45:27 +02:00
}
2017-03-24 23:15:25 +01:00
2023-06-13 16:34:22 +02:00
if ( old_verbosity > = 1 )
2015-11-19 17:03:05 +01:00
{
2022-02-14 15:06:07 +01:00
ostringstream res1 ;
2017-04-28 18:25:47 +02:00
res1 < < std : : scientific < < max_res ;
2022-07-28 16:56:40 +02:00
mexPrintf ( " %s|%s| %4d | x | \n " , elastic ( symbol_table . getName ( SymbolType : : endogenous , max_res_idx ) , endo_name_length_l + 2 , true ) . c_str ( ) , elastic ( res1 . str ( ) , real_max_length + 2 , false ) . c_str ( ) , iter ) ;
2015-11-19 17:03:05 +01:00
mexPrintf ( line . c_str ( ) ) ;
mexEvalString ( " drawnow; " ) ;
}
2017-05-16 16:30:27 +02:00
}
2023-06-13 16:34:22 +02:00
verbosity = old_verbosity ;
2017-05-16 16:30:27 +02:00
for ( int i = 0 ; i < y_size * col_y ; i + + )
2019-12-20 14:50:19 +01:00
y [ i ] = y_save [ i ] ;
2017-05-05 14:22:38 +02:00
for ( int j = 0 ; j < col_x * nb_row_x ; j + + )
2017-05-16 16:30:27 +02:00
x [ j ] = x_save [ j ] ;
2017-03-24 23:15:25 +01:00
if ( y_save )
2017-05-16 16:30:27 +02:00
mxFree ( y_save ) ;
2017-03-24 23:15:25 +01:00
if ( x_save )
2017-05-16 16:30:27 +02:00
mxFree ( x_save ) ;
2015-09-22 12:45:27 +02:00
if ( T & & ! global_temporary_terms )
2017-05-16 16:30:27 +02:00
mxFree ( T ) ;
2023-02-23 23:37:08 +01:00
return { true , blocks } ;
2015-09-22 12:45:27 +02:00
}
2023-02-23 23:37:08 +01:00
pair < bool , vector < int > >
Interpreter : : compute_blocks ( const string & file_name , bool evaluate , int block )
2015-09-22 12:45:27 +02:00
{
//The big loop on intructions
vector < s_plan > s_plan_junk ;
vector_table_conditional_local_type vector_table_conditional_local_junk ;
2023-02-23 23:37:08 +01:00
auto [ r , blocks ] = MainLoop ( file_name , evaluate , block , false , s_plan_junk , vector_table_conditional_local_junk ) ;
2017-03-24 23:15:25 +01:00
2013-03-22 15:44:34 +01:00
if ( T & & ! global_temporary_terms )
2009-07-10 17:10:11 +02:00
mxFree ( T ) ;
2023-02-23 23:37:08 +01:00
return { true , blocks } ;
2007-11-21 00:27:30 +01:00
}
2023-04-18 15:49:56 +02:00
void
Interpreter : : initializeTemporaryTerms ( bool global_temporary_terms )
{
2023-04-18 17:53:27 +02:00
int ntt { evaluator . getNumberOfTemporaryTerms ( ) } ;
2023-04-18 15:49:56 +02:00
if ( steady_state )
{
if ( T )
mxFree ( T ) ;
if ( global_temporary_terms )
{
if ( ! GlobalTemporaryTerms )
{
mexPrintf ( " GlobalTemporaryTerms is nullptr \n " ) ;
mexEvalString ( " drawnow; " ) ;
}
if ( ntt ! = static_cast < int > ( mxGetNumberOfElements ( GlobalTemporaryTerms ) ) )
GlobalTemporaryTerms = mxCreateDoubleMatrix ( ntt , 1 , mxREAL ) ;
T = mxGetPr ( GlobalTemporaryTerms ) ;
}
else
{
T = static_cast < double * > ( mxMalloc ( ntt * sizeof ( double ) ) ) ;
test_mxMalloc ( T , __LINE__ , __FILE__ , __func__ , ntt * sizeof ( double ) ) ;
}
}
else
{
if ( T )
mxFree ( T ) ;
T = static_cast < double * > ( mxMalloc ( ntt * ( periods + y_kmin + y_kmax ) * sizeof ( double ) ) ) ;
test_mxMalloc ( T , __LINE__ , __FILE__ , __func__ , ntt * ( periods + y_kmin + y_kmax ) * sizeof ( double ) ) ;
}
}