openCARP
Doxygen code documentation for the open cardiac electrophysiology simulator openCARP
ludec.cc
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
4 #include "DataTypes.h"
5 #include "ludec.h"
6 
7 #define TINY 1.0e-20;
8 
22 bool ludcmp(Real **a, size_t n, int *indx, Real *d)
23 {
24  bool decomposed = true;
25  size_t i,j;
26  size_t imax = 0,k;
27  Real big,dum,temp;
28  Real sum;
29  Real *dumpoint, *vv;
30 
31  vv=(Real *)malloc((n+1)*sizeof(Real));
32  *d=1.0;
33  i = 1;
34  do {
35  big=0.0;
36  for (j=1;j<=n;j++)
37  if ((temp=fabs(a[i][j])) > big) big=temp;
38  if (big == 0.0) {
39  //printf("Singular matrix in routine LUDCMP");
40  //exit(1);
41  decomposed = false;
42  return decomposed;
43  }
44  vv[i]=1.0/big;
45  } while ( ++i <= n );
46 
47  j = 1;
48  do {
49  if ( j > 1 ) {
50  i = 1;
51  do {
52  sum=a[i][j];
53  if ( i != 1 ) {
54  k = 1;
55  do {
56  sum -= a[i][k]*a[k][j];
57  } while ( ++k < i );
58  }
59  a[i][j]=sum;
60  } while ( ++i < j );
61  }
62  big=0.0;
63  i = j;
64  do {
65  sum=a[i][j];
66  if ( j > 1 ) {
67  k =1 ;
68  do {
69  sum -= a[i][k]*a[k][j];
70  } while ( ++k < j );
71  }
72  a[i][j]=sum;
73  if ( (dum=vv[i]*fabs(sum)) >= big) {
74  big=dum;
75  imax=i;
76  }
77  } while ( ++i <= n );
78  if (j != imax) { /* exchange rows */
79  dumpoint=a[imax];
80  a[imax]=a[j];
81  a[j]=dumpoint;
82  *d = -(*d);
83  vv[imax]=vv[j];
84  }
85  indx[j]=imax;
86  if (a[j][j] == 0.0) a[j][j]=TINY;
87  if (j != n) {
88  dum=1.0/(a[j][j]);
89  for (i=j+1;i<=n;i++) a[i][j] *= dum;
90  }
91  } while ( ++j <= n );
92  free(vv);
93 
94  return decomposed;
95 }
96 
97 #undef TINY
98 
99 
100 
101 void lubksb(Real **a, size_t n, int *indx, Real *b)
102 {
103  size_t i, ii=0, ip;
104  size_t j;
105  Real sum;
106 
107  for (i=1;i<=n;i++) {
108  ip=indx[i];
109  sum=b[ip];
110  b[ip]=b[i];
111  if (ii)
112  for (j=ii;j<=i-1;j++)
113  sum -= a[i][j]*b[j];
114  else if (sum)
115  ii=i;
116  b[i]=sum;
117  }
118  for (i=n;i>=1;i--) {
119  sum=b[i];
120  for (j=i+1;j<=n;j++)
121  sum -= a[i][j]*b[j];
122  b[i]=sum/a[i][i];
123  }
124 }
125 
126 
127 Real *
128 lumult( int n, Real **a, Real *b, Real *c, int *indx )
129 /* routine to multiply LUdecomposed matrix by vector: ab=c */
130 {
131  int i,j, dum, *order;
132  Real *product;
133 
134  /* allocate memory */
135  order = ( int * )calloc( n, sizeof(int ) );
136  product = ( Real * )calloc( n, sizeof(Real) );
137 
138  /* unscramble row wise permutations and store them
139  so that multiplication may be performed */
140  for (i=0; i<n; i++)
141  order[i]=i+1;
142  for (i=n-1; i>=0;i--) {
143  dum = order[i];
144  order[i] = order[indx[i]-1];
145  order[indx[i]-1] = dum;
146  }
147 
148  /* perform multiplication by upper triangular matrix */
149  for (i=0; i<n; i++) {
150  product[i] = 0.0;
151  for (j=i; j<n; j++ )
152  product[i] += a[i][j]*b[j];
153  }
154 
155  /* perform multiplication by lower triangiular matrix */
156  for (i=0; i<n; i++) {
157  c[i] = 0.0;
158  for (j=0; j<order[i]-1; j++ )
159  c[i] += a[order[i]-1][j]*product[j];
160  c[i] += product[order[i]-1];
161  }
162 
163  return( c );
164 }
165 
166 
167 Real **
168 mat_mult_ludcmp( int n, Real **a, int *indx, Real **b, Real **c )
169 /* routine to multiply LUdecomposed matrix by matrix: ab=c */
170 {
171  int i,j, k, dum, *order;
172  Real *product;
173 
174  /* allocate memory */
175  order = ( int * )calloc( n, sizeof(int ) );
176  product = ( Real * )calloc( n, sizeof(Real) );
177 
178  /* unscramble row wise permutations and store them
179  so that multiplication may be performed */
180  for (i=0; i<n; i++)
181  order[i]=i+1;
182  for (i=n-1; i>=0;i--) {
183  dum = order[i];
184  order[i] = order[indx[i]-1];
185  order[indx[i]-1] = dum;
186  }
187 
188  for ( k=0; k<n; k++ ) {
189  /* perform multiplication by upper triangular matrix */
190  for (i=0; i<n; i++) {
191  product[i] = 0.0;
192  for (j=i; j<n; j++ )
193  product[i] += a[i][j]*b[j][k];
194  }
195 
196  /* perform multiplication by lower triangiular matrix */
197  for (i=0; i<n; i++) {
198  c[i][k] = 0.0;
199  for (j=0; j<order[i]-1; j++ )
200  c[i][k] += a[order[i]-1][j]*product[j];
201  c[i][k] += product[order[i]-1];
202  }
203  }
204  return( c );
205 }
206 
225 void
226 tridiagDecomp( int n, Real *a, Real *b, Real *c )
227 {
228  int i;
229 
230  for ( i=1; i<n; i++ ) {
231  b[i] /= a[i-1];
232  a[i] -= b[i]*c[i-1];
233  }
234 }
235 
236 
237 void tridiagbksb( int n, Real *a, Real *b, Real *c, Real *f )
238 /*
239  * Given a decomposed tridiagonal matrix with rows a, b, and c
240  * back substitute to find the solution. f is altered to contain the answer
241  *
242  */
243 {
244  int i;
245 
246  for ( i=1; i<n; i++ )
247  f[i] -= b[i]*f[i-1];
248  f[n-1] /= a[n-1];
249  for ( i=n-2; i>=0; i-- )
250  f[i] = (f[i]-c[i]*f[i+1])/a[i];
251 }
252 
253 void choldc(Real **a, int n, Real p[])
254 {
255  int i,j,k;
256  Real sum;
257 
258  for (i=1;i<=n;i++) {
259  for (j=i;j<=n;j++) {
260  for (sum=a[i][j],k=i-1;k>=1;k--) sum -= a[i][k]*a[j][k];
261  if (i == j) {
262  if (sum <= 0.0) {
263  fprintf( stderr, "choldc failed\n");
264  exit(1);
265  }
266  p[i]=sqrt(sum);
267  } else a[j][i]=sum/p[i];
268  }
269  }
270 }
271 
272 void cholsl(Real **a, int n, Real p[], Real b[], Real x[])
273 {
274  int i,k;
275  Real sum;
276 
277  for (i=1;i<=n;i++) {
278  for (sum=b[i],k=i-1;k>=1;k--) sum -= a[i][k]*x[k];
279  x[i]=sum/p[i];
280  }
281  for (i=n;i>=1;i--) {
282  for (sum=x[i],k=i+1;k<=n;k++) sum -= a[k][i]*x[k];
283  x[i]=sum/p[i];
284  }
285 }
double Real
Definition: DataTypes.h:14
bool ludcmp(Real **a, size_t n, int *indx, Real *d)
Definition: ludec.cc:22
void cholsl(Real **a, int n, Real p[], Real b[], Real x[])
Definition: ludec.cc:272
Real ** mat_mult_ludcmp(int n, Real **a, int *indx, Real **b, Real **c)
Definition: ludec.cc:168
void choldc(Real **a, int n, Real p[])
Definition: ludec.cc:253
void tridiagbksb(int n, Real *a, Real *b, Real *c, Real *f)
Definition: ludec.cc:237
void tridiagDecomp(int n, Real *a, Real *b, Real *c)
Definition: ludec.cc:226
Real * lumult(int n, Real **a, Real *b, Real *c, int *indx)
Definition: ludec.cc:128
void lubksb(Real **a, size_t n, int *indx, Real *b)
Definition: ludec.cc:101
#define TINY
Definition: ludec.cc:7
T sum(const vector< T > &vec)
Compute sum of a vector's entries.
Definition: SF_vector.h:340