dynare/dynare++/sylv/cc/TriangularSylvester.hh

134 lines
5.8 KiB
C++
Raw Normal View History

/*
* 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 TRIANGULAR_SYLVESTER_H
#define TRIANGULAR_SYLVESTER_H
#include "SylvesterSolver.hh"
#include "KronVector.hh"
#include "QuasiTriangular.hh"
#include "QuasiTriangularZero.hh"
#include "SimilarityDecomp.hh"
#include <memory>
2017-05-16 16:30:27 +02:00
class TriangularSylvester : public SylvesterSolver
{
const std::unique_ptr<const QuasiTriangular> matrixKK;
const std::unique_ptr<const QuasiTriangular> matrixFF;
public:
2017-05-16 16:30:27 +02:00
TriangularSylvester(const QuasiTriangular &k, const QuasiTriangular &f);
TriangularSylvester(const SchurDecompZero &kdecomp, const SchurDecomp &fdecomp);
TriangularSylvester(const SchurDecompZero &kdecomp, const SimilarityDecomp &fdecomp);
2019-12-20 14:36:20 +01:00
~TriangularSylvester() override = default;
2017-05-16 16:30:27 +02:00
void print() const;
void solve(SylvParams &pars, KronVector &d) const override;
2017-05-16 16:30:27 +02:00
void solvi(double r, KronVector &d, double &eig_min) const;
void solvii(double alpha, double beta1, double beta2,
KronVector &d1, KronVector &d2,
double &eig_min) const;
void solviip(double alpha, double betas,
KronVector &d, double &eig_min) const;
/* Computes:
x d α β d
= + FFK·
x d β α d
2017-05-16 16:30:27 +02:00
*/
void linEval(double alpha, double beta1, double beta2,
KronVector &x1, KronVector &x2,
const ConstKronVector &d1, const ConstKronVector &d2) const;
void
linEval(double alpha, double beta1, double beta2,
KronVector &x1, KronVector &x2,
const KronVector &d1, const KronVector &d2) const
{
linEval(alpha, beta1, beta2, x1, x2,
ConstKronVector(d1), ConstKronVector(d2));
}
/* Computes:
x d γ δ d γ δ² d
= +2α FFK· +(α²+β) F²F²K²·
x d δ γ d δ γ d
2017-05-16 16:30:27 +02:00
*/
void quaEval(double alpha, double betas,
double gamma, double delta1, double delta2,
KronVector &x1, KronVector &x2,
const ConstKronVector &d1, const ConstKronVector &d2) const;
void
quaEval(double alpha, double betas,
double gamma, double delta1, double delta2,
KronVector &x1, KronVector &x2,
const KronVector &d1, const KronVector &d2) const
{
quaEval(alpha, betas, gamma, delta1, delta2, x1, x2,
ConstKronVector(d1), ConstKronVector(d2));
}
private:
/* Returns square of size of minimal eigenvalue of the system solved,
2017-05-16 16:30:27 +02:00
now obsolete */
double getEigSep(int depth) const;
// Recursively calculates kronecker product of complex vectors (used in getEigSep)
2017-05-16 16:30:27 +02:00
static void multEigVector(KronVector &eig, const Vector &feig, const Vector &keig);
using const_diag_iter = QuasiTriangular::const_diag_iter;
using const_row_iter = QuasiTriangular::const_row_iter;
// Called from solvi
2017-05-16 16:30:27 +02:00
void solviRealAndEliminate(double r, const_diag_iter di,
KronVector &d, double &eig_min) const;
void solviComplexAndEliminate(double r, const_diag_iter di,
KronVector &d, double &eig_min) const;
// Called from solviip
2017-05-16 16:30:27 +02:00
void solviipRealAndEliminate(double alpha, double betas,
const_diag_iter di, const_diag_iter dsi,
KronVector &d, double &eig_min) const;
void solviipComplexAndEliminate(double alpha, double betas,
const_diag_iter di, const_diag_iter dsi,
KronVector &d, double &eig_min) const;
// Eliminations
2017-05-16 16:30:27 +02:00
void solviEliminateReal(const_diag_iter di, KronVector &d,
const KronVector &y, double divisor) const;
void solviEliminateComplex(const_diag_iter di, KronVector &d,
const KronVector &y1, const KronVector &y2,
double divisor) const;
void solviipEliminateReal(const_diag_iter di, const_diag_iter dsi,
KronVector &d,
const KronVector &y1, const KronVector &y2,
double divisor, double divisor2) const;
void solviipEliminateComplex(const_diag_iter di, const_diag_iter dsi,
KronVector &d,
const KronVector &y1, const KronVector &y11,
const KronVector &y2, const KronVector &y22,
double divisor) const;
// Lemma 2
2017-05-16 16:30:27 +02:00
void solviipComplex(double alpha, double betas, double gamma,
double delta1, double delta2,
KronVector &d1, KronVector &d2,
double &eig_min) const;
// Norms for what we consider zero on diagonal of F
static constexpr double diag_zero = 1.e-15;
static constexpr double diag_zero_sq = diag_zero*diag_zero;
};
#endif /* TRIANGULAR_SYLVESTER_H */