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.

54 CHAPTER 2. <strong>C++</strong> BASICS<br />

As a practical exercise, we now go step-by-step through the development process of a function<br />

<strong>for</strong> matrix inversion. This is easier than it seems. 25 For it, we use the Matrix Template Library 4<br />

— see http://www.mtl4.org. It already provides most of the functionality we need. 26<br />

In the program development, we follow some principles of Extreme Programming, especially<br />

writing tests first and implement the functionality afterwards. This has two significant advantages:<br />

• It prevents you as programmer (to some extend) from featurism — the obsession to add<br />

more features instead of finishing one thing after another. If you write down what you<br />

want to achieve you work more directly towards this goal and accomplish it usually much<br />

earlier. When writing the function call you specify the interface of the function you plan<br />

implementing, when testing your results against expected values you say something about<br />

the semantics of your function. Thus, tests are compilable documentation. The tests<br />

might not tell everything about the functions and classes you are going to implement, but<br />

what it says it does very precisely. Documentation in text can be much more detailed and<br />

comprehensible but also much vaguer than tests.<br />

• If you start writing tests after you finally finished the implementation — say on a late<br />

Friday afternoon — You Do Not Want To See It Failing. You will write the test with your<br />

nice data (whatever this means <strong>for</strong> the program in question) and minimize the risk that<br />

it fails. You might decide going home and swear to God that you will test it on Monday.<br />

For those reasons, you will be more honest if you write your tests first. Of course, you can<br />

modify your tests later if you realize that something does not work or you changed the design<br />

of some item or you want test more details. It goes without saying that verifying partial<br />

implementations requires uncommenting parts of your test, temporarily.<br />

Be<strong>for</strong>e we start implementing our inverse function and even the tests we have to choose an<br />

algorithm. We can use determinants of sub-matrices, block algorithms, Gauß-Jordan, or LU<br />

decomposition with or without pivoting. Let’s say we prefer LU factorization with column<br />

pivoting so that we have<br />

LU = P A,<br />

with a unit lower triangular matrix L, an upper triangular matrix U, and a permutation matrix<br />

P . Thus it is<br />

A = P −1 LU<br />

and<br />

A −1 = U −1 L −1 P. (2.1)<br />

We use the LU factorization from MTL4, implement the inversion of the lower and upper<br />

triangular matrix and compose it appropriately.<br />

Now we start with our test by defining an invertible matrix and printing it out.<br />

int main(int argc, char∗ argv[])<br />

{<br />

const unsigned size= 3;<br />

typedef dense2D Matrix;<br />

Matrix A(size, size);<br />

A= 4, 1, 2,<br />

25 At least with the implementations we already have.<br />

26 It actualy provides the inversion function inv already but we want to learn now how to get there.

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

Saved successfully!

Ooh no, something went wrong!