dynare/mex/sources/libkorder/sylv/SylvParams.hh

239 lines
6.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
* Copyright © 2004-2011 Ondra Kamenik
* Copyright © 2019-2023 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 <https://www.gnu.org/licenses/>.
*/
#ifndef SYLV_PARAMS_H
#define SYLV_PARAMS_H
#include <ostream>
#include <string>
#include <vector>
#include <dynmex.h>
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;
}
[[nodiscard]] 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;
}
[[nodiscard]] mxArray* createMatlabArray() const;
};
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;
}
[[nodiscard]] mxArray* createMatlabArray() const;
};
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;
}
[[nodiscard]] mxArray* createMatlabArray() const;
};
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;
}
[[nodiscard]] mxArray* createMatlabArray() const;
};
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 CV·F·V⁻¹
DoubleParamItem f_errI; // norm ∞ of diagonalization abs. error CV·F·V⁻¹
DoubleParamItem viv_err1; // norm 1 of error IV·V⁻¹
DoubleParamItem viv_errI; // norm ∞ of error IV·V⁻¹
DoubleParamItem ivv_err1; // norm 1 of error IV⁻¹·V
DoubleParamItem ivv_errI; // norm ∞ of error IV⁻¹·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·XB·X·⊗ⁱCD
DoubleParamItem mat_errI; // rel. matrix ∞ norm of A·XB·X·⊗ⁱCD
DoubleParamItem mat_errF; // rel. matrix Frob. norm of A·XB·X·⊗ⁱCD
DoubleParamItem vec_err1; // rel. vector 1 norm of A·XB·X·⊗ⁱCD
DoubleParamItem vec_errI; // rel. vector ∞ norm of A·XB·X·⊗ⁱCD
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;
[[nodiscard]] std::vector<const char*> getArrayNames() const;
[[nodiscard]] mxArray* createStructArray() const;
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 */