source: LMDZ4/branches/LMDZ4V5.0-dev/libf/filtrez/jacobi.F90 @ 1349

Last change on this file since 1349 was 1289, checked in by Ehouarn Millour, 15 years ago

Minor improvement: Bring Jacobi into the XXIst century.
Routine can now handle matix of any size (tested on local Linux machines and IBM Power6 that this doesn't change results compared to old version).

EM

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 2.7 KB
Line 
1!
2! $Id: jacobi.F90 1289 2009-12-18 14:51:22Z musat $
3!
4      SUBROUTINE JACOBI(A,N,NP,D,V,NROT)
5      implicit none
6! Arguments:
7      integer,intent(in) :: N
8      integer,intent(in) :: NP
9      integer,intent(out) :: NROT
10      real,intent(inout) :: A(NP,NP)
11      real,intent(out) :: D(NP)
12      real,intent(out) :: V(NP,NP)
13
14! local variables:
15      integer :: IP,IQ,I,J
16      real :: SM,TRESH,G,H,T,THETA,C,S,TAU
17      real :: B(N)
18      real :: Z(N)
19     
20      DO IP=1,N
21        DO IQ=1,N
22          V(IP,IQ)=0.
23        ENDDO
24        V(IP,IP)=1.
25      ENDDO
26      DO IP=1,N
27        B(IP)=A(IP,IP)
28        D(IP)=B(IP)
29        Z(IP)=0.
30      ENDDO
31      NROT=0
32      DO I=1,50 ! 50? I suspect this should be NP
33                !     but convergence is fast enough anyway
34        SM=0.
35        DO IP=1,N-1
36          DO IQ=IP+1,N
37            SM=SM+ABS(A(IP,IQ))
38          ENDDO
39        ENDDO
40        IF(SM.EQ.0.)RETURN
41        IF(I.LT.4)THEN
42          TRESH=0.2*SM/N**2
43        ELSE
44          TRESH=0.
45        ENDIF
46        DO IP=1,N-1
47          DO IQ=IP+1,N
48            G=100.*ABS(A(IP,IQ))
49            IF((I.GT.4).AND.(ABS(D(IP))+G.EQ.ABS(D(IP))) &
50               .AND.(ABS(D(IQ))+G.EQ.ABS(D(IQ))))THEN
51              A(IP,IQ)=0.
52            ELSE IF(ABS(A(IP,IQ)).GT.TRESH)THEN
53              H=D(IQ)-D(IP)
54              IF(ABS(H)+G.EQ.ABS(H))THEN
55                T=A(IP,IQ)/H
56              ELSE
57                THETA=0.5*H/A(IP,IQ)
58                T=1./(ABS(THETA)+SQRT(1.+THETA**2))
59                IF(THETA.LT.0.)T=-T
60              ENDIF
61              C=1./SQRT(1+T**2)
62              S=T*C
63              TAU=S/(1.+C)
64              H=T*A(IP,IQ)
65              Z(IP)=Z(IP)-H
66              Z(IQ)=Z(IQ)+H
67              D(IP)=D(IP)-H
68              D(IQ)=D(IQ)+H
69              A(IP,IQ)=0.
70              DO J=1,IP-1
71                G=A(J,IP)
72                H=A(J,IQ)
73                A(J,IP)=G-S*(H+G*TAU)
74                A(J,IQ)=H+S*(G-H*TAU)
75             ENDDO
76              DO J=IP+1,IQ-1
77                G=A(IP,J)
78                H=A(J,IQ)
79                A(IP,J)=G-S*(H+G*TAU)
80                A(J,IQ)=H+S*(G-H*TAU)
81              ENDDO
82              DO J=IQ+1,N
83                G=A(IP,J)
84                H=A(IQ,J)
85                A(IP,J)=G-S*(H+G*TAU)
86                A(IQ,J)=H+S*(G-H*TAU)
87              ENDDO
88              DO J=1,N
89                G=V(J,IP)
90                H=V(J,IQ)
91                V(J,IP)=G-S*(H+G*TAU)
92                V(J,IQ)=H+S*(G-H*TAU)
93              ENDDO
94              NROT=NROT+1
95            ENDIF
96          ENDDO
97        ENDDO
98        DO IP=1,N
99          B(IP)=B(IP)+Z(IP)
100          D(IP)=B(IP)
101          Z(IP)=0.
102        ENDDO
103      ENDDO ! of DO I=1,50
104      STOP 'Jacobi: 50 iterations should never happen'
105      RETURN
106      END SUBROUTINE JACOBI
Note: See TracBrowser for help on using the repository browser.