25#include <ql/math/functional.hpp>
26#include <ql/math/matrixutilities/gmres.hpp>
27#include <ql/math/matrixutilities/qrdecomposition.hpp>
34 : A_(
std::move(A)), M_(
std::move(preConditioner)), maxIter_(maxIter), relTol_(relTol) {
36 QL_REQUIRE(
maxIter_ > 0,
"maxIter must be greater than zero");
42 QL_REQUIRE(result.
errors.back() <
relTol_,
"could not converge");
52 std::list<Real> errors = result.
errors;
57 errors.end(), result.
errors.begin(), result.
errors.end());
60 QL_REQUIRE(errors.back() <
relTol_,
"could not converge");
69 GMRESResult result = { std::list<Real>(1, 0.0), b };
78 GMRESResult result = { std::list<Real>(1, g/bn), x };
82 std::vector<Array> v(1, r/g);
88 std::list<Real> errors(1, g/bn);
94 for (
Size i=0; i <= j; ++i) {
104 v.push_back(w / h[j+1][j]);
106 for (
Size i=0; i < j; ++i) {
107 const Real h0 = c[i]*h[i][j] + s[i]*h[i+1][j];
108 const Real h1 =-s[i]*h[i][j] + c[i]*h[i+1][j];
125 errors.push_back(std::fabs(z[j+1]/bn));
128 const Size k = v.size()-1;
131 y[k-1]=z[k-1]/h[k-1][k-1];
133 for (
Integer i=k-2; i >= 0; --i) {
134 y[i] = (z[i] - std::inner_product(
135 h[i].begin()+i+1, h[i].begin()+k, y.begin()+i+1,
Real(0.0)))/h[i][i];
138 Array xm = std::inner_product(
139 v.begin(), v.begin()+k, y.begin(),
Array(x.
size(),
Real(0.0)));
141 xm = x + (!
M_ ? xm :
M_(xm));
1-D array used in linear algebra.
bool empty() const
whether the array is empty
Size size() const
dimension of the array
GMRESResult solveWithRestart(Size restart, const Array &b, const Array &x0=Array()) const
GMRESResult solve(const Array &b, const Array &x0=Array()) const
GMRES(MatrixMult A, Size maxIter, Real relTol, MatrixMult preConditioner=MatrixMult())
GMRESResult solveImpl(const Array &b, const Array &x0) const
ext::function< Array(const Array &)> MatrixMult
QL_INTEGER Integer
integer number
std::size_t Size
size of a container
Real Norm2(const Array &v)
Real DotProduct(const Array &v1, const Array &v2)