2009-12-16 14:21:31 +01:00
/*
2017-05-16 14:11:15 +02:00
* Copyright ( C ) 2007 - 2017 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
* along with Dynare . If not , see < http : //www.gnu.org/licenses/>.
*/
2010-02-05 12:05:21 +01:00
# include <cstring>
2009-12-16 14:21:31 +01:00
# include "Interpreter.hh"
2013-03-22 15:44:34 +01:00
# include "ErrorHandling.hh"
# include <ctime>
# include <math.h>
2015-11-06 15:06:17 +01:00
# ifdef DYN_MEX_FUNC_ERR_MSG_TXT
2017-05-16 16:30:27 +02:00
# undef DYN_MEX_FUNC_ERR_MSG_TXT
2015-11-06 15:06:17 +01:00
# endif // DYN_MEX_FUNC_ERR_MSG_TXT
2017-05-16 16:30:27 +02:00
# define DYN_MEX_FUNC_ERR_MSG_TXT(str) \
do { \
mexPrintf ( " %s \n " , str ) ; \
if ( nlhs > 0 ) \
{ \
plhs [ 0 ] = mxCreateDoubleScalar ( 1 ) ; \
if ( nlhs > 1 ) \
{ \
double * pind ; \
plhs [ 1 ] = mxCreateDoubleMatrix ( int ( row_y ) , int ( col_y ) , mxREAL ) ; \
pind = mxGetPr ( plhs [ 1 ] ) ; \
if ( evaluate ) \
{ \
for ( unsigned int i = 0 ; i < row_y * col_y ; i + + ) \
pind [ i ] = 0 ; \
} \
else \
{ \
for ( unsigned int i = 0 ; i < row_y * col_y ; i + + ) \
pind [ i ] = yd [ i ] ; \
} \
for ( int i = 2 ; i < nlhs ; i + + ) \
plhs [ i ] = mxCreateDoubleScalar ( 1 ) ; \
} \
} \
return ; \
2015-11-06 15:06:17 +01:00
} while ( 0 )
2009-07-10 17:10:11 +02:00
# ifdef DEBUG_EX
2007-10-04 00:01:08 +02:00
2009-07-10 17:10:11 +02:00
using namespace std ;
2009-12-16 18:18:38 +01:00
# include <sstream>
2010-02-05 12:05:21 +01:00
2009-09-11 19:06:54 +02:00
string
Get_Argument ( const char * argv )
{
string f ( argv ) ;
return f ;
}
2009-07-10 17:10:11 +02:00
# else
2009-09-11 19:06:54 +02:00
2013-03-22 15:44:34 +01:00
void ( * prev_fn ) ( int ) ;
2009-09-11 19:06:54 +02:00
string
Get_Argument ( const mxArray * prhs )
{
const mxArray * mxa = prhs ;
2013-03-22 15:44:34 +01:00
mwSize buflen = mwSize ( mxGetM ( mxa ) * mxGetN ( mxa ) + 1 ) ;
2009-09-11 19:06:54 +02:00
char * first_argument ;
2009-12-16 18:18:38 +01:00
first_argument = ( 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 ;
}
2010-10-11 19:21:32 +02:00
# endif
2009-12-16 14:21:31 +01:00
2017-03-24 23:15:25 +01:00
//#include <windows.h>
# include <stdio.h>
2013-03-22 15:44:34 +01:00
# ifdef CUDA
int
GPU_Test_and_Info ( cublasHandle_t * cublas_handle , cusparseHandle_t * cusparse_handle , cusparseMatDescr_t * descr )
{
cudaDeviceProp deviceProp ;
int device_count , device , version , version_max = 0 ;
cublasStatus_t cublas_status ;
cudaError_t cuda_error ;
2017-05-16 16:30:27 +02:00
* descr = 0 ;
2013-03-22 15:44:34 +01:00
/* ask cuda how many devices it can find */
cudaGetDeviceCount ( & device_count ) ;
if ( device_count < 1 )
{
/* if it couldn't find any fail out */
ostringstream tmp ;
tmp < < " Unable to find a CUDA device. Unable to implement CUDA solvers \n " ;
throw FatalExceptionHandling ( tmp . str ( ) ) ;
}
else
{
mexPrintf ( " ----------------------------------------- \n " ) ;
for ( int i = 0 ; i < device_count ; i + + )
{
cudaSetDevice ( i ) ;
// Statistics about the GPU device
cuda_error = cudaGetDeviceProperties ( & deviceProp , i ) ;
if ( cuda_error ! = cudaSuccess )
{
2017-05-16 16:30:27 +02:00
ostringstream tmp ;
tmp < < " bytecode cudaGetDeviceProperties failed \n " ;
throw FatalExceptionHandling ( tmp . str ( ) ) ;
2013-03-22 15:44:34 +01:00
}
mexPrintf ( " > GPU device %d: \" %s \" has: \n - %d Multi-Processors, \n - %d threads per multiprocessor, \n " , i , deviceProp . name , deviceProp . multiProcessorCount , deviceProp . maxThreadsPerMultiProcessor ) ;
mexEvalString ( " drawnow; " ) ;
version = ( deviceProp . major * 0x10 + deviceProp . minor ) ;
if ( version > = version_max )
{
device = i ;
version_max = version ;
}
2017-05-16 16:30:27 +02:00
mexPrintf ( " - %4.2fMhz clock rate, \n - %2.0fMb of memory, \n - %d.%d compute capabilities. \n " , double ( deviceProp . clockRate ) / ( 1024 * 1024 ) , double ( deviceProp . totalGlobalMem ) / ( 1024 * 1024 ) , deviceProp . major , deviceProp . minor ) ;
2013-03-22 15:44:34 +01:00
mexEvalString ( " drawnow; " ) ;
}
}
mexPrintf ( " > Device %d selected \n " , device ) ;
mexEvalString ( " drawnow; " ) ;
cuda_error = cudaSetDevice ( device ) ;
if ( cuda_error ! = cudaSuccess )
{
2017-05-16 16:30:27 +02:00
ostringstream tmp ;
tmp < < " bytecode cudaSetDevice failed \n " ;
throw FatalExceptionHandling ( tmp . str ( ) ) ;
2013-03-22 15:44:34 +01:00
}
2017-05-16 16:30:27 +02:00
if ( version_max < 0x11 )
2013-03-22 15:44:34 +01:00
{
2017-05-16 16:30:27 +02:00
ostringstream tmp ;
tmp < < " bytecode requires a minimum CUDA compute 1.1 capability \n " ;
cudaDeviceReset ( ) ;
throw FatalExceptionHandling ( tmp . str ( ) ) ;
2013-03-22 15:44:34 +01:00
}
// Initialize CuBlas library
cublas_status = cublasCreate ( cublas_handle ) ;
if ( cublas_status ! = CUBLAS_STATUS_SUCCESS )
{
ostringstream tmp ;
2017-05-16 16:30:27 +02:00
switch ( cublas_status )
2013-03-22 15:44:34 +01:00
{
2017-05-16 16:30:27 +02:00
case CUBLAS_STATUS_NOT_INITIALIZED :
tmp < < " the CUBLAS initialization failed. \n " ;
break ;
case CUBLAS_STATUS_ALLOC_FAILED :
tmp < < " the resources could not be allocated. \n " ;
break ;
default :
tmp < < " unknown error during the initialization of cusparse library. \n " ;
2013-03-22 15:44:34 +01:00
}
throw FatalExceptionHandling ( tmp . str ( ) ) ;
}
// Initialize the CuSparse library
cusparseStatus_t cusparse_status ;
cusparse_status = cusparseCreate ( cusparse_handle ) ;
if ( cusparse_status ! = CUSPARSE_STATUS_SUCCESS )
{
ostringstream tmp ;
2017-05-16 16:30:27 +02:00
switch ( cusparse_status )
2013-03-22 15:44:34 +01:00
{
2017-05-16 16:30:27 +02:00
case CUSPARSE_STATUS_NOT_INITIALIZED :
tmp < < " the CUDA Runtime initialization failed. \n " ;
break ;
case CUSPARSE_STATUS_ALLOC_FAILED :
tmp < < " the resources could not be allocated. \n " ;
break ;
case CUSPARSE_STATUS_ARCH_MISMATCH :
tmp < < " the device compute capability (CC) is less than 1.1. The CC of at least 1.1 is required. \n " ;
break ;
default :
tmp < < " unknown error during the initialization of cusparse library. \n " ;
2013-03-22 15:44:34 +01:00
}
throw FatalExceptionHandling ( tmp . str ( ) ) ;
}
// Create and setup matrix descriptor
cusparse_status = cusparseCreateMatDescr ( descr ) ;
if ( cusparse_status ! = CUSPARSE_STATUS_SUCCESS )
{
ostringstream tmp ;
tmp < < " Matrix descriptor initialization failed \n " ;
throw FatalExceptionHandling ( tmp . str ( ) ) ;
}
cusparseSetMatType ( * descr , CUSPARSE_MATRIX_TYPE_GENERAL ) ;
cusparseSetMatIndexBase ( * descr , CUSPARSE_INDEX_BASE_ZERO ) ;
mexPrintf ( " > Driver version: \n " ) ;
int cuda_version ;
cuda_error = cudaDriverGetVersion ( & cuda_version ) ;
if ( cuda_error ! = cudaSuccess )
{
ostringstream tmp ;
tmp < < " cudaGetVersion has failed \n " ;
throw FatalExceptionHandling ( tmp . str ( ) ) ;
}
2017-05-16 16:30:27 +02:00
mexPrintf ( " - CUDA version %5.3f \n " , double ( cuda_version ) / 1000 ) ;
2013-03-22 15:44:34 +01:00
int cublas_version ;
cublas_status = cublasGetVersion ( * cublas_handle , & cublas_version ) ;
if ( cublas_status ! = CUBLAS_STATUS_SUCCESS )
{
ostringstream tmp ;
tmp < < " cublasGetVersion has failed \n " ;
throw FatalExceptionHandling ( tmp . str ( ) ) ;
}
2017-05-16 16:30:27 +02:00
mexPrintf ( " - CUBLAS version %5.3f \n " , double ( cublas_version ) / 1000 ) ;
2013-03-22 15:44:34 +01:00
int cusparse_version ;
cusparse_status = cusparseGetVersion ( * cusparse_handle , & cusparse_version ) ;
if ( cusparse_status ! = CUSPARSE_STATUS_SUCCESS )
{
ostringstream tmp ;
tmp < < " cusparseGetVersion has failed \n " ;
throw FatalExceptionHandling ( tmp . str ( ) ) ;
}
2017-05-16 16:30:27 +02:00
mexPrintf ( " - CUSPARSE version %5.3f \n " , double ( cusparse_version ) / 1000 ) ;
2013-03-22 15:44:34 +01:00
mexPrintf ( " ----------------------------------------- \n " ) ;
return device ;
}
void
GPU_close ( cublasHandle_t cublas_handle , cusparseHandle_t cusparse_handle , cusparseMatDescr_t descr )
{
2017-05-16 16:30:27 +02:00
cublasChk ( cublasDestroy ( cublas_handle ) , " in bytecode cublasDestroy failed \n " ) ;
2013-03-22 15:44:34 +01:00
cusparseChk ( cusparseDestroyMatDescr ( descr ) , " in bytecode cusparseDestroyMatDescr failed \n " ) ;
2017-05-16 16:30:27 +02:00
cusparseChk ( cusparseDestroy ( cusparse_handle ) , " in bytecode cusparseDestroy failed \n " ) ;
2013-03-22 15:44:34 +01:00
}
# endif
string
deblank ( string x )
{
2017-05-16 16:30:27 +02:00
for ( int i = 0 ; i < ( 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 ,
2010-08-18 13:51:57 +02:00
# ifndef DEBUG_EX
2010-10-11 19:21:32 +02:00
const mxArray * prhs [ ] ,
2010-08-18 13:51:57 +02:00
# else
2010-10-11 19:21:32 +02:00
const char * prhs [ ] ,
2010-08-18 13:51:57 +02:00
# endif
2010-10-11 19:21:32 +02:00
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
# ifndef DEBUG_EX
mxArray * block_structur [ ] ,
# endif
bool & steady_state , 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 ;
2010-08-18 13:51:57 +02:00
# ifdef DEBUG_EX
2010-10-11 19:21:32 +02:00
for ( int i = 2 ; i < nrhs ; i + + )
2010-08-18 13:51:57 +02:00
# else
2011-02-04 16:53:12 +01:00
for ( int i = 0 ; i < nrhs ; i + + )
2010-08-18 13:51:57 +02:00
# endif
2011-02-04 16:53:12 +01:00
{
2010-08-18 13:51:57 +02:00
# ifndef DEBUG_EX
2011-02-04 16:53:12 +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 :
2011-03-14 17:46:00 +01:00
* steady_yd = mxGetPr ( prhs [ i ] ) ;
steady_row_y = mxGetM ( prhs [ i ] ) ;
steady_col_y = mxGetN ( prhs [ i ] ) ;
2011-02-04 16:53:12 +01:00
break ;
case 4 :
2017-05-16 16:30:27 +02:00
periods = int ( mxGetScalar ( prhs [ i ] ) ) ;
2011-02-04 16:53:12 +01:00
break ;
case 5 :
2011-03-14 17:46:00 +01:00
* block_structur = mxDuplicateArray ( prhs [ i ] ) ;
break ;
case 6 :
2011-02-04 16:53:12 +01:00
global_temporary_terms = true ;
* GlobalTemporaryTerms = mxDuplicateArray ( prhs [ i ] ) ;
break ;
default :
2017-05-16 16:30:27 +02:00
mexPrintf ( " Unknown argument count_array_argument=%d \n " , count_array_argument ) ;
2011-02-04 16:53:12 +01:00
break ;
}
count_array_argument + + ;
}
else
2010-08-18 13:51:57 +02:00
# endif
2011-02-04 16:53:12 +01:00
if ( Get_Argument ( prhs [ i ] ) = = " static " )
steady_state = true ;
else if ( Get_Argument ( prhs [ i ] ) = = " dynamic " )
steady_state = false ;
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 ;
2011-06-17 16:37:36 +02:00
else if ( Get_Argument ( prhs [ i ] ) = = " no_print_error " )
print_error = false ;
2010-10-11 19:21:32 +02:00
else
{
2015-09-22 12:45:27 +02:00
pos = 0 ;
if ( Get_Argument ( prhs [ i ] ) . substr ( 0 , 5 ) = = " block " )
2011-02-04 16:53:12 +01:00
{
2015-09-22 12:45:27 +02:00
size_t pos1 = Get_Argument ( prhs [ i ] ) . find ( " = " , pos + 5 ) ;
2013-06-12 16:05:10 +02:00
if ( pos1 ! = string : : npos )
2011-02-04 16:53:12 +01:00
pos = pos1 + 1 ;
else
pos + = 5 ;
block = atoi ( Get_Argument ( prhs [ i ] ) . substr ( pos , string : : npos ) . c_str ( ) ) - 1 ;
}
2017-05-16 16:30:27 +02:00
else if ( Get_Argument ( prhs [ i ] ) . substr ( 0 , 13 ) = = " extended_path " )
2013-03-22 15:44:34 +01:00
{
2015-09-22 12:45:27 +02:00
* extended_path = true ;
if ( ( i + 1 ) > = nrhs )
* ep_struct = NULL ;
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 ) ;
2013-06-12 16:05:10 +02:00
if ( pos1 ! = string : : npos )
2013-03-22 15:44:34 +01:00
pos = pos1 + 1 ;
else
pos + = 6 ;
* pfplan_struct_name = deblank ( Get_Argument ( prhs [ i ] ) . substr ( pos , string : : npos ) ) ;
}
2015-09-22 12:45:27 +02:00
else if ( Get_Argument ( prhs [ i ] ) . substr ( 0 , 4 ) = = " plan " )
2013-03-22 15:44:34 +01:00
{
2015-09-22 12:45:27 +02:00
size_t pos1 = Get_Argument ( prhs [ i ] ) . find ( " = " , pos + 4 ) ;
2013-06-12 16:05:10 +02:00
if ( pos1 ! = string : : npos )
2013-03-22 15:44:34 +01:00
pos = pos1 + 1 ;
else
pos + = 4 ;
* plan_struct_name = deblank ( Get_Argument ( prhs [ i ] ) . substr ( pos , string : : npos ) ) ;
}
2011-02-04 16:53:12 +01:00
else
{
ostringstream tmp ;
tmp < < " in main, unknown argument : " < < Get_Argument ( prhs [ i ] ) < < " \n " ;
throw FatalExceptionHandling ( tmp . str ( ) ) ;
}
2010-10-11 19:21:32 +02:00
}
2011-02-04 16:53:12 +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
{
ostringstream tmp ;
2011-03-14 17:46:00 +01:00
tmp < < " in main, missing arguments. All the following arguments have to be indicated y, x, params, it_, ys \n " ;
2010-10-11 19:21:32 +02:00
throw FatalExceptionHandling ( tmp . str ( ) ) ;
}
2010-07-23 11:20:24 +02:00
}
2010-10-11 19:21:32 +02:00
* M_ = mexGetVariable ( " global " , " M_ " ) ;
2013-10-28 14:26:42 +01:00
if ( * M_ = = NULL )
2007-10-04 00:01:08 +02:00
{
2010-09-24 12:52:58 +02:00
ostringstream tmp ;
tmp < < " in main, global variable not found: M_ \n " ;
throw FatalExceptionHandling ( tmp . str ( ) ) ;
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_ " ) ;
2013-10-28 14:26:42 +01:00
if ( * oo_ = = NULL )
2007-10-04 00:01:08 +02:00
{
2010-09-24 12:52:58 +02:00
ostringstream tmp ;
tmp < < " in main, global variable not found: oo_ \n " ;
throw FatalExceptionHandling ( tmp . str ( ) ) ;
2007-10-04 00:01:08 +02:00
}
2010-10-11 19:21:32 +02:00
* options_ = mexGetVariable ( " global " , " options_ " ) ;
2013-10-28 14:26:42 +01:00
if ( * options_ = = NULL )
2007-10-04 00:01:08 +02:00
{
2010-09-24 12:52:58 +02:00
ostringstream tmp ;
tmp < < " in main, global variable not found: options_ \n " ;
throw FatalExceptionHandling ( tmp . str ( ) ) ;
2007-10-04 00:01:08 +02:00
}
2010-10-11 19:21:32 +02:00
}
# ifdef DEBUG_EX
int
main ( int nrhs , const char * prhs [ ] )
# else
/* The gateway routine */
2011-02-04 16:53:12 +01:00
void
mexFunction ( int nlhs , mxArray * plhs [ ] , int nrhs , const mxArray * prhs [ ] )
2010-10-11 19:21:32 +02:00
# endif
{
mxArray * M_ , * oo_ , * options_ ;
2011-02-04 16:53:12 +01:00
mxArray * GlobalTemporaryTerms ;
2010-10-11 19:21:32 +02:00
# ifndef DEBUG_EX
mxArray * block_structur = NULL ;
# else
int nlhs = 0 ;
char * plhs [ 1 ] ;
2011-02-04 16:53:12 +01:00
load_global ( ( char * ) prhs [ 1 ] ) ;
2010-10-11 19:21:32 +02:00
# endif
2017-05-16 16:30:27 +02:00
mxArray * pfplan_struct = NULL ;
2017-03-24 23:15:25 +01:00
ErrorMsg error_msg ;
2013-03-22 15:44:34 +01:00
size_t i , row_y = 0 , col_y = 0 , row_x = 0 , col_x = 0 , nb_row_xd = 0 ;
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 ;
bool evaluate = false ;
int block = - 1 ;
double * params = NULL ;
double * yd = NULL , * xd = NULL ;
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 ;
2011-03-14 17:46:00 +01:00
double * steady_yd = NULL , * steady_xd = NULL ;
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
# ifdef CUDA
int CUDA_device = - 1 ;
cublasHandle_t cublas_handle ;
cusparseHandle_t cusparse_handle ;
cusparseMatDescr_t descr ;
# 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 ,
2010-10-11 19:21:32 +02:00
# ifndef DEBUG_EX
2011-02-04 16:53:12 +01:00
& block_structur ,
2010-10-11 19:21:32 +02:00
# endif
2011-02-04 16:53:12 +01:00
steady_state , evaluate , block ,
& 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
}
catch ( GeneralExceptionHandling & feh )
{
DYN_MEX_FUNC_ERR_MSG_TXT ( feh . GetErrorMsg ( ) . c_str ( ) ) ;
}
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 )
DYN_MEX_FUNC_ERR_MSG_TXT ( " params is not a field of M_ " ) ;
params = mxGetPr ( mxGetFieldByNumber ( M_ , 0 , field ) ) ;
}
2010-09-24 12:52:58 +02:00
2013-03-22 15:44:34 +01:00
ErrorMsg emsg ;
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 )
{
if ( extended_path_struct = = NULL )
{
string tmp = " The 'extended_path' option must be followed by the extended_path descriptor " ;
DYN_MEX_FUNC_ERR_MSG_TXT ( tmp . c_str ( ) ) ;
}
2017-05-16 16:30:27 +02:00
mxArray * date_str = mxGetField ( extended_path_struct , 0 , " date_str " ) ;
2015-09-22 12:45:27 +02:00
if ( date_str = = NULL )
{
string tmp = " date_str " ;
2017-05-16 16:30:27 +02:00
tmp . insert ( 0 , " The extended_path description structure does not contain the member: " ) ;
2015-09-22 12:45:27 +02:00
DYN_MEX_FUNC_ERR_MSG_TXT ( tmp . c_str ( ) ) ;
}
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_ " ) ;
2015-09-22 12:45:27 +02:00
if ( constrained_vars_ = = NULL )
{
string tmp = " constrained_vars_ " ;
2017-05-16 16:30:27 +02:00
tmp . insert ( 0 , " The extended_path description structure does not contain the member: " ) ;
2015-09-22 12:45:27 +02:00
DYN_MEX_FUNC_ERR_MSG_TXT ( tmp . c_str ( ) ) ;
}
2017-05-16 16:30:27 +02:00
mxArray * constrained_paths_ = mxGetField ( extended_path_struct , 0 , " constrained_paths_ " ) ;
2015-09-22 12:45:27 +02:00
if ( constrained_paths_ = = NULL )
{
string tmp = " constrained_paths_ " ;
2017-05-16 16:30:27 +02:00
tmp . insert ( 0 , " The extended_path description structure does not contain the member: " ) ;
2015-09-22 12:45:27 +02:00
DYN_MEX_FUNC_ERR_MSG_TXT ( tmp . c_str ( ) ) ;
}
2017-05-16 16:30:27 +02:00
mxArray * constrained_int_date_ = mxGetField ( extended_path_struct , 0 , " constrained_int_date_ " ) ;
2015-09-22 12:45:27 +02:00
if ( constrained_int_date_ = = NULL )
{
string tmp = " constrained_int_date_ " ;
2017-05-16 16:30:27 +02:00
tmp . insert ( 0 , " The extended_path description structure does not contain the member: " ) ;
2015-09-22 12:45:27 +02:00
DYN_MEX_FUNC_ERR_MSG_TXT ( tmp . c_str ( ) ) ;
}
2017-05-16 16:30:27 +02:00
mxArray * constrained_perfect_foresight_ = mxGetField ( extended_path_struct , 0 , " constrained_perfect_foresight_ " ) ;
2015-09-22 12:45:27 +02:00
if ( constrained_perfect_foresight_ = = NULL )
{
string tmp = " constrained_perfect_foresight_ " ;
2017-05-16 16:30:27 +02:00
tmp . insert ( 0 , " The extended_path description structure does not contain the member: " ) ;
2015-09-22 12:45:27 +02:00
DYN_MEX_FUNC_ERR_MSG_TXT ( tmp . c_str ( ) ) ;
}
2017-03-24 23:15:25 +01:00
2017-05-16 16:30:27 +02:00
mxArray * shock_var_ = mxGetField ( extended_path_struct , 0 , " shock_vars_ " ) ;
2015-09-22 12:45:27 +02:00
if ( shock_var_ = = NULL )
{
string tmp = " shock_vars_ " ;
2017-05-16 16:30:27 +02:00
tmp . insert ( 0 , " The extended_path description structure does not contain the member: " ) ;
2015-09-22 12:45:27 +02:00
DYN_MEX_FUNC_ERR_MSG_TXT ( tmp . c_str ( ) ) ;
}
2017-05-16 16:30:27 +02:00
mxArray * shock_paths_ = mxGetField ( extended_path_struct , 0 , " shock_paths_ " ) ;
2015-09-22 12:45:27 +02:00
if ( shock_paths_ = = NULL )
{
string tmp = " shock_paths_ " ;
2017-05-16 16:30:27 +02:00
tmp . insert ( 0 , " The extended_path description structure does not contain the member: " ) ;
2015-09-22 12:45:27 +02:00
DYN_MEX_FUNC_ERR_MSG_TXT ( tmp . c_str ( ) ) ;
}
2017-05-16 16:30:27 +02:00
mxArray * shock_int_date_ = mxGetField ( extended_path_struct , 0 , " shock_int_date_ " ) ;
2015-09-22 12:45:27 +02:00
if ( shock_int_date_ = = NULL )
{
string tmp = " shock_int_date_ " ;
2017-05-16 16:30:27 +02:00
tmp . insert ( 0 , " The extended_path description structure does not contain the member: " ) ;
2015-09-22 12:45:27 +02:00
DYN_MEX_FUNC_ERR_MSG_TXT ( tmp . c_str ( ) ) ;
}
2017-05-16 16:30:27 +02:00
mxArray * shock_str_date_ = mxGetField ( extended_path_struct , 0 , " shock_str_date_ " ) ;
2015-09-22 12:45:27 +02:00
if ( shock_str_date_ = = NULL )
{
string tmp = " shock_str_date_ " ;
2017-05-16 16:30:27 +02:00
tmp . insert ( 0 , " The extended_path description structure does not contain the member: " ) ;
2015-09-22 12:45:27 +02:00
DYN_MEX_FUNC_ERR_MSG_TXT ( tmp . c_str ( ) ) ;
}
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_ " ) ;
mxArray * controlled_varexo = NULL ;
2015-09-22 12:45:27 +02:00
if ( options_cond_fcst_ ! = NULL )
{
controlled_varexo = mxGetField ( options_cond_fcst_ , 0 , " controlled_varexo " ) ;
nb_controlled = mxGetM ( controlled_varexo ) * mxGetN ( controlled_varexo ) ;
if ( nb_controlled ! = nb_constrained )
{
DYN_MEX_FUNC_ERR_MSG_TXT ( " The number of exogenized variables and the number of exogenous controlled variables should be equal. " ) ;
}
}
2017-05-16 16:30:27 +02:00
double * controlled_varexo_value = NULL ;
2015-09-22 12:45:27 +02:00
if ( controlled_varexo ! = NULL )
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_ ) ;
2017-05-16 16:30:27 +02:00
int * constrained_int_date = ( int * ) mxMalloc ( nb_local_periods * sizeof ( int ) ) ;
error_msg . 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 )
{
ostringstream oss ;
oss < < nb_periods ;
string tmp = oss . str ( ) ;
2017-05-16 16:30:27 +02:00
tmp . insert ( 0 , " The total number of simulation periods ( " ) ;
2015-09-22 12:45:27 +02:00
tmp . append ( " ) is lesser than the number of periods in the shock definitions ( " ) ;
oss < < nb_local_periods ;
string tmp1 = oss . str ( ) ;
tmp . append ( tmp1 ) ;
2017-03-24 23:15:25 +01:00
tmp . append ( " ) " ) ;
2015-09-22 12:45:27 +02:00
DYN_MEX_FUNC_ERR_MSG_TXT ( tmp . c_str ( ) ) ;
}
( sconditional_extended_path [ i ] ) . per_value . resize ( nb_local_periods ) ;
( sconditional_extended_path [ i ] ) . value . resize ( nb_periods ) ;
for ( int j = 0 ; j < nb_periods ; j + + )
sconditional_extended_path [ i ] . value [ j ] = 0 ;
for ( int j = 0 ; j < nb_local_periods ; j + + )
{
2017-05-16 16:30:27 +02:00
constrained_int_date [ j ] = 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 ;
sconditional_extended_path [ i ] . per_value [ j ] = make_pair ( 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 ] ;
2015-09-22 12:45:27 +02:00
if ( max_periods < constrained_int_date [ j ] + 1 )
2017-05-16 16:30:27 +02:00
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 )
{
ostringstream oss ;
oss < < nb_periods ;
string tmp = oss . str ( ) ;
2017-05-16 16:30:27 +02:00
tmp . insert ( 0 , " The total number of simulation periods ( " ) ;
2015-09-22 12:45:27 +02:00
tmp . append ( " ) is lesser than the number of periods in the shock definitions ( " ) ;
oss < < nb_local_periods ;
string tmp1 = oss . str ( ) ;
tmp . append ( tmp1 ) ;
2017-03-24 23:15:25 +01:00
tmp . append ( " ) " ) ;
2015-09-22 12:45:27 +02:00
DYN_MEX_FUNC_ERR_MSG_TXT ( tmp . c_str ( ) ) ;
}
( sextended_path [ i ] ) . per_value . resize ( nb_local_periods ) ;
( sextended_path [ i ] ) . value . resize ( nb_periods ) ;
for ( int j = 0 ; j < nb_periods ; j + + )
sextended_path [ i ] . value [ j ] = 0 ;
for ( int j = 0 ; j < nb_local_periods ; j + + )
{
2017-05-16 16:30:27 +02:00
sextended_path [ i ] . per_value [ j ] = make_pair ( int ( specific_shock_int_date_ [ j ] ) , specific_shock_paths_ [ j ] ) ;
sextended_path [ i ] . value [ int ( specific_shock_int_date_ [ j ] - 1 ) ] = specific_shock_paths_ [ j ] ;
if ( max_periods < int ( specific_shock_int_date_ [ j ] ) )
max_periods = 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 ;
2017-05-16 16:30:27 +02:00
char * buf = ( char * ) mxCalloc ( buflen , sizeof ( char ) ) ;
2015-09-22 12:45:27 +02:00
int info = mxGetString ( mxGetCell ( date_str , i ) , buf , buflen ) ;
if ( info )
{
string tmp = " Can not allocated memory to store the date_str in the extended path descriptor " ;
DYN_MEX_FUNC_ERR_MSG_TXT ( tmp . c_str ( ) ) ;
}
dates . push_back ( string ( buf ) ) ; //string(Dates[i]);
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 ( ) ) ;
2013-03-22 15:44:34 +01:00
if ( plan_struct = = NULL )
{
string tmp = plan ;
2017-05-16 16:30:27 +02:00
tmp . insert ( 0 , " Can't find the plan: " ) ;
2013-03-22 15:44:34 +01:00
DYN_MEX_FUNC_ERR_MSG_TXT ( tmp . c_str ( ) ) ;
}
size_t n_plan = mxGetN ( plan_struct ) ;
splan . resize ( n_plan ) ;
2013-06-12 16:05:10 +02:00
for ( int i = 0 ; i < ( 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 )
{
char name [ 100 ] ;
mxGetString ( tmp , name , 100 ) ;
splan [ i ] . var = name ;
2015-09-22 12:45:27 +02:00
SymbolType variable_type = eEndogenous ;
2013-03-22 15:44:34 +01:00
int exo_num = emsg . get_ID ( name , & variable_type ) ;
if ( variable_type = = eExogenous | | variable_type = = eExogenousDet )
splan [ i ] . var_num = exo_num ;
else
{
string tmp = name ;
2017-05-16 16:30:27 +02:00
tmp . insert ( 0 , " the variable ' " ) ;
2013-03-22 15:44:34 +01:00
tmp . append ( " ' defined as var in plan is not an exogenous or a deterministic exogenous \n " ) ;
DYN_MEX_FUNC_ERR_MSG_TXT ( tmp . c_str ( ) ) ;
}
}
tmp = mxGetField ( plan_struct , i , " var " ) ;
if ( tmp )
{
char name [ 100 ] ;
mxGetString ( tmp , name , 100 ) ;
splan [ i ] . exo = name ;
SymbolType variable_type ;
int exo_num = emsg . get_ID ( name , & variable_type ) ;
if ( variable_type = = eEndogenous )
splan [ i ] . exo_num = exo_num ;
else
{
string tmp = name ;
2017-05-16 16:30:27 +02:00
tmp . insert ( 0 , " the variable ' " ) ;
2013-03-22 15:44:34 +01:00
tmp . append ( " ' defined as exo in plan is not an endogenous variable \n " ) ;
DYN_MEX_FUNC_ERR_MSG_TXT ( tmp . c_str ( ) ) ;
}
}
tmp = mxGetField ( plan_struct , i , " per_value " ) ;
if ( tmp )
{
size_t num_shocks = mxGetM ( tmp ) ;
( splan [ i ] ) . per_value . resize ( num_shocks ) ;
2017-05-16 16:30:27 +02:00
double * per_value = mxGetPr ( tmp ) ;
2013-06-12 16:05:10 +02:00
for ( int j = 0 ; j < ( int ) num_shocks ; j + + )
2013-03-22 15:44:34 +01:00
( splan [ i ] ) . per_value [ j ] = make_pair ( ceil ( per_value [ j ] ) , per_value [ j + num_shocks ] ) ;
}
}
2013-06-12 16:05:10 +02:00
int i = 0 ;
2013-03-22 15:44:34 +01:00
for ( vector < s_plan > : : iterator it = splan . begin ( ) ; it ! = splan . end ( ) ; it + + )
{
mexPrintf ( " ---------------------------------------------------------------------------------------------------- \n " ) ;
2017-06-28 15:06:54 +02:00
mexPrintf ( " surprise #%d \n " , i + 1 ) ;
2013-03-22 15:44:34 +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 ) ;
else
mexPrintf ( " plan shocks on var=%s for the following periods and with the following values: \n " , it - > var . c_str ( ) ) ;
for ( vector < pair < int , double > > : : iterator it1 = it - > per_value . begin ( ) ; it1 ! = it - > per_value . end ( ) ; it1 + + )
{
2017-05-16 16:30:27 +02:00
mexPrintf ( " %3d %10.5f \n " , it1 - > first , it1 - > second ) ;
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 )
{
string tmp = pfplan ;
2017-05-16 16:30:27 +02:00
tmp . insert ( 0 , " Can't find the pfplan: " ) ;
2013-03-22 15:44:34 +01:00
DYN_MEX_FUNC_ERR_MSG_TXT ( tmp . c_str ( ) ) ;
}
size_t n_plan = mxGetN ( pfplan_struct ) ;
spfplan . resize ( n_plan ) ;
2013-06-12 16:05:10 +02:00
for ( int i = 0 ; i < ( 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 )
{
char name [ 100 ] ;
mxGetString ( tmp , name , 100 ) ;
spfplan [ i ] . var = name ;
2015-09-22 12:45:27 +02:00
SymbolType variable_type = eEndogenous ;
2013-03-22 15:44:34 +01:00
int exo_num = emsg . get_ID ( name , & variable_type ) ;
if ( variable_type = = eExogenous | | variable_type = = eExogenousDet )
splan [ i ] . var_num = exo_num ;
else
{
string tmp = name ;
2017-05-16 16:30:27 +02:00
tmp . insert ( 0 , " the variable ' " ) ;
2013-03-22 15:44:34 +01:00
tmp . append ( " ' defined as var in pfplan is not an exogenous or a deterministic exogenous \n " ) ;
DYN_MEX_FUNC_ERR_MSG_TXT ( tmp . c_str ( ) ) ;
}
}
tmp = mxGetField ( pfplan_struct , i , " exo " ) ;
if ( tmp )
{
char name [ 100 ] ;
mxGetString ( tmp , name , 100 ) ;
spfplan [ i ] . exo = name ;
SymbolType variable_type ;
int exo_num = emsg . get_ID ( name , & variable_type ) ;
if ( variable_type = = eEndogenous )
spfplan [ i ] . exo_num = exo_num ;
else
{
string tmp = name ;
2017-05-16 16:30:27 +02:00
tmp . insert ( 0 , " the variable ' " ) ;
2013-03-22 15:44:34 +01:00
tmp . append ( " ' defined as exo in pfplan is not an endogenous variable \n " ) ;
DYN_MEX_FUNC_ERR_MSG_TXT ( tmp . c_str ( ) ) ;
}
}
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 ) ;
2013-03-22 15:44:34 +01:00
( spfplan [ i ] ) . per_value . resize ( num_shocks ) ;
2013-06-12 16:05:10 +02:00
for ( int j = 0 ; j < ( int ) num_shocks ; j + + )
2013-03-22 15:44:34 +01:00
spfplan [ i ] . per_value [ j ] = make_pair ( ceil ( per_value [ j ] ) , per_value [ j + num_shocks ] ) ;
}
}
2013-06-12 16:05:10 +02:00
int i = 0 ;
2013-03-22 15:44:34 +01:00
for ( vector < s_plan > : : iterator it = spfplan . begin ( ) ; it ! = spfplan . end ( ) ; it + + )
{
mexPrintf ( " ---------------------------------------------------------------------------------------------------- \n " ) ;
2013-11-05 13:51:18 +01:00
mexPrintf ( " perfect foresight #%d \n " , i + 1 ) ;
2013-03-22 15:44:34 +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 ) ;
else
mexPrintf ( " plan shocks on var=%s (%d) for the following periods and with the following values: \n " , it - > var . c_str ( ) , it - > var_num ) ;
for ( vector < pair < int , double > > : : iterator it1 = it - > per_value . begin ( ) ; it1 ! = it - > per_value . end ( ) ; it1 + + )
{
2017-05-16 16:30:27 +02:00
mexPrintf ( " %3d %10.5f \n " , it1 - > first , it1 - > second ) ;
2013-03-22 15:44:34 +01:00
}
i + + ;
}
}
int field_steady_state = mxGetFieldNumber ( oo_ , " steady_state " ) ;
if ( field_steady_state < 0 )
DYN_MEX_FUNC_ERR_MSG_TXT ( " steady_state is not a field of oo_ " ) ;
int field_exo_steady_state = mxGetFieldNumber ( oo_ , " exo_steady_state " ) ;
if ( field_exo_steady_state < 0 )
DYN_MEX_FUNC_ERR_MSG_TXT ( " exo_steady_state is not a field of oo_ " ) ;
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 )
DYN_MEX_FUNC_ERR_MSG_TXT ( " endo_simul is not a field of oo_ " ) ;
int field_exo_simul = mxGetFieldNumber ( oo_ , " exo_simul " ) ;
if ( field_exo_simul < 0 )
DYN_MEX_FUNC_ERR_MSG_TXT ( " exo_simul is not a field of oo_ " ) ;
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 ) ;
2011-03-18 01:09:20 +01:00
nb_row_xd = row_x ;
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 )
y_kmin = int ( floor ( * ( mxGetPr ( mxGetFieldByNumber ( M_ , 0 , field ) ) ) ) ) ;
else
DYN_MEX_FUNC_ERR_MSG_TXT ( " maximum_lag is not a field of M_ " ) ;
field = mxGetFieldNumber ( M_ , " maximum_lead " ) ;
if ( field > = 0 )
y_kmax = int ( floor ( * ( mxGetPr ( mxGetFieldByNumber ( M_ , 0 , field ) ) ) ) ) ;
else
DYN_MEX_FUNC_ERR_MSG_TXT ( " maximum_lead is not a field of M_ " ) ;
field = mxGetFieldNumber ( M_ , " maximum_endo_lag " ) ;
if ( field > = 0 )
y_decal = max ( 0 , y_kmin - int ( floor ( * ( mxGetPr ( mxGetFieldByNumber ( M_ , 0 , field ) ) ) ) ) ) ;
else
DYN_MEX_FUNC_ERR_MSG_TXT ( " 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 )
periods = int ( floor ( * ( mxGetPr ( mxGetFieldByNumber ( options_ , 0 , field ) ) ) ) ) ;
else
DYN_MEX_FUNC_ERR_MSG_TXT ( " options_ is not a field of options_ " ) ;
}
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
}
2013-03-22 15:44:34 +01:00
steady_xd = mxGetPr ( mxGetFieldByNumber ( oo_ , 0 , field_exo_steady_state ) ) ;
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 ) ;
2011-03-18 01:09:20 +01:00
nb_row_xd = row_x ;
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 )
2017-05-16 16:30:27 +02:00
verbose = int ( * mxGetPr ( ( mxGetFieldByNumber ( options_ , 0 , field ) ) ) ) ;
2013-03-22 15:44:34 +01:00
else
DYN_MEX_FUNC_ERR_MSG_TXT ( " 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 )
DYN_MEX_FUNC_ERR_MSG_TXT ( " simul is not a field of options_ " ) ;
else
DYN_MEX_FUNC_ERR_MSG_TXT ( " steady is not a field of options_ " ) ;
}
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 )
DYN_MEX_FUNC_ERR_MSG_TXT ( " maxit is not a field of options_.simul " ) ;
else
DYN_MEX_FUNC_ERR_MSG_TXT ( " maxit is not a field of options_.steady " ) ;
}
2013-10-09 16:55:46 +02:00
int maxit_ = int ( floor ( * ( mxGetPr ( mxGetFieldByNumber ( temporaryfield , 0 , field ) ) ) ) ) ;
2013-03-22 15:44:34 +01:00
field = mxGetFieldNumber ( options_ , " slowc " ) ;
if ( field < 0 )
DYN_MEX_FUNC_ERR_MSG_TXT ( " slows is not a field of options_ " ) ;
double slowc = double ( * ( mxGetPr ( mxGetFieldByNumber ( options_ , 0 , field ) ) ) ) ;
field = mxGetFieldNumber ( options_ , " markowitz " ) ;
if ( field < 0 )
DYN_MEX_FUNC_ERR_MSG_TXT ( " markowitz is not a field of options_ " ) ;
double markowitz_c = double ( * ( mxGetPr ( mxGetFieldByNumber ( options_ , 0 , field ) ) ) ) ;
field = mxGetFieldNumber ( options_ , " minimal_solving_periods " ) ;
if ( field < 0 )
DYN_MEX_FUNC_ERR_MSG_TXT ( " minimal_solving_periods is not a field of options_ " ) ;
int minimal_solving_periods = int ( * ( mxGetPr ( mxGetFieldByNumber ( options_ , 0 , field ) ) ) ) ;
field = mxGetFieldNumber ( options_ , " stack_solve_algo " ) ;
if ( field < 0 )
DYN_MEX_FUNC_ERR_MSG_TXT ( " stack_solve_algo is not a field of options_ " ) ;
int stack_solve_algo = 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 )
solve_algo = int ( * ( mxGetPr ( mxGetFieldByNumber ( options_ , 0 , field ) ) ) ) ;
else
DYN_MEX_FUNC_ERR_MSG_TXT ( " solve_algo is not a field of options_ " ) ;
field = mxGetFieldNumber ( options_ , " solve_tolf " ) ;
if ( field > = 0 )
solve_tolf = * ( mxGetPr ( mxGetFieldByNumber ( options_ , 0 , field ) ) ) ;
else
DYN_MEX_FUNC_ERR_MSG_TXT ( " 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
DYN_MEX_FUNC_ERR_MSG_TXT ( " dynatol is not a field of options_ " ) ;
field = mxGetFieldNumber ( dynatol , " f " ) ;
if ( field > = 0 )
2017-05-16 16:30:27 +02:00
solve_tolf = * mxGetPr ( ( mxGetFieldByNumber ( dynatol , 0 , field ) ) ) ;
2013-03-22 15:44:34 +01:00
else
DYN_MEX_FUNC_ERR_MSG_TXT ( " 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
DYN_MEX_FUNC_ERR_MSG_TXT ( " fname is not a field of M_ " ) ;
size_t buflen = mxGetM ( mxa ) * mxGetN ( mxa ) + 1 ;
2007-10-04 00:01:08 +02:00
char * fname ;
2010-08-18 13:51:57 +02:00
fname = ( char * ) mxCalloc ( buflen + 1 , sizeof ( char ) ) ;
2017-05-16 16:30:27 +02:00
size_t status = mxGetString ( mxa , fname , 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 ;
2009-08-25 11:43:01 +02:00
2013-03-22 15:44:34 +01:00
# ifdef CUDA
try
{
if ( stack_solve_algo = = 7 & & ! steady_state )
CUDA_device = GPU_Test_and_Info ( & cublas_handle , & cusparse_handle , & descr ) ;
}
catch ( GeneralExceptionHandling & feh )
{
DYN_MEX_FUNC_ERR_MSG_TXT ( feh . GetErrorMsg ( ) . c_str ( ) ) ;
}
# else
if ( stack_solve_algo = = 7 & & ! steady_state )
DYN_MEX_FUNC_ERR_MSG_TXT ( " bytecode has not been compiled with CUDA option. Bytecode Can't use options_.stack_solve_algo=7 \n " ) ;
2017-05-16 16:30:27 +02:00
# endif
2013-03-22 15:44:34 +01:00
size_t size_of_direction = col_y * row_y * sizeof ( double ) ;
2009-12-16 18:18:38 +01:00
double * y = ( double * ) mxMalloc ( size_of_direction ) ;
2017-03-24 23:15:25 +01:00
error_msg . test_mxMalloc ( y , __LINE__ , __FILE__ , __func__ , size_of_direction ) ;
2009-12-16 18:18:38 +01:00
double * ya = ( double * ) mxMalloc ( size_of_direction ) ;
2017-03-24 23:15:25 +01:00
error_msg . test_mxMalloc ( ya , __LINE__ , __FILE__ , __func__ , size_of_direction ) ;
2009-12-16 18:18:38 +01:00
direction = ( double * ) mxMalloc ( size_of_direction ) ;
2017-03-24 23:15:25 +01:00
error_msg . test_mxMalloc ( direction , __LINE__ , __FILE__ , __func__ , size_of_direction ) ;
2017-05-16 16:30:27 +02:00
memset ( direction , 0 , size_of_direction ) ;
/*mexPrintf("col_x : %d, row_x : %d\n",col_x, row_x);*/
2009-12-16 18:18:38 +01:00
double * x = ( double * ) mxMalloc ( col_x * row_x * sizeof ( double ) ) ;
2017-03-24 23:15:25 +01:00
error_msg . 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 + + )
2013-03-22 15:44:34 +01:00
{
x [ i ] = 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
{
2009-12-16 18:18:38 +01:00
y [ i ] = double ( yd [ i ] ) ;
ya [ i ] = 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 ( ) ;
2013-03-22 15:44:34 +01:00
Interpreter interprete ( params , y , ya , x , steady_yd , steady_xd , direction , y_size , nb_row_x , nb_row_xd , periods , y_kmin , y_kmax , maxit_ , solve_tolf , size_of_direction , slowc , y_decal ,
markowitz_c , file_name , minimal_solving_periods , stack_solve_algo , solve_algo , global_temporary_terms , print , print_error , GlobalTemporaryTerms , steady_state ,
2017-05-05 14:22:38 +02:00
print_it , col_x , col_y
2013-03-22 15:44:34 +01:00
# ifdef CUDA
, CUDA_device , cublas_handle , cusparse_handle , descr
# endif
) ;
2007-10-04 00:01:08 +02:00
string f ( fname ) ;
2010-08-18 13:51:57 +02:00
mxFree ( fname ) ;
2010-07-23 11:20:24 +02:00
int nb_blocks = 0 ;
2010-09-24 12:52:58 +02:00
double * pind ;
2012-02-17 10:59:39 +01:00
bool no_error = true ;
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
{
interprete . extended_path ( f , f , evaluate , block , nb_blocks , max_periods , sextended_path , sconditional_extended_path , dates , table_conditional_global ) ;
}
catch ( GeneralExceptionHandling & feh )
{
DYN_MEX_FUNC_ERR_MSG_TXT ( feh . GetErrorMsg ( ) . c_str ( ) ) ;
}
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
{
interprete . compute_blocks ( f , f , evaluate , block , nb_blocks ) ;
}
catch ( GeneralExceptionHandling & feh )
{
DYN_MEX_FUNC_ERR_MSG_TXT ( feh . GetErrorMsg ( ) . c_str ( ) ) ;
}
2010-09-24 12:52:58 +02:00
}
2013-03-22 15:44:34 +01:00
# ifdef CUDA
if ( stack_solve_algo = = 7 & & ! steady_state )
GPU_close ( cublas_handle , cusparse_handle , descr ) ;
# endif
2009-12-16 18:18:38 +01:00
clock_t t1 = clock ( ) ;
2011-12-12 12:40:46 +01:00
if ( ! steady_state & & ! evaluate & & no_error & & print )
2009-12-16 18:18:38 +01:00
mexPrintf ( " Simulation Time=%f milliseconds \n " , 1000.0 * ( double ( t1 ) - double ( t0 ) ) / double ( CLOCKS_PER_SEC ) ) ;
2010-08-18 13:51:57 +02:00
# ifndef DEBUG_EX
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
{
2010-09-24 12:52:58 +02:00
plhs [ 0 ] = mxCreateDoubleMatrix ( 1 , 1 , mxREAL ) ;
2007-10-04 00:01:08 +02:00
pind = mxGetPr ( plhs [ 0 ] ) ;
2010-09-24 12:52:58 +02:00
if ( no_error )
pind [ 0 ] = 0 ;
2009-09-11 19:06:54 +02:00
else
2010-09-24 12:52:58 +02:00
pind [ 0 ] = 1 ;
2009-12-16 18:18:38 +01:00
if ( nlhs > 1 )
{
2010-10-11 19:21:32 +02:00
if ( block > = 0 )
{
if ( evaluate )
{
vector < double > residual = interprete . get_residual ( ) ;
2017-05-16 16:30:27 +02:00
plhs [ 1 ] = mxCreateDoubleMatrix ( int ( residual . size ( ) / double ( col_y ) ) , int ( col_y ) , mxREAL ) ;
2010-10-11 19:21:32 +02:00
pind = mxGetPr ( plhs [ 1 ] ) ;
for ( i = 0 ; i < residual . size ( ) ; i + + )
pind [ i ] = residual [ i ] ;
}
else
2017-05-05 14:22:38 +02:00
{
int out_periods ;
if ( extended_path )
out_periods = max_periods + y_kmin ;
else
2017-04-28 18:25:47 +02:00
out_periods = row_y ;
2017-05-16 16:30:27 +02:00
plhs [ 1 ] = mxCreateDoubleMatrix ( out_periods , int ( col_y ) , mxREAL ) ;
2010-10-11 19:21:32 +02:00
pind = mxGetPr ( plhs [ 1 ] ) ;
2017-05-05 14:22:38 +02:00
for ( i = 0 ; i < out_periods * col_y ; i + + )
pind [ i ] = y [ 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
{
2017-05-05 14:22:38 +02:00
int out_periods ;
if ( extended_path )
out_periods = max_periods + y_kmin ;
else
2017-04-28 18:25:47 +02:00
out_periods = col_y ;
2017-05-16 16:30:27 +02:00
plhs [ 1 ] = mxCreateDoubleMatrix ( int ( row_y ) , out_periods , mxREAL ) ;
2010-10-11 19:21:32 +02:00
pind = mxGetPr ( plhs [ 1 ] ) ;
if ( evaluate )
2011-01-31 12:30:16 +01:00
{
vector < double > residual = interprete . get_residual ( ) ;
for ( i = 0 ; i < residual . size ( ) ; i + + )
pind [ i ] = residual [ i ] ;
}
2010-10-11 19:21:32 +02:00
else
2017-05-05 14:22:38 +02:00
for ( i = 0 ; i < row_y * out_periods ; i + + )
2017-05-16 16:30:27 +02:00
pind [ i ] = y [ i ] ;
2010-10-11 19:21:32 +02:00
}
2010-07-23 11:20:24 +02:00
if ( nlhs > 2 )
{
2011-02-02 00:31:37 +01:00
if ( evaluate )
2010-07-23 11:20:24 +02:00
{
2011-02-02 00:31:37 +01:00
int jacob_field_number = 0 , jacob_exo_field_number = 0 , jacob_exo_det_field_number = 0 , jacob_other_endo_field_number = 0 ;
if ( ! block_structur )
{
2011-02-04 16:53:12 +01:00
const char * field_names [ ] = { " g1 " , " g1_x " , " g1_xd " , " g1_o " } ;
jacob_field_number = 0 ;
jacob_exo_field_number = 1 ;
jacob_exo_det_field_number = 2 ;
2011-06-17 16:37:36 +02:00
jacob_other_endo_field_number = 3 ;
2017-05-16 16:30:27 +02:00
mwSize dims [ 1 ] = { ( mwSize ) nb_blocks } ;
2011-02-02 00:31:37 +01:00
plhs [ 2 ] = mxCreateStructArray ( 1 , dims , 4 , field_names ) ;
}
else if ( ! mxIsStruct ( block_structur ) )
{
plhs [ 2 ] = interprete . get_jacob ( 0 ) ;
//mexCallMATLAB(0,NULL, 1, &plhs[2], "disp");
dont_store_a_structure = true ;
}
else
{
plhs [ 2 ] = block_structur ;
jacob_field_number = mxAddField ( plhs [ 2 ] , " g1 " ) ;
if ( jacob_field_number = = - 1 )
DYN_MEX_FUNC_ERR_MSG_TXT ( " Fatal error in bytecode: in main, cannot add extra field jacob to the structArray \n " ) ;
jacob_exo_field_number = mxAddField ( plhs [ 2 ] , " g1_x " ) ;
if ( jacob_exo_field_number = = - 1 )
DYN_MEX_FUNC_ERR_MSG_TXT ( " Fatal error in bytecode: in main, cannot add extra field jacob_exo to the structArray \n " ) ;
jacob_exo_det_field_number = mxAddField ( plhs [ 2 ] , " g1_xd " ) ;
if ( jacob_exo_det_field_number = = - 1 )
DYN_MEX_FUNC_ERR_MSG_TXT ( " Fatal error in bytecode: in main, cannot add extra field jacob_exo_det to the structArray \n " ) ;
jacob_other_endo_field_number = mxAddField ( plhs [ 2 ] , " g1_o " ) ;
if ( jacob_other_endo_field_number = = - 1 )
DYN_MEX_FUNC_ERR_MSG_TXT ( " Fatal error in bytecode: in main, cannot add extra field jacob_other_endo to the structArray \n " ) ;
}
if ( ! dont_store_a_structure )
{
for ( int i = 0 ; i < nb_blocks ; i + + )
2011-02-04 16:53:12 +01:00
{
mxSetFieldByNumber ( plhs [ 2 ] , i , jacob_field_number , interprete . get_jacob ( i ) ) ;
2012-06-06 16:32:01 +02:00
if ( ! steady_state )
{
mxSetFieldByNumber ( plhs [ 2 ] , i , jacob_exo_field_number , interprete . get_jacob_exo ( i ) ) ;
mxSetFieldByNumber ( plhs [ 2 ] , i , jacob_exo_det_field_number , interprete . get_jacob_exo_det ( i ) ) ;
mxSetFieldByNumber ( plhs [ 2 ] , i , jacob_other_endo_field_number , interprete . get_jacob_other_endo ( i ) ) ;
}
2011-02-02 00:31:37 +01:00
}
}
2010-07-23 11:20:24 +02:00
}
2011-02-04 16:53:12 +01:00
else
2017-05-16 16:30:27 +02:00
{
plhs [ 2 ] = mxCreateDoubleMatrix ( int ( row_x ) , int ( col_x ) , mxREAL ) ;
2015-09-22 12:45:27 +02:00
pind = mxGetPr ( plhs [ 2 ] ) ;
2017-05-16 16:30:27 +02:00
for ( i = 0 ; i < row_x * col_x ; i + + )
{
pind [ i ] = x [ i ] ;
2017-04-28 18:25:47 +02:00
}
2017-05-16 16:30:27 +02:00
2010-10-11 19:21:32 +02:00
}
if ( nlhs > 3 )
2010-07-23 11:20:24 +02:00
{
2017-05-16 16:30:27 +02:00
plhs [ 3 ] = mxCreateDoubleMatrix ( int ( row_y ) , int ( col_y ) , mxREAL ) ;
2010-10-11 19:21:32 +02:00
pind = mxGetPr ( plhs [ 3 ] ) ;
for ( i = 0 ; i < row_y * col_y ; i + + )
pind [ i ] = y [ i ] ;
2011-01-14 19:22:29 +01:00
if ( nlhs > 4 )
{
2011-02-04 16:53:12 +01:00
mxArray * GlobalTemporaryTerms = interprete . get_Temporary_Terms ( ) ;
2013-03-22 15:44:34 +01:00
size_t nb_temp_terms = mxGetM ( GlobalTemporaryTerms ) ;
2017-05-16 16:30:27 +02:00
plhs [ 4 ] = mxCreateDoubleMatrix ( int ( nb_temp_terms ) , 1 , mxREAL ) ;
2011-01-14 19:22:29 +01:00
pind = mxGetPr ( plhs [ 4 ] ) ;
double * tt = mxGetPr ( GlobalTemporaryTerms ) ;
for ( i = 0 ; i < nb_temp_terms ; i + + )
pind [ i ] = tt [ i ] ;
}
2010-07-23 11:20:24 +02:00
}
2011-01-14 19:22:29 +01:00
2010-07-23 11:20:24 +02:00
}
2009-12-16 18:18:38 +01:00
}
2007-10-04 00:01:08 +02:00
}
2010-08-18 13:51:57 +02:00
# else
Free_global ( ) ;
2017-05-16 16:30:27 +02:00
# endif
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 ) ;
2013-03-22 15:44:34 +01:00
# ifdef _MSC_VER_
/*fFreeResult =*/ FreeLibrary ( hinstLib ) ;
# endif
return ;
2007-10-04 00:01:08 +02:00
}