03.12.2012 Views

C++ for Scientists - Technische Universität Dresden

C++ for Scientists - Technische Universität Dresden

C++ for Scientists - Technische Universität Dresden

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

14.1. COMPUTING AN EIGENFUNCTION OF THE POISSON EQUATION 267<br />

glas::random( f, seed ) ;<br />

v type x( 10 ) ;<br />

x = 0.0 ;<br />

// Richardson iteration<br />

double res nrm = athens::richardson( poisson scaled(), 0.5∗f, x, 1.e−4, 1000 ) ;<br />

{<br />

glas::dense vector r( size(x) ) ;<br />

athens::poisson 1d( x, r ) ;<br />

std::cout ≪ ”res nrm = ” ≪ norm 2( f −r ) ≪ std::endl ;<br />

std::cout ≪ ”f = ” ≪ f ≪ std::endl ;<br />

std::cout ≪ ”x = ” ≪ x ≪ std::endl ;<br />

}<br />

return 0 ;<br />

}<br />

We multiply right-hand side and matrix vector product by 0.5 to make sure the Richardson<br />

method converges.<br />

The output looks like<br />

res_nrm = 0.000195164<br />

f = (10)[0.0484811,0.822283,0.102721,0.436631,0.46112,0.0475317,0.864644,0.0772845,0.920099,0.105434]<br />

x = (10)[1.85463,3.66081,4.64473,5.52601,5.97071,5.9544,5.8906,4.96226,3.95668,2.03105]<br />

Note that the Richardson method converges very slowly. For the Poisson equation, there exist<br />

much faster methods.<br />

14.1.3 LAPACK tridiagonal solver<br />

The LAPACK [?] software package contains routines <strong>for</strong> solving linear systems with a symmetric<br />

positive definite tridiagonal matrix. This package is written in FORTRAN 77. The<br />

corresponding functions are<br />

• Cholesky factorization: A = LL T by<br />

SUBROUTINE DPTTRF( N, D, E, INFO )<br />

• Linear solve: Ax = b using LL T x = b by<br />

SUBROUTINE DPTTRS( N, NRHS, D, E, B, LDB, INFO )<br />

In order to solve Au = f, first A is factorized by the Cholesky factorization into A = LDL T<br />

where L is a matrix consisting of a main diagonal of ones and a diagonal below the main diagonal<br />

and D is a diagonal matrix. Once the factorization is per<strong>for</strong>med, the solution is computed as<br />

u = L −T D(L −1 f). Note the inversions of L and L T are not computed explicitly. For example<br />

L −1 f is computed as a linear solve with L. Linear solves <strong>for</strong> triangular matrices are easy to<br />

program. This is what DPTTRS does <strong>for</strong> us.<br />

A <strong>C++</strong> interface to DPTTRF and DPTTRS is available from the BoostSandbox.Bindings. For<br />

our application, we can solve a linear system as follows.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!