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