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.

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

we need smaller unit vectors now and only sub-matrices of A. This can nicely be expressed with<br />

ranges:<br />

Inv= 0;<br />

<strong>for</strong> (unsigned k= 0; k < n; ++k)<br />

Inv[irange(0, k+1)][k]= upper trisolve(A[irange(0, k+1)][irange(0, k+1)], unit vector(k, k+1));<br />

Admittedly, the irange makes the expression hard to read. Although it looks like a function,<br />

irange is a type and we just created objects on the fly and passed them to passed them to the<br />

operator[]. As we use the same range 3 times, it is shorter to create a variable (or a constant).<br />

<strong>for</strong> (unsigned k= 0; k < n; ++k) {<br />

const irange r(0, k+1);<br />

Inv[r][k]= upper trisolve(A[r][r], unit vector(k, k+1));<br />

}<br />

This does not only make the second line shorter, it is also easier to see that this is all the same<br />

range.<br />

Another observation: after shortening the unit vectors they all have the one in the last entry.<br />

Thus, we only need the size of the vector and the position of the one is implied:<br />

dense vector inline last unit vector(unsigned n)<br />

{<br />

dense vector v(n, 0.0);<br />

v[n−1]= 1;<br />

return v;<br />

}<br />

We choose a different name to reflect the different meaning. Nonetheless, we wonder if we really<br />

want such a function. How is the probability to need this ever again? Charles H. Moore,<br />

the creator of the programming language Forth once said that “The purpose of functions is not<br />

to hash a program into tiny pieces but to create highly reusable entities.” All this said, we<br />

prefer the more general function that is much more likely to be useful later.<br />

After all these modifications, we are now satisfied with the implementation and go to the next<br />

function. We still might change something at a later point in time but having it made clearer<br />

and better structured will make the later modification much easier <strong>for</strong> us or somebody else.<br />

The more experience you gain, the less steps you will need to achieve the implementation that<br />

makes you happy. And it goes without saying that we tested the inverse upper repeatedly while<br />

modifying it.<br />

Now that we know how to invert triangular matrices we can do the same <strong>for</strong> the lower triangular<br />

accordingly. Alternatively we can just transpose the input and output:<br />

dense2D inline inverse lower(dense2D const& A)<br />

{<br />

dense2D T(trans(A));<br />

return dense2D(trans(inverse upper(T)));<br />

}<br />

Ideally this implementation should look like this:<br />

dense2D inline inverse lower(dense2D const& A)<br />

{<br />

return trans(inverse upper(trans(T)));<br />

}

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

Saved successfully!

Ooh no, something went wrong!