minres.h
Go to the documentation of this file.
# ifndef _RHEOLEF_MINRES_H
# define _RHEOLEF_MINRES_H
//
// This file is part of Rheolef.
//
// Copyright (C) 2000-2009 Pierre Saramito <Pierre.Saramito@imag.fr>
//
// Rheolef 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 2 of the License, or
// (at your option) any later version.
//
// Rheolef 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 Rheolef; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// =========================================================================
// AUTHOR: Pierre.Saramito@imag.fr
// DATE: 22 april 2009
namespace rheolef {
} // namespace rheolef
#include "rheolef/solver_option.h"
namespace rheolef {
// [verbatim_minres_synopsis]
template <class Matrix, class Vector, class Preconditioner>
int minres (const Matrix &A, Vector &x, const Vector &Mb, const Preconditioner &M,
const solver_option& sopt = solver_option())
// [verbatim_minres_synopsis]
// [verbatim_minres]
{
// Size &max_iter, Real &tol, odiststream *p_derr = 0
typedef typename Vector::size_type Size;
typedef typename Vector::float_type Real;
std::string label = (sopt.label != "" ? sopt.label : "minres");
Vector b = M.solve(Mb);
Real norm_b = sqrt(fabs(dot(Mb,b)));
if (sopt.absolute_stopping || norm_b == Real(0.)) norm_b = 1;
Vector Mr = Mb - A*x;
Vector z = M.solve(Mr);
Real beta2 = dot(Mr, z);
Real norm_r = sqrt(fabs(beta2));
sopt.residue = norm_r/norm_b;
if (sopt.p_err) (*sopt.p_err) << "[" << label << "] #iteration residue" << std::endl
<< "[" << label << "] 0 " << sopt.residue << std::endl;
if (beta2 < 0 || sopt.residue <= sopt.tol) {
dis_warning_macro ("beta2 = " << beta2 << " < 0: stop");
return 0;
}
Real beta = sqrt(beta2);
Real eta = beta;
Vector Mv = Mr/beta;
Vector u = z/beta;
Real c_old = 1.;
Real s_old = 0.;
Real c = 1.;
Real s = 0.;
Vector u_old (x.ownership(), 0.);
Vector Mv_old (x.ownership(), 0.);
Vector w (x.ownership(), 0.);
Vector w_old (x.ownership(), 0.);
Vector w_old2 (x.ownership(), 0.);
for (sopt.n_iter = 1; sopt.n_iter <= sopt.max_iter; sopt.n_iter++) {
// Lanczos
Mr = A*u;
z = M.solve(Mr);
Real alpha = dot(Mr, u);
Mr = Mr - alpha*Mv - beta*Mv_old;
z = z - alpha*u - beta*u_old;
beta2 = dot(Mr, z);
if (beta2 < 0) {
dis_warning_macro ("minres: machine precision problem");
sopt.residue = norm_r/norm_b;
return 2;
}
Real beta_old = beta;
beta = sqrt(beta2);
// QR factorisation
Real c_old2 = c_old;
Real s_old2 = s_old;
c_old = c;
s_old = s;
Real rho0 = c_old*alpha - c_old2*s_old*beta_old;
Real rho2 = s_old*alpha + c_old2*c_old*beta_old;
Real rho1 = sqrt(sqr(rho0) + sqr(beta));
Real rho3 = s_old2 * beta_old;
// Givens rotation
c = rho0 / rho1;
s = beta / rho1;
// update
w_old2 = w_old;
w_old = w;
w = (u - rho2*w_old - rho3*w_old2)/rho1;
x += c*eta*w;
eta = -s*eta;
Mv_old = Mv;
u_old = u;
Mv = Mr/beta;
u = z/beta;
// check residue
norm_r *= s;
sopt.residue = norm_r/norm_b;
if (sopt.p_err) (*sopt.p_err) << "[" << label << "] " << sopt.n_iter << " " << sopt.residue << std::endl;
if (sopt.residue <= sopt.tol) return 0;
}
return 1;
}
// [verbatim_minres]
}// namespace rheolef
# endif // _RHEOLEF_MINRES_H
rheolef::solver_option
see the solver_option page for the full documentation
Definition: solver_option.h:155
dis_warning_macro
#define dis_warning_macro(message)
Definition: dis_macros.h:66
bdf::alpha
Float alpha[pmax+1][pmax+1]
Definition: bdf.icc:28
mkgeo_ball.b
int b
Definition: mkgeo_ball.sh:152
mkgeo_ball.c
int c
Definition: mkgeo_ball.sh:153
rheolef
This file is part of Rheolef.
Definition: compiler_eigen.h:37
rheolef::dot
rheolef::std enable_if ::type dot const Expr1 expr1, const Expr2 expr2 dot(const Expr1 &expr1, const Expr2 &expr2)
dot(x,y): see the expression page for the full documentation
Definition: vec_expr_v2.h:415
rheolef::minres
int minres(const Matrix &A, Vector &x, const Vector &Mb, const Preconditioner &M, const solver_option &sopt=solver_option())
Definition: minres.h:100
rk::beta
Float beta[][pmax+1]
Definition: runge_kutta_semiimplicit.icc:60
eta
Definition: eta.h:25
rheolef::Vector
Definition: Vector.h:176
rheolef::Vector::size_type
DATA::size_type size_type
Definition: Vector.h:188
u
Definition: leveque.h:25
u
Float u(const point &x)
Definition: transmission_error.cc:26
M
Expr1::memory_type M
Definition: vec_expr_v2.h:416