2010-06-11 19:18:16 +02:00
/*
2012-01-09 12:37:55 +01:00
* Copyright ( C ) 2010 - 2012 Dynare Team
2010-06-11 19:18:16 +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/>.
*/
# include <string>
# include <vector>
# include <algorithm>
# include <functional>
2012-02-21 22:26:31 +01:00
# include <sstream>
2010-06-11 19:18:16 +02:00
# include "Vector.hh"
# include "Matrix.hh"
2010-07-08 10:55:22 +02:00
# include "LogPosteriorDensity.hh"
2010-06-11 19:18:16 +02:00
2011-02-11 11:07:50 +01:00
# include <dynmex.h>
2010-06-11 19:18:16 +02:00
2010-09-20 15:38:47 +02:00
class LogposteriorMexErrMsgTxtException
{
public :
std : : string errMsg ;
LogposteriorMexErrMsgTxtException ( const std : : string & msg ) : errMsg ( msg )
{
}
inline const char * getErrMsg ( ) { return errMsg . c_str ( ) ; }
} ;
2010-06-11 19:18:16 +02:00
void
2012-02-21 22:26:31 +01:00
fillEstParamsInfo ( const mxArray * bayestopt_ , const mxArray * estim_params_info , EstimatedParameter : : pType type ,
2010-06-11 19:18:16 +02:00
std : : vector < EstimatedParameter > & estParamsInfo )
{
2010-07-08 10:55:22 +02:00
// execute once only
static const mxArray * bayestopt_ubp = mxGetField ( bayestopt_ , 0 , " ub " ) ; // upper bound
static const mxArray * bayestopt_lbp = mxGetField ( bayestopt_ , 0 , " lb " ) ; // lower bound
static const mxArray * bayestopt_p1p = mxGetField ( bayestopt_ , 0 , " p1 " ) ; // prior mean
static const mxArray * bayestopt_p2p = mxGetField ( bayestopt_ , 0 , " p2 " ) ; // prior standard deviation
static const mxArray * bayestopt_p3p = mxGetField ( bayestopt_ , 0 , " p3 " ) ; // lower bound
static const mxArray * bayestopt_p4p = mxGetField ( bayestopt_ , 0 , " p4 " ) ; // upper bound
static const mxArray * bayestopt_p6p = mxGetField ( bayestopt_ , 0 , " p6 " ) ; // first hyper-parameter (\alpha for the BETA and GAMMA distributions, s for the INVERSE GAMMAs, expectation for the GAUSSIAN distribution, lower bound for the UNIFORM distribution).
static const mxArray * bayestopt_p7p = mxGetField ( bayestopt_ , 0 , " p7 " ) ; // second hyper-parameter (\beta for the BETA and GAMMA distributions, \nu for the INVERSE GAMMAs, standard deviation for the GAUSSIAN distribution, upper bound for the UNIFORM distribution).
static const mxArray * bayestopt_jscalep = mxGetField ( bayestopt_ , 0 , " jscale " ) ; // MCMC jump scale
static const size_t bayestopt_size = mxGetM ( bayestopt_ ) ;
static const VectorConstView bayestopt_ub ( mxGetPr ( bayestopt_ubp ) , bayestopt_size , 1 ) ;
static const VectorConstView bayestopt_lb ( mxGetPr ( bayestopt_lbp ) , bayestopt_size , 1 ) ;
static const VectorConstView bayestopt_p1 ( mxGetPr ( bayestopt_p1p ) , bayestopt_size , 1 ) ; //=mxGetField(bayestopt_, 0, "p1");
static const VectorConstView bayestopt_p2 ( mxGetPr ( bayestopt_p2p ) , bayestopt_size , 1 ) ; //=mxGetField(bayestopt_, 0, "p2");
static const VectorConstView bayestopt_p3 ( mxGetPr ( bayestopt_p3p ) , bayestopt_size , 1 ) ; //=mxGetField(bayestopt_, 0, "p3");
static const VectorConstView bayestopt_p4 ( mxGetPr ( bayestopt_p4p ) , bayestopt_size , 1 ) ; //=mxGetField(bayestopt_, 0, "p4");
static const VectorConstView bayestopt_p6 ( mxGetPr ( bayestopt_p6p ) , bayestopt_size , 1 ) ; //=mxGetField(bayestopt_, 0, "p6");
static const VectorConstView bayestopt_p7 ( mxGetPr ( bayestopt_p7p ) , bayestopt_size , 1 ) ; //=mxGetField(bayestopt_, 0, "p7");
static const VectorConstView bayestopt_jscale ( mxGetPr ( bayestopt_jscalep ) , bayestopt_size , 1 ) ; //=mxGetField(bayestopt_, 0, "jscale");
// loop processsing
2010-06-11 19:18:16 +02:00
size_t m = mxGetM ( estim_params_info ) , n = mxGetN ( estim_params_info ) ;
MatrixConstView epi ( mxGetPr ( estim_params_info ) , m , n , m ) ;
2010-07-08 10:55:22 +02:00
size_t bayestopt_count = estParamsInfo . size ( ) ;
2010-06-11 19:18:16 +02:00
for ( size_t i = 0 ; i < m ; i + + )
{
size_t col = 0 ;
size_t id1 = ( size_t ) epi ( i , col + + ) - 1 ;
size_t id2 = 0 ;
if ( type = = EstimatedParameter : : shock_Corr
| | type = = EstimatedParameter : : measureErr_Corr )
id2 = ( size_t ) epi ( i , col + + ) - 1 ;
2010-07-08 10:55:22 +02:00
col + + ; // Skip init_val #2 or #3
double par_low_bound = bayestopt_lb ( bayestopt_count ) ; col + + ; //#3 epi(i, col++);
double par_up_bound = bayestopt_ub ( bayestopt_count ) ; col + + ; //#4 epi(i, col++);
2010-06-11 19:18:16 +02:00
Prior : : pShape shape = ( Prior : : pShape ) epi ( i , col + + ) ;
double mean = epi ( i , col + + ) ;
double std = epi ( i , col + + ) ;
2010-07-08 10:55:22 +02:00
double low_bound = bayestopt_p3 ( bayestopt_count ) ;
double up_bound = bayestopt_p4 ( bayestopt_count ) ;
double fhp = bayestopt_p6 ( bayestopt_count ) ; // double p3 = epi(i, col++);
double shp = bayestopt_p7 ( bayestopt_count ) ; // double p4 = epi(i, col++);
2010-06-11 19:18:16 +02:00
2010-07-08 10:55:22 +02:00
Prior * p = Prior : : constructPrior ( shape , mean , std , low_bound , up_bound , fhp , shp ) ; //1.0,INFINITY);//p3, p4);
2010-06-11 19:18:16 +02:00
// Only one subsample
std : : vector < size_t > subSampleIDs ;
subSampleIDs . push_back ( 0 ) ;
estParamsInfo . push_back ( EstimatedParameter ( type , id1 , id2 , subSampleIDs ,
2010-07-08 10:55:22 +02:00
par_low_bound , par_up_bound , p ) ) ;
bayestopt_count + + ;
2010-06-11 19:18:16 +02:00
}
}
2012-02-21 22:26:31 +01:00
template < class VEC1 , class VEC2 >
2010-06-11 19:18:16 +02:00
double
2012-02-21 22:26:31 +01:00
logposterior ( VEC1 & estParams , const MatrixConstView & data ,
const mxArray * options_ , const mxArray * M_ , const mxArray * estim_params_ ,
const mxArray * bayestopt_ , const mxArray * oo_ , VEC2 & steadyState , double * trend_coeff ,
int & info , VectorView & deepParams , Matrix & H , MatrixView & Q )
2010-06-11 19:18:16 +02:00
{
// Construct arguments of constructor of LogLikelihoodMain
char * fName = mxArrayToString ( mxGetField ( M_ , 0 , " fname " ) ) ;
std : : string dynamicDllFile ( fName ) ;
mxFree ( fName ) ;
2012-01-09 12:37:55 +01:00
dynamicDllFile + = " _dynamic " ;
dynamicDllFile + = MEXEXT ;
2010-06-11 19:18:16 +02:00
size_t n_endo = ( size_t ) * mxGetPr ( mxGetField ( M_ , 0 , " endo_nbr " ) ) ;
size_t n_exo = ( size_t ) * mxGetPr ( mxGetField ( M_ , 0 , " exo_nbr " ) ) ;
size_t n_param = ( size_t ) * mxGetPr ( mxGetField ( M_ , 0 , " param_nbr " ) ) ;
size_t n_estParams = estParams . getSize ( ) ;
std : : vector < size_t > zeta_fwrd , zeta_back , zeta_mixed , zeta_static ;
const mxArray * lli_mx = mxGetField ( M_ , 0 , " lead_lag_incidence " ) ;
MatrixConstView lli ( mxGetPr ( lli_mx ) , mxGetM ( lli_mx ) , mxGetN ( lli_mx ) , mxGetM ( lli_mx ) ) ;
if ( lli . getRows ( ) ! = 3 | | lli . getCols ( ) ! = n_endo )
2010-09-20 15:38:47 +02:00
throw LogposteriorMexErrMsgTxtException ( " Incorrect lead/lag incidence matrix " ) ;
2010-07-08 10:55:22 +02:00
2010-06-11 19:18:16 +02:00
for ( size_t i = 0 ; i < n_endo ; i + + )
{
if ( lli ( 0 , i ) = = 0 & & lli ( 2 , i ) = = 0 )
zeta_static . push_back ( i ) ;
else if ( lli ( 0 , i ) ! = 0 & & lli ( 2 , i ) = = 0 )
zeta_back . push_back ( i ) ;
else if ( lli ( 0 , i ) = = 0 & & lli ( 2 , i ) ! = 0 )
zeta_fwrd . push_back ( i ) ;
else
zeta_mixed . push_back ( i ) ;
}
double qz_criterium = * mxGetPr ( mxGetField ( options_ , 0 , " qz_criterium " ) ) ;
double lyapunov_tol = * mxGetPr ( mxGetField ( options_ , 0 , " lyapunov_complex_threshold " ) ) ;
double riccati_tol = * mxGetPr ( mxGetField ( options_ , 0 , " riccati_tol " ) ) ;
2010-07-23 13:08:00 +02:00
size_t presample = ( size_t ) * mxGetPr ( mxGetField ( options_ , 0 , " presample " ) ) ;
2010-06-11 19:18:16 +02:00
std : : vector < size_t > varobs ;
const mxArray * varobs_mx = mxGetField ( options_ , 0 , " varobs_id " ) ;
if ( mxGetM ( varobs_mx ) ! = 1 )
2010-09-20 15:38:47 +02:00
throw LogposteriorMexErrMsgTxtException ( " options_.varobs_id must be a row vector " ) ;
2010-06-11 19:18:16 +02:00
size_t n_varobs = mxGetN ( varobs_mx ) ;
2012-02-21 22:26:31 +01:00
// substract 1.0 from obsverved variables index
2010-06-11 19:18:16 +02:00
std : : transform ( mxGetPr ( varobs_mx ) , mxGetPr ( varobs_mx ) + n_varobs , back_inserter ( varobs ) ,
std : : bind2nd ( std : : minus < size_t > ( ) , 1 ) ) ;
if ( data . getRows ( ) ! = n_varobs )
2011-02-11 11:07:50 +01:00
throw LogposteriorMexErrMsgTxtException ( " Data does not have as many rows as there are observed variables " ) ;
2010-07-08 10:55:22 +02:00
2010-06-11 19:18:16 +02:00
std : : vector < EstimationSubsample > estSubsamples ;
estSubsamples . push_back ( EstimationSubsample ( 0 , data . getCols ( ) - 1 ) ) ;
std : : vector < EstimatedParameter > estParamsInfo ;
2012-02-21 22:26:31 +01:00
fillEstParamsInfo ( bayestopt_ , mxGetField ( estim_params_ , 0 , " var_exo " ) , EstimatedParameter : : shock_SD ,
2010-06-11 19:18:16 +02:00
estParamsInfo ) ;
2012-02-21 22:26:31 +01:00
fillEstParamsInfo ( bayestopt_ , mxGetField ( estim_params_ , 0 , " var_endo " ) , EstimatedParameter : : measureErr_SD ,
2010-06-11 19:18:16 +02:00
estParamsInfo ) ;
2012-02-21 22:26:31 +01:00
fillEstParamsInfo ( bayestopt_ , mxGetField ( estim_params_ , 0 , " corrx " ) , EstimatedParameter : : shock_Corr ,
2010-06-11 19:18:16 +02:00
estParamsInfo ) ;
2012-02-21 22:26:31 +01:00
fillEstParamsInfo ( bayestopt_ , mxGetField ( estim_params_ , 0 , " corrn " ) , EstimatedParameter : : measureErr_Corr ,
2010-06-11 19:18:16 +02:00
estParamsInfo ) ;
2012-02-21 22:26:31 +01:00
fillEstParamsInfo ( bayestopt_ , mxGetField ( estim_params_ , 0 , " param_vals " ) , EstimatedParameter : : deepPar ,
2010-06-11 19:18:16 +02:00
estParamsInfo ) ;
EstimatedParametersDescription epd ( estSubsamples , estParamsInfo ) ;
2010-07-08 10:55:22 +02:00
// Allocate LogPosteriorDensity object
LogPosteriorDensity lpd ( dynamicDllFile , epd , n_endo , n_exo , zeta_fwrd , zeta_back , zeta_mixed , zeta_static ,
2011-02-04 16:53:12 +01:00
qz_criterium , varobs , riccati_tol , lyapunov_tol , info ) ;
2010-06-11 19:18:16 +02:00
// Construct arguments of compute() method
2010-07-08 10:55:22 +02:00
// Compute the posterior
2012-02-21 22:26:31 +01:00
double logPD = lpd . compute ( steadyState , estParams , deepParams , data , Q , H , presample , info ) ;
2010-06-11 19:18:16 +02:00
// Cleanups
for ( std : : vector < EstimatedParameter > : : iterator it = estParamsInfo . begin ( ) ;
it ! = estParamsInfo . end ( ) ; it + + )
delete it - > prior ;
2010-07-08 10:55:22 +02:00
return logPD ;
2010-06-11 19:18:16 +02:00
}
void
mexFunction ( int nlhs , mxArray * plhs [ ] ,
int nrhs , const mxArray * prhs [ ] )
{
2012-02-21 22:26:31 +01:00
if ( nrhs ! = 7 )
DYN_MEX_FUNC_ERR_MSG_TXT ( " logposterior: exactly 7 input arguments are required. " ) ;
2010-06-11 19:18:16 +02:00
2012-02-21 22:26:31 +01:00
if ( nlhs > 9 )
DYN_MEX_FUNC_ERR_MSG_TXT ( " logposterior returns 8 output arguments at the most. " ) ;
// Check and retrieve the RHS arguments
2010-06-11 19:18:16 +02:00
if ( ! mxIsDouble ( prhs [ 0 ] ) | | mxGetN ( prhs [ 0 ] ) ! = 1 )
2010-09-20 15:38:47 +02:00
DYN_MEX_FUNC_ERR_MSG_TXT ( " logposterior: First argument must be a column vector of double-precision numbers " ) ;
2010-06-11 19:18:16 +02:00
VectorConstView estParams ( mxGetPr ( prhs [ 0 ] ) , mxGetM ( prhs [ 0 ] ) , 1 ) ;
2012-02-21 22:26:31 +01:00
for ( int i = 1 ; i < 7 ; + + i )
if ( ! mxIsStruct ( prhs [ i ] ) )
{
std : : stringstream msg ;
msg < < " logposterior: argument " < < i + 1 < < " must be a Matlab structure " ;
DYN_MEX_FUNC_ERR_MSG_TXT ( msg . str ( ) . c_str ( ) ) ;
}
const mxArray * dataset = prhs [ 1 ] ;
const mxArray * options_ = prhs [ 2 ] ;
const mxArray * M_ = prhs [ 3 ] ;
const mxArray * estim_params_ = prhs [ 4 ] ;
const mxArray * bayestopt_ = prhs [ 5 ] ;
const mxArray * oo_ = prhs [ 6 ] ;
mxArray * dataset_data = mxGetField ( dataset , 0 , " data " ) ;
MatrixConstView data ( mxGetPr ( dataset_data ) , mxGetM ( dataset_data ) , mxGetN ( dataset_data ) , mxGetM ( dataset_data ) ) ;
// Creaete LHS arguments
size_t endo_nbr = ( size_t ) * mxGetPr ( mxGetField ( M_ , 0 , " endo_nbr " ) ) ;
size_t exo_nbr = ( size_t ) * mxGetPr ( mxGetField ( M_ , 0 , " exo_nbr " ) ) ;
size_t param_nbr = ( size_t ) * mxGetPr ( mxGetField ( M_ , 0 , " param_nbr " ) ) ;
size_t varobs_nbr = mxGetM ( mxGetField ( options_ , 0 , " varobs " ) ) ;
plhs [ 0 ] = mxCreateDoubleMatrix ( 1 , 1 , mxREAL ) ;
plhs [ 1 ] = mxCreateDoubleMatrix ( 1 , 1 , mxREAL ) ;
plhs [ 2 ] = mxCreateDoubleMatrix ( endo_nbr , 1 , mxREAL ) ;
plhs [ 3 ] = mxCreateDoubleMatrix ( varobs_nbr , 1 , mxREAL ) ;
plhs [ 4 ] = mxCreateDoubleMatrix ( 1 , 1 , mxREAL ) ;
plhs [ 5 ] = mxCreateDoubleMatrix ( param_nbr , 1 , mxREAL ) ;
plhs [ 6 ] = mxCreateDoubleMatrix ( varobs_nbr , varobs_nbr , mxREAL ) ;
plhs [ 7 ] = mxCreateDoubleMatrix ( exo_nbr , exo_nbr , mxREAL ) ;
double * lik = mxGetPr ( plhs [ 0 ] ) ;
double * exit_flag = mxGetPr ( plhs [ 1 ] ) ;
VectorView steadyState ( mxGetPr ( mxGetField ( oo_ , 0 , " steady_state " ) ) , endo_nbr , 1 ) ;
VectorView deepParams ( mxGetPr ( mxGetField ( M_ , 0 , " params " ) ) , param_nbr , 1 ) ;
MatrixView Q ( mxGetPr ( mxGetField ( M_ , 0 , " Sigma_e " ) ) , exo_nbr , exo_nbr , exo_nbr ) ;
Matrix H ( varobs_nbr , varobs_nbr ) ;
const mxArray * H_mx = mxGetField ( M_ , 0 , " H " ) ;
if ( mxGetM ( H_mx ) = = 1 & & mxGetN ( H_mx ) = = 1 & & * mxGetPr ( H_mx ) = = 0 )
H . setAll ( 0.0 ) ;
else
H = MatrixConstView ( mxGetPr ( H_mx ) , varobs_nbr , varobs_nbr , varobs_nbr ) ;
double * trend_coeff = mxGetPr ( plhs [ 3 ] ) ;
double * info_mx = mxGetPr ( plhs [ 4 ] ) ;
2010-06-11 19:18:16 +02:00
// Compute and return the value
2010-09-20 15:38:47 +02:00
try
{
2012-02-21 22:26:31 +01:00
int info ;
* lik = logposterior ( estParams , data , options_ , M_ , estim_params_ , bayestopt_ , oo_ ,
steadyState , trend_coeff , info , deepParams , H , Q ) ;
* info_mx = info ;
* exit_flag = info ;
2010-09-20 15:38:47 +02:00
}
catch ( LogposteriorMexErrMsgTxtException e )
{
DYN_MEX_FUNC_ERR_MSG_TXT ( e . getErrMsg ( ) ) ;
}
2010-06-11 19:18:16 +02:00
}