Tighten input sanity checks of various MEX files
Note that the unitary test in lyapunov_solver.m that checks sparse matrix input had to be removed. Previously, this test was passing by chance (because the sparse test matrices had actually no zero element, hence the internal double float storage was the same as in the dense case). Now it consistently fails with the additional checks in disclyap_fast MEX.trustregion
parent
4f6d8a198a
commit
d5472d2338
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2004-2011 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
* Copyright © 2019-2022 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
|
@ -125,8 +125,8 @@ Vector::Vector(mxArray *p)
|
|||
: len{static_cast<int>(mxGetNumberOfElements(p))},
|
||||
data{mxGetPr(p)}, destroy{false}
|
||||
{
|
||||
if (!mxIsDouble(p))
|
||||
throw SYLV_MES_EXCEPTION("This is not a MATLAB array of doubles.");
|
||||
if (!mxIsDouble(p) || mxIsComplex(p) || mxIsSparse(p))
|
||||
throw SYLV_MES_EXCEPTION("This is not a dense array of real doubles.");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ function P=lyapunov_solver(T,R,Q,DynareOptions) % --*-- Unitary tests --*--
|
|||
% Square-root solver for discrete-time Lyapunov equations (requires Matlab System Control toolbox
|
||||
% or Octave control package)
|
||||
|
||||
% Copyright (C) 2016-2021 Dynare Team
|
||||
% Copyright (C) 2016-2022 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
@ -136,72 +136,51 @@ end
|
|||
%$ t(4) = 0;
|
||||
%$ end
|
||||
%$
|
||||
%$ % Standard with sparse matrix
|
||||
%$ try
|
||||
%$ Pstar5_small = lyapunov_solver(sparse(T_small),sparse(R_small),sparse(Q_small),options_);
|
||||
%$ Pstar5_large = lyapunov_solver(sparse(T_large),sparse(R_large),sparse(Q_large),options_);
|
||||
%$ t(5) = 1;
|
||||
%$ catch
|
||||
%$ t(5) = 0;
|
||||
%$ end
|
||||
%$
|
||||
%$ % Test the results.
|
||||
%$
|
||||
%$ if max(max(abs(Pstar1_small-Pstar2_small)))>1e-8
|
||||
%$ t(6) = 0;
|
||||
%$ t(5) = 0;
|
||||
%$ else
|
||||
%$ t(6) = 1;
|
||||
%$ t(5) = 1;
|
||||
%$ end
|
||||
%$
|
||||
%$ if (isoctave && user_has_octave_forge_package('control')) || (~isoctave && user_has_matlab_license('control_toolbox'))
|
||||
%$ if max(max(abs(Pstar1_small-Pstar3_small)))>1e-8
|
||||
%$ t(7) = 0;
|
||||
%$ t(6) = 0;
|
||||
%$ else
|
||||
%$ t(7) = 1;
|
||||
%$ t(6) = 1;
|
||||
%$ end
|
||||
%$ else
|
||||
%$ t(6) = 1;
|
||||
%$ end
|
||||
%$
|
||||
%$ if max(max(abs(Pstar1_small-Pstar4_small)))>1e-8
|
||||
%$ t(7) = 0;
|
||||
%$ else
|
||||
%$ t(7) = 1;
|
||||
%$ end
|
||||
%$
|
||||
%$ if max(max(abs(Pstar1_small-Pstar4_small)))>1e-8
|
||||
%$ if max(max(abs(Pstar1_large-Pstar2_large)))>2e-8
|
||||
%$ t(8) = 0;
|
||||
%$ else
|
||||
%$ t(8) = 1;
|
||||
%$ end
|
||||
%$
|
||||
%$ if max(max(abs(Pstar1_small-Pstar5_small)))>1e-8
|
||||
%$ t(9) = 0;
|
||||
%$ if (isoctave && user_has_octave_forge_package('control')) || (~isoctave && user_has_matlab_license('control_toolbox'))
|
||||
%$ if max(max(abs(Pstar1_large-Pstar3_large)))>1e-8
|
||||
%$ t(9) = 0;
|
||||
%$ else
|
||||
%$ t(9) = 1;
|
||||
%$ end
|
||||
%$ else
|
||||
%$ t(9) = 1;
|
||||
%$ end
|
||||
%$
|
||||
%$ if max(max(abs(Pstar1_large-Pstar2_large)))>2e-8
|
||||
%$
|
||||
%$ if max(max(abs(Pstar1_large-Pstar4_large)))>2e-8
|
||||
%$ t(10) = 0;
|
||||
%$ else
|
||||
%$ t(10) = 1;
|
||||
%$ end
|
||||
%$
|
||||
%$ if (isoctave && user_has_octave_forge_package('control')) || (~isoctave && user_has_matlab_license('control_toolbox'))
|
||||
%$ if max(max(abs(Pstar1_large-Pstar3_large)))>1e-8
|
||||
%$ t(11) = 0;
|
||||
%$ else
|
||||
%$ t(11) = 1;
|
||||
%$ end
|
||||
%$ else
|
||||
%$ t(11) = 1;
|
||||
%$ end
|
||||
%$
|
||||
%$ if max(max(abs(Pstar1_large-Pstar4_large)))>2e-8
|
||||
%$ t(12) = 0;
|
||||
%$ else
|
||||
%$ t(12) = 1;
|
||||
%$ end
|
||||
%$
|
||||
%$ if max(max(abs(Pstar1_large-Pstar5_large)))>2e-8
|
||||
%$ t(13) = 0;
|
||||
%$ else
|
||||
%$ t(13) = 1;
|
||||
%$ end
|
||||
%$
|
||||
%$ T = all(t);
|
||||
%@eof:1
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
! Copyright © 2019-2021 Dynare Team
|
||||
! Copyright © 2019-2022 Dynare Team
|
||||
!
|
||||
! This file is part of Dynare.
|
||||
!
|
||||
|
@ -51,8 +51,9 @@ subroutine mexFunction(nlhs, plhs, nrhs, prhs) bind(c, name='mexFunction')
|
|||
call mexErrMsgTxt("First argument (function) should be a string or a function handle")
|
||||
end if
|
||||
|
||||
if (.not. (mxIsDouble(prhs(2)) .and. (mxGetM(prhs(2)) == 1 .or. mxGetN(prhs(2)) == 1))) then
|
||||
call mexErrMsgTxt("Second argument (initial guess) should be a real vector")
|
||||
if (.not. (mxIsDouble(prhs(2)) .and. (mxGetM(prhs(2)) == 1 .or. mxGetN(prhs(2)) == 1)) &
|
||||
.or. mxIsComplex(prhs(2)) .or. mxIsSparse(prhs(2))) then
|
||||
call mexErrMsgTxt("Second argument (initial guess) should be a real dense vector")
|
||||
end if
|
||||
|
||||
if (.not. (mxIsScalar(prhs(3)) .and. mxIsNumeric(prhs(3)))) then
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
! This is a Fortran translation of a code originally written by Joe Pearlman
|
||||
! and Alejandro Justiniano.
|
||||
|
||||
! Copyright © 2020-2021 Dynare Team
|
||||
! Copyright © 2020-2022 Dynare Team
|
||||
!
|
||||
! This file is part of Dynare.
|
||||
!
|
||||
|
@ -64,10 +64,10 @@ subroutine mexFunction(nlhs, plhs, nrhs, prhs) bind(c, name='mexFunction')
|
|||
end if
|
||||
|
||||
n = mxGetM(prhs(1))
|
||||
if (.not. mxIsDouble(prhs(1)) .or. mxIsComplex(prhs(1)) &
|
||||
.or. .not. mxIsDouble(prhs(2)) .or. mxIsComplex(prhs(2)) &
|
||||
if (.not. mxIsDouble(prhs(1)) .or. mxIsComplex(prhs(1)) .or. mxIsSparse(prhs(1)) &
|
||||
.or. .not. mxIsDouble(prhs(2)) .or. mxIsComplex(prhs(2)) .or. mxIsSparse(prhs(2)) &
|
||||
.or. mxGetN(prhs(1)) /= n .or. mxGetM(prhs(2)) /= n .or. mxGetN(prhs(2)) /= n) then
|
||||
call mexErrMsgTxt("disclyap_fast: first two arguments should be real matrices of the same dimension")
|
||||
call mexErrMsgTxt("disclyap_fast: first two arguments should be real dense matrices of the same dimension")
|
||||
end if
|
||||
|
||||
if (.not. (mxIsScalar(prhs(3)) .and. mxIsNumeric(prhs(3)))) then
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2005-2011 Ondra Kamenik
|
||||
* Copyright © 2019-2020 Dynare Team
|
||||
* Copyright © 2019-2022 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
|
@ -54,11 +54,24 @@ extern "C" {
|
|||
if (nhrs != 5 || nlhs > 2 || nlhs < 1)
|
||||
mexErrMsgTxt("Gensylv: Must have exactly 5 input args and either 1 or 2 output args.");
|
||||
|
||||
if (!(mxIsScalar(prhs[0]) && mxIsNumeric(prhs[0])))
|
||||
mexErrMsgTxt("First argument should be a numeric scalar");
|
||||
|
||||
auto order = static_cast<int>(mxGetScalar(prhs[0]));
|
||||
const mxArray *const A = prhs[1];
|
||||
const mxArray *const B = prhs[2];
|
||||
const mxArray *const C = prhs[3];
|
||||
const mxArray *const D = prhs[4];
|
||||
|
||||
if (!mxIsDouble(A) || mxIsComplex(A) || mxIsSparse(A))
|
||||
mexErrMsgTxt("Matrix A must be a real dense matrix.");
|
||||
if (!mxIsDouble(B) || mxIsComplex(B) || mxIsSparse(B))
|
||||
mexErrMsgTxt("Matrix B must be a real dense matrix.");
|
||||
if (!mxIsDouble(C) || mxIsComplex(C) || mxIsSparse(C))
|
||||
mexErrMsgTxt("Matrix C must be a real dense matrix.");
|
||||
if (!mxIsDouble(D) || mxIsComplex(D) || mxIsSparse(D))
|
||||
mexErrMsgTxt("Matrix D must be a real dense matrix.");
|
||||
|
||||
const mwSize *const Adims = mxGetDimensions(A);
|
||||
const mwSize *const Bdims = mxGetDimensions(B);
|
||||
const mwSize *const Cdims = mxGetDimensions(C);
|
||||
|
|
|
@ -77,37 +77,39 @@ subroutine mexFunction(nlhs, plhs, nrhs, prhs) bind(c, name='mexFunction')
|
|||
if (nrhs /= 12) then
|
||||
call mexErrMsgTxt("Must have exactly 12 inputs")
|
||||
end if
|
||||
if (.not. (mxIsScalar(order_mx)) .and. mxIsNumeric(order_mx)) then
|
||||
if (.not. (mxIsScalar(order_mx) .and. mxIsNumeric(order_mx))) then
|
||||
call mexErrMsgTxt("1st argument (order) should be a numeric scalar")
|
||||
end if
|
||||
if (.not. (mxIsScalar(nstatic_mx)) .and. mxIsNumeric(nstatic_mx)) then
|
||||
if (.not. (mxIsScalar(nstatic_mx) .and. mxIsNumeric(nstatic_mx))) then
|
||||
call mexErrMsgTxt("2nd argument (nstat) should be a numeric scalar")
|
||||
end if
|
||||
if (.not. (mxIsScalar(npred_mx)) .and. mxIsNumeric(npred_mx)) then
|
||||
if (.not. (mxIsScalar(npred_mx) .and. mxIsNumeric(npred_mx))) then
|
||||
call mexErrMsgTxt("3rd argument (npred) should be a numeric scalar")
|
||||
end if
|
||||
if (.not. (mxIsScalar(nboth_mx)) .and. mxIsNumeric(nboth_mx)) then
|
||||
if (.not. (mxIsScalar(nboth_mx) .and. mxIsNumeric(nboth_mx))) then
|
||||
call mexErrMsgTxt("4th argument (nboth) should be a numeric scalar")
|
||||
end if
|
||||
if (.not. (mxIsScalar(nfwrd_mx)) .and. mxIsNumeric(nfwrd_mx)) then
|
||||
if (.not. (mxIsScalar(nfwrd_mx) .and. mxIsNumeric(nfwrd_mx))) then
|
||||
call mexErrMsgTxt("5th argument (nforw) should be a numeric scalar")
|
||||
end if
|
||||
if (.not. (mxIsScalar(nexog_mx)) .and. mxIsNumeric(nexog_mx)) then
|
||||
if (.not. (mxIsScalar(nexog_mx) .and. mxIsNumeric(nexog_mx))) then
|
||||
call mexErrMsgTxt("6th argument (nexog) should be a numeric scalar")
|
||||
end if
|
||||
if (.not. (mxIsScalar(order_moment_mx)) .and. mxIsNumeric(order_moment_mx)) then
|
||||
if (.not. (mxIsScalar(order_moment_mx) .and. mxIsNumeric(order_moment_mx))) then
|
||||
call mexErrMsgTxt("7th argument (order_moment) should be a numeric scalar")
|
||||
end if
|
||||
if (.not. (mxIsScalar(nburn_mx)) .and. mxIsNumeric(nburn_mx)) then
|
||||
if (.not. (mxIsScalar(nburn_mx) .and. mxIsNumeric(nburn_mx))) then
|
||||
call mexErrMsgTxt("8th argument (nburn) should be a numeric scalar")
|
||||
end if
|
||||
if (.not. (mxIsDouble(yhat_start_mx) .and. (mxGetM(yhat_start_mx) == 1 .or. mxGetN(yhat_start_mx) == 1))) then
|
||||
call mexErrMsgTxt("9th argument (yhat_start) should be a real vector")
|
||||
if (.not. (mxIsDouble(yhat_start_mx) .and. (mxGetM(yhat_start_mx) == 1 .or. mxGetN(yhat_start_mx) == 1)) &
|
||||
.or. mxIsComplex(yhat_start_mx) .or. mxIsSparse(yhat_start_mx)) then
|
||||
call mexErrMsgTxt("9th argument (yhat_start) should be a real dense vector")
|
||||
end if
|
||||
if (.not. (mxIsDouble(shocks_mx))) then
|
||||
call mexErrMsgTxt("10th argument (shocks) should be a real matrix")
|
||||
if (.not. (mxIsDouble(shocks_mx)) .or. mxIsComplex(shocks_mx) .or. mxIsSparse(shocks_mx)) then
|
||||
call mexErrMsgTxt("10th argument (shocks) should be a real dense matrix")
|
||||
end if
|
||||
if (.not. (mxIsDouble(ysteady_mx) .and. (mxGetM(ysteady_mx) == 1 .or. mxGetN(ysteady_mx) == 1))) then
|
||||
if (.not. (mxIsDouble(ysteady_mx) .and. (mxGetM(ysteady_mx) == 1 .or. mxGetN(ysteady_mx) == 1)) &
|
||||
.or. mxIsComplex(ysteady_mx) .or. mxIsSparse(ysteady_mx)) then
|
||||
call mexErrMsgTxt("11th argument (ysteady) should be a real vector")
|
||||
end if
|
||||
if (.not. mxIsStruct(dr_mx)) then
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2008-2021 Dynare Team
|
||||
* Copyright © 2008-2022 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
|
@ -133,15 +133,16 @@ extern "C" {
|
|||
std::string fname{mxArrayToString(fname_mx)};
|
||||
|
||||
const mxArray *params_mx = mxGetField(M_mx, 0, "params");
|
||||
if (!(params_mx && mxIsDouble(params_mx)))
|
||||
mexErrMsgTxt("M_.params should be a double precision array");
|
||||
if (!(params_mx && mxIsDouble(params_mx) && !mxIsComplex(params_mx) && !mxIsSparse(params_mx)))
|
||||
mexErrMsgTxt("M_.params should be a real dense array");
|
||||
Vector modParams{ConstVector{params_mx}};
|
||||
if (!modParams.isFinite())
|
||||
mexErrMsgTxt("M_.params contains NaN or Inf");
|
||||
|
||||
const mxArray *sigma_e_mx = mxGetField(M_mx, 0, "Sigma_e");
|
||||
if (!(sigma_e_mx && mxIsDouble(sigma_e_mx) && mxGetM(sigma_e_mx) == mxGetN(sigma_e_mx)))
|
||||
mexErrMsgTxt("M_.Sigma_e should be a double precision square matrix");
|
||||
if (!(sigma_e_mx && mxIsDouble(sigma_e_mx) && !mxIsComplex(sigma_e_mx) && !mxIsSparse(sigma_e_mx)
|
||||
&& mxGetM(sigma_e_mx) == mxGetN(sigma_e_mx)))
|
||||
mexErrMsgTxt("M_.Sigma_e should be a real dense square matrix");
|
||||
TwoDMatrix vCov{ConstTwoDMatrix{sigma_e_mx}};
|
||||
if (!vCov.isFinite())
|
||||
mexErrMsgTxt("M_.Sigma_e contains NaN or Inf");
|
||||
|
@ -156,13 +157,16 @@ extern "C" {
|
|||
const int nPar = get_int_field(M_mx, "param_nbr");
|
||||
|
||||
const mxArray *lead_lag_incidence_mx = mxGetField(M_mx, 0, "lead_lag_incidence");
|
||||
if (!(lead_lag_incidence_mx && mxIsDouble(lead_lag_incidence_mx) && mxGetM(lead_lag_incidence_mx) == 3
|
||||
if (!(lead_lag_incidence_mx && mxIsDouble(lead_lag_incidence_mx)
|
||||
&& !mxIsComplex(lead_lag_incidence_mx) && !mxIsSparse(lead_lag_incidence_mx)
|
||||
&& mxGetM(lead_lag_incidence_mx) == 3
|
||||
&& mxGetN(lead_lag_incidence_mx) == static_cast<size_t>(nEndo)))
|
||||
mexErrMsgTxt("M_.lead_lag_incidence should be a double precision matrix with 3 rows and M_.endo_nbr columns");
|
||||
mexErrMsgTxt("M_.lead_lag_incidence should be a real dense matrix with 3 rows and M_.endo_nbr columns");
|
||||
ConstTwoDMatrix llincidence{lead_lag_incidence_mx};
|
||||
|
||||
const mxArray *nnzderivatives_mx = mxGetField(M_mx, 0, "NNZDerivatives");
|
||||
if (!(nnzderivatives_mx && mxIsDouble(nnzderivatives_mx)))
|
||||
if (!(nnzderivatives_mx && mxIsDouble(nnzderivatives_mx) && !mxIsComplex(nnzderivatives_mx)
|
||||
&& !mxIsSparse(nnzderivatives_mx)))
|
||||
mexErrMsgTxt("M_.NNZDerivatives should be a double precision array");
|
||||
ConstVector NNZD{nnzderivatives_mx};
|
||||
if (NNZD.length() < kOrder || NNZD[kOrder-1] == -1)
|
||||
|
@ -179,21 +183,24 @@ extern "C" {
|
|||
std::vector<std::string> exoNames = DynareMxArrayToString(exo_names_mx);
|
||||
|
||||
const mxArray *dynamic_tmp_nbr_mx = mxGetField(M_mx, 0, "dynamic_tmp_nbr");
|
||||
if (!(dynamic_tmp_nbr_mx && mxIsDouble(dynamic_tmp_nbr_mx) && mxGetNumberOfElements(dynamic_tmp_nbr_mx) >= static_cast<size_t>(kOrder+1)))
|
||||
mexErrMsgTxt("M_.dynamic_tmp_nbr should be a double precision array with strictly more elements than the order of derivation");
|
||||
if (!(dynamic_tmp_nbr_mx && mxIsDouble(dynamic_tmp_nbr_mx) && !mxIsComplex(dynamic_tmp_nbr_mx)
|
||||
&& !mxIsSparse(dynamic_tmp_nbr_mx)
|
||||
&& mxGetNumberOfElements(dynamic_tmp_nbr_mx) >= static_cast<size_t>(kOrder+1)))
|
||||
mexErrMsgTxt("M_.dynamic_tmp_nbr should be a real dense array with strictly more elements than the order of derivation");
|
||||
int ntt = std::accumulate(mxGetPr(dynamic_tmp_nbr_mx), mxGetPr(dynamic_tmp_nbr_mx)+kOrder+1, 0);
|
||||
|
||||
// Extract various fields from dr
|
||||
const mxArray *ys_mx = mxGetField(dr_mx, 0, "ys"); // and not in order of dr.order_var
|
||||
if (!(ys_mx && mxIsDouble(ys_mx)))
|
||||
mexErrMsgTxt("dr.ys should be a double precision array");
|
||||
if (!(ys_mx && mxIsDouble(ys_mx) && !mxIsComplex(ys_mx) && !mxIsSparse(ys_mx)))
|
||||
mexErrMsgTxt("dr.ys should be a real dense array");
|
||||
Vector ySteady{ConstVector{ys_mx}};
|
||||
if (!ySteady.isFinite())
|
||||
mexErrMsgTxt("dr.ys contains NaN or Inf");
|
||||
|
||||
const mxArray *order_var_mx = mxGetField(dr_mx, 0, "order_var");
|
||||
if (!(order_var_mx && mxIsDouble(order_var_mx) && mxGetNumberOfElements(order_var_mx) == static_cast<size_t>(nEndo)))
|
||||
mexErrMsgTxt("dr.order_var should be a double precision array of M_.endo_nbr elements");
|
||||
if (!(order_var_mx && mxIsDouble(order_var_mx) && !mxIsComplex(order_var_mx) && !mxIsSparse(order_var_mx)
|
||||
&& mxGetNumberOfElements(order_var_mx) == static_cast<size_t>(nEndo)))
|
||||
mexErrMsgTxt("dr.order_var should be a real dense array of M_.endo_nbr elements");
|
||||
std::vector<int> dr_order(nEndo);
|
||||
std::transform(mxGetPr(order_var_mx), mxGetPr(order_var_mx)+nEndo, dr_order.begin(),
|
||||
[](double x) { return static_cast<int>(x)-1; });
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
! Copyright © 2021 Dynare Team
|
||||
! Copyright © 2021-2022 Dynare Team
|
||||
!
|
||||
! This file is part of Dynare.
|
||||
!
|
||||
|
@ -85,14 +85,16 @@ subroutine mexFunction(nlhs, plhs, nrhs, prhs) bind(c, name='mexFunction')
|
|||
if (.not. (mxIsScalar(nexog_mx)) .and. mxIsNumeric(nexog_mx)) then
|
||||
call mexErrMsgTxt("6th argument (nexog) should be a numeric scalar")
|
||||
end if
|
||||
if (.not. (mxIsDouble(ystart_mx) .and. (mxGetM(ystart_mx) == 1 .or. mxGetN(ystart_mx) == 1))) then
|
||||
call mexErrMsgTxt("7th argument (ystart) should be a real vector")
|
||||
if (.not. (mxIsDouble(ystart_mx) .and. (mxGetM(ystart_mx) == 1 .or. mxGetN(ystart_mx) == 1)) &
|
||||
.or. mxIsComplex(ystart_mx) .or. mxIsSparse(ystart_mx)) then
|
||||
call mexErrMsgTxt("7th argument (ystart) should be a real dense vector")
|
||||
end if
|
||||
if (.not. (mxIsDouble(shocks_mx))) then
|
||||
call mexErrMsgTxt("8th argument (shocks) should be a real matrix")
|
||||
if (.not. mxIsDouble(shocks_mx) .or. mxIsComplex(shocks_mx) .or. mxIsSparse(shocks_mx)) then
|
||||
call mexErrMsgTxt("8th argument (shocks) should be a real dense matrix")
|
||||
end if
|
||||
if (.not. (mxIsDouble(ysteady_mx) .and. (mxGetM(ysteady_mx) == 1 .or. mxGetN(ysteady_mx) == 1))) then
|
||||
call mexErrMsgTxt("9th argument (ysteady) should be a real vector")
|
||||
if (.not. (mxIsDouble(ysteady_mx) .and. (mxGetM(ysteady_mx) == 1 .or. mxGetN(ysteady_mx) == 1)) &
|
||||
.or. mxIsComplex(ysteady_mx) .or. mxIsSparse(ysteady_mx)) then
|
||||
call mexErrMsgTxt("9th argument (ysteady) should be a real dense vector")
|
||||
end if
|
||||
if (.not. mxIsStruct(dr_mx)) then
|
||||
call mexErrMsgTxt("10th argument (dr) should be a struct")
|
||||
|
@ -130,7 +132,7 @@ subroutine mexFunction(nlhs, plhs, nrhs, prhs) bind(c, name='mexFunction')
|
|||
do i = 0, order
|
||||
write (fieldname, '(a2, i1)') "g_", i
|
||||
tmp = mxGetField(dr_mx, 1_mwIndex, trim(fieldname))
|
||||
if (.not. (c_associated(tmp) .and. mxIsDouble(tmp))) then
|
||||
if (.not. (c_associated(tmp) .and. mxIsDouble(tmp) .and. .not. mxIsComplex(tmp) .and. .not. mxIsSparse(tmp))) then
|
||||
call mexErrMsgTxt(trim(fieldname)//" is not allocated in dr")
|
||||
end if
|
||||
m = int(mxGetM(tmp))
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2021 Dynare Team
|
||||
* Copyright © 2021-2022 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
|
@ -194,8 +194,8 @@ extern "C" {
|
|||
mexErrMsgTxt("The derivatives were not computed for the required order. Make sure that you used the right order option inside the `stoch_simul' command");
|
||||
|
||||
const mxArray *nnzderivatives_obj_mx = mxGetField(M_mx, 0, "NNZDerivatives_objective");
|
||||
if (!(nnzderivatives_obj_mx && mxIsDouble(nnzderivatives_obj_mx)))
|
||||
mexErrMsgTxt("M_.NNZDerivatives should be a double precision array");
|
||||
if (!(nnzderivatives_obj_mx && mxIsDouble(nnzderivatives_obj_mx) && !mxIsComplex(nnzderivatives_obj_mx) && !mxIsSparse(nnzderivatives_obj_mx)))
|
||||
mexErrMsgTxt("M_.NNZDerivatives should be a real dense array");
|
||||
ConstVector NNZD_obj{nnzderivatives_obj_mx};
|
||||
if (NNZD.length() < kOrder || NNZD_obj[kOrder-1] == -1)
|
||||
mexErrMsgTxt("The derivatives were not computed for the required order. Make sure that you used the right order option inside the `stoch_simul' command");
|
||||
|
@ -211,21 +211,24 @@ extern "C" {
|
|||
std::vector<std::string> exoNames = DynareMxArrayToString(exo_names_mx);
|
||||
|
||||
const mxArray *dynamic_tmp_nbr_mx = mxGetField(M_mx, 0, "dynamic_tmp_nbr");
|
||||
if (!(dynamic_tmp_nbr_mx && mxIsDouble(dynamic_tmp_nbr_mx) && mxGetNumberOfElements(dynamic_tmp_nbr_mx) >= static_cast<size_t>(kOrder+1)))
|
||||
if (!(dynamic_tmp_nbr_mx && mxIsDouble(dynamic_tmp_nbr_mx) && !mxIsComplex(dynamic_tmp_nbr_mx)
|
||||
&& !mxIsSparse(dynamic_tmp_nbr_mx) && mxGetNumberOfElements(dynamic_tmp_nbr_mx) >= static_cast<size_t>(kOrder+1)))
|
||||
mexErrMsgTxt("M_.dynamic_tmp_nbr should be a double precision array with strictly more elements than the order of derivation");
|
||||
int ntt = std::accumulate(mxGetPr(dynamic_tmp_nbr_mx), mxGetPr(dynamic_tmp_nbr_mx)+kOrder+1, 0);
|
||||
|
||||
// Extract various fields from dr
|
||||
const mxArray *ys_mx = mxGetField(dr_mx, 0, "ys"); // and not in order of dr.order_var
|
||||
if (!(ys_mx && mxIsDouble(ys_mx)))
|
||||
mexErrMsgTxt("dr.ys should be a double precision array");
|
||||
if (!(ys_mx && mxIsDouble(ys_mx) && !mxIsComplex(ys_mx) && !mxIsSparse(ys_mx)))
|
||||
mexErrMsgTxt("dr.ys should be a real dense array");
|
||||
Vector ySteady{ConstVector{ys_mx}};
|
||||
if (!ySteady.isFinite())
|
||||
mexErrMsgTxt("dr.ys contains NaN or Inf");
|
||||
|
||||
const mxArray *order_var_mx = mxGetField(dr_mx, 0, "order_var");
|
||||
if (!(order_var_mx && mxIsDouble(order_var_mx) && mxGetNumberOfElements(order_var_mx) == static_cast<size_t>(nEndo)))
|
||||
mexErrMsgTxt("dr.order_var should be a double precision array of M_.endo_nbr elements");
|
||||
if (!(order_var_mx && mxIsDouble(order_var_mx) && !mxIsComplex(order_var_mx)
|
||||
&& !mxIsSparse(order_var_mx)
|
||||
&& mxGetNumberOfElements(order_var_mx) == static_cast<size_t>(nEndo)))
|
||||
mexErrMsgTxt("dr.order_var should be a real dense array of M_.endo_nbr elements");
|
||||
std::vector<int> dr_order(nEndo);
|
||||
std::transform(mxGetPr(order_var_mx), mxGetPr(order_var_mx)+nEndo, dr_order.begin(),
|
||||
[](double x) { return static_cast<int>(x)-1; });
|
||||
|
@ -262,8 +265,10 @@ extern "C" {
|
|||
app.walkStochSteady();
|
||||
|
||||
const mxArray *objective_tmp_nbr_mx = mxGetField(M_mx, 0, "objective_tmp_nbr");
|
||||
if (!(objective_tmp_nbr_mx && mxIsDouble(objective_tmp_nbr_mx) && mxGetNumberOfElements(objective_tmp_nbr_mx) >= static_cast<size_t>(kOrder+1)))
|
||||
mexErrMsgTxt("M_.objective_tmp_nbr should be a double precision array with strictly more elements than the order of derivation");
|
||||
if (!(objective_tmp_nbr_mx && mxIsDouble(objective_tmp_nbr_mx)
|
||||
&& !mxIsComplex(objective_tmp_nbr_mx) && !mxIsSparse(objective_tmp_nbr_mx)
|
||||
&& mxGetNumberOfElements(objective_tmp_nbr_mx) >= static_cast<size_t>(kOrder+1)))
|
||||
mexErrMsgTxt("M_.objective_tmp_nbr should be a real dense array with strictly more elements than the order of derivation");
|
||||
int ntt_objective = std::accumulate(mxGetPr(objective_tmp_nbr_mx), mxGetPr(objective_tmp_nbr_mx)+kOrder+1, 0);
|
||||
|
||||
//Getting derivatives of the planner's objective function
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
! This MEX file computes A·(B⊗C) or A·(B⊗B) without explicitly building B⊗C or
|
||||
! B⊗B, so that one can consider large matrices B and/or C.
|
||||
|
||||
! Copyright © 2007-2021 Dynare Team
|
||||
! Copyright © 2007-2022 Dynare Team
|
||||
!
|
||||
! This file is part of Dynare.
|
||||
!
|
||||
|
@ -36,9 +36,9 @@ subroutine mexFunction(nlhs, plhs, nrhs, prhs) bind(c, name='mexFunction')
|
|||
call mexErrMsgTxt("A_times_B_kronecker_C takes 2 or 3 input arguments and provides 1 output argument")
|
||||
end if
|
||||
|
||||
if (.not. mxIsDouble(prhs(1)) .or. mxIsComplex(prhs(1)) &
|
||||
.or. .not. mxIsDouble(prhs(2)) .or. mxIsComplex(prhs(2))) then
|
||||
call mexErrMsgTxt("A_times_B_kronecker_C: first two arguments should be real matrices")
|
||||
if (.not. mxIsDouble(prhs(1)) .or. mxIsComplex(prhs(1)) .or. mxIsSparse(prhs(1)) &
|
||||
.or. .not. mxIsDouble(prhs(2)) .or. mxIsComplex(prhs(2)) .or. mxIsSparse(prhs(2))) then
|
||||
call mexErrMsgTxt("A_times_B_kronecker_C: first two arguments should be real dense matrices")
|
||||
end if
|
||||
mA = mxGetM(prhs(1))
|
||||
nA = mxGetN(prhs(1))
|
||||
|
@ -49,8 +49,8 @@ subroutine mexFunction(nlhs, plhs, nrhs, prhs) bind(c, name='mexFunction')
|
|||
|
||||
if (nrhs == 3) then
|
||||
! A·(B⊗C) is to be computed.
|
||||
if (.not. mxIsDouble(prhs(3)) .or. mxIsComplex(prhs(3))) then
|
||||
call mexErrMsgTxt("A_times_B_kronecker_C: third argument should be a real matrix")
|
||||
if (.not. mxIsDouble(prhs(3)) .or. mxIsComplex(prhs(3)) .or. mxIsSparse(prhs(3))) then
|
||||
call mexErrMsgTxt("A_times_B_kronecker_C: third argument should be a real dense matrix")
|
||||
end if
|
||||
mC = mxGetM(prhs(3))
|
||||
nC = mxGetN(prhs(3))
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2007-2021 Dynare Team
|
||||
* Copyright © 2007-2022 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
|
@ -141,8 +141,12 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
return; // Needed to shut up some GCC warnings
|
||||
}
|
||||
|
||||
if (!mxIsSparse(prhs[0]))
|
||||
mexErrMsgTxt("sparse_hessian_times_B_kronecker_C: First input must be a sparse (dynare) hessian matrix.");
|
||||
if (!mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) || !mxIsSparse(prhs[0]))
|
||||
mexErrMsgTxt("sparse_hessian_times_B_kronecker_C: First input must be a real sparse matrix.");
|
||||
if (!mxIsDouble(prhs[1]) || mxIsComplex(prhs[1]) || mxIsSparse(prhs[1]))
|
||||
mexErrMsgTxt("sparse_hessian_times_B_kronecker_C: Second input must be a real dense matrix.");
|
||||
if (nrhs == 4 && (!mxIsDouble(prhs[2]) || mxIsComplex(prhs[2]) || mxIsSparse(prhs[2])))
|
||||
mexErrMsgTxt("sparse_hessian_times_B_kronecker_C: Third input must be a real dense matrix.");
|
||||
|
||||
// Get & Check dimensions (columns and rows):
|
||||
size_t mA = mxGetM(prhs[0]);
|
||||
|
@ -166,12 +170,21 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
int numthreads;
|
||||
const double *B = mxGetPr(prhs[1]);
|
||||
const double *C;
|
||||
numthreads = static_cast<int>(mxGetScalar(prhs[2]));
|
||||
const mxArray *numthreads_mx;
|
||||
if (nrhs == 4)
|
||||
{
|
||||
C = mxGetPr(prhs[2]);
|
||||
numthreads = static_cast<int>(mxGetScalar(prhs[3]));
|
||||
numthreads_mx = prhs[3];
|
||||
}
|
||||
else
|
||||
numthreads_mx = prhs[2];
|
||||
|
||||
if (!(mxIsScalar(numthreads_mx) && mxIsNumeric(numthreads_mx)))
|
||||
mexErrMsgTxt("sparse_hessian_times_B_kronecker_C: Last input must be a numeric scalar.");
|
||||
numthreads = static_cast<int>(mxGetScalar(numthreads_mx));
|
||||
if (numthreads <= 0)
|
||||
mexErrMsgTxt("sparse_hessian_times_B_kronecker_C: Last input must be a positive integer.");
|
||||
|
||||
// Sparse (dynare) hessian matrix.
|
||||
const mwIndex *isparseA = mxGetIr(prhs[0]);
|
||||
const mwIndex *jsparseA = mxGetJc(prhs[0]);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2010-2021 Dynare Team
|
||||
* Copyright © 2010-2022 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
|
@ -25,6 +25,7 @@
|
|||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <tuple>
|
||||
#include <string>
|
||||
|
||||
#include <dynmex.h>
|
||||
#include <dynblas.h>
|
||||
|
@ -224,6 +225,15 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
if (nlhs > 2)
|
||||
mexErrMsgTxt("Too many output arguments.");
|
||||
|
||||
auto check_input_real_dense_array = [=](int i)
|
||||
{
|
||||
if (!mxIsDouble(prhs[i]) || mxIsComplex(prhs[i]) || mxIsSparse(prhs[i]))
|
||||
mexErrMsgTxt(("Input argument " + std::to_string(i+1) + " should be a real dense array").c_str());
|
||||
};
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
check_input_real_dense_array(i);
|
||||
|
||||
// Get dimensions.
|
||||
size_t n = mxGetM(prhs[0]); // Number of states.
|
||||
size_t s = mxGetN(prhs[0]); // Number of particles.
|
||||
|
@ -243,10 +253,15 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
|| n*q != mxGetN(prhs[7])) // Number of rows for ghxu
|
||||
mexErrMsgTxt("Input dimension mismatch!.");
|
||||
if (nrhs > 9)
|
||||
if (n != mxGetM(prhs[8]) // Number of rows for yhat_
|
||||
|| s != mxGetN(prhs[8]) // Number of columns for yhat_
|
||||
|| m != mxGetM(prhs[9])) // Number of rows for ss
|
||||
mexErrMsgTxt("Input dimension mismatch!.");
|
||||
{
|
||||
for (int i = 8; i < 10; i++)
|
||||
check_input_real_dense_array(i);
|
||||
|
||||
if (n != mxGetM(prhs[8]) // Number of rows for yhat_
|
||||
|| s != mxGetN(prhs[8]) // Number of columns for yhat_
|
||||
|| m != mxGetM(prhs[9])) // Number of rows for ss
|
||||
mexErrMsgTxt("Input dimension mismatch!.");
|
||||
}
|
||||
|
||||
// Get Input arrays.
|
||||
const double *yhat = mxGetPr(prhs[0]);
|
||||
|
@ -263,7 +278,14 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
yhat_ = mxGetPr(prhs[8]);
|
||||
ss = mxGetPr(prhs[9]);
|
||||
}
|
||||
int numthreads = static_cast<int>(mxGetScalar(prhs[nrhs == 9 ? 8 : 10]));
|
||||
|
||||
const mxArray *numthreads_mx = prhs[nrhs == 9 ? 8 : 10];
|
||||
if (!(mxIsScalar(numthreads_mx) && mxIsNumeric(numthreads_mx)))
|
||||
mexErrMsgTxt("Last argument should be a numeric scalar");
|
||||
int numthreads = static_cast<int>(mxGetScalar(numthreads_mx));
|
||||
if (numthreads <= 0)
|
||||
mexErrMsgTxt("Last argument should be a positive integer");
|
||||
|
||||
#if defined(USE_BLAS_AT_FIRST_ORDER) && defined(MATLAB_MEX_FILE)
|
||||
if (numthreads != 1)
|
||||
mexErrMsgTxt("Parallelization is not possible when compiled with USE_BLAS_AT_FIRST_ORDER.");
|
||||
|
|
|
@ -58,11 +58,13 @@ subroutine mexFunction(nlhs, plhs, nrhs, prhs) bind(c, name='mexFunction')
|
|||
if (nrhs /= 6 .or. nlhs /= 1) then
|
||||
call mexErrMsgTxt("Must have exactly 5 inputs and 1 output")
|
||||
end if
|
||||
if (.not. (mxIsDouble(yhat_mx) .and. mxGetM(yhat_mx) >= 1 .and. mxGetN(yhat_mx) >= 1)) then
|
||||
call mexErrMsgTxt("1st argument (yhat) should be a real vector")
|
||||
if (.not. (mxIsDouble(yhat_mx) .and. mxGetM(yhat_mx) >= 1 .and. mxGetN(yhat_mx) >= 1) &
|
||||
.or. mxIsComplex(yhat_mx) .or. mxIsSparse(yhat_mx)) then
|
||||
call mexErrMsgTxt("1st argument (yhat) should be a real dense vector")
|
||||
end if
|
||||
if (.not. (mxIsDouble(epsilon_mx) .and. mxGetM(epsilon_mx) >= 1 .or. mxGetN(epsilon_mx) == 1)) then
|
||||
call mexErrMsgTxt("2nd argument (epsilon) should be a real vector")
|
||||
if (.not. (mxIsDouble(epsilon_mx) .and. mxGetM(epsilon_mx) >= 1 .or. mxGetN(epsilon_mx) == 1) &
|
||||
.or. mxIsComplex(epsilon_mx) .or. mxIsSparse(epsilon_mx)) then
|
||||
call mexErrMsgTxt("2nd argument (epsilon) should be a real dense vector")
|
||||
end if
|
||||
if (.not. mxIsStruct(dr_mx)) then
|
||||
call mexErrMsgTxt("3rd argument (dr) should be a struct")
|
||||
|
@ -88,15 +90,17 @@ subroutine mexFunction(nlhs, plhs, nrhs, prhs) bind(c, name='mexFunction')
|
|||
nvar = nys + exo_nbr
|
||||
|
||||
associate (order_var_mx => mxGetField(dr_mx, 1_mwIndex, "order_var"))
|
||||
if (.not. (mxIsDouble(order_var_mx) .and. int(mxGetNumberOfElements(order_var_mx)) == endo_nbr)) then
|
||||
call mexErrMsgTxt("Field dr.order_var should be a double precision vector with endo_nbr elements")
|
||||
if (.not. (mxIsDouble(order_var_mx) .and. int(mxGetNumberOfElements(order_var_mx)) == endo_nbr) &
|
||||
.or. mxIsComplex(order_var_mx) .or. mxIsSparse(order_var_mx)) then
|
||||
call mexErrMsgTxt("Field dr.order_var should be a real dense vector with endo_nbr elements")
|
||||
end if
|
||||
order_var => mxGetPr(order_var_mx)
|
||||
end associate
|
||||
|
||||
associate (ys_mx => mxGetField(dr_mx, 1_mwIndex, "ys"))
|
||||
if (.not. (mxIsDouble(ys_mx) .and. int(mxGetNumberOfElements(ys_mx)) == endo_nbr)) then
|
||||
call mexErrMsgTxt("Field dr.ys should be a double precision vector with endo_nbr elements")
|
||||
if (.not. (mxIsDouble(ys_mx) .and. int(mxGetNumberOfElements(ys_mx)) == endo_nbr) &
|
||||
.or. mxIsComplex(ys_mx) .or. mxIsSparse(ys_mx)) then
|
||||
call mexErrMsgTxt("Field dr.ys should be a real dense vector with endo_nbr elements")
|
||||
end if
|
||||
ys => mxGetPr(ys_mx)
|
||||
! Construct the reordered steady state
|
||||
|
@ -107,8 +111,8 @@ subroutine mexFunction(nlhs, plhs, nrhs, prhs) bind(c, name='mexFunction')
|
|||
end associate
|
||||
|
||||
associate (restrict_var_list_mx => mxGetField(dr_mx, 1_mwIndex, "restrict_var_list"))
|
||||
if (.not. (mxIsDouble(restrict_var_list_mx))) then
|
||||
call mexErrMsgTxt("Field dr.restrict_var_list should be a double precision vector")
|
||||
if (.not. mxIsDouble(restrict_var_list_mx) .or. mxIsComplex(restrict_var_list_mx) .or. mxIsSparse(restrict_var_list_mx)) then
|
||||
call mexErrMsgTxt("Field dr.restrict_var_list should be a real dense vector")
|
||||
end if
|
||||
nrestricted = size(mxGetPr(restrict_var_list_mx))
|
||||
restrict_var_list => mxGetPr(restrict_var_list_mx)
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
! Fortran compiler better optimize the code (in some cases, this will avoid
|
||||
! array copies)
|
||||
|
||||
! Copyright © 2019-2021 Dynare Team
|
||||
! Copyright © 2019-2022 Dynare Team
|
||||
!
|
||||
! This file is part of Dynare.
|
||||
!
|
||||
|
@ -177,6 +177,11 @@ module matlab_mat
|
|||
integer(mxComplexity), intent(in), value :: ComplexFlag
|
||||
end function mxCreateSparse
|
||||
|
||||
logical(c_bool) function mxIsSparse(pm) bind(c, name="mxIsSparse"//API_VER)
|
||||
use iso_c_binding
|
||||
type(c_ptr), intent(in), value :: pm
|
||||
end function mxIsSparse
|
||||
|
||||
type(c_ptr) function mxGetIr(pm) bind(c, name="mxGetIr"//API_VER2)
|
||||
use iso_c_binding
|
||||
type(c_ptr), intent(in), value :: pm
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
! eigval [complex] (n×1) vector of generalized eigenvalues
|
||||
! info [integer] scalar, error code of dgges (or 30 if eigenvalue close to 0÷0)
|
||||
|
||||
! Copyright © 2006-2021 Dynare Team
|
||||
! Copyright © 2006-2022 Dynare Team
|
||||
!
|
||||
! This file is part of Dynare.
|
||||
!
|
||||
|
@ -83,10 +83,10 @@ subroutine mexFunction(nlhs, plhs, nrhs, prhs) bind(c, name='mexFunction')
|
|||
end if
|
||||
|
||||
n = mxGetM(prhs(1))
|
||||
if (.not. mxIsDouble(prhs(1)) .or. mxIsComplex(prhs(1)) &
|
||||
.or. .not. mxIsDouble(prhs(2)) .or. mxIsComplex(prhs(2)) &
|
||||
if (.not. mxIsDouble(prhs(1)) .or. mxIsComplex(prhs(1)) .or. mxIsSparse(prhs(1)) &
|
||||
.or. .not. mxIsDouble(prhs(2)) .or. mxIsComplex(prhs(2)) .or. mxIsSparse(prhs(2)) &
|
||||
.or. mxGetN(prhs(1)) /= n .or. mxGetM(prhs(2)) /= n .or. mxGetN(prhs(2)) /= n) then
|
||||
call mexErrMsgTxt("MJDGGES: first two arguments should be real matrices of the same dimension")
|
||||
call mexErrMsgTxt("MJDGGES: first two arguments should be real dense matrices of the same dimension")
|
||||
end if
|
||||
|
||||
! Set criterium for stable eigenvalues
|
||||
|
|
|
@ -160,6 +160,12 @@ DynamicModelMatlabCaller::eval(int it, double *resid)
|
|||
return; // Avoid manipulating null pointers in plhs, see #1832
|
||||
}
|
||||
|
||||
if (!mxIsDouble(plhs[0]) || mxIsSparse(plhs[0]))
|
||||
{
|
||||
error_msg = "Residuals should be a dense array of double floats";
|
||||
return;
|
||||
}
|
||||
|
||||
if (mxIsComplex(plhs[0]))
|
||||
plhs[0] = cmplxToReal(plhs[0]);
|
||||
|
||||
|
@ -186,6 +192,12 @@ DynamicModelMatlabCaller::eval(int it, double *resid)
|
|||
jacobian_mx = nullptr;
|
||||
}
|
||||
|
||||
if (!mxIsDouble(plhs[0]) || mxIsSparse(plhs[0]))
|
||||
{
|
||||
error_msg = "Jacobian should be a dense array of double floats";
|
||||
return;
|
||||
}
|
||||
|
||||
if (mxIsComplex(plhs[0]))
|
||||
jacobian_mx = cmplxToReal(plhs[0]);
|
||||
else
|
||||
|
@ -196,6 +208,8 @@ DynamicModelMatlabCaller::eval(int it, double *resid)
|
|||
}
|
||||
}
|
||||
|
||||
/* NB: This is a duplicate of DynamicModelMFile::cmplxToReal() in
|
||||
k_order_perturbation MEX */
|
||||
mxArray *
|
||||
DynamicModelMatlabCaller::cmplxToReal(mxArray *cmplx_mx)
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2019 Dynare Team
|
||||
* Copyright © 2019-2022 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
|
@ -87,7 +87,7 @@ class DynamicModelMatlabCaller : public DynamicModelCaller
|
|||
private:
|
||||
std::string basename;
|
||||
mxArray *T_mx, *y_mx, *it_mx, *T_flag_mx, *jacobian_mx, *x_mx, *params_mx, *steady_state_mx;
|
||||
/* Given a complex matrix, returns a real matrix of same size.
|
||||
/* Given a complex dense matrix (of double floats), returns a real dense matrix of same size.
|
||||
Real elements of the original matrix are copied as-is to the new one.
|
||||
Complex elements are replaced by NaNs.
|
||||
Destroys the original matrix. */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2019-2020 Dynare Team
|
||||
* Copyright © 2019-2022 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
|
@ -65,14 +65,16 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
mwIndex maximum_endo_lag = static_cast<mwIndex>(mxGetScalar(maximum_endo_lag_mx));
|
||||
|
||||
const mxArray *dynamic_tmp_nbr_mx = mxGetField(M_mx, 0, "dynamic_tmp_nbr");
|
||||
if (!(dynamic_tmp_nbr_mx && mxIsDouble(dynamic_tmp_nbr_mx) && mxGetNumberOfElements(dynamic_tmp_nbr_mx) >= 2))
|
||||
mexErrMsgTxt("M_.dynamic_tmp_nbr should be a double array of at least 2 elements");
|
||||
if (!(dynamic_tmp_nbr_mx && mxIsDouble(dynamic_tmp_nbr_mx) && mxGetNumberOfElements(dynamic_tmp_nbr_mx) >= 2)
|
||||
|| mxIsComplex(dynamic_tmp_nbr_mx) || mxIsSparse(dynamic_tmp_nbr_mx))
|
||||
mexErrMsgTxt("M_.dynamic_tmp_nbr should be a real dense array of at least 2 elements");
|
||||
size_t ntt = mxGetPr(dynamic_tmp_nbr_mx)[0] + mxGetPr(dynamic_tmp_nbr_mx)[1];
|
||||
|
||||
const mxArray *lead_lag_incidence_mx = mxGetField(M_mx, 0, "lead_lag_incidence");
|
||||
if (!(lead_lag_incidence_mx && mxIsDouble(lead_lag_incidence_mx) && mxGetM(lead_lag_incidence_mx) == static_cast<size_t>(2+maximum_endo_lag)
|
||||
&& mxGetN(lead_lag_incidence_mx) == static_cast<size_t>(ny)))
|
||||
mexErrMsgTxt("M_.lead_lag_incidence should be a double precision matrix with 2+M_.maximum_endo_lag rows and M_.endo_nbr columns");
|
||||
&& mxGetN(lead_lag_incidence_mx) == static_cast<size_t>(ny))
|
||||
|| mxIsComplex(lead_lag_incidence_mx) || mxIsSparse(lead_lag_incidence_mx))
|
||||
mexErrMsgTxt("M_.lead_lag_incidence should be a real dense matrix with 2+M_.maximum_endo_lag rows and M_.endo_nbr columns");
|
||||
const double *lead_lag_incidence = mxGetPr(lead_lag_incidence_mx);
|
||||
|
||||
const mxArray *has_external_function_mx = mxGetField(M_mx, 0, "has_external_function");
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
** Computes Quasi Monte-Carlo sequence.
|
||||
**
|
||||
** Copyright © 2010-2020 Dynare Team
|
||||
** Copyright © 2010-2022 Dynare Team
|
||||
**
|
||||
** This file is part of Dynare (can be used outside Dynare).
|
||||
**
|
||||
|
@ -60,10 +60,13 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
/*
|
||||
** Test the first input argument and assign it to dimension.
|
||||
*/
|
||||
if (!mxIsNumeric(prhs[0]))
|
||||
mexErrMsgTxt("qmc_sequence:: First input (dimension) has to be a positive integer!");
|
||||
if (!(mxIsScalar(prhs[0]) && mxIsNumeric(prhs[0])))
|
||||
mexErrMsgTxt("qmc_sequence:: First input (dimension) has to be a numeric scalar!");
|
||||
|
||||
int dimension = static_cast<int>(mxGetScalar(prhs[0]));
|
||||
if (dimension <= 0)
|
||||
mexErrMsgTxt("qmc_sequence:: First input (dimension) has to be a positive integer!");
|
||||
|
||||
/*
|
||||
** Test the second input argument and assign it to seed.
|
||||
*/
|
||||
|
@ -75,7 +78,7 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
** Test the third input argument and assign it to type (kind of QMC sequence).
|
||||
*/
|
||||
int error_flag_3 = 0;
|
||||
if (!mxIsNumeric(prhs[2]))
|
||||
if (!(mxIsScalar(prhs[2]) && mxIsNumeric(prhs[2])))
|
||||
error_flag_3 = 1;
|
||||
|
||||
int type = static_cast<int>(mxGetScalar(prhs[2]));
|
||||
|
@ -97,30 +100,37 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
/*
|
||||
** Test the optional fourth input argument and assign it to sequence_size.
|
||||
*/
|
||||
if (nrhs > 3 && !mxIsNumeric(prhs[3]))
|
||||
mexErrMsgTxt("qmc_sequence:: Fourth input (qmc sequence size) has to be a positive integer!");
|
||||
if (nrhs > 3 && !(mxIsScalar(prhs[3]) && mxIsNumeric(prhs[3])))
|
||||
mexErrMsgTxt("qmc_sequence:: Fourth input (qmc sequence size) has to be a numeric scalar!");
|
||||
|
||||
int sequence_size;
|
||||
if (nrhs > 3)
|
||||
sequence_size = static_cast<int>(mxGetScalar(prhs[3]));
|
||||
{
|
||||
sequence_size = static_cast<int>(mxGetScalar(prhs[3]));
|
||||
if (sequence_size <= 0)
|
||||
mexErrMsgTxt("qmc_sequence:: Fourth input (qmc sequence size) has to be a positive integer!");
|
||||
}
|
||||
else
|
||||
sequence_size = 1;
|
||||
|
||||
/*
|
||||
** Test the optional fifth input argument and assign it to lower_and_upper_bounds.
|
||||
*/
|
||||
if (nrhs > 4 && type == 0 && mxGetN(prhs[4]) != 2) // Sequence of uniformly distributed numbers in an hypercube
|
||||
mexErrMsgTxt("qmc_sequence:: The fifth input argument must be an array with two columns!");
|
||||
if (nrhs > 4 && type == 0
|
||||
&& !(mxIsDouble(prhs[4]) && !mxIsComplex(prhs[4]) && !mxIsSparse(prhs[4])
|
||||
&& mxGetN(prhs[4]) == 2
|
||||
&& static_cast<int>(mxGetM(prhs[4])) == dimension)) // Sequence of uniformly distributed numbers in an hypercube
|
||||
mexErrMsgTxt("qmc_sequence:: The fifth input argument must be a real dense array with two columns and number of lines equal to dimension (first input argument)!");
|
||||
|
||||
if (nrhs > 4 && type == 0 && static_cast<int>(mxGetM(prhs[4])) != dimension)
|
||||
mexErrMsgTxt("qmc_sequence:: The fourth input argument must be an array with a number of lines equal to dimension (first input argument)!");
|
||||
if (nrhs > 4 && type == 1
|
||||
&& !(mxIsDouble(prhs[4]) && !mxIsComplex(prhs[4]) && !mxIsSparse(prhs[4])
|
||||
&& static_cast<int>(mxGetN(prhs[4])) == dimension
|
||||
&& static_cast<int>(mxGetM(prhs[4])) == dimension)) // Sequence of normally distributed numbers
|
||||
mexErrMsgTxt("qmc_sequence:: The fifth input argument must be a real dense square matrix (whose dimension is given by the first input argument)!");
|
||||
|
||||
if (nrhs > 4 && type == 1 && !(static_cast<int>(mxGetN(prhs[4])) == dimension
|
||||
&& static_cast<int>(mxGetM(prhs[4])) == dimension)) // Sequence of normally distributed numbers
|
||||
mexErrMsgTxt("qmc_sequence:: The fifth input argument must be a squared matrix (whose dimension is given by the first input argument)!");
|
||||
|
||||
if (nrhs > 4 && type == 2 && !(mxGetN(prhs[4]) == 1 && mxGetM(prhs[4]) == 1)) // Sequence of uniformly distributed numbers on a hypershere
|
||||
mexErrMsgTxt("qmc_sequence:: The fifth input argument must be a positive scalar!");
|
||||
if (nrhs > 4 && type == 2
|
||||
&& !(mxIsScalar(prhs[4]) && mxIsNumeric(prhs[4]))) // Sequence of uniformly distributed numbers on a hypershere
|
||||
mexErrMsgTxt("qmc_sequence:: The fifth input argument must be a numeric scalar!");
|
||||
|
||||
const double *lower_bounds = nullptr, *upper_bounds = nullptr;
|
||||
int unit_hypercube_flag = 1;
|
||||
|
@ -141,7 +151,9 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
int unit_radius = 1;
|
||||
if (type == 2 && nrhs > 4)
|
||||
{
|
||||
radius = *mxGetPr(prhs[4]);
|
||||
radius = mxGetScalar(prhs[4]);
|
||||
if (radius <= 0)
|
||||
mexErrMsgTxt("qmc_sequence:: The fifth input argument must be a positive real number!");
|
||||
unit_radius = 0;
|
||||
}
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue