// Author: Douglas Wilhelm Harder // Copyright (c) 2009 by Douglas Wilhelm Harder. All rights reserved. // Reference: Yousef Saad, Iterative Methods for Sparse Linear Systems, SIAM, Philadelphia, 2003. template Vector steepest_descent( Matrix const &A, Vector const &b, int K, double epsilon ) { Vector x = diagonal_solve( A, b ); Vector r = b - A*x; Vector p = A*r; for ( int i = 0; i < K; ++i ) { double alpha = (transpose(r)*r) / (transpose(p)*r); x = x + alpha*r; if ( norm( alpha*r ) < epsilon ) { return x; } r = r - alpha*p; p = A*r; } throw non_convergence( K ); } template Vector minimal_residual( Matrix const &A, Vector const &b, int K, double epsilon ) { Vector x = diagonal_solve( A, b ); Vector r = b - A*x; Vector p = A*r; for ( int i = 0; i < K; ++i ) { double alpha = (transpose(r)*r) / (transpose(p)*p); x = x + alpha*r; if ( norm( alpha*r ) < epsilon ) { return x; } r = r - alpha*p; p = A*r; } throw non_convergence( K ); } template Vector residual_norm_steepest_descent( Matrix const &A, Vector const &b, int K, double epsilon ) { Vector x = diagonal_solve( A, b ); Vector r = b - A*x; for ( int i = 0; i < K; ++i ) { // A'*r Vector v = transpose( transpose(r)*A ); Vector Av = A*v; double alpha = norm( v, 2 )/norm( Av, 2 ); alpha *= alpha; x = x + alpha*v; if ( norm( alpha*v ) < epsilon ) { return x; } r = r - alpha*Av; } throw non_convergence( K ); }