2019-06-19 14:34:30 +02:00
|
|
|
|
/*
|
|
|
|
|
* Copyright © 2004-2011 Ondra Kamenik
|
2023-12-05 15:44:23 +01:00
|
|
|
|
* Copyright © 2019-2023 Dynare Team
|
2019-06-19 14:34:30 +02:00
|
|
|
|
*
|
|
|
|
|
* 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
|
2021-06-09 17:33:48 +02:00
|
|
|
|
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
2019-06-19 14:34:30 +02:00
|
|
|
|
*/
|
2009-09-08 15:55:19 +02:00
|
|
|
|
|
|
|
|
|
#ifndef SYLV_PARAMS_H
|
|
|
|
|
#define SYLV_PARAMS_H
|
|
|
|
|
|
2019-01-16 17:52:16 +01:00
|
|
|
|
#include <ostream>
|
2023-11-29 19:00:21 +01:00
|
|
|
|
#include <string>
|
2023-12-06 15:34:02 +01:00
|
|
|
|
#include <vector>
|
2009-09-08 15:55:19 +02:00
|
|
|
|
|
2023-12-07 17:56:36 +01:00
|
|
|
|
#include <dynmex.h>
|
2009-09-08 15:55:19 +02:00
|
|
|
|
|
2023-11-29 19:00:21 +01:00
|
|
|
|
enum class status
|
|
|
|
|
{
|
|
|
|
|
def,
|
|
|
|
|
changed,
|
|
|
|
|
undef
|
|
|
|
|
};
|
2009-09-08 15:55:19 +02:00
|
|
|
|
|
2019-12-20 14:36:20 +01:00
|
|
|
|
template<class _Type>
|
2017-05-16 16:30:27 +02:00
|
|
|
|
struct ParamItem
|
|
|
|
|
{
|
2009-09-08 15:55:19 +02:00
|
|
|
|
protected:
|
2019-01-09 17:21:14 +01:00
|
|
|
|
using _Self = ParamItem<_Type>;
|
2017-05-16 16:30:27 +02:00
|
|
|
|
status s;
|
|
|
|
|
_Type value;
|
2023-11-29 19:00:21 +01:00
|
|
|
|
|
2009-09-08 15:55:19 +02:00
|
|
|
|
public:
|
2017-05-16 16:30:27 +02:00
|
|
|
|
ParamItem()
|
|
|
|
|
{
|
2019-01-25 15:27:20 +01:00
|
|
|
|
s = status::undef;
|
2017-05-16 16:30:27 +02:00
|
|
|
|
}
|
|
|
|
|
ParamItem(_Type val)
|
|
|
|
|
{
|
2019-01-25 15:27:20 +01:00
|
|
|
|
value = val;
|
|
|
|
|
s = status::def;
|
2017-05-16 16:30:27 +02:00
|
|
|
|
}
|
2023-11-29 19:00:21 +01:00
|
|
|
|
ParamItem(const _Self& item) = default;
|
|
|
|
|
_Self& operator=(const _Self& item) = default;
|
|
|
|
|
_Self&
|
|
|
|
|
operator=(const _Type& val)
|
2017-05-16 16:30:27 +02:00
|
|
|
|
{
|
2019-01-25 15:27:20 +01:00
|
|
|
|
value = val;
|
|
|
|
|
s = status::changed;
|
|
|
|
|
return *this;
|
2017-05-16 16:30:27 +02:00
|
|
|
|
}
|
|
|
|
|
_Type
|
|
|
|
|
operator*() const
|
|
|
|
|
{
|
|
|
|
|
return value;
|
|
|
|
|
}
|
2023-12-05 15:44:23 +01:00
|
|
|
|
[[nodiscard]] status
|
2017-05-16 16:30:27 +02:00
|
|
|
|
getStatus() const
|
|
|
|
|
{
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
void
|
2023-11-29 19:00:21 +01:00
|
|
|
|
print(std::ostream& out, const std::string& prefix, const std::string& str) const
|
2017-05-16 16:30:27 +02:00
|
|
|
|
{
|
2019-01-25 15:27:20 +01:00
|
|
|
|
if (s == status::undef)
|
2017-05-16 16:30:27 +02:00
|
|
|
|
return;
|
2019-01-16 17:52:16 +01:00
|
|
|
|
out << prefix << str << "= " << value;
|
2019-01-25 15:27:20 +01:00
|
|
|
|
if (s == status::def)
|
2019-01-16 17:52:16 +01:00
|
|
|
|
out << " <default>";
|
|
|
|
|
out << std::endl;
|
2017-05-16 16:30:27 +02:00
|
|
|
|
}
|
2009-09-08 15:55:19 +02:00
|
|
|
|
};
|
|
|
|
|
|
2017-05-16 16:30:27 +02:00
|
|
|
|
class SylvParams
|
|
|
|
|
{
|
2009-09-08 15:55:19 +02:00
|
|
|
|
public:
|
2023-11-29 19:00:21 +01:00
|
|
|
|
enum class solve_method
|
|
|
|
|
{
|
|
|
|
|
iter,
|
|
|
|
|
recurse
|
|
|
|
|
};
|
2009-09-08 15:55:19 +02:00
|
|
|
|
|
|
|
|
|
protected:
|
2017-05-16 16:30:27 +02:00
|
|
|
|
class DoubleParamItem : public ParamItem<double>
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
DoubleParamItem() : ParamItem<double>()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
DoubleParamItem(double val) : ParamItem<double>(val)
|
|
|
|
|
{
|
|
|
|
|
}
|
2023-11-29 19:00:21 +01:00
|
|
|
|
DoubleParamItem(const DoubleParamItem& item) = default;
|
|
|
|
|
DoubleParamItem&
|
|
|
|
|
operator=(const double& val)
|
2017-05-16 16:30:27 +02:00
|
|
|
|
{
|
2023-11-29 19:00:21 +01:00
|
|
|
|
ParamItem<double>::operator=(val);
|
|
|
|
|
return *this;
|
2017-05-16 16:30:27 +02:00
|
|
|
|
}
|
2023-12-05 15:44:23 +01:00
|
|
|
|
[[nodiscard]] mxArray* createMatlabArray() const;
|
2017-05-16 16:30:27 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class IntParamItem : public ParamItem<int>
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
IntParamItem() : ParamItem<int>()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
IntParamItem(int val) : ParamItem<int>(val)
|
|
|
|
|
{
|
|
|
|
|
}
|
2023-11-29 19:00:21 +01:00
|
|
|
|
IntParamItem(const IntParamItem& item) = default;
|
|
|
|
|
IntParamItem&
|
|
|
|
|
operator=(const int& val)
|
2017-05-16 16:30:27 +02:00
|
|
|
|
{
|
2023-11-29 19:00:21 +01:00
|
|
|
|
ParamItem<int>::operator=(val);
|
|
|
|
|
return *this;
|
2017-05-16 16:30:27 +02:00
|
|
|
|
}
|
2023-12-05 15:44:23 +01:00
|
|
|
|
[[nodiscard]] mxArray* createMatlabArray() const;
|
2017-05-16 16:30:27 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class BoolParamItem : public ParamItem<bool>
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
BoolParamItem() : ParamItem<bool>()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
BoolParamItem(bool val) : ParamItem<bool>(val)
|
|
|
|
|
{
|
|
|
|
|
}
|
2023-11-29 19:00:21 +01:00
|
|
|
|
BoolParamItem(const BoolParamItem& item) = default;
|
|
|
|
|
BoolParamItem&
|
|
|
|
|
operator=(const bool& val)
|
2017-05-16 16:30:27 +02:00
|
|
|
|
{
|
2023-11-29 19:00:21 +01:00
|
|
|
|
ParamItem<bool>::operator=(val);
|
|
|
|
|
return *this;
|
2017-05-16 16:30:27 +02:00
|
|
|
|
}
|
2023-12-05 15:44:23 +01:00
|
|
|
|
[[nodiscard]] mxArray* createMatlabArray() const;
|
2017-05-16 16:30:27 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class MethodParamItem : public ParamItem<solve_method>
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
MethodParamItem() : ParamItem<solve_method>()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
MethodParamItem(solve_method val) : ParamItem<solve_method>(val)
|
|
|
|
|
{
|
|
|
|
|
}
|
2023-11-29 19:00:21 +01:00
|
|
|
|
MethodParamItem(const MethodParamItem& item) = default;
|
2019-01-16 17:52:16 +01:00
|
|
|
|
MethodParamItem
|
2023-11-29 19:00:21 +01:00
|
|
|
|
operator=(const solve_method& val)
|
2017-05-16 16:30:27 +02:00
|
|
|
|
{
|
2023-11-29 19:00:21 +01:00
|
|
|
|
ParamItem<solve_method>::operator=(val);
|
|
|
|
|
return *this;
|
2017-05-16 16:30:27 +02:00
|
|
|
|
}
|
2023-12-05 15:44:23 +01:00
|
|
|
|
[[nodiscard]] mxArray* createMatlabArray() const;
|
2017-05-16 16:30:27 +02:00
|
|
|
|
};
|
2009-09-08 15:55:19 +02:00
|
|
|
|
|
|
|
|
|
public:
|
2017-05-16 16:30:27 +02:00
|
|
|
|
// input parameters
|
2023-11-29 19:00:21 +01:00
|
|
|
|
MethodParamItem method; // method of solution: iter/recurse
|
2017-05-16 16:30:27 +02:00
|
|
|
|
DoubleParamItem convergence_tol; // norm for what we consider converged
|
2023-11-29 19:00:21 +01:00
|
|
|
|
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
|
2017-05-16 16:30:27 +02:00
|
|
|
|
// output parameters
|
2023-11-29 19:00:21 +01:00
|
|
|
|
BoolParamItem converged; // true if converged
|
2017-05-16 16:30:27 +02:00
|
|
|
|
DoubleParamItem iter_last_norm; // norm of the last iteration
|
2023-11-29 19:00:21 +01:00
|
|
|
|
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
|
2017-05-16 16:30:27 +02:00
|
|
|
|
|
2023-11-29 19:00:21 +01:00
|
|
|
|
SylvParams(bool wc = false) :
|
2023-11-30 14:37:05 +01:00
|
|
|
|
method(solve_method::recurse),
|
|
|
|
|
convergence_tol(1.e-30),
|
|
|
|
|
max_num_iter(15),
|
|
|
|
|
bs_norm(1.3),
|
2023-11-29 19:00:21 +01:00
|
|
|
|
want_check(wc)
|
2017-05-16 16:30:27 +02:00
|
|
|
|
{
|
|
|
|
|
}
|
2023-11-29 19:00:21 +01:00
|
|
|
|
SylvParams(const SylvParams& p) = default;
|
|
|
|
|
SylvParams& operator=(const SylvParams& p) = default;
|
2019-01-16 17:52:16 +01:00
|
|
|
|
~SylvParams() = default;
|
2023-11-29 19:00:21 +01:00
|
|
|
|
void print(const std::string& prefix) const;
|
|
|
|
|
void print(std::ostream& fdesc, const std::string& prefix) const;
|
2023-12-06 15:34:02 +01:00
|
|
|
|
[[nodiscard]] std::vector<const char*> getArrayNames() const;
|
2023-12-05 15:44:23 +01:00
|
|
|
|
[[nodiscard]] mxArray* createStructArray() const;
|
2023-12-07 17:56:36 +01:00
|
|
|
|
|
2009-09-08 15:55:19 +02:00
|
|
|
|
private:
|
2023-11-29 19:00:21 +01:00
|
|
|
|
void copy(const SylvParams& p);
|
2009-09-08 15:55:19 +02:00
|
|
|
|
};
|
|
|
|
|
|
2023-11-29 19:00:21 +01:00
|
|
|
|
inline std::ostream&
|
|
|
|
|
operator<<(std::ostream& out, SylvParams::solve_method m)
|
2019-01-18 16:08:19 +01:00
|
|
|
|
{
|
|
|
|
|
switch (m)
|
|
|
|
|
{
|
2019-01-25 15:27:20 +01:00
|
|
|
|
case SylvParams::solve_method::iter:
|
2019-01-18 16:08:19 +01:00
|
|
|
|
out << "iterative";
|
|
|
|
|
break;
|
2019-01-25 15:27:20 +01:00
|
|
|
|
case SylvParams::solve_method::recurse:
|
2019-01-18 16:08:19 +01:00
|
|
|
|
out << "recurse (a.k.a. triangular)";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return out;
|
|
|
|
|
}
|
|
|
|
|
|
2009-09-08 15:55:19 +02:00
|
|
|
|
#endif /* SYLV_PARAMS_H */
|