C++ for Scientists - Technische Universität Dresden
C++ for Scientists - Technische Universität Dresden
C++ for Scientists - Technische Universität Dresden
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.