|
|
C $Id: minv.f 3304 2011-01-17 15:25:59Z brideout $
|
|
|
C
|
|
|
SUBROUTINE MINV(A,N,D,L,M)
|
|
|
C
|
|
|
C Inverts general matrix A (overwrites A) using standard
|
|
|
C gauss-jordan method. The determinant is also calculated. a
|
|
|
C determinant of zero indicates that the matrix is singular.
|
|
|
C
|
|
|
C Input:
|
|
|
C n - order of matrix a
|
|
|
C l - work vector of length n
|
|
|
C m - work vector of length n
|
|
|
C
|
|
|
C Input, Output:
|
|
|
C a - input matrix, destroyed in computation and replaced by
|
|
|
C resultant inverse.
|
|
|
C
|
|
|
C Output:
|
|
|
C d - resultant determinant
|
|
|
C
|
|
|
C .. Scalar Arguments ..
|
|
|
DOUBLE PRECISION D
|
|
|
INTEGER N
|
|
|
C ..
|
|
|
C .. Array Arguments ..
|
|
|
DOUBLE PRECISION A(*)
|
|
|
INTEGER L(*),M(*)
|
|
|
C ..
|
|
|
C .. Local Scalars ..
|
|
|
DOUBLE PRECISION BIGA,HOLD
|
|
|
INTEGER I,IJ,IK,IZ,J,JI,JK,JP,JQ,JR,K,KI,KJ,KK,NK
|
|
|
C ..
|
|
|
C .. Intrinsic Functions ..
|
|
|
INTRINSIC ABS
|
|
|
C ..
|
|
|
C search for largest element
|
|
|
D = 1.0D0
|
|
|
NK = -N
|
|
|
DO 90 K = 1,N
|
|
|
NK = NK + N
|
|
|
L(K) = K
|
|
|
M(K) = K
|
|
|
KK = NK + K
|
|
|
BIGA = A(KK)
|
|
|
DO 20 J = K,N
|
|
|
IZ = N*(J-1)
|
|
|
DO 10 I = K,N
|
|
|
IJ = IZ + I
|
|
|
IF (ABS(BIGA).LT.ABS(A(IJ))) THEN
|
|
|
BIGA = A(IJ)
|
|
|
L(K) = I
|
|
|
M(K) = J
|
|
|
END IF
|
|
|
10 CONTINUE
|
|
|
20 CONTINUE
|
|
|
C
|
|
|
C interchange rows
|
|
|
C
|
|
|
J = L(K)
|
|
|
IF (J.GT.K) THEN
|
|
|
KI = K - N
|
|
|
DO 30 I = 1,N
|
|
|
KI = KI + N
|
|
|
HOLD = -A(KI)
|
|
|
JI = KI - K + J
|
|
|
A(KI) = A(JI)
|
|
|
A(JI) = HOLD
|
|
|
30 CONTINUE
|
|
|
END IF
|
|
|
C
|
|
|
C interchange columns
|
|
|
C
|
|
|
I = M(K)
|
|
|
IF (I.GT.K) THEN
|
|
|
JP = N*(I-1)
|
|
|
DO 40 J = 1,N
|
|
|
JK = NK + J
|
|
|
JI = JP + J
|
|
|
HOLD = -A(JK)
|
|
|
A(JK) = A(JI)
|
|
|
A(JI) = HOLD
|
|
|
40 CONTINUE
|
|
|
END IF
|
|
|
C
|
|
|
C divide column by minus pivot (value of pivot element is
|
|
|
C contained in biga)
|
|
|
C
|
|
|
IF (BIGA.EQ.0) GO TO 130
|
|
|
DO 50 I = 1,N
|
|
|
IF (I.NE.K) THEN
|
|
|
IK = NK + I
|
|
|
A(IK) = A(IK)/(-BIGA)
|
|
|
END IF
|
|
|
50 CONTINUE
|
|
|
C
|
|
|
C reduce matrix
|
|
|
C
|
|
|
DO 70 I = 1,N
|
|
|
IK = NK + I
|
|
|
HOLD = A(IK)
|
|
|
IJ = I - N
|
|
|
DO 60 J = 1,N
|
|
|
IJ = IJ + N
|
|
|
IF (I.NE.K) THEN
|
|
|
IF (J.NE.K) THEN
|
|
|
KJ = IJ - I + K
|
|
|
A(IJ) = HOLD*A(KJ) + A(IJ)
|
|
|
END IF
|
|
|
END IF
|
|
|
60 CONTINUE
|
|
|
70 CONTINUE
|
|
|
C
|
|
|
C divide row by pivot
|
|
|
C
|
|
|
KJ = K - N
|
|
|
DO 80 J = 1,N
|
|
|
KJ = KJ + N
|
|
|
IF (J.NE.K) A(KJ) = A(KJ)/BIGA
|
|
|
80 CONTINUE
|
|
|
C
|
|
|
C product of pivots
|
|
|
C
|
|
|
D = D*BIGA
|
|
|
C
|
|
|
C replace pivot by reciprocal
|
|
|
C
|
|
|
A(KK) = 1.0D0/BIGA
|
|
|
90 CONTINUE
|
|
|
C
|
|
|
C final row and column interchange
|
|
|
C
|
|
|
K = N
|
|
|
100 CONTINUE
|
|
|
K = (K-1)
|
|
|
IF (K.LE.0) GO TO 140
|
|
|
I = L(K)
|
|
|
IF (I.GT.K) THEN
|
|
|
JQ = N*(K-1)
|
|
|
JR = N*(I-1)
|
|
|
DO 110 J = 1,N
|
|
|
JK = JQ + J
|
|
|
HOLD = A(JK)
|
|
|
JI = JR + J
|
|
|
A(JK) = -A(JI)
|
|
|
A(JI) = HOLD
|
|
|
110 CONTINUE
|
|
|
END IF
|
|
|
J = M(K)
|
|
|
IF (J.GT.K) THEN
|
|
|
KI = K - N
|
|
|
DO 120 I = 1,N
|
|
|
KI = KI + N
|
|
|
HOLD = A(KI)
|
|
|
JI = KI - K + J
|
|
|
A(KI) = -A(JI)
|
|
|
A(JI) = HOLD
|
|
|
120 CONTINUE
|
|
|
END IF
|
|
|
GO TO 100
|
|
|
130 CONTINUE
|
|
|
D = 0.0D0
|
|
|
140 CONTINUE
|
|
|
RETURN
|
|
|
END
|
|
|
|