C++ for Scientists - Technische Universität Dresden

C++ for Scientists - Technische Universität Dresden C++ for Scientists - Technische Universität Dresden

math.tu.dresden.de
from math.tu.dresden.de More from this publisher
03.12.2012 Views

12 CHAPTER 1. GOOD AND BAD SCIENTIFIC SOFTWARE Programmers transform this mathematical notation into a form that a compiler understands, by using operations from the language. The result could look like Listing 1.1. Do not read it in detail, just skim it. #include #include double one norm(int size, double ∗vp) { int i; double sum= 0; for (i= 0; i < size; i++) sum+= fabs(vp[i]); return sum; } double dot(int size, double ∗vp, double ∗wp) { int i; double sum= 0; for (inti= 0; i < size; i++) sum+= vp[i] ∗ wp[i]; return sum; } int cg(int size, int nnz, int∗ aip, int∗ ajp, double∗ avp, double ∗x, double ∗b, void (∗lpre)(int, double∗, double∗), double eps) { int i, j, iter= 0; double rho, rho 1, alpha; double ∗p= (double∗) malloc(size ∗ sizeof(double)); double ∗q= (double∗) malloc(size ∗ sizeof(double)); double ∗r= (double∗) malloc(size ∗ sizeof(double)); double ∗z= (double∗) malloc(size ∗ sizeof(double)); // r= b; for (i= 0; i < size; i++) r[i]= b[i]; // r−= A∗x; for (i= 0; i < nnz; i++) r[aip[i]]−= avp[i] ∗ b[ajp[i]]; while (one norm(size, r) >= eps) { // z = solve(L, r); (∗lpre)(size, z, r); // function pointer call rho= dot(size, r, z); if (!iter) { for (i= 0; i < size; i++) p[i]= z[i]; } else { for (i= 0; i < size; i++) p[i]= z[i] + rho / rho 1 ∗ p[i];

} } // q= A ∗ p; for (i= 0; i < size; i++) q[i]= 0; for (i= 0; i < nnz; i++) q[aip[i]]+= avp[i] ∗ p[ajp[i]]; alpha= rho / dot(size, p, q); // x+= alpa ∗ p; r−= alpha ∗ q; for (i= 0; i < size; i++) { x[i]+= alpha ∗ p[i]; r[i]−= alpha ∗ q[i]; } iter++; } free(q); free(p); free(r); free(z); return iter; void ic 0(int size, double∗ out, double∗ in) { /∗ .. ∗/ } int main (int argc, char∗ argv[]) { int nnz, size; } // set nnz and size int ∗aip= (int∗) malloc(nnz ∗ sizeof(double)); int ∗ajp= (int∗) malloc(nnz ∗ sizeof(double)); double ∗avp= (double∗) malloc(nnz ∗ sizeof(double)); double ∗x= (double∗) malloc(size ∗ sizeof(double)); double ∗b= (double∗) malloc(size ∗ sizeof(double)); // set A and b cg(size, nnz, aip, ajp, avp, x, b, ilu, 1e−9); return 0 ; Listing 1.1: Low Abstraction Implementation of CG As said before the details do not matter here but only the principal approach. The good thing about this code is that it is self-contained. But this is about the only advantage. The problem with this implemenation is its low abstraction level. This creates three major disadvantages: • Bad readability; • No flexibility; and • High error-proneness. The bad readability manifests in the fact that almost every operation is implemented in one or multiple loops. For instance, would we have found the matrix vector multiplication q = Ap 13

}<br />

}<br />

// q= A ∗ p;<br />

<strong>for</strong> (i= 0; i < size; i++)<br />

q[i]= 0;<br />

<strong>for</strong> (i= 0; i < nnz; i++)<br />

q[aip[i]]+= avp[i] ∗ p[ajp[i]];<br />

alpha= rho / dot(size, p, q);<br />

// x+= alpa ∗ p; r−= alpha ∗ q;<br />

<strong>for</strong> (i= 0; i < size; i++) {<br />

x[i]+= alpha ∗ p[i];<br />

r[i]−= alpha ∗ q[i];<br />

}<br />

iter++;<br />

}<br />

free(q); free(p); free(r); free(z);<br />

return iter;<br />

void ic 0(int size, double∗ out, double∗ in) { /∗ .. ∗/ }<br />

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

{<br />

int nnz, size;<br />

}<br />

// set nnz and size<br />

int ∗aip= (int∗) malloc(nnz ∗ sizeof(double));<br />

int ∗ajp= (int∗) malloc(nnz ∗ sizeof(double));<br />

double ∗avp= (double∗) malloc(nnz ∗ sizeof(double));<br />

double ∗x= (double∗) malloc(size ∗ sizeof(double));<br />

double ∗b= (double∗) malloc(size ∗ sizeof(double));<br />

// set A and b<br />

cg(size, nnz, aip, ajp, avp, x, b, ilu, 1e−9);<br />

return 0 ;<br />

Listing 1.1: Low Abstraction Implementation of CG<br />

As said be<strong>for</strong>e the details do not matter here but only the principal approach. The good thing<br />

about this code is that it is self-contained. But this is about the only advantage. The problem<br />

with this implemenation is its low abstraction level. This creates three major disadvantages:<br />

• Bad readability;<br />

• No flexibility; and<br />

• High error-proneness.<br />

The bad readability manifests in the fact that almost every operation is implemented in one<br />

or multiple loops. For instance, would we have found the matrix vector multiplication q = Ap<br />

13

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

Saved successfully!

Ooh no, something went wrong!