232 lines
6.4 KiB
C++
232 lines
6.4 KiB
C++
/*
|
||
* 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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#ifndef SYLV_PARAMS_H
|
||
#define SYLV_PARAMS_H
|
||
|
||
#include <string>
|
||
#include <ostream>
|
||
|
||
#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
|
||
# include <dynmex.h>
|
||
#endif
|
||
|
||
enum class status { def, changed, undef };
|
||
|
||
template<class _Type>
|
||
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 << " <default>";
|
||
out << std::endl;
|
||
}
|
||
};
|
||
|
||
class SylvParams
|
||
{
|
||
public:
|
||
enum class solve_method { iter, recurse };
|
||
|
||
protected:
|
||
class DoubleParamItem : public ParamItem<double>
|
||
{
|
||
public:
|
||
DoubleParamItem() : ParamItem<double>()
|
||
{
|
||
}
|
||
DoubleParamItem(double val) : ParamItem<double>(val)
|
||
{
|
||
}
|
||
DoubleParamItem(const DoubleParamItem &item) = default;
|
||
DoubleParamItem &
|
||
operator=(const double &val)
|
||
{
|
||
ParamItem<double>::operator=(val); return *this;
|
||
}
|
||
#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
|
||
mxArray *createMatlabArray() const;
|
||
#endif
|
||
};
|
||
|
||
class IntParamItem : public ParamItem<int>
|
||
{
|
||
public:
|
||
IntParamItem() : ParamItem<int>()
|
||
{
|
||
}
|
||
IntParamItem(int val) : ParamItem<int>(val)
|
||
{
|
||
}
|
||
IntParamItem(const IntParamItem &item) = default;
|
||
IntParamItem &
|
||
operator=(const int &val)
|
||
{
|
||
ParamItem<int>::operator=(val); return *this;
|
||
}
|
||
#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
|
||
mxArray *createMatlabArray() const;
|
||
#endif
|
||
};
|
||
|
||
class BoolParamItem : public ParamItem<bool>
|
||
{
|
||
public:
|
||
BoolParamItem() : ParamItem<bool>()
|
||
{
|
||
}
|
||
BoolParamItem(bool val) : ParamItem<bool>(val)
|
||
{
|
||
}
|
||
BoolParamItem(const BoolParamItem &item) = default;
|
||
BoolParamItem &
|
||
operator=(const bool &val)
|
||
{
|
||
ParamItem<bool>::operator=(val); return *this;
|
||
}
|
||
#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
|
||
mxArray *createMatlabArray() const;
|
||
#endif
|
||
};
|
||
|
||
class MethodParamItem : public ParamItem<solve_method>
|
||
{
|
||
public:
|
||
MethodParamItem() : ParamItem<solve_method>()
|
||
{
|
||
}
|
||
MethodParamItem(solve_method val) : ParamItem<solve_method>(val)
|
||
{
|
||
}
|
||
MethodParamItem(const MethodParamItem &item) = default;
|
||
MethodParamItem
|
||
operator=(const solve_method &val)
|
||
{
|
||
ParamItem<solve_method>::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 */
|