libode
Easy to compile, fast ODE integrators as C++ classes
Loading...
Searching...
No Matches
ode_linalg.cc
Go to the documentation of this file.
1
2
3#include "ode_linalg.h"
4
5namespace ode {
6
7void ode_crout_forw_sub (double **L, double *b, int *p, int n, double *out) {
8
9 for (int i=0; i<n; i++) {
10 out[i] = b[p[i]]; //the permutation is handled here
11 for (int j=0; j<i; j++) {
12 out[i] -= L[i][j]*out[j];
13 }
14 //element on the diagonal is 1 for crout LU decomposed matrices
15 }
16}
17
18void ode_back_sub (double **U, double *b, int n, double *out) {
19
20 for (int i=n-1; i>=0; i--) {
21 out[i] = b[i];
22 for (int j=i+1; j<n; j++) {
23 out[i] -= U[i][j]*out[j];
24 }
25 out[i] /= U[i][i];
26 }
27}
28
29void ode_crout_LU (double **A, int n, int *p) {
30
31 int i, j, k, idx, ti;
32 double m, td;
33
34 //initialize the permutation array
35 for (i=0; i<n; i++) p[i] = i;
36
37 //move through the matrix
38 for (i=0; i<n; i++) {
39 //find the largest element in the column beneath A[i][i]
40 m = 0.0;
41 idx = i;
42 for (j=i; j<n; j++) {
43 td = fabs(A[j][i]);
44 if ( td > m ) {
45 m = td;
46 idx = j;
47 }
48 }
49 //if all elements are zero, the matrix is singular
50 if ( !(fabs(m) > 0.0) ) {
51 printf("\nLINALG FAILURE: the matrix is singular\n\n");
52 exit(EXIT_FAILURE);
53 }
54 //if the largest element isn't on the diagonal, pivot
55 if ( idx != i ) {
56 //swap rows
57 for (j=0; j<n; j++) {
58 td = A[i][j];
59 A[i][j] = A[idx][j];
60 A[idx][j] = td;
61 }
62 //swap permutation indices
63 ti = p[i];
64 p[i] = p[idx];
65 p[idx] = ti;
66 }
67 //continue with the decomposition
68 for (j=i+1; j<n; j++)
69 A[j][i] /= A[i][i];
70 for (j=i+1; j<n; j++)
71 for (k=i+1; k<n; k++)
72 A[j][k] -= A[j][i]*A[i][k];
73 }
74}
75
76void ode_solve_LU (double **LU, int *p, double *b, int n, double *out) {
77
78 //run forward substitution, handling the permutation along the way
79 ode_crout_forw_sub(LU, b, p, n, out);
80 //run backward substitution, overwriting "out" along the way
81 ode_back_sub(LU, out, n, out); //solution is now in "out"
82}
83
84void ode_solve_A (double **A, double *b, int n, double *out) {
85
86 //make room for permutation array
87 int *p = new int[n];
88 //decompose the matrix
89 ode_crout_LU(A, n, p);
90 //run forward substitution, handling the permutation along the way
91 ode_crout_forw_sub(A, b, p, n, out);
92 //run backward substitution, overwriting "out" along the way
93 ode_back_sub(A, out, n, out); //solution is now in "out"
94 //clear p
95 delete [] p;
96}
97
98void ode_solve_tridiag (double **T, double *r, double *temp, int n, double *out) {
99
100 //set pointers to each row of values representing the diagonals
101 double *a = T[2];
102 double *b = T[1];
103 double *c = T[0] + 1;
104 //temporary number
105 double z;
106 //decomposition and forward substitution
107 z = b[0];
108 out[0] = r[0]/z;
109 for (int i=1; i<n; i++) {
110 temp[i] = c[i-1]/z;
111 z = b[i] - a[i-1]*temp[i];
112 out[i] = (r[i] - a[i-1]*out[i-1])/z;
113 }
114 for (int i=n-2; i>=0; i--)
115 out[i] -= temp[i+1]*out[i+1];
116}
117
118} // namespace ode
void ode_solve_LU(double **LU, int *p, double *b, int n, double *out)
Solves a matrix equation where the matrix has already be crout LU decomposed.
Definition ode_linalg.cc:76
void ode_back_sub(double **U, double *b, int n, double *out)
Backward substitution.
Definition ode_linalg.cc:18
void ode_solve_A(double **A, double *b, int n, double *out)
Solves a matrix equation A x = b with crout LU decomposition.
Definition ode_linalg.cc:84
void ode_crout_LU(double **A, int n, int *p)
Crout LU decomposition.
Definition ode_linalg.cc:29
void ode_crout_forw_sub(double **L, double *b, int *p, int n, double *out)
Crout forward substitution.
Definition ode_linalg.cc:7
void ode_solve_tridiag(double **T, double *r, double *temp, int n, double *out)
Solves a tridiagonal matrix equation.
Definition ode_linalg.cc:98