/* * Copyright © 2019 Dynare Team * * 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 . */ #include #include #include class DynamicModelCaller { public: const bool compute_jacobian; // Used to store error messages (as exceptions cannot cross the OpenMP boundary) static std::string error_msg; DynamicModelCaller(bool compute_jacobian_arg) : compute_jacobian{compute_jacobian_arg} {}; virtual ~DynamicModelCaller() = default; virtual double &y(size_t i) const = 0; virtual double jacobian(size_t i) const = 0; virtual void eval(int it, double *resid) = 0; }; class DynamicModelDllCaller : public DynamicModelCaller { private: static void *dynamic_mex; using dynamic_tt_fct = void (*)(const double *y, const double *x, int nb_row_x, const double *params, const double *steady_state, int it_, double *T); using dynamic_deriv_fct = void (*) (const double *y, const double *x, int nb_row_x, const double *params, const double *steady_state, int it_, const double *T, double *deriv); static dynamic_tt_fct residual_tt_fct, g1_tt_fct; static dynamic_deriv_fct residual_fct, g1_fct; size_t nb_row_x; const double *x, *params, *steady_state; std::unique_ptr tt, y_p, jacobian_p; public: DynamicModelDllCaller(size_t ntt, mwIndex nx, mwIndex ny, size_t ndynvars, const double *x_arg, size_t nb_row_x_arg, const double *params_arg, const double *steady_state_arg, bool compute_jacobian_arg); virtual ~DynamicModelDllCaller() = default; double &y(size_t i) const override { return y_p[i]; }; double jacobian(size_t i) const override { return jacobian_p[i]; }; void eval(int it, double *resid) override; static void load_dll(const std::string &basename); static void unload_dll(); }; 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. Real elements of the original matrix are copied as-is to the new one. Complex elements are replaced by NaNs. Destroys the original matrix. */ static mxArray *cmplxToReal(mxArray *m); public: DynamicModelMatlabCaller(std::string basename_arg, size_t ntt, size_t ndynvars, const mxArray *x_mx_arg, const mxArray *params_mx_arg, const mxArray *steady_state_mx_arg, bool compute_jacobian_arg); ~DynamicModelMatlabCaller() override; double &y(size_t i) const override { return mxGetPr(y_mx)[i]; }; double jacobian(size_t i) const override { return jacobian_mx ? mxGetPr(jacobian_mx)[i] : std::numeric_limits::quiet_NaN(); }; void eval(int it, double *resid) override; class Exception { public: const std::string msg; Exception(std::string msg_arg) : msg{std::move(msg_arg)} {}; }; };