12 #ifndef __INCLUDE_ORTHOGONAL_HPP__
13 #define __INCLUDE_ORTHOGONAL_HPP__
15 #include <boost/numeric/ublas/vector.hpp>
16 #include <boost/numeric/ublas/vector_proxy.hpp>
17 #include <boost/numeric/ublas/vector_of_vector.hpp>
18 #include <boost/numeric/ublas/vector_expression.hpp>
19 #include <boost/numeric/ublas/io.hpp>
21 #include <boost/numeric/ublas/matrix.hpp>
22 #include <boost/numeric/ublas/matrix_proxy.hpp>
23 #include <boost/numeric/ublas/operation.hpp>
24 #include <boost/numeric/ublas/operation_sparse.hpp>
26 #include <boost/numeric/ublas/matrix_sparse.hpp>
27 #include <boost/numeric/ublas/banded.hpp>
28 #include <boost/numeric/ublas/io.hpp>
32 namespace ublas = boost::numeric::ublas;
38 template <
class Vector>
41 ublas::matrix<double> r (basis.size(), basis.size());
42 std::vector< Vector > q(basis.size());
44 for (
int i = 0; i < basis.size(); ++i){
46 r(i, i) = ublas::norm_2(basis[i]);
47 q[i] = basis[i]/r(i, i);
49 for (
int j = i+1; j < basis.size(); ++j){
50 r(i, j) = ublas::inner_prod(q[i], basis[j]);
51 basis[j] -= r(i, j)*q[i];
62 template <
class Vector>
65 for (
int i = 0; i < basis.size(); ++i){
66 double r = ublas::inner_prod(basis[i], v);
69 return v/ublas::norm_2(v);
77 template <
class Matrix,
class Vector>
78 Vector
arnoldi_step (std::vector< Vector > & q, Matrix & A, Matrix & H,
int n){
79 Vector v = ublas::prod(A, q[n]);
81 for (
int j = 0; j <= n; ++j){
82 H(j, n) = ublas::inner_prod(q[j], v);
85 H(n+1, n) = ublas::norm_2(v);
97 template <
class Matrix,
class Vector>
98 void gmres (
const Matrix & A, Vector & x,
const Vector & b,
double tol){
100 const std::size_t image_size = A.size1();
101 const std::size_t preimage_size = A.size1();
106 Matrix Q(image_size, preimage_size+1);
107 Matrix H(image_size, preimage_size);
110 Vector v(image_size);
111 Vector c(image_size+1);
112 Vector s(image_size+1);
113 Vector z(image_size+1);
116 v = b - ublas::prod<Matrix>(A, x);
117 column(Q, 0) = v/ublas::norm_2(v);
119 z(0) = ublas::norm_2(v);
128 while (k < image_size && t > tol){
129 v = ublas::prod(A, column(Q, k));
131 Vector h = column(H, k);
135 for (
int j = 0; j <= k; ++j){
137 h(j) = ublas::inner_prod(q, v);
141 h(k+1) = ublas::norm_2(v);
142 column(Q, k+1) = v/h(k+1);
144 for (
int i = 0; i < k; ++i){
146 h(i) = c(i+1)*h(i) + s(i+1)*h(i+1);
147 h(i+1) = s(i+1)*h_i - c(i+1)*h(i+1);
151 double h_k1k = h(k+1);
152 double alpha = sqrt(h_kk*h_kk + h_k1k*h_k1k);
153 s(k+1) = h_k1k/alpha;
159 z(k+1) = s(k+1)*z(k);
169 for (
int i = k; i >= 0; --i)
170 c(i) = (z(i) - inner_prod(project(row(H, i), ublas::range(i+1, k+1) ), project( c, ublas::range(i+1, k+1) )))/H(i, i);
171 for (
int i = 0; i < k; ++i)
172 s += c(i)*column(Q, i);
173 cout << norm_2(prod(A,s)-b) << endl;
181 for (
int i = k; i >= 0; --i)
182 c(i) = (z(i) - inner_prod(project(row(H, i), ublas::range(i+1, k+1) ), project( c, ublas::range(i+1, k+1) )))/H(i, i);
185 for (
int i = 0; i < k; ++i)
186 x += c(i)*column(Q, i);
198 template <
class Matrix,
class LinOp,
class Vector,
class Precond>
203 unsigned int const maxiter,
207 unsigned int size = A.image_size();
209 Matrix Q(size, maxiter + 1);
210 Matrix H(size, maxiter + 1);
218 Vector c(maxiter + 1);
219 Vector s(maxiter + 1);
220 Vector z(maxiter + 1);
228 column(Q, 0) = g/ublas::norm_2(g);
230 z(0) = ublas::norm_2(g);
240 while (k < maxiter && t > tol){
242 A.
mult ( column(Q, k), v );
245 for (
unsigned int j = 0; j <= k; ++j) {
246 ublas::matrix_column<Matrix> q = column(Q, j);
247 h(j) = ublas::inner_prod(q, g);
251 for (
unsigned int i = 0; i < k; ++i) {
252 double h_i = c(i+1)*h(i) + s(i+1)*h(i+1);
253 double h_i1 = s(i+1)*h(i) - c(i+1)*h(i+1);
258 h(k+1) = ublas::norm_2(g);
259 column(Q, k+1) = g/h(k+1);
262 double h_k1k = h(k+1);
263 double alpha = sqrt(h_kk*h_kk + h_k1k*h_k1k);
264 s(k+1) = h_k1k/alpha;
270 z(k+1) = s(k+1)*z(k);
280 Vector c(maxiter + 1);
285 while ( (i--) > 0 ) {
286 c(i) = (z(i) - inner_prod(project(row(H, i), ublas::range(i+1, k+1) ), project( c, ublas::range(i+1, k+1) )))/H(i, i);
291 current_x += prod(project(Q, ublas::range::all(), ublas::range(0, k)), project(c, ublas::range(0, k) ) );
293 std::cout << k <<
" " << current_x <<
"\n";
301 while ( (i--) > 0 ) {
302 c(i) = (z(i) - inner_prod(project(row(H, i), ublas::range(i+1, k+1) ), project( c, ublas::range(i+1, k+1) )))/H(i, i);
316 x += prod(project(Q, ublas::range::all(), ublas::range(0, k)), project(c, ublas::range(0, k) ) );
330 template <
class Matrix,
class LinOp,
class Vector,
class Precond>
335 unsigned int const maxiter,
336 unsigned int const nrestarts,
340 unsigned int iter = 0;
341 bool converged =
false;
343 Vector resid( b.size() );
347 double z_0 = norm_2(resid);
349 while (i <= nrestarts && ! converged) {
350 unsigned int ret = gmres_step< Matrix > (A, x, b, B, maxiter, tol);
352 A.residuum(x,b,resid);
353 double t = (norm_2(resid) / z_0);
354 converged = ( t < tol);
370 template <
class Matrix,
class LinOp,
class Vector,
class Precond>
380 int size = A.image_size();
382 Matrix Q(size, number+1); Q.clear();
383 Matrix P(size, number); P.clear();
392 Vector h(number + 1);
397 column(Q, 0) = g/ublas::norm_2(g);
399 double z_0 = ublas::norm_2(g);
408 while (k < maxiter && !end){
413 A.
mult ( column(Q, k % (number + 1)), v );
416 int lower = max<int>(0, k-number);
418 for (
int j = lower; j <= k; ++j) {
419 ublas::matrix_column<Matrix> q = column(Q, j % (number+1));
420 h(j % (number + 1)) = ublas::inner_prod(q, g);
421 g -= h(j % (number + 1))*q;
424 for (
int i = lower; i < k; ++i) {
425 double h_i = c((i+1) % (number + 1))*h(i % (number + 1)) + s((i+1) % (number + 1))*h((i+1) % (number + 1));
426 double h_i1 = s((i+1) % (number + 1))*h(i % (number + 1)) - c((i+1) % (number + 1))*h((i+1) % (number + 1));
427 h(i % (number + 1)) = h_i;
428 h((i+1) % (number + 1)) = h_i1;
431 double h_k1 = ublas::norm_2(g);
432 column(Q, (k+1) % (number+1)) = g/h_k1;
434 double h_kk = h(k % (number + 1));
436 double alpha = sqrt(h_kk*h_kk + h_k1*h_k1);
437 s((k+1) % (number + 1)) = h_k1/alpha;
438 c((k+1) % (number + 1)) = h_kk/alpha;
439 h(k % (number + 1)) = alpha;
442 z_2 = s((k+1) % (number + 1))*z_1;
443 z_1 = c((k+1) % (number + 1))*z_1;
445 sum = h(lower % (number + 1))*column(P, lower % number);
446 for (
int i=lower+1; i < k; ++i){
447 sum += h(i % (number + 1))*column(P, i%number);
450 column(P, k % number) = (column(Q, k % (number +1)) - sum)/h(k % (number + 1));
452 x += z_1 * column(P, k % number);
454 h((k+1) % (number + 1) ) = h_k1;
456 t = sqrt((
double)k+1) * (z_2/z_0);
void residuum(const VEC1 &x, const VEC2 &b, VEC3 &y) const
compute y <- b - Ax
Definition: lin_op.hpp:37
int gmres_short(LinOp const &A, Vector &x, const Vector &b, Precond const &B, int number, int maxiter, double tol)
/QGMRES. Only the last "number" vectors are taken into account, i.e. the orthogonalization depends on...
Definition: orthogonal.hpp:371
Vector arnoldi_step(std::vector< Vector > &q, Matrix &A, Matrix &H, int n)
preforms the orthogonalization of a given vector to a given basis using the arnoldi approach the basi...
Definition: orthogonal.hpp:78
unsigned int gmres_step(LinOp const &A, Vector &x, const Vector &b, Precond const &B, unsigned int const maxiter, double const tol)
a single step of the gmres algorithm, one iteration. Returns true if the approach converges...
Definition: orthogonal.hpp:199
a matrix based linear operator mapping a vector x (preimage) to a vector y (image).
Definition: lin_op.hpp:18
int gmres_restarts(LinOp const &A, Vector &x, const Vector &b, Precond const &B, unsigned int const maxiter, unsigned int const nrestarts, double const tol)
the gmres algorithm restarting after maxiter steps. nrestarts is the number of the allowed restarts ...
Definition: orthogonal.hpp:331
std::vector< Vector > orthogonal_system(std::vector< Vector > &basis)
returns the orthogonal system of a given set of vectors
Definition: orthogonal.hpp:39
void gmres(const Matrix &A, Vector &x, const Vector &b, double tol)
the standard gmres algorithm, without linear operator or any improvements
Definition: orthogonal.hpp:98
void mult(const VEC1 &x, VEC2 &y) const
compute y <- Ax
Definition: lin_op.hpp:31
Vector orthogonal_vector(std::vector< Vector > &basis, Vector &v)
preforms the orthogonalization of a given vector to a given basis using the arnoldi approach ...
Definition: orthogonal.hpp:63