C++ for Scientists - Technische Universität Dresden
C++ for Scientists - Technische Universität Dresden C++ for Scientists - Technische Universität Dresden
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
- Page 1 and 2: Technische Universität Dresden Fak
- Page 3 and 4: Contents I Understanding C++ 7 Intr
- Page 5 and 6: CONTENTS 5 10.5 Unix and Linux . .
- Page 7: Part I Understanding C ++ 7
- Page 10 and 11: 10 C ++ was not a reliable computer
- Page 14 and 15: 14 CHAPTER 1. GOOD AND BAD SCIENTIF
- Page 16 and 17: 16 CHAPTER 1. GOOD AND BAD SCIENTIF
- Page 18 and 19: 18 CHAPTER 1. GOOD AND BAD SCIENTIF
- Page 20 and 21: 20 CHAPTER 2. C++ BASICS • std::c
- Page 22 and 23: 22 CHAPTER 2. C++ BASICS In the fir
- Page 24 and 25: 24 CHAPTER 2. C++ BASICS int main (
- Page 26 and 27: 26 CHAPTER 2. C++ BASICS Operator A
- Page 28 and 29: 28 CHAPTER 2. C++ BASICS The bitwis
- Page 30 and 31: 30 CHAPTER 2. C++ BASICS cast (type
- Page 32 and 33: 32 CHAPTER 2. C++ BASICS complicate
- Page 34 and 35: 34 CHAPTER 2. C++ BASICS } else if
- Page 36 and 37: 36 CHAPTER 2. C++ BASICS eps/= 2.0;
- Page 38 and 39: 38 CHAPTER 2. C++ BASICS for (...;
- Page 40 and 41: 40 CHAPTER 2. C++ BASICS 2.6.1 Inli
- Page 42 and 43: 42 CHAPTER 2. C++ BASICS To make su
- Page 44 and 45: 44 CHAPTER 2. C++ BASICS float divi
- Page 46 and 47: 46 CHAPTER 2. C++ BASICS The first
- Page 48 and 49: 48 CHAPTER 2. C++ BASICS #ifndef at
- Page 50 and 51: 50 CHAPTER 2. C++ BASICS float A[7]
- Page 52 and 53: 52 CHAPTER 2. C++ BASICS Encapsulat
- Page 54 and 55: 54 CHAPTER 2. C++ BASICS As a pract
- Page 56 and 57: 56 CHAPTER 2. C++ BASICS A function
- Page 58 and 59: 58 CHAPTER 2. C++ BASICS Now that t
- Page 60 and 61: 60 CHAPTER 2. C++ BASICS we need sm
}<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