Вы находитесь на странице: 1из 3

DIMENSION AO(3,3), A(3,3)

DATA N,ITMAX, EPS /3,100,1.0E-06/


AO(1,1)=2.0
AO(1,2)=8.0
AO(1,3)=10.
AO(2,1)=8.0
AO(2,2)=3.0
AO(2,3)=4.0
AO(3,1)=10.
AO(3,2)=4.
AO(3,3)=7.0
CALL JACOBI(AO,N,A,EPS,ITMAX)
PRINT 10, (AO(I,I),I=1,N),((A(I,J), J=1,N), I=1,N)
10 FORMAT (1X,'EIGENVALUES ARE',/,3X,3E18.8,//3X,
# 'EIGENVECTORS',/,8X,' FIRST',15X,' SECOND',13X,'THIRD',
# /,(3X,3E18.8))
STOP
END
C **********************************
SUBROUTINE JACOBI (AO,N,A,EPS,ITMAX)
DIMENSION AO(N,N), A(N,N)
ITER=0
DO 10 I=1,N
DO 10 J=1,N
A(I,J)=0.0
10 A(I,I)=1.0
20 Z=0.
NM1=N-1
DO 30 I=1,NM1
IP1=I+1
DO 30 J=IP1,N
IF (ABS(AO(I,J)) .LE. Z) GO TO 30
Z=ABS(AO(I,J))
IROW=I
ICOL=J
30 CONTINUE
IF (ITER .EQ. 0) Y=Z*EPS
IF (Z .LT. Y) GO TO 200
DIF=AO(IROW,IROW)-AO(ICOL,ICOL)
TANG= (-DIF+SQRT(DIF**2+4.0*Z**2))/(2.0*AO(IROW,ICOL))
COSE=1.0/SQRT(1.0+TANG**2)
SINE=COSE*TANG
DO 40 I=1,N
ZZ=A(I,IROW)
A(I,IROW)=COSE*ZZ+SINE*A(I,ICOL)
40 A(I,ICOL)=COSE*A(I,ICOL)-SINE*ZZ
I=1
50 IF (I .EQ. IROW) GO TO 60
YY=AO(I,IROW)
AO(I,IROW)=COSE*YY+SINE*AO(I,ICOL)
AO(I,ICOL)=COSE*AO(I,ICOL)-SINE*YY
I=I+1
GO TO 50
60 I=IROW+1
70 IF (I .EQ. ICOL) GO TO 80
YY=AO(IROW,I)
AO(IROW,I)=COSE*YY+SINE*AO(I,ICOL)
AO(I,ICOL)=COSE*AO(I,ICOL)-SINE*YY
I=I+1
GO TO 70
80 I=ICOL+1
90 IF (I .GT. N) GO TO 100
ZZ=AO(IROW,I)
AO(IROW,I)=COSE*ZZ+SINE*AO(ICOL,I)
AO(ICOL,I)=COSE*AO(ICOL,I)-SINE*ZZ
I=I+1
GO TO 90
100 YY=AO(IROW,IROW)
AO(IROW,IROW)=YY*COSE**2+AO(IROW,ICOL)*2.0*COSE*SINE+
# AO(ICOL,ICOL)*SINE**2
AO(ICOL,ICOL)=AO(ICOL,ICOL)*COSE**2+YY*SINE**2-AO(IROW,ICOL)
# *2.0*COSE*SINE
AO(IROW,ICOL)=0.0
ITER=ITER+1
IF (ITER .LT. ITMAX) GO TO 20
200 RETURN
END

! matrix A
data (a(1,i), i=1,3) / 1.0, 2.0, 3.0 /
data (a(2,i), i=1,3) / 2.0, 2.0, -2.0 /
data (a(3,i), i=1,3) / 3.0, -2.0, 4.0 /

! print a header and the original matrix


write (*,200)
do i=1,n
write (*,201) (a(i,j),j=1,n)
end do

call Jacobi(a,x,abserr,n)

! print solutions
write (*,202)
write (*,201) (a(i,i),i=1,n)
write (*,203)
do i = 1,n
write (*,201) (x(i,j),j=1,n)
end do

200 format (' Eigenvalues and eigenvectors (Jacobi method) ',/, &
' Matrix A')
201 format (6f12.6)
202 format (/,' Eigenvalues')
203 format (/,' Eigenvectors')
end program main

subroutine Jacobi(a,x,abserr,n)
!===========================================================

! initialize x(i,j)=0, x(i,i)=1


! *** the array operation x=0.0 is specific for Fortran 90/95
x = 0.0
do i=1,n
x(i,i) = 1.0
end do

! find the sum of all off-diagonal elements (squared)


b2 = 0.0
do i=1,n
do j=1,n
if (i.ne.j) b2 = b2 + a(i,j)**2
end do
end do

if (b2 <= abserr) return

! average for off-diagonal elements /2


bar = 0.5*b2/float(n*n)

do while (b2.gt.abserr)
do i=1,n-1
do j=i+1,n
if (a(j,i)**2 <= bar) cycle ! do not touch small elements
b2 = b2 - 2.0*a(j,i)**2
bar = 0.5*b2/float(n*n)
! calculate coefficient c and s for Givens matrix
beta = (a(j,j)-a(i,i))/(2.0*a(j,i)) !cotangente2fi
coeff = 0.5*beta/sqrt(1.0+beta**2) !??
s = sqrt(max(0.5+coeff,0.0))
c = sqrt(max(0.5-coeff,0.0))
! recalculate rows i and j
do k=1,n
cs = c*a(i,k)+s*a(j,k)
sc = -s*a(i,k)+c*a(j,k)
a(i,k) = cs
a(j,k) = sc
end do
! new matrix a_{k+1} from a_{k}, and eigenvectors
do k=1,n
cs = c*a(k,i)+s*a(k,j)
sc = -s*a(k,i)+c*a(k,j)
a(k,i) = cs
a(k,j) = sc
cs = c*x(k,i)+s*x(k,j)
sc = -s*x(k,i)+c*x(k,j)
x(k,i) = cs
x(k,j) = sc
end do
end do
end do
end do
return
end

Вам также может понравиться