130 lines
4.6 KiB
C++
130 lines
4.6 KiB
C++
// Copyright (C) 2005-2011, Ondra Kamenik
|
|
|
|
// This is the mexFunction providing interface to
|
|
// DecisionRule<>::simulate(). It takes the following input
|
|
// parameters:
|
|
// order the order of approximation, needs order+1 derivatives
|
|
// nstat
|
|
// npred
|
|
// nboth
|
|
// nforw
|
|
// nexog
|
|
// ystart starting value (full vector of endogenous)
|
|
// shocks matrix of shocks (nexog x number of period)
|
|
// vcov covariance matrix of shocks (nexog x nexog)
|
|
// seed integer seed
|
|
// ysteady full vector of decision rule's steady
|
|
// ... order+1 matrices of derivatives
|
|
|
|
// output:
|
|
// res simulated results
|
|
|
|
#include "dynmex.h"
|
|
#include "mex.h"
|
|
|
|
#include "decision_rule.h"
|
|
#include "fs_tensor.h"
|
|
#include "SylvException.h"
|
|
|
|
extern "C" {
|
|
void mexFunction(int nlhs, mxArray* plhs[],
|
|
int nhrs, const mxArray* prhs[])
|
|
{
|
|
if (nhrs < 12 || nlhs != 2)
|
|
DYN_MEX_FUNC_ERR_MSG_TXT("dynare_simul_ must have at least 12 input parameters and exactly 2 output arguments.\n");
|
|
|
|
int order = (int)mxGetScalar(prhs[0]);
|
|
if (nhrs != 12 + order)
|
|
DYN_MEX_FUNC_ERR_MSG_TXT("dynare_simul_ must have exactly 11+order input parameters.\n");
|
|
|
|
int nstat = (int)mxGetScalar(prhs[1]);
|
|
int npred = (int)mxGetScalar(prhs[2]);
|
|
int nboth = (int)mxGetScalar(prhs[3]);
|
|
int nforw = (int)mxGetScalar(prhs[4]);
|
|
int nexog = (int)mxGetScalar(prhs[5]);
|
|
|
|
const mxArray* const ystart = prhs[6];
|
|
const mxArray* const shocks = prhs[7];
|
|
const mxArray* const vcov = prhs[8];
|
|
int seed = (int)mxGetScalar(prhs[9]);
|
|
const mxArray* const ysteady = prhs[10];
|
|
const mwSize* const ystart_dim = mxGetDimensions(ystart);
|
|
const mwSize* const shocks_dim = mxGetDimensions(shocks);
|
|
const mwSize* const vcov_dim = mxGetDimensions(vcov);
|
|
const mwSize* const ysteady_dim = mxGetDimensions(ysteady);
|
|
|
|
int ny = nstat + npred + nboth + nforw;
|
|
if (ny != (int) ystart_dim[0])
|
|
DYN_MEX_FUNC_ERR_MSG_TXT("ystart has wrong number of rows.\n");
|
|
if (1 != ystart_dim[1])
|
|
DYN_MEX_FUNC_ERR_MSG_TXT("ystart has wrong number of cols.\n");
|
|
int nper = shocks_dim[1];
|
|
if (nexog != (int) shocks_dim[0])
|
|
DYN_MEX_FUNC_ERR_MSG_TXT("shocks has a wrong number of rows.\n");
|
|
if (nexog != (int) vcov_dim[0])
|
|
DYN_MEX_FUNC_ERR_MSG_TXT("vcov has a wrong number of rows.\n");
|
|
if (nexog != (int) vcov_dim[1])
|
|
DYN_MEX_FUNC_ERR_MSG_TXT("vcov has a wrong number of cols.\n");
|
|
if (ny != (int) ysteady_dim[0])
|
|
DYN_MEX_FUNC_ERR_MSG_TXT("ysteady has wrong number of rows.\n");
|
|
if (1 != ysteady_dim[1])
|
|
DYN_MEX_FUNC_ERR_MSG_TXT("ysteady has wrong number of cols.\n");
|
|
|
|
mxArray* res = mxCreateDoubleMatrix(ny, nper, mxREAL);
|
|
|
|
try {
|
|
// initialize tensor library
|
|
tls.init(order, npred+nboth+nexog);
|
|
|
|
// form the polynomial
|
|
UTensorPolynomial pol(ny, npred+nboth+nexog);
|
|
for (int dim = 0; dim <= order; dim++) {
|
|
const mxArray* gk = prhs[11+dim];
|
|
const mwSize* const gk_dim = mxGetDimensions(gk);
|
|
FFSTensor ft(ny, npred+nboth+nexog, dim);
|
|
if (ft.ncols() != (int) gk_dim[1]) {
|
|
char buf[1000];
|
|
sprintf(buf, "Wrong number of columns for folded tensor: got %d but I want %d\n",
|
|
(int) gk_dim[1], ft.ncols());
|
|
DYN_MEX_FUNC_ERR_MSG_TXT(buf);
|
|
}
|
|
if (ft.nrows() != (int) gk_dim[0]) {
|
|
char buf[1000];
|
|
sprintf(buf, "Wrong number of rows for folded tensor: got %d but I want %d\n",
|
|
(int) gk_dim[0], ft.nrows());
|
|
DYN_MEX_FUNC_ERR_MSG_TXT(buf);
|
|
}
|
|
ft.zeros();
|
|
ConstTwoDMatrix gk_mat(ft.nrows(), ft.ncols(), mxGetPr(gk));
|
|
ft.add(1.0, gk_mat);
|
|
UFSTensor* ut = new UFSTensor(ft);
|
|
pol.insert(ut);
|
|
}
|
|
// form the decision rule
|
|
UnfoldDecisionRule
|
|
dr(pol, PartitionY(nstat, npred, nboth, nforw),
|
|
nexog, ConstVector(mxGetPr(ysteady), ny));
|
|
// form the shock realization
|
|
TwoDMatrix shocks_mat(nexog, nper, (const double*)mxGetPr(shocks));
|
|
TwoDMatrix vcov_mat(nexog, nexog, (const double*)mxGetPr(vcov));
|
|
GenShockRealization sr(vcov_mat, shocks_mat, seed);
|
|
// simulate and copy the results
|
|
Vector ystart_vec((const double*)mxGetPr(ystart), ny);
|
|
TwoDMatrix* res_mat =
|
|
dr.simulate(DecisionRule::horner, nper,
|
|
ystart_vec, sr);
|
|
TwoDMatrix res_tmp_mat(ny, nper, mxGetPr(res));
|
|
res_tmp_mat = (const TwoDMatrix&)(*res_mat);
|
|
delete res_mat;
|
|
plhs[1] = res;
|
|
} catch (const KordException& e) {
|
|
DYN_MEX_FUNC_ERR_MSG_TXT("Caugth Kord exception.");
|
|
} catch (const TLException& e) {
|
|
DYN_MEX_FUNC_ERR_MSG_TXT("Caugth TL exception.");
|
|
} catch (SylvException& e) {
|
|
DYN_MEX_FUNC_ERR_MSG_TXT("Caught Sylv exception.");
|
|
}
|
|
plhs[0] = mxCreateDoubleScalar(0);
|
|
}
|
|
};
|