MoDeNa  1.0
Software framework facilitating sequential multi-scale modelling
matrix_inversion.f90
1 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
2 ! LU decomposition routines used by test_lu.f90
3 !
4 ! F90 version by J-P Moreau, Paris (www.jpmoreau.fr)
5 !
6 ! Reference:
7 ! Numerical Recipes By W.H. Press, B. P. Flannery, S.A. Teukolsky
8 ! and W.T. Vetterling, Cambridge University Press, 1986
9 !
10 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
11 MODULE lu
12 
13 implicit none
14 
15 CONTAINS
16 
17 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
18 ! Given an N x N matrix A, this routine replaces it by the LU decomposition of
19 ! a rowwise permutation of itself. A and N are input. INDX is an output vector
20 ! which records the row permutation effected by the partial pivoting; D is
21 ! output as -1 or 1, depending on whether the number of row interchanges was
22 ! even or odd, respectively. This routine is used in combination with LUBKSB to
23 ! solve linear equations or to invert a matrix. Return code is 1, if matrix is
24 ! singular.
25 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
26 
27  Subroutine ludcmp(A,N,INDX,D,CODE)
28 
29  parameter(nmax=100,tiny=1.5d-16)
30  INTEGER :: code, d, indx(n)
31  REAL :: amax,dum, sum, a(n,n),vv(nmax)
32 
33  d = 1
34  code = 0
35 
36  DO i = 1, n
37  amax = 0.0
38  DO j = 1, n
39  IF (dabs(a(i,j)).GT.amax) amax=dabs(a(i,j))
40  END DO ! j loop
41  IF(amax.LT.tiny) THEN
42  code = 1
43  RETURN
44  END IF
45  vv(i) = 1.d0 / amax
46  END DO ! i loop
47 
48  DO j=1,n
49  DO i=1,j-1
50  sum = a(i,j)
51  DO k=1,i-1
52  sum = sum - a(i,k)*a(k,j)
53  END DO ! k loop
54  a(i,j) = sum
55  END DO ! i loop
56  amax = 0.d0
57  DO i=j,n
58  sum = a(i,j)
59  DO k=1,j-1
60  sum = sum - a(i,k)*a(k,j)
61  END DO ! k loop
62  a(i,j) = sum
63  dum = vv(i)*dabs(sum)
64  IF(dum.GE.amax) THEN
65  imax = i
66  amax = dum
67  END IF
68  END DO ! i loop
69 
70  IF(j.NE.imax) THEN
71  DO k=1,n
72  dum = a(imax,k)
73  a(imax,k) = a(j,k)
74  a(j,k) = dum
75  END DO ! k loop
76  d = -d
77  vv(imax) = vv(j)
78  END IF
79 
80  indx(j) = imax
81  IF(dabs(a(j,j)) < tiny) a(j,j) = tiny
82 
83  IF(j.NE.n) THEN
84  dum = 1.d0 / a(j,j)
85  DO i=j+1,n
86  a(i,j) = a(i,j)*dum
87  END DO ! i loop
88  END IF
89  END DO ! j loop
90 
91  END subroutine ludcmp
92 
93 
94 ! ******************************************************************
95 ! * Solves the set of N linear equations A . X = B. Here A is *
96 ! * input, not as the matrix A but rather as its LU decomposition, *
97 ! * determined by the routine LUDCMP. INDX is input as the permuta-*
98 ! * tion vector returned by LUDCMP. B is input as the right-hand *
99 ! * side vector B, and returns with the solution vector X. A, N and*
100 ! * INDX are not modified by this routine and can be used for suc- *
101 ! * cessive calls with different right-hand sides. This routine is *
102 ! * also efficient for plain matrix inversion. *
103 ! ******************************************************************
104  Subroutine lubksb(A,N,INDX,B)
105  REAL*8 sum, a(n,n),b(n)
106  INTEGER indx(n)
107 
108  ii = 0
109 
110  DO i=1,n
111  ll = indx(i)
112  sum = b(ll)
113  b(ll) = b(i)
114  IF(ii.NE.0) THEN
115  DO j=ii,i-1
116  sum = sum - a(i,j)*b(j)
117  END DO ! j loop
118  ELSE IF(sum.NE.0.d0) THEN
119  ii = i
120  END IF
121  b(i) = sum
122  END DO ! i loop
123 
124  DO i=n,1,-1
125  sum = b(i)
126  IF(i < n) THEN
127  DO j=i+1,n
128  sum = sum - a(i,j)*b(j)
129  END DO ! j loop
130  END IF
131  b(i) = sum / a(i,i)
132  END DO ! i loop
133 
134  END subroutine lubksb
135 
136 END MODULE lu
137