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.

126 CHAPTER 4. GENERIC PROGRAMMING<br />

private:<br />

Matrix& ref;<br />

};<br />

In contrast to the previous maps it contains a mutable reference and another operator <strong>for</strong> setting<br />

a value.<br />

To test our implementation we create matrix A:<br />

coo matrix A(3, 5);<br />

A.insert(0, 0, 2.3);<br />

A.insert(0, 3, 3.4);<br />

A.insert(1, 2, 4.5);<br />

and define the three property maps:<br />

coo col col(A);<br />

coo row row(A);<br />

coo value value(A);<br />

A read-only traversal of all non-zero entries reads:<br />

<strong>for</strong> (nz cursor c= nz begin(A), end= nz end(A); c != end; ++c)<br />

std::cout ≪ ”A[” ≪ row(∗c) ≪ ”][” ≪ col(∗c) ≪ ”] = ” ≪ value(∗c) ≪ ”\n”;<br />

Scaling all non-zero elements can be achieved similarly:<br />

<strong>for</strong> (nz cursor c= nz begin(A), end= nz end(A); c != end; ++c)<br />

value(∗c, 2.0 ∗ value(∗c));<br />

Note that we did not used all property maps in the last algorithm. In fact, this is one of the<br />

motivation <strong>for</strong> property maps. Only data really needed in the algorithm must be provided. In<br />

today’s computer landscape, this can make a significant difference in per<strong>for</strong>mance since reading<br />

and writing data is much more time-consuming than most numeric computations. Or if data is<br />

only available implicitly and needs recomputation.<br />

Another advantage of this approach is the easier realization of nested traversals. Say we have<br />

an algorithm that iterates over rows and within each row over the non-zero entries. In this case,<br />

we need other cursor type(s) but can reuse the property maps — if our new cursor derefer to<br />

the same key type. First we need a cursor to iterate over all rows of a matrix:<br />

template <br />

struct row cursor<br />

{<br />

row cursor(int r, const Matrix& ref) : r(r), ref(ref) {}<br />

row cursor& operator++() { r++; return ∗this; }<br />

row cursor operator++(int) { row cursor tmp(∗this); r++; return tmp; }<br />

bool operator!=(const row cursor& other) { return r != other.r; }<br />

nz cursor begin() const { return nz cursor(ref.begin row(r)); }<br />

nz cursor end() const { return nz cursor(ref.begin row(r+1)); }<br />

protected:<br />

int r;<br />

const Matrix& ref;<br />

};

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

Saved successfully!

Ooh no, something went wrong!