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

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

14 CHAPTER 1. GOOD AND BAD SCIENTIFIC SOFTWARE<br />

without the comments? We would easily catch where the variables representing q, A, and p<br />

are used but to see that this is a matrix vector product will take a closer look and a good<br />

understanding how the matrix is stored.<br />

This leads us to the second problem: the implementation commits to many technical details<br />

and only works in precisely this context. Algorithm 1 only requires that matrix A is symmetric<br />

positive-definite but it does not demand a certain storage scheme. There are many other sparse<br />

matrix <strong>for</strong>mats that we can all use in the CG method but not with this implementation. The<br />

matrix <strong>for</strong>mat is not the only detail the code commits to. What if we want to compute in lower<br />

(float) or higher precision (long double)? Or solve a complex linear system? For every such<br />

new CG application, we need a new implementation. Needless to say that running on parallel<br />

computers or exploring GPGPU (General-Purpose Graphic Processing Units) acceleration<br />

needs reimplementations as well. Much worse, every combination of the above needs a new<br />

implementation.<br />

Some of the readers might think: “It is only one function of 20–30 lines. Rewriting this little<br />

function, how much work can this be. And we do not introduce new matrix <strong>for</strong>mats or computer<br />

architectures every month.” Certainly true but in some sense it is putting the cart be<strong>for</strong>e<br />

the horse. Because of such inflexible and detail-obsessed programming style, many scientific<br />

applications grew into the 100,000s and millions of lines of code. Once an application or library<br />

reached such a monstruous size, it is very arduous modifying features of the software and only<br />

rarely done. The road to success is starting scientific software from a higher level of abstraction<br />

from the beginning, even if it is more work initially.<br />

The last major disadvantage is how error-prone it is. All arguments are given as pointers and<br />

the size of the underlying arrays is given as an extra argument. We as programmer of function<br />

cg can only hope that the caller did everything right because we have no way to verify it. If<br />

the user does not allocate enough memory (or does not allocate at all) the execution will crash<br />

at some more or less random position or even worse, will generate some nonsensical results<br />

because data and software can be randomly owerwritten. Good programmers must avoid such<br />

fragile interfaces because the slightest mistake can have catastrophic consequences and the<br />

program errors are extremely difficult to find. Un<strong>for</strong>tunately, even recently released and widely<br />

used software is written in this manner, either <strong>for</strong> backward-compatibility to C and Fortran or<br />

because it is written in one of these two languages. In fact, the implementation above is C and<br />

not C ++. If this is way you love software, you probably will not like this script.<br />

So much about software we do not like. In Listing 1.2 we show how scientific software could<br />

look like.<br />

// This source is part of MTL4<br />

#include <br />

#include <br />

template < typename LinearOperator, typename HilbertSpaceX, typename HilbertSpaceB,<br />

typename Preconditioner, typename Iteration ><br />

int conjugate gradient(const LinearOperator& A, HilbertSpaceX& x, const HilbertSpaceB& b,<br />

const Preconditioner& L, Iteration& iter)<br />

{<br />

typedef HilbertSpaceX Vector;<br />

typedef typename mtl::Collection::value type Scalar;<br />

Scalar rho(0), rho 1(0), alpha(0);

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

Saved successfully!

Ooh no, something went wrong!