Lsqr.cxx
1 // Copyright (C) 2003-2009 Marc DuruflĂ©
2 //
3 // This file is part of the linear-algebra library Seldon,
4 // http://seldon.sourceforge.net/.
5 //
6 // Seldon is free software; you can redistribute it and/or modify it under the
7 // terms of the GNU Lesser General Public License as published by the Free
8 // Software Foundation; either version 2.1 of the License, or (at your option)
9 // any later version.
10 //
11 // Seldon is distributed in the hope that it will be useful, but WITHOUT ANY
12 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
14 // more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public License
17 // along with Seldon. If not, see http://www.gnu.org/licenses/.
18 
19 
20 #ifndef SELDON_FILE_ITERATIVE_LSQR_CXX
21 
22 namespace Seldon
23 {
24 
26 
40 #ifdef SELDON_WITH_VIRTUAL
41  template<class T, class Vector1>
42  int Lsqr(const VirtualMatrix<T>& A, Vector1& x, const Vector1& b,
43  Preconditioner_Base<T>& M,
44  Iteration<typename ClassComplexType<T>::Treal>& iter)
45 #else
46  template <class Titer, class Matrix1, class Vector1, class Preconditioner>
47  int Lsqr(const Matrix1& A, Vector1& x, const Vector1& b,
48  Preconditioner& M, Iteration<Titer> & iter)
49 #endif
50  {
51  const int N = A.GetM();
52  if (N <= 0)
53  return 0;
54 
55  typedef typename Vector1::value_type Complexe;
56  Complexe rho, rho_bar, phi, phi_bar, theta, c, s, tmp;
57  typename ClassComplexType<Complexe>::Treal beta, alpha, rnorm;
58  Vector1 v(b), v1(b), u(b), u1(b), w(b);
59  Complexe zero, one;
60  SetComplexZero(zero);
61  SetComplexOne(one);
62 
63  int success_init = iter.Init(b);
64  if (success_init != 0)
65  return iter.ErrorCode();
66 
67  Copy(b, u);
68  if (!iter.IsInitGuess_Null())
69  iter.MltAdd(-one, A, x, one, u);
70  else
71  x.Fill(zero);
72 
73  rnorm = Norm2(u);
74 
75  Copy(b, u);
76  beta = Norm2(u);
77  tmp = one/beta; Mlt(tmp, u);
78  // matrix vector product
79  iter.Mlt(SeldonTrans, A, u, v);
80  alpha = Norm2(v);
81  tmp = one/alpha; Mlt(tmp, v);
82 
83  Copy(v, w); x.Fill(zero);
84 
85  phi_bar = beta; rho_bar = alpha;
86 
87  iter.SetNumberIteration(0);
88  // Loop until the stopping criteria are satisfied
89  while (! iter.Finished(rnorm))
90  {
91  // matrix vector product u1 = A*v
92  iter.Mlt(A, v, u1);
93  // u1 = u1 - alpha*u
94  Add(-alpha, u, u1);
95  beta = Norm2(u1);
96  if (beta == zero)
97  {
98  iter.Fail(1, "Lsqr breakdown #1");
99  break;
100  }
101  tmp = one/beta; Mlt(tmp, u1);
102 
103  // matrix vector product v1 = A^t u1
104  iter.Mlt(SeldonTrans, A, u1, v1);
105  // v1 = v1 - beta*v
106  Add(-beta, v, v1);
107  alpha = Norm2(v1);
108  if (alpha == zero)
109  {
110  iter.Fail(2, "Lsqr breakdown #2");
111  break;
112  }
113  tmp = one/alpha; Mlt(tmp, v1);
114 
115  rho = sqrt(rho_bar*rho_bar+beta*beta);
116  if (rho == zero)
117  {
118  iter.Fail(3, "Lsqr breakdown #3");
119  break;
120  }
121 
122  c = rho_bar/rho;
123  s = beta / rho;
124  theta = s*alpha;
125  rho_bar = -c * alpha;
126  phi = c * phi_bar;
127  phi_bar = s * phi_bar;
128 
129  // x = x + (phi/rho) w
130  tmp = phi/rho;
131  Add(tmp, w, x);
132  // w = v1 - (theta/rho) w
133  tmp = -theta/rho;
134  Mlt(tmp, w);
135  Add(one, v1, w);
136 
137  rnorm = abs(phi_bar);
138 
139  Swap(u1, u); Swap(v1, v);
140 
141  ++iter;
142  ++iter;
143  }
144 
145  return iter.ErrorCode();
146  }
147 
148 } // end namespace
149 
150 #define SELDON_FILE_ITERATIVE_LSQR_CXX
151 #endif
Seldon::Norm2
ClassComplexType< T >::Treal Norm2(const VectorExpression< T, E > &X)
returns 2-norm of an expression with vectors
Definition: Functions_BaseInline.cxx:153
Seldon::Iteration::Init
int Init(const Vector1 &r)
Initialization with the right hand side.
Definition: Iterative.cxx:218
Seldon::Iteration::Mlt
void Mlt(const Matrix1 &A, const Vector1 &x, Vector1 &y)
Computes y = A x.
Definition: IterativeInline.cxx:123
Seldon::Iteration::ErrorCode
int ErrorCode()
Returns the error code (if an error occured)
Definition: Iterative.cxx:351
Seldon::Iteration::Fail
void Fail(int i, const string &s)
Informs of a failure in the iterative solver.
Definition: Iterative.cxx:330
Seldon::Iteration::MltAdd
void MltAdd(const T1 &alpha, const Matrix1 &A, const Vector1 &x, const T1 &beta, Vector1 &y)
Computes y = beta y + alpha A x.
Definition: IterativeInline.cxx:109
Seldon::Iteration::SetNumberIteration
void SetNumberIteration(int nb)
Changes the number of iterations.
Definition: Iterative.cxx:177
Seldon::Lsqr
int Lsqr(const Matrix1 &A, Vector1 &x, const Vector1 &b, Preconditioner &M, Iteration< Titer > &iter)
Solves a linear system by using Least Squares (LSQR)
Definition: Lsqr.cxx:47
Seldon
Seldon namespace.
Definition: Array.cxx:24
Seldon::Iteration
Class containing parameters for an iterative resolution.
Definition: Iterative.hxx:59
Seldon::Swap
void Swap(Vector< T, Storage, Allocator > &X, Vector< T, Storage, Allocator > &Y)
Swaps X and Y without copying all elements.
Definition: Functions_Vector.cxx:348
Seldon::Iteration::IsInitGuess_Null
bool IsInitGuess_Null() const
Returns true if the initial guess is null.
Definition: Iterative.cxx:247
Seldon::Iteration::Finished
bool Finished(const Vector1 &r) const
Returns true if the iterative solver has reached its end.
Definition: Iterative.cxx:264