/* * Copyright © 2004-2011 Ondra Kamenik * 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 . */ #ifndef SYLV_PARAMS_H #define SYLV_PARAMS_H #include #include #if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE) # include #endif enum class status { def, changed, undef }; template struct ParamItem { protected: using _Self = ParamItem<_Type>; status s; _Type value; public: ParamItem() { s = status::undef; } ParamItem(_Type val) { value = val; s = status::def; } ParamItem(const _Self &item) = default; _Self &operator=(const _Self &item) = default; _Self & operator=(const _Type &val) { value = val; s = status::changed; return *this; } _Type operator*() const { return value; } status getStatus() const { return s; } void print(std::ostream &out, const std::string &prefix, const std::string &str) const { if (s == status::undef) return; out << prefix << str << "= " << value; if (s == status::def) out << " "; out << std::endl; } }; class SylvParams { public: enum class solve_method { iter, recurse }; protected: class DoubleParamItem : public ParamItem { public: DoubleParamItem() : ParamItem() { } DoubleParamItem(double val) : ParamItem(val) { } DoubleParamItem(const DoubleParamItem &item) = default; DoubleParamItem & operator=(const double &val) { ParamItem::operator=(val); return *this; } #if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE) mxArray *createMatlabArray() const; #endif }; class IntParamItem : public ParamItem { public: IntParamItem() : ParamItem() { } IntParamItem(int val) : ParamItem(val) { } IntParamItem(const IntParamItem &item) = default; IntParamItem & operator=(const int &val) { ParamItem::operator=(val); return *this; } #if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE) mxArray *createMatlabArray() const; #endif }; class BoolParamItem : public ParamItem { public: BoolParamItem() : ParamItem() { } BoolParamItem(bool val) : ParamItem(val) { } BoolParamItem(const BoolParamItem &item) = default; BoolParamItem & operator=(const bool &val) { ParamItem::operator=(val); return *this; } #if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE) mxArray *createMatlabArray() const; #endif }; class MethodParamItem : public ParamItem { public: MethodParamItem() : ParamItem() { } MethodParamItem(solve_method val) : ParamItem(val) { } MethodParamItem(const MethodParamItem &item) = default; MethodParamItem operator=(const solve_method &val) { ParamItem::operator=(val); return *this; } #if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE) mxArray *createMatlabArray() const; #endif }; public: // input parameters MethodParamItem method; // method of solution: iter/recurse DoubleParamItem convergence_tol; // norm for what we consider converged IntParamItem max_num_iter; // max number of iterations DoubleParamItem bs_norm; // Bavely Stewart log₁₀ of norm for diagonalization BoolParamItem want_check; // true => allocate extra space for checks // output parameters BoolParamItem converged; // true if converged DoubleParamItem iter_last_norm; // norm of the last iteration IntParamItem num_iter; // number of iterations DoubleParamItem f_err1; // norm 1 of diagonalization abs. error C−V·F·V⁻¹ DoubleParamItem f_errI; // norm ∞ of diagonalization abs. error C−V·F·V⁻¹ DoubleParamItem viv_err1; // norm 1 of error I−V·V⁻¹ DoubleParamItem viv_errI; // norm ∞ of error I−V·V⁻¹ DoubleParamItem ivv_err1; // norm 1 of error I−V⁻¹·V DoubleParamItem ivv_errI; // norm ∞ of error I−V⁻¹·V IntParamItem f_blocks; // number of diagonal blocks of F IntParamItem f_largest; // size of largest diagonal block in F IntParamItem f_zeros; // number of off diagonal zeros in F IntParamItem f_offdiag; // number of all off diagonal elements in F DoubleParamItem rcondA1; // reciprocal cond 1 number of A DoubleParamItem rcondAI; // reciprocal cond ∞ number of A DoubleParamItem eig_min; // minimum eigenvalue of the solved system DoubleParamItem mat_err1; // rel. matrix 1 norm of A·X−B·X·⊗ⁱC−D DoubleParamItem mat_errI; // rel. matrix ∞ norm of A·X−B·X·⊗ⁱC−D DoubleParamItem mat_errF; // rel. matrix Frob. norm of A·X−B·X·⊗ⁱC−D DoubleParamItem vec_err1; // rel. vector 1 norm of A·X−B·X·⊗ⁱC−D DoubleParamItem vec_errI; // rel. vector ∞ norm of A·X−B·X·⊗ⁱC−D DoubleParamItem cpu_time; // time of the job in CPU seconds SylvParams(bool wc = false) : method(solve_method::recurse), convergence_tol(1.e-30), max_num_iter(15), bs_norm(1.3), want_check(wc) { } SylvParams(const SylvParams &p) = default; SylvParams &operator=(const SylvParams &p) = default; ~SylvParams() = default; void print(const std::string &prefix) const; void print(std::ostream &fdesc, const std::string &prefix) const; void setArrayNames(int &num, const char **names) const; #if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE) mxArray *createStructArray() const; #endif private: void copy(const SylvParams &p); }; inline std::ostream & operator<<(std::ostream &out, SylvParams::solve_method m) { switch (m) { case SylvParams::solve_method::iter: out << "iterative"; break; case SylvParams::solve_method::recurse: out << "recurse (a.k.a. triangular)"; break; } return out; } #endif /* SYLV_PARAMS_H */