root / src / gaussj.f90
Historique | Voir | Annoter | Télécharger (3,89 ko)
1 |
SUBROUTINE gaussj(a,n,np,b,m,mp) |
---|---|
2 |
|
3 |
! This routine solves the system AX=B by inverting A. |
4 |
! This is based on Gauss-Jordan pivoting. |
5 |
! Input: |
6 |
! A is NxN REAL(KREAL) matrix, order N |
7 |
! B is NxM REAL(KREAL) matrix (each ocolumn j of this B matrix corresponds to |
8 |
! a AX=B_j problem in fact). |
9 |
! np: actual size of A(np,np) |
10 |
! mp: actual size of B(np,mp) |
11 |
! |
12 |
! Output: |
13 |
! A is destroyed and contains A inverse |
14 |
! B is destroyed and contains the solution X vectors. |
15 |
! |
16 |
! Adapted from "Numerical Recipes in F77" |
17 |
|
18 |
!---------------------------------------------------------------------- |
19 |
! Copyright 2003-2014 Ecole Normale Supérieure de Lyon, |
20 |
! Centre National de la Recherche Scientifique, |
21 |
! Université Claude Bernard Lyon 1. All rights reserved. |
22 |
! |
23 |
! This work is registered with the Agency for the Protection of Programs |
24 |
! as IDDN.FR.001.100009.000.S.P.2014.000.30625 |
25 |
! |
26 |
! Authors: P. Fleurat-Lessard, P. Dayal |
27 |
! Contact: optnpath@gmail.com |
28 |
! |
29 |
! This file is part of "Opt'n Path". |
30 |
! |
31 |
! "Opt'n Path" is free software: you can redistribute it and/or modify |
32 |
! it under the terms of the GNU Affero General Public License as |
33 |
! published by the Free Software Foundation, either version 3 of the License, |
34 |
! or (at your option) any later version. |
35 |
! |
36 |
! "Opt'n Path" is distributed in the hope that it will be useful, |
37 |
! but WITHOUT ANY WARRANTY; without even the implied warranty of |
38 |
! |
39 |
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
40 |
! GNU Affero General Public License for more details. |
41 |
! |
42 |
! You should have received a copy of the GNU Affero General Public License |
43 |
! along with "Opt'n Path". If not, see <http://www.gnu.org/licenses/>. |
44 |
! |
45 |
! Contact The Office of Technology Licensing, valorisation@ens-lyon.fr, |
46 |
! for commercial licensing opportunities. |
47 |
!---------------------------------------------------------------------- |
48 |
|
49 |
|
50 |
IMPLICIT NONE |
51 |
|
52 |
INTEGER, PARAMETER :: KINT=KIND(1) |
53 |
INTEGER, PARAMETER :: KREAL=KIND(1.0D0) |
54 |
|
55 |
|
56 |
INTEGER(KINT) :: m,mp,n,np,NMAX |
57 |
REAL(KREAL) :: a(np,np),b(np,mp) |
58 |
PARAMETER (NMAX=50) |
59 |
INTEGER(KINT) :: i,icol,irow,j,k,l,ll,indxc(NMAX),indxr(NMAX),ipiv(NMAX) |
60 |
REAL(KREAL) :: big,dum,pivinv |
61 |
do 11 j=1,n |
62 |
ipiv(j)=0 |
63 |
11 continue |
64 |
do 22 i=1,n |
65 |
big=0.d0 |
66 |
do 13 j=1,n |
67 |
if(ipiv(j).ne.1)then |
68 |
do 12 k=1,n |
69 |
if (ipiv(k).eq.0) then |
70 |
if (abs(a(j,k)).ge.big)then |
71 |
big=abs(a(j,k)) |
72 |
irow=j |
73 |
icol=k |
74 |
endif |
75 |
else if (ipiv(k).gt.1) then |
76 |
Write(*,*) 'singular matrix in gaussj' |
77 |
STOP |
78 |
endif |
79 |
12 continue |
80 |
endif |
81 |
13 continue |
82 |
ipiv(icol)=ipiv(icol)+1 |
83 |
if (irow.ne.icol) then |
84 |
do 14 l=1,n |
85 |
dum=a(irow,l) |
86 |
a(irow,l)=a(icol,l) |
87 |
a(icol,l)=dum |
88 |
14 continue |
89 |
do 15 l=1,m |
90 |
dum=b(irow,l) |
91 |
b(irow,l)=b(icol,l) |
92 |
b(icol,l)=dum |
93 |
15 continue |
94 |
endif |
95 |
indxr(i)=irow |
96 |
indxc(i)=icol |
97 |
if (a(icol,icol).eq.0.d0) THEN |
98 |
WRITE(*,*) 'singular matrix in gaussj' |
99 |
STOP |
100 |
END IF |
101 |
pivinv=1.d0/a(icol,icol) |
102 |
a(icol,icol)=1.d0 |
103 |
do 16 l=1,n |
104 |
a(icol,l)=a(icol,l)*pivinv |
105 |
16 continue |
106 |
do 17 l=1,m |
107 |
b(icol,l)=b(icol,l)*pivinv |
108 |
17 continue |
109 |
do 21 ll=1,n |
110 |
if(ll.ne.icol)then |
111 |
dum=a(ll,icol) |
112 |
a(ll,icol)=0.d0 |
113 |
do 18 l=1,n |
114 |
a(ll,l)=a(ll,l)-a(icol,l)*dum |
115 |
18 continue |
116 |
do 19 l=1,m |
117 |
b(ll,l)=b(ll,l)-b(icol,l)*dum |
118 |
19 continue |
119 |
endif |
120 |
21 continue |
121 |
22 continue |
122 |
do 24 l=n,1,-1 |
123 |
if(indxr(l).ne.indxc(l))then |
124 |
do 23 k=1,n |
125 |
dum=a(k,indxr(l)) |
126 |
a(k,indxr(l))=a(k,indxc(l)) |
127 |
a(k,indxc(l))=dum |
128 |
23 continue |
129 |
endif |
130 |
24 continue |
131 |
return |
132 |
END |