Home ,
Post
#*************************************************************
#* This subroutine computes all eigenvalues and eigenvectors *
#* of a real symmetric square matrix A(N,N). On output, ele- *
#* ments of A above the diagonal are destroyed. D(N) returns *
#* the eigenvalues of matrix A. V(N,N) contains, on output, *
#* the eigenvectors of A by columns. THe normalization to *
#* unity is made by main program before printing results. *
#* NROT returns the number of Jacobi matrix rotations which *
#* were required. *
#* --------------------------------------------------------- *
#* Ref.:"NUMERICAL RECIPES, Cambridge University Press, 1986,*
#* chap. 11, pages 346-348" [BIBLI 08]. *
#*************************************************************
def Jacobi(A,N,D,V,NROT):
#integer N,NROT
#real*8 A(1:N,1:N),D(1:N),V(1:N,1:N)
#real*8, pointer :: B(:), Z(:)
#real*8 c,g,h,s,sm,t,tau,theta,tresh
#allocate(B(1:100),stat=ialloc)
#allocate(Z(1:100),stat=ialloc)
for ip in range(0, N): #initialize V to identity matrix
for iq in range(0, N):
V[ip,iq]=0.0
V[ip,ip]=1.0
for ip in range(0, N):
B[ip]=A[ip,ip]
D[ip]=B[ip]
Z[ip]=0.0
NROT=0
for i in range(0, 50):
sm=0.0
for ip in range(0, N-1): #sum off-diagonal elements
for iq in range(ip+1, N):
sm=sm+abs(A[ip,iq])
if(sm==0.0) return #normal return
if(i < 4) :
tresh=0.20*sm**2
else:
tresh=0.0
## end if
for ip in range(0, N-1):
for iq in range(ip+1, N):
g=100.0*abs(A[ip,iq])
# after 4 sweeps, skip the rotation if the off-diagonal element is small
if((i > 4) and (abs(D[ip])+g == abs(D[ip])) \
and (abs(D[iq])+g == abs(D[iq]))) :
A[ip,iq]=0.0
elif(abs(A[ip,iq]) > tresh) :
h=D[iq]-D[ip]
if(abs(h)+g == abs(h)) :
t=A[ip,iq]/h
else:
theta=0.50*h/A[ip,iq]
t=1.0/(abs(theta)+math.sqrt(1.0+theta**2))
if(theta < 0.0) t=-t
## end if
c=1.0/math.sqrt(1.0+t**2)
s=t*c
tau=s/(1.0+c)
h=t*A[ip,iq]
Z[ip]=Z[ip]-h
Z[iq]=Z[iq]+h
D[ip]=D[ip]-h
D[iq]=D[iq]+h
A[ip,iq]=0.0
for j in range(0, ip-1):
g=A[j,ip]
h=A[j,iq]
A[j,ip]=g-s*(h+g*tau)
A[j,iq]=h+s*(g-h*tau)
for j in range(ip+1, iq-1):
g=A[ip,j]
h=A[j,iq]
A[ip,j]=g-s*(h+g*tau)
A[j,iq]=h+s*(g-h*tau)
for j in range(iq+1, N):
g=A[ip,j]
h=A[iq,j]
A[ip,j]=g-s*(h+g*tau)
A[iq,j]=h+s*(g-h*tau)
for j in range(0, N):
g=V[j,ip]
h=V[j,iq]
V[j,ip]=g-s*(h+g*tau)
V[j,iq]=h+s*(g-h*tau)
NROT=NROT+1
## end if #if ((i > 4)...
#main iq loop
#main ip loop
for ip in range(0, N):
B[ip]=B[ip]+Z[ip]
D[ip]=B[ip]
Z[ip]=0.0
#main i loop
#pause ' 50 iterations #'
return
# end
# end of file ujacobi.f90
Home ,
Post