The TELEMAC-MASCARET system  trunk
ludcmp.f
Go to the documentation of this file.
1 ! *****************
2  SUBROUTINE ludcmp
3 ! *****************
4 !
5  &(a,n,np,indx)
6 !
7 !***********************************************************************
8 ! BIEF V6P2 21/08/2010
9 !***********************************************************************
10 !
11 !brief GIVEN A MATRIX A(1:N,1:N), WITH PHYSICAL DIMENSION NP
12 !+ BY NP, THIS ROUTINE REPLACES IT BY THE LU FACTORISATION
13 !+ OF A ROWWISE PERMUTATION OF ITSELF. A AND N ARE INPUT.
14 !+ A IS OUTPUT, ARRANGED AS IN EQUATION (2.3.14) ABOVE;
15 !+ INDX(1:N) IS AN OUTPUT VECTOR THAT RECORDS THE ROW
16 !+ PERMUTATION EFFECTED BY THE PARTIAL PIVOTING; D IS
17 !+ OUTPUT AS SIGMA1 DEPENDING ON WHETHER THE NUMBER OF
18 !+ ROW INTERCHANGES WAS EVEN OR ODD, RESPECTIVELY. THIS
19 !+ SUBROUTINE IS USED IN COMBINATION WITH LUBKSB TO SOLVE
20 !+ LINEAR EQUATIONS OR INVERT A MATRIX.
21 !
22 !history CHUN WANG
23 !+ 28/07/2006
24 !+ V5P7
25 !+
26 !
27 !history N.DURAND (HRW), S.E.BOURBAN (HRW)
28 !+ 13/07/2010
29 !+ V6P0
30 !+ Translation of French comments within the FORTRAN sources into
31 !+ English comments
32 !
33 !history N.DURAND (HRW), S.E.BOURBAN (HRW)
34 !+ 21/08/2010
35 !+ V6P0
36 !+ Creation of DOXYGEN tags for automated documentation and
37 !+ cross-referencing of the FORTRAN sources
38 !
39 !history J-M HERVOUET (LNHE)
40 !+ 25/07/2012
41 !+ V6P2
42 !+ Correction of one test of division by 0.
43 !
44 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
45 !| A |-->| MATRIX OF THE SYSTEM
46 !| INDX |-->| ADDRESS IN RIGHT-HAND SIDE
47 !| N |-->| SIZE OF B
48 !| NP |-->| RANK OF MATRIX A
49 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
50 !
52  IMPLICIT NONE
53 !
54 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
55 !
56  INTEGER, INTENT(IN) :: N,NP
57  INTEGER, INTENT(INOUT) :: INDX(n)
58  DOUBLE PRECISION, INTENT(INOUT) :: A(np,np)
59 !
60 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61 !
62  DOUBLE PRECISION D
63  INTEGER I,IMAX,J,K
64  DOUBLE PRECISION AAMAX,DUM,XSOM,VV(500)
65  DOUBLE PRECISION, PARAMETER:: CHOUIA=1.d-20
66 !
67 !------------------------------------------------------------------------
68 !
69  d=1.d0 ! NO ROW INTERCHANGES YET
70 !
71 ! LOOP OVER ROWS TO GET THE IMPLICIT SCALING INFORMATION
72 !
73  DO i=1,n
74  aamax=0.d0
75  DO j=1,n
76  IF(abs(a(i,j)).GT.aamax) aamax=abs(a(i,j))
77  ENDDO
78  IF(aamax.LT.chouia) THEN
79  WRITE(lu,*) 'SINGULAR MATRIX IN LUDCMP'
80  CALL plante(1)
81  stop
82  ENDIF
83  vv(i)=1.d0/aamax ! SAVES THE SCALING
84  ENDDO
85 !
86 ! LOOP OVER COLUMNS OF CROUT'S METHOD
87 !
88  DO j=1,n
89  DO i=1,j-1 ! EQUATION (2.3.12) EXCEPT FOR I = J
90  xsom=a(i,j)
91  DO k=1,i-1
92  xsom=xsom-a(i,k)*a(k,j)
93  ENDDO
94  a(i,j)=xsom
95  ENDDO
96  aamax=0.d0 ! INITIALISES FOR THE SEARCH OF LARGEST PIVOT ELEMENT
97  DO i=j,n ! THIS IS I = J OF EQUATION (2.3.12) AND
98  ! I = J +1 : : : N OF EQUATION (2.3.13)
99  xsom=a(i,j)
100  DO k=1,j-1
101  xsom=xsom-a(i,k)*a(k,j)
102  ENDDO
103  a(i,j)=xsom
104  dum=vv(i)*abs(xsom) ! FIGURE OF MERIT FOR THE PIVOT
105  IF (dum.GE.aamax) THEN ! IS IT BETTER THAN THE BEST SO FAR?
106  imax=i
107  aamax=dum
108  ENDIF
109  ENDDO
110  IF (j.NE.imax) THEN ! NEEDS TO INTERCHANGE ROWS?
111  DO k=1,n
112  dum=a(imax,k)
113  a(imax,k)=a(j,k)
114  a(j,k)=dum
115  ENDDO
116  d=-d !...AND CHANGES THE PARITY OF D
117  vv(imax)=vv(j) ! ALSO INTERCHANGES THE SCALE FACTOR
118  ENDIF
119  indx(j)=imax
120  IF(abs(a(j,j)).LT.chouia) a(j,j)=chouia
121 !
122 ! IF THE PIVOT ELEMENT IS 0 THE MATRIX IS SINGULAR (AT LEAST TO THE
123 ! PRECISION OF THE ALGORITHM)
124 !
125  IF(j.NE.n) THEN ! DIVIDES BY THE PIVOT ELEMENT
126  dum=1.d0/a(j,j)
127  DO i=j+1,n
128  a(i,j)=a(i,j)*dum
129  ENDDO
130  ENDIF
131 !
132  ENDDO
133 !
134 !------------------------------------------------------------------------
135 !
136  RETURN
137  END
subroutine ludcmp(A, N, NP, INDX)
Definition: ludcmp.f:7