Statistiques
| Révision :

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