2009-05-06 12:10:27 +02:00
/*
2019-03-07 18:17:43 +01:00
* Copyright ( C ) 2008 - 2019 Dynare Team
2009-05-19 10:57:07 +02: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/>.
*/
2009-05-06 12:10:27 +02:00
2019-04-02 16:33:15 +02:00
/* Defines the entry point for the k-order perturbation application DLL.
2010-08-30 17:11:58 +02:00
2019-04-02 16:33:15 +02:00
See matlab / mex / k_order_perturbation . m for a description of inputs and
outputs .
2010-08-30 17:11:58 +02:00
*/
2009-05-06 12:10:27 +02:00
2010-12-17 18:34:23 +01:00
# include "dynamic_m.hh"
2009-12-17 12:00:50 +01:00
# include "dynamic_dll.hh"
2019-04-02 16:33:15 +02:00
# include "k_ord_dynare.hh"
# include "approximation.hh"
# include "exception.hh"
# include "dynare_exception.hh"
# include "kord_exception.hh"
# include "tl_exception.hh"
# include "SylvException.hh"
2009-05-06 12:10:27 +02:00
2019-03-07 18:17:43 +01:00
# include <algorithm>
2010-02-08 16:58:24 +01:00
# include <cassert>
2009-05-06 12:10:27 +02:00
2019-03-07 18:17:43 +01:00
# include "dynmex.h"
2010-09-20 16:57:02 +02:00
2019-04-08 16:59:48 +02:00
/* Vector for storing field names like “g_0”, “g_1”, …
A static structure is needed since MATLAB apparently does not create its own
copy of the strings ( contrary to what is said at :
https : //fr.mathworks.com/matlabcentral/answers/315937-mxcreatestructarray-and-mxcreatestructmatrix-field-name-memory-management
) */
std : : vector < std : : string > g_fieldnames ;
2019-04-08 17:53:20 +02:00
/* Convert MATLAB Dynare endo and exo names cell array to a vector<string> array of
string pointers . */
std : : vector < std : : string >
DynareMxArrayToString ( const mxArray * mxFldp )
2009-11-30 17:31:27 +01:00
{
2019-04-08 17:53:20 +02:00
assert ( mxIsCell ( mxFldp ) ) ;
std : : vector < std : : string > r ;
for ( size_t i = 0 ; i < mxGetNumberOfElements ( mxFldp ) ; i + + )
r . emplace_back ( mxArrayToString ( mxGetCell ( mxFldp , i ) ) ) ;
2010-03-09 18:22:33 +01:00
2019-04-08 17:53:20 +02:00
return r ;
2009-11-30 17:31:27 +01:00
}
2017-05-16 16:30:27 +02:00
void
2019-04-08 16:59:48 +02:00
copy_derivatives ( mxArray * destin , const Symmetry & sym , const FGSContainer & derivs , const char * fieldname )
2012-07-31 21:50:28 +02:00
{
2019-04-02 16:39:32 +02:00
const FGSTensor & x = derivs . get ( sym ) ;
auto x_unfolded = x . unfold ( ) ;
int n = x_unfolded - > numRows ( ) ;
int m = x_unfolded - > numCols ( ) ;
2012-07-31 21:50:28 +02:00
mxArray * tmp = mxCreateDoubleMatrix ( n , m , mxREAL ) ;
2019-04-02 16:39:32 +02:00
std : : copy_n ( x_unfolded - > getData ( ) . base ( ) , n * m , mxGetPr ( tmp ) ) ;
2019-04-08 16:59:48 +02:00
mxSetField ( destin , 0 , fieldname , tmp ) ;
2012-07-31 21:50:28 +02:00
}
2009-05-06 12:10:27 +02:00
extern " C " {
2009-05-27 16:28:23 +02:00
void
mexFunction ( int nlhs , mxArray * plhs [ ] ,
int nrhs , const mxArray * prhs [ ] )
2009-05-06 12:10:27 +02:00
{
2012-07-07 21:21:28 +02:00
if ( nrhs < 3 | | nlhs < 2 )
DYN_MEX_FUNC_ERR_MSG_TXT ( " Must have at least 3 input parameters and takes at least 2 output parameters. " ) ;
2009-12-16 18:18:38 +01:00
2009-05-27 16:28:23 +02:00
const mxArray * dr = prhs [ 0 ] ;
2010-08-30 17:11:58 +02:00
const mxArray * M_ = prhs [ 1 ] ;
const mxArray * options_ = prhs [ 2 ] ;
2019-03-07 18:17:43 +01:00
bool use_dll = mxGetScalar ( mxGetField ( options_ , 0 , " use_dll " ) ) ! = 0 ;
2009-05-27 16:28:23 +02:00
mxArray * mFname = mxGetField ( M_ , 0 , " fname " ) ;
if ( ! mxIsChar ( mFname ) )
2010-09-20 16:57:02 +02:00
DYN_MEX_FUNC_ERR_MSG_TXT ( " Input must be of type char. " ) ;
2019-02-06 15:50:01 +01:00
std : : string fName = mxArrayToString ( mFname ) ;
2009-05-27 16:28:23 +02:00
2009-05-06 12:10:27 +02:00
int kOrder ;
2009-05-27 16:28:23 +02:00
mxArray * mxFldp = mxGetField ( options_ , 0 , " order " ) ;
2009-05-06 12:10:27 +02:00
if ( mxIsNumeric ( mxFldp ) )
2019-03-07 18:17:43 +01:00
kOrder = static_cast < int > ( mxGetScalar ( mxFldp ) ) ;
2009-05-06 12:10:27 +02:00
else
kOrder = 1 ;
2009-12-16 18:18:38 +01:00
2009-05-06 12:10:27 +02:00
double qz_criterium = 1 + 1e-6 ;
2009-05-27 16:28:23 +02:00
mxFldp = mxGetField ( options_ , 0 , " qz_criterium " ) ;
2014-01-27 15:33:37 +01:00
if ( mxGetNumberOfElements ( mxFldp ) > 0 & & mxIsNumeric ( mxFldp ) )
2019-03-07 18:17:43 +01:00
qz_criterium = mxGetScalar ( mxFldp ) ;
2009-05-27 16:28:23 +02:00
2010-08-30 17:11:58 +02:00
mxFldp = mxGetField ( M_ , 0 , " params " ) ;
Dynare++ / sylvester equation solver: refactor Vector and ConstVector classes
- these classes now encapsulate a std::shared_ptr<{const, }double>, so that
they do not perform memory management, and several {Const,}Vector instances
can transparently share the same underlying data
- make converting constructor from ConstVector to Vector explicit, since that
entails memory allocation (but the reverse conversion is almost costless, so
keep it implicit); do the same for GeneralMatrix/ConstGeneralMatrix,
TwoDMatrix/ConstTwoDMatrix
- remove the constructors that were extracting a row/column from a matrix, and
replace them by getRow() and getCol() methods on {Const,}GeneralMatrix
- rename and change the API of the complex version Vector::add(), so that it is
explicit that it deals with complex numbers
- add constructors that take a MATLAB mxArray
2019-01-22 16:07:44 +01:00
Vector modParams { mxFldp } ;
2011-02-07 11:12:32 +01:00
if ( ! modParams . isFinite ( ) )
DYN_MEX_FUNC_ERR_MSG_TXT ( " The parameters vector contains NaN or Inf " ) ;
2009-05-27 16:28:23 +02:00
2010-08-30 17:11:58 +02:00
mxFldp = mxGetField ( M_ , 0 , " Sigma_e " ) ;
Dynare++ / sylvester equation solver: refactor Vector and ConstVector classes
- these classes now encapsulate a std::shared_ptr<{const, }double>, so that
they do not perform memory management, and several {Const,}Vector instances
can transparently share the same underlying data
- make converting constructor from ConstVector to Vector explicit, since that
entails memory allocation (but the reverse conversion is almost costless, so
keep it implicit); do the same for GeneralMatrix/ConstGeneralMatrix,
TwoDMatrix/ConstTwoDMatrix
- remove the constructors that were extracting a row/column from a matrix, and
replace them by getRow() and getCol() methods on {Const,}GeneralMatrix
- rename and change the API of the complex version Vector::add(), so that it is
explicit that it deals with complex numbers
- add constructors that take a MATLAB mxArray
2019-01-22 16:07:44 +01:00
int npar = static_cast < int > ( mxGetN ( mxFldp ) ) ;
TwoDMatrix vCov ( npar , npar , Vector { mxFldp } ) ;
2011-02-07 11:12:32 +01:00
if ( ! vCov . isFinite ( ) )
DYN_MEX_FUNC_ERR_MSG_TXT ( " The covariance matrix of shocks contains NaN or Inf " ) ;
2009-05-27 16:28:23 +02:00
2010-08-30 17:11:58 +02:00
mxFldp = mxGetField ( dr , 0 , " ys " ) ; // and not in order of dr.order_var
Dynare++ / sylvester equation solver: refactor Vector and ConstVector classes
- these classes now encapsulate a std::shared_ptr<{const, }double>, so that
they do not perform memory management, and several {Const,}Vector instances
can transparently share the same underlying data
- make converting constructor from ConstVector to Vector explicit, since that
entails memory allocation (but the reverse conversion is almost costless, so
keep it implicit); do the same for GeneralMatrix/ConstGeneralMatrix,
TwoDMatrix/ConstTwoDMatrix
- remove the constructors that were extracting a row/column from a matrix, and
replace them by getRow() and getCol() methods on {Const,}GeneralMatrix
- rename and change the API of the complex version Vector::add(), so that it is
explicit that it deals with complex numbers
- add constructors that take a MATLAB mxArray
2019-01-22 16:07:44 +01:00
Vector ySteady { mxFldp } ;
2011-02-07 11:12:32 +01:00
if ( ! ySteady . isFinite ( ) )
DYN_MEX_FUNC_ERR_MSG_TXT ( " The steady state vector contains NaN or Inf " ) ;
2009-05-27 16:28:23 +02:00
2012-11-16 20:05:13 +01:00
mxFldp = mxGetField ( M_ , 0 , " nstatic " ) ;
2019-03-07 18:17:43 +01:00
const int nStat = static_cast < int > ( mxGetScalar ( mxFldp ) ) ;
2012-11-16 20:05:13 +01:00
mxFldp = mxGetField ( M_ , 0 , " npred " ) ;
2019-03-07 18:17:43 +01:00
const int nPred = static_cast < int > ( mxGetScalar ( mxFldp ) ) ;
2012-11-16 20:05:13 +01:00
mxFldp = mxGetField ( M_ , 0 , " nboth " ) ;
2019-03-07 18:17:43 +01:00
const int nBoth = static_cast < int > ( mxGetScalar ( mxFldp ) ) ;
2012-11-16 20:05:13 +01:00
mxFldp = mxGetField ( M_ , 0 , " nfwrd " ) ;
2019-03-07 18:17:43 +01:00
const int nForw = static_cast < int > ( mxGetScalar ( mxFldp ) ) ;
2009-05-27 16:28:23 +02:00
mxFldp = mxGetField ( M_ , 0 , " exo_nbr " ) ;
2019-03-07 18:17:43 +01:00
const int nExog = static_cast < int > ( mxGetScalar ( mxFldp ) ) ;
2009-05-27 16:28:23 +02:00
mxFldp = mxGetField ( M_ , 0 , " endo_nbr " ) ;
2019-03-07 18:17:43 +01:00
const int nEndo = static_cast < int > ( mxGetScalar ( mxFldp ) ) ;
2009-05-27 16:28:23 +02:00
mxFldp = mxGetField ( M_ , 0 , " param_nbr " ) ;
2019-03-07 18:17:43 +01:00
const int nPar = static_cast < int > ( mxGetScalar ( mxFldp ) ) ;
2009-08-24 18:01:25 +02:00
2010-08-30 17:11:58 +02:00
mxFldp = mxGetField ( dr , 0 , " order_var " ) ;
Dynare++ / sylvester equation solver: refactor Vector and ConstVector classes
- these classes now encapsulate a std::shared_ptr<{const, }double>, so that
they do not perform memory management, and several {Const,}Vector instances
can transparently share the same underlying data
- make converting constructor from ConstVector to Vector explicit, since that
entails memory allocation (but the reverse conversion is almost costless, so
keep it implicit); do the same for GeneralMatrix/ConstGeneralMatrix,
TwoDMatrix/ConstTwoDMatrix
- remove the constructors that were extracting a row/column from a matrix, and
replace them by getRow() and getCol() methods on {Const,}GeneralMatrix
- rename and change the API of the complex version Vector::add(), so that it is
explicit that it deals with complex numbers
- add constructors that take a MATLAB mxArray
2019-01-22 16:07:44 +01:00
auto dparams = mxGetPr ( mxFldp ) ;
2019-03-07 18:17:43 +01:00
npar = static_cast < int > ( mxGetM ( mxFldp ) ) ;
2010-08-30 17:11:58 +02:00
if ( npar ! = nEndo )
2010-09-20 16:57:02 +02:00
DYN_MEX_FUNC_ERR_MSG_TXT ( " Incorrect number of input var_order vars. " ) ;
2019-02-06 15:50:01 +01:00
std : : vector < int > var_order_vp ( nEndo ) ;
2009-05-27 16:28:23 +02:00
for ( int v = 0 ; v < nEndo ; v + + )
2019-03-07 18:17:43 +01:00
var_order_vp [ v ] = static_cast < int > ( * ( dparams + + ) ) ;
2009-05-27 16:28:23 +02:00
2009-05-06 12:10:27 +02:00
// the lag, current and lead blocks of the jacobian respectively
2010-08-30 17:11:58 +02:00
mxFldp = mxGetField ( M_ , 0 , " lead_lag_incidence " ) ;
2019-03-07 18:17:43 +01:00
npar = static_cast < int > ( mxGetN ( mxFldp ) ) ;
int nrows = static_cast < int > ( mxGetM ( mxFldp ) ) ;
2009-11-29 21:50:39 +01:00
Dynare++ / sylvester equation solver: refactor Vector and ConstVector classes
- these classes now encapsulate a std::shared_ptr<{const, }double>, so that
they do not perform memory management, and several {Const,}Vector instances
can transparently share the same underlying data
- make converting constructor from ConstVector to Vector explicit, since that
entails memory allocation (but the reverse conversion is almost costless, so
keep it implicit); do the same for GeneralMatrix/ConstGeneralMatrix,
TwoDMatrix/ConstTwoDMatrix
- remove the constructors that were extracting a row/column from a matrix, and
replace them by getRow() and getCol() methods on {Const,}GeneralMatrix
- rename and change the API of the complex version Vector::add(), so that it is
explicit that it deals with complex numbers
- add constructors that take a MATLAB mxArray
2019-01-22 16:07:44 +01:00
TwoDMatrix llincidence ( nrows , npar , Vector { mxFldp } ) ;
2009-05-27 16:28:23 +02:00
if ( npar ! = nEndo )
2019-04-01 16:05:47 +02:00
DYN_MEX_FUNC_ERR_MSG_TXT ( ( " dynare:k_order_perturbation: Incorrect length of lead lag incidences: ncol= "
+ std : : to_string ( npar ) + " != nEndo= " + std : : to_string ( nEndo ) ) . c_str ( ) ) ;
2019-03-07 18:17:43 +01:00
2009-08-24 18:01:25 +02:00
mxFldp = mxGetField ( M_ , 0 , " NNZDerivatives " ) ;
Dynare++ / sylvester equation solver: refactor Vector and ConstVector classes
- these classes now encapsulate a std::shared_ptr<{const, }double>, so that
they do not perform memory management, and several {Const,}Vector instances
can transparently share the same underlying data
- make converting constructor from ConstVector to Vector explicit, since that
entails memory allocation (but the reverse conversion is almost costless, so
keep it implicit); do the same for GeneralMatrix/ConstGeneralMatrix,
TwoDMatrix/ConstTwoDMatrix
- remove the constructors that were extracting a row/column from a matrix, and
replace them by getRow() and getCol() methods on {Const,}GeneralMatrix
- rename and change the API of the complex version Vector::add(), so that it is
explicit that it deals with complex numbers
- add constructors that take a MATLAB mxArray
2019-01-22 16:07:44 +01:00
Vector NNZD { mxFldp } ;
2010-07-17 10:14:22 +02:00
if ( NNZD [ kOrder - 1 ] = = - 1 )
2019-04-02 16:33:15 +02:00
DYN_MEX_FUNC_ERR_MSG_TXT ( " The derivatives were not computed for the required order. Make sure that you used the right order option inside the 'stoch_simul' command " ) ;
2009-05-27 16:28:23 +02:00
mxFldp = mxGetField ( M_ , 0 , " var_order_endo_names " ) ;
2019-04-08 17:53:20 +02:00
std : : vector < std : : string > endoNames = DynareMxArrayToString ( mxFldp ) ;
2009-05-27 16:28:23 +02:00
2010-08-30 17:11:58 +02:00
mxFldp = mxGetField ( M_ , 0 , " exo_names " ) ;
2019-04-08 17:53:20 +02:00
std : : vector < std : : string > exoNames = DynareMxArrayToString ( mxFldp ) ;
2009-05-27 16:28:23 +02:00
2019-04-08 17:53:20 +02:00
if ( nEndo ! = static_cast < int > ( endoNames . size ( ) ) | | nExog ! = static_cast < int > ( exoNames . size ( ) ) )
2010-09-20 16:57:02 +02:00
DYN_MEX_FUNC_ERR_MSG_TXT ( " Incorrect number of input parameters. " ) ;
2009-05-27 16:28:23 +02:00
2019-03-07 18:17:43 +01:00
std : : unique_ptr < TwoDMatrix > g1m , g2m , g3m ;
2017-05-16 16:30:27 +02:00
if ( nrhs > 3 )
2012-07-07 21:21:28 +02:00
{
2019-04-02 16:33:15 +02:00
// Derivatives have been passed as arguments
2017-05-16 16:30:27 +02:00
const mxArray * g1 = prhs [ 3 ] ;
2019-03-07 18:17:43 +01:00
int m = static_cast < int > ( mxGetM ( g1 ) ) ;
int n = static_cast < int > ( mxGetN ( g1 ) ) ;
g1m = std : : make_unique < TwoDMatrix > ( m , n , Vector { ConstVector { g1 } } ) ;
2017-05-16 16:30:27 +02:00
if ( nrhs > 4 )
{
const mxArray * g2 = prhs [ 4 ] ;
2019-03-07 18:17:43 +01:00
int m = static_cast < int > ( mxGetM ( g2 ) ) ;
int n = static_cast < int > ( mxGetN ( g2 ) ) ;
g2m = std : : make_unique < TwoDMatrix > ( m , n , Vector { ConstVector { g2 } } ) ;
2017-05-16 16:30:27 +02:00
if ( nrhs > 5 )
{
const mxArray * g3 = prhs [ 5 ] ;
2019-03-07 18:17:43 +01:00
int m = static_cast < int > ( mxGetM ( g3 ) ) ;
int n = static_cast < int > ( mxGetN ( g3 ) ) ;
g3m = std : : make_unique < TwoDMatrix > ( m , n , Vector { ConstVector { g3 } } ) ;
2017-05-16 16:30:27 +02:00
}
}
2012-07-07 21:21:28 +02:00
}
2009-05-27 16:28:23 +02:00
const int nSteps = 0 ; // Dynare++ solving steps, for time being default to 0 = deterministic steady state
try
{
2019-03-07 18:17:43 +01:00
Journal journal ( fName + " .jnl " ) ;
2010-12-17 18:34:23 +01:00
2019-02-06 15:50:01 +01:00
std : : unique_ptr < DynamicModelAC > dynamicModelFile ;
2019-03-07 18:17:43 +01:00
if ( use_dll )
2019-02-06 15:50:01 +01:00
dynamicModelFile = std : : make_unique < DynamicModelDLL > ( fName ) ;
2010-12-17 18:34:23 +01:00
else
2019-02-06 15:50:01 +01:00
dynamicModelFile = std : : make_unique < DynamicModelMFile > ( fName ) ;
2009-05-27 16:28:23 +02:00
// intiate tensor library
2019-02-21 18:46:53 +01:00
TLStatic : : init ( kOrder , nStat + 2 * nPred + 3 * nBoth + 2 * nForw + nExog ) ;
2009-05-27 16:28:23 +02:00
// make KordpDynare object
2019-04-02 16:33:15 +02:00
KordpDynare dynare ( endoNames , exoNames , nExog , nPar ,
2009-05-27 16:28:23 +02:00
ySteady , vCov , modParams , nStat , nPred , nForw , nBoth ,
2019-04-02 16:33:15 +02:00
NNZD , nSteps , kOrder , journal , std : : move ( dynamicModelFile ) ,
var_order_vp , llincidence ,
2019-03-07 18:17:43 +01:00
std : : move ( g1m ) , std : : move ( g2m ) , std : : move ( g3m ) ) ;
2009-05-27 16:28:23 +02:00
// construct main K-order approximation class
2009-12-16 18:18:38 +01:00
2019-03-07 18:17:43 +01:00
Approximation app ( dynare , journal , nSteps , false , qz_criterium ) ;
2009-05-27 16:28:23 +02:00
// run stochastic steady
app . walkStochSteady ( ) ;
2019-04-08 16:59:48 +02:00
const FoldDecisionRule & fdr = app . getFoldDecisionRule ( ) ;
2009-05-27 16:28:23 +02:00
2019-04-08 16:59:48 +02:00
// Add possibly missing field names
for ( int i = static_cast < int > ( g_fieldnames . size ( ) ) ; i < = kOrder ; i + + )
g_fieldnames . emplace_back ( " g_ " + std : : to_string ( i ) ) ;
// Create structure for storing derivatives in Dynare++ format
const char * g_fieldnames_c [ kOrder + 1 ] ;
for ( int i = 0 ; i < = kOrder ; i + + )
g_fieldnames_c [ i ] = g_fieldnames [ i ] . c_str ( ) ;
plhs [ 1 ] = mxCreateStructMatrix ( 1 , 1 , kOrder + 1 , g_fieldnames_c ) ;
2009-05-27 16:28:23 +02:00
2019-04-08 16:59:48 +02:00
// Fill that structure
for ( int i = 0 ; i < = kOrder ; i + + )
2009-05-27 16:28:23 +02:00
{
2019-04-08 16:59:48 +02:00
const FFSTensor & t = fdr . get ( Symmetry { i } ) ;
mxArray * tmp = mxCreateDoubleMatrix ( t . numRows ( ) , t . numCols ( ) , mxREAL ) ;
const ConstVector & vec = t . getData ( ) ;
2010-02-08 16:58:24 +01:00
assert ( vec . skip ( ) = = 1 ) ;
2019-04-08 16:59:48 +02:00
std : : copy_n ( vec . base ( ) , vec . length ( ) , mxGetPr ( tmp ) ) ;
mxSetField ( plhs [ 1 ] , 0 , ( " g_ " + std : : to_string ( i ) ) . c_str ( ) , tmp ) ;
2009-05-27 16:28:23 +02:00
}
2019-04-08 16:59:48 +02:00
if ( nlhs > 2 )
2009-05-27 16:28:23 +02:00
{
2019-04-08 16:59:48 +02:00
/* Return as 3rd argument a struct containing derivatives in Dynare
format ( unfolded matrices , without Taylor coefficient ) up to 3 rd
order */
const FGSContainer & derivs = app . get_rule_ders ( ) ;
size_t nfields = ( kOrder = = 1 ? 2 : ( kOrder = = 2 ? 6 : 12 ) ) ;
const char * c_fieldnames [ ] = { " gy " , " gu " , " gyy " , " gyu " , " guu " , " gss " ,
" gyyy " , " gyyu " , " gyuu " , " guuu " , " gyss " , " guss " } ;
plhs [ 2 ] = mxCreateStructMatrix ( 1 , 1 , nfields , c_fieldnames ) ;
copy_derivatives ( plhs [ 2 ] , Symmetry { 1 , 0 , 0 , 0 } , derivs , " gy " ) ;
copy_derivatives ( plhs [ 2 ] , Symmetry { 0 , 1 , 0 , 0 } , derivs , " gu " ) ;
if ( kOrder > = 2 )
2009-05-27 16:28:23 +02:00
{
2019-04-08 16:59:48 +02:00
copy_derivatives ( plhs [ 2 ] , Symmetry { 2 , 0 , 0 , 0 } , derivs , " gyy " ) ;
copy_derivatives ( plhs [ 2 ] , Symmetry { 0 , 2 , 0 , 0 } , derivs , " guu " ) ;
copy_derivatives ( plhs [ 2 ] , Symmetry { 1 , 1 , 0 , 0 } , derivs , " gyu " ) ;
copy_derivatives ( plhs [ 2 ] , Symmetry { 0 , 0 , 0 , 2 } , derivs , " gss " ) ;
2009-05-27 16:28:23 +02:00
}
2019-04-08 16:59:48 +02:00
if ( kOrder > = 3 )
2017-05-16 16:30:27 +02:00
{
2019-04-08 16:59:48 +02:00
copy_derivatives ( plhs [ 2 ] , Symmetry { 3 , 0 , 0 , 0 } , derivs , " gyyy " ) ;
copy_derivatives ( plhs [ 2 ] , Symmetry { 0 , 3 , 0 , 0 } , derivs , " guuu " ) ;
copy_derivatives ( plhs [ 2 ] , Symmetry { 2 , 1 , 0 , 0 } , derivs , " gyyu " ) ;
copy_derivatives ( plhs [ 2 ] , Symmetry { 1 , 2 , 0 , 0 } , derivs , " gyuu " ) ;
copy_derivatives ( plhs [ 2 ] , Symmetry { 1 , 0 , 0 , 2 } , derivs , " gyss " ) ;
copy_derivatives ( plhs [ 2 ] , Symmetry { 0 , 1 , 0 , 2 } , derivs , " guss " ) ;
2017-05-16 16:30:27 +02:00
}
}
2009-05-06 12:10:27 +02:00
}
2009-05-27 16:28:23 +02:00
catch ( const KordException & e )
2009-05-06 12:10:27 +02:00
{
2009-05-27 16:28:23 +02:00
e . print ( ) ;
2019-04-01 16:05:47 +02:00
DYN_MEX_FUNC_ERR_MSG_TXT ( ( " dynare:k_order_perturbation: Caught Kord exception: " + e . get_message ( ) ) . c_str ( ) ) ;
2009-05-06 12:10:27 +02:00
}
2009-05-27 16:28:23 +02:00
catch ( const TLException & e )
{
e . print ( ) ;
2010-09-20 16:57:02 +02:00
DYN_MEX_FUNC_ERR_MSG_TXT ( " dynare:k_order_perturbation: Caught TL exception " ) ;
2009-05-06 12:10:27 +02:00
}
2009-05-27 16:28:23 +02:00
catch ( SylvException & e )
{
e . printMessage ( ) ;
2010-09-20 16:57:02 +02:00
DYN_MEX_FUNC_ERR_MSG_TXT ( " dynare:k_order_perturbation: Caught Sylv exception " ) ;
2009-05-06 12:10:27 +02:00
}
2009-05-27 16:28:23 +02:00
catch ( const DynareException & e )
{
2019-04-01 16:05:47 +02:00
DYN_MEX_FUNC_ERR_MSG_TXT ( ( " dynare:k_order_perturbation: Caught KordDynare exception: " + e . message ( ) ) . c_str ( ) ) ;
2009-05-06 12:10:27 +02:00
}
2009-05-27 16:28:23 +02:00
catch ( const ogu : : Exception & e )
{
2019-04-01 16:05:47 +02:00
DYN_MEX_FUNC_ERR_MSG_TXT ( ( " dynare:k_order_perturbation: Caught general exception: " + e . message ( ) ) . c_str ( ) ) ;
2009-11-30 17:31:27 +01:00
}
2010-09-20 16:57:02 +02:00
plhs [ 0 ] = mxCreateDoubleScalar ( 0 ) ;
2009-11-30 17:31:27 +01:00
} // end of mexFunction()
} // end of extern C
2019-03-07 18:17:43 +01:00