root / src / minv.f90 @ 4
Historique | Voir | Annoter | Télécharger (3,03 ko)
1 |
SUBROUTINE MINV(A,N,D) |
---|---|
2 |
|
3 |
IMPLICIT NONE |
4 |
integer, parameter :: KINT = kind(1) |
5 |
integer, parameter :: KREAL = kind(1.0d0) |
6 |
|
7 |
REAL(KREAL), INTENT(INOUT) :: A(N*N) |
8 |
INTEGER(KINT), INTENT(IN) :: N |
9 |
REAL(KREAL), INTENT(OUT) :: D |
10 |
|
11 |
|
12 |
!********************************************************************** |
13 |
!* |
14 |
!* INVERT A MATRIX USING GAUSS-JORDAN METHOD. PART OF DIIS |
15 |
!* A - INPUT MATRIX (MUST BE A GENERAL MATRIX), DESTROYED IN |
16 |
!* COMPUTATION AND REPLACED BY RESULTANT INVERSE. |
17 |
!* N - ORDER OF MATRIX A |
18 |
!* D - RESULTANT DETERMINANT |
19 |
!* |
20 |
!********************************************************************** |
21 |
INTEGER(KINT), ALLOCATABLE :: L(:), M(:) |
22 |
INTEGER(KINT) :: I,J,K,NK,KK,KI,KJ,IZ,IJ,JP,JK,IK,JR,JQ,JI |
23 |
|
24 |
REAL(KREAL) :: BigA,Hold |
25 |
|
26 |
ALLOCATE(L(N),M(N)) |
27 |
! |
28 |
! SEARCH FOR LARGEST ELEMENT |
29 |
! |
30 |
D=1.0D0 |
31 |
NK=-N |
32 |
DO 180 K=1,N |
33 |
NK=NK+N |
34 |
L(K)=K |
35 |
M(K)=K |
36 |
KK=NK+K |
37 |
BIGA=A(KK) |
38 |
DO 20 J=K,N |
39 |
IZ=N*(J-1) |
40 |
DO 20 I=K,N |
41 |
IJ=IZ+I |
42 |
10 IF (ABS(BIGA).LT.ABS(A(IJ)))THEN |
43 |
BIGA=A(IJ) |
44 |
L(K)=I |
45 |
M(K)=J |
46 |
ENDIF |
47 |
20 CONTINUE |
48 |
! |
49 |
! INTERCHANGE ROWS |
50 |
! |
51 |
J=L(K) |
52 |
IF (J-K) 50,50,30 |
53 |
30 KI=K-N |
54 |
DO 40 I=1,N |
55 |
KI=KI+N |
56 |
HOLD=-A(KI) |
57 |
JI=KI-K+J |
58 |
A(KI)=A(JI) |
59 |
40 A(JI)=HOLD |
60 |
! |
61 |
! INTERCHANGE COLUMNS |
62 |
! |
63 |
50 I=M(K) |
64 |
IF (I-K) 80,80,60 |
65 |
60 JP=N*(I-1) |
66 |
DO 70 J=1,N |
67 |
JK=NK+J |
68 |
JI=JP+J |
69 |
HOLD=-A(JK) |
70 |
A(JK)=A(JI) |
71 |
70 A(JI)=HOLD |
72 |
!C |
73 |
!C DIVIDE COLUMN BY MINUS PIVOT (VALUE OF PIVOT ELEMENT IS |
74 |
!C CONTAINED IN BIGA) |
75 |
!C |
76 |
80 IF (BIGA) 100,90,100 |
77 |
90 D=0.0 |
78 |
RETURN |
79 |
100 DO 120 I=1,N |
80 |
IF (I-K) 110,120,110 |
81 |
110 IK=NK+I |
82 |
A(IK)=A(IK)/(-BIGA) |
83 |
120 CONTINUE |
84 |
!C REDUCE MATRIX |
85 |
DO 150 I=1,N |
86 |
IK=NK+I |
87 |
HOLD=A(IK) |
88 |
IJ=I-N |
89 |
DO 150 J=1,N |
90 |
IJ=IJ+N |
91 |
IF (I-K) 130,150,130 |
92 |
130 IF (J-K) 140,150,140 |
93 |
140 KJ=IJ-I+K |
94 |
A(IJ)=HOLD*A(KJ)+A(IJ) |
95 |
150 CONTINUE |
96 |
!C |
97 |
!C DIVIDE ROW BY PIVOT |
98 |
!C |
99 |
KJ=K-N |
100 |
DO 170 J=1,N |
101 |
KJ=KJ+N |
102 |
IF (J-K) 160,170,160 |
103 |
160 A(KJ)=A(KJ)/BIGA |
104 |
170 CONTINUE |
105 |
!C |
106 |
!C PRODUCT OF PIVOTS |
107 |
!C |
108 |
D=MAX(-1.D25,MIN(1.D25,D)) |
109 |
D=D*BIGA |
110 |
!C |
111 |
!C REPLACE PIVOT BY RECIPROCAL |
112 |
!C |
113 |
A(KK)=1.0/BIGA |
114 |
180 CONTINUE |
115 |
!C |
116 |
!C FINAL ROW AND COLUMN INTERCHANGE |
117 |
!C |
118 |
K=N |
119 |
190 K=(K-1) |
120 |
IF (K) 260,260,200 |
121 |
200 I=L(K) |
122 |
IF (I-K) 230,230,210 |
123 |
210 JQ=N*(K-1) |
124 |
JR=N*(I-1) |
125 |
DO 220 J=1,N |
126 |
JK=JQ+J |
127 |
HOLD=A(JK) |
128 |
JI=JR+J |
129 |
A(JK)=-A(JI) |
130 |
220 A(JI)=HOLD |
131 |
230 J=M(K) |
132 |
IF (J-K) 190,190,240 |
133 |
240 KI=K-N |
134 |
DO 250 I=1,N |
135 |
KI=KI+N |
136 |
HOLD=A(KI) |
137 |
JI=KI-K+J |
138 |
A(KI)=-A(JI) |
139 |
250 A(JI) =HOLD |
140 |
GO TO 190 |
141 |
260 RETURN |
142 |
END |