// 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); } };