PLUTO
math_lu_decomp.c File Reference

Functions for LU decomposition and matrix inversion. More...

#include "pluto.h"
Include dependency graph for math_lu_decomp.c:

Go to the source code of this file.

Macros

#define TINY   1.0e-20;
 

Functions

int LUDecompose (double **a, int n, int *indx, double *d)
 
void LUBackSubst (double **a, int n, int *indx, double b[])
 
void TridiagonalSolve (double *am, double *a0, double *ap, double *b, double *y, int n)
 

Detailed Description

Functions for LU decomposition and matrix inversion.

Author
A. Mignone (migno.nosp@m.ne@p.nosp@m.h.uni.nosp@m.to.i.nosp@m.t)
Date
June 20, 2014

Definition in file math_lu_decomp.c.

Macro Definition Documentation

#define TINY   1.0e-20;

Function Documentation

void LUBackSubst ( double **  a,
int  n,
int *  indx,
double  b[] 
)

Solve a linear system of the type Ax = b, where A is a square matrix, x is the array of unknowns and b is given. This function must be called after LUDecompose() (adapted from Numerical Recipes). For the 1st time, use:

1 LUDecompose (A,n,indx,&d);
2 LUBackSubst (A,n,indx,b);

The answer x will be given back in b and the original matrix A will be destroyed. For all subsequent time, to solve the same system wth a different right-hand side b, use

1 LUBackSubst(A,n,indx,b);

where A is the matrix that has been decomposed by LUDecompose() and not the original matrix A.

Definition at line 84 of file math_lu_decomp.c.

106 {
107  int i, ii = 0, ip, j;
108  double sum;
109 
110  for (i = 0; i < n; i++) {
111  ip = indx[i];
112  sum = b[ip];
113  b[ip] = b[i];
114  if (ii)
115  for (j = ii - 1; j <= i - 1; j++)
116  sum -= a[i][j] * b[j];
117  else if (sum)
118  ii = i + 1;
119  b[i] = sum;
120  }
121  for (i = n - 1; i >= 0; i--) {
122  sum = b[i];
123  for (j = i + 1; j < n; j++) sum -= a[i][j]*b[j];
124  b[i] = sum / a[i][i];
125  }
126 }
static double a
Definition: init.c:135
static int n
Definition: analysis.c:3
int j
Definition: analysis.c:2
int i
Definition: analysis.c:2

Here is the caller graph for this function:

int LUDecompose ( double **  a,
int  n,
int *  indx,
double *  d 
)

Perform LU decomposition. Adapted from Numerical Recipes. On output, replaces the matrix a[0..n-1][0..n-1] with its LU decomposition. indx[0..n-1] is a row vector that records the row permutation while d = 1 (-1) if the number of raw interchanges was even (odd). This function should be used in combination with LUBackSubst() to solve linear system of equations.

Definition at line 12 of file math_lu_decomp.c.

24 {
25  int i, imax, j, k;
26  double big, dum, sum, temp;
27  double *vv;
28 
29  vv = ARRAY_1D (n, double);
30  *d = 1.0;
31  for (i = 0; i < n; i++) {
32  big = 0.0;
33  for (j = 0; j < n; j++)
34  if ((temp = fabs (a[i][j])) > big)
35  big = temp;
36  if (big == 0.0) {
37 /* print1 ("! Singular matrix in routine LUDecompose - (i=%d, j=%d)",i,j); */
38  return (0);
39  }
40  vv[i] = 1.0 / big;
41  }
42  for (j = 0; j < n; j++) {
43  for (i = 0; i < j; i++) {
44  sum = a[i][j];
45  for (k = 0; k < i; k++)
46  sum -= a[i][k] * a[k][j];
47  a[i][j] = sum;
48  }
49  big = 0.0;
50  for (i = j; i < n; i++) {
51  sum = a[i][j];
52  for (k = 0; k < j; k++)
53  sum -= a[i][k] * a[k][j];
54  a[i][j] = sum;
55  if ((dum = vv[i] * fabs (sum)) >= big) {
56  big = dum;
57  imax = i;
58  }
59  }
60  if (j != imax) {
61  for (k = 0; k < n; k++) {
62  dum = a[imax][k];
63  a[imax][k] = a[j][k];
64  a[j][k] = dum;
65  }
66  *d = -(*d);
67  vv[imax] = vv[j];
68  }
69  indx[j] = imax;
70  if (a[j][j] == 0.0)
71  a[j][j] = TINY;
72  if (j != n - 1) {
73  dum = 1.0 / (a[j][j]);
74  for (i = j + 1; i < n; i++)
75  a[i][j] *= dum;
76  }
77  }
78  FreeArray1D(vv);
79  return (1); /* -- success -- */
80 }
void FreeArray1D(void *v)
Definition: arrays.c:37
static double a
Definition: init.c:135
static int n
Definition: analysis.c:3
int j
Definition: analysis.c:2
int k
Definition: analysis.c:2
#define ARRAY_1D(nx, type)
Definition: prototypes.h:170
#define TINY
int i
Definition: analysis.c:2

Here is the call graph for this function:

Here is the caller graph for this function:

void TridiagonalSolve ( double *  am,
double *  a0,
double *  ap,
double *  b,
double *  y,
int  n 
)

Use recursion formula to solve a tridiagonal system of the type

am[i]*y[i-1] + a0[i]*y[i] + ap[i]*y[i+1] = b[i]

from i = 1..n-1. Boundary coefficients must have been imposed at y[0] and y[n] On output y[] is replaced with the updated solution.

Definition at line 129 of file math_lu_decomp.c.

140 {
141  int i;
142  double alpha[n], beta[n], gamma;
143 
144  alpha[n-1] = 0.0;
145  beta[n-1] = y[n];
146  for (i = n-1; i > 0; i--){
147  gamma = -1.0/(a0[i] + ap[i]*alpha[i]);
148  alpha[i-1] = gamma*am[i];
149  beta[i-1] = gamma*(ap[i]*beta[i] - b[i]);
150  }
151 
152  for (i = 0; i < n-1; i++){
153  y[i+1] = alpha[i]*y[i] + beta[i];
154  }
155 
156 /* Verify solution of tridiagonal matrix */
157 /*
158  double res;
159  for (i = 1; i < n; i++){
160  res = am[i]*phi[i-1] + a0[i]*phi[i] + ap[i]*phi[i+1] - b[i];
161  if (fabs(res) > 1.e-9){
162  cout << "! TridiagonalSolve: not correct" << endl;
163  exit(1);
164  }
165  }
166 */
167 }
static double alpha
Definition: init.c:3
static int n
Definition: analysis.c:3
int i
Definition: analysis.c:2