主题:[讨论]关于矩阵特征向量(fortran与matlab对照)
tianhy2010
[专家分:60] 发布于 2010-08-31 11:06:00
最近一直很疑惑,为什么对于复数矩阵,得到的特征向量会有差距呢?尽管从数学上讲,对于一个矩阵,特征向量有无穷多个,但是yeg001说,matlab是用lapack求解矩阵的, IMSL也是用lapack求解矩阵的. 也就是说二者应该得到相同的特征向量,为了检查到底哪里出了问题,我做了以下操作:
1。matlab和fortran解同一个复数矩阵c(4,4),程序如下:
matlab程序:
clear;
clc;
format long;
t=1;
f=1/4;
w=0.0;
n=3;
C=[w,t*exp(-i*(-pi+2*pi/3*f*(1.5*n+1/4))),0,0;t*exp(i*(-pi+2*pi/3*f*(1.5*n+1/4))),w,t,0;0,t,w,t*exp(i*(-pi+2*pi/3*f*(1.5*(n+1)+1/4)));0,0,t*exp(-i*(-pi+2*pi/3*f*(1.5*(n+1)+1/4))),w];
vvvv=eig(C)
[u,v]=eig(C);
fortran程序:
program main
use IMSL
implicit none
real*8, parameter::pi=3.14159265
complex*16, parameter:: fi=(0.0, 1.0)
real*8 t,f,w,temp
complex*16 ::c(4,4)
complex*16::eigenvector(4,4)
real*8:: eigenvalue(4) !特征值的矩阵
integer ::i,n,j,p
w=0.0
t=1.0
f=0.25
call hmatr(c)
!求矩阵特征值和特征向量
eigenvalue=eig(c,w=eigenvector)
open(1,file='dmatr.txt')
do i=1,4
do j=1,4
write(1,*) c(j,i)
end do
end do
close(1)
!特征值排序
do j=1,4-1
p=j
do i=j+1,4
if(eigenvalue(i)<eigenvalue(p)) p=i
end do
temp=eigenvalue(j)
eigenvalue(j)=eigenvalue(p)
eigenvalue(p)=temp
end do
!特征值求值,写入文件
open(10,file='eeig.txt')
do i=1,4
write(10,*) eigenvalue(i)
end do
close(10)
!将特征向量写入文件
open(20,file='jing2.txt')
do i=1,4
do j=1,4
write(20,*) eigenvector(j,i)
end do
end do
close(20)
stop
contains
subroutine hmatr(c)
integer n0
complex*16:: c(4,4)
c=0.0
n0=3
c(1,1)=w
c(2, 1) = t*exp(fi*(-pi+2.0*pi/3.0*f*(1.5*n0+0.25)))
c(1, 2) = t*exp(-fi*(-pi+2.0*pi/3.0*f*(1.5*n0+0.25)))
c(2, 2) = w
c(2, 3) = t
c(3, 2) = t
c(3, 3) = w
c(3, 4) = t*exp(fi*(-pi+2.0*pi/3.0*f*(1.5*(n0+1)+0.25)))
c(4, 3) = t*exp(-fi*(-pi+2.0*pi/3.0*f*(1.5*(n0+1)+0.25)))
c(4, 4) = w
end subroutine hmatr
end program main
两个程序我都求了,理论上讲应该是相同的,但是不知道为什么,得到的矩阵相同,得到的特征值相同,但是特征向量还是不同啊。是因为复数矩阵的原因吗?
回复列表 (共32个回复)
21 楼
tianhy2010 [专家分:60] 发布于 2010-09-01 13:57:00
能否把你调的程序贴上来我看下啊?用EVCHF怎么提示出错呢,我没用过那个,提示出错了。Error: The type of the actual argument differs from the type of the dummy argument. [EIGENVALUE]
call EVCHF(4, c, 4, eigenvalue, eigenvector, 4)
22 楼
tianhy2010 [专家分:60] 发布于 2010-09-01 13:59:00
你的意思是说,eig函数和EVCHF函数用来求都可以,只是在我的程序中由于对特征值排序但是没对特征向量排序所以出错。能否把你调的程序贴上来我看下啊?我加上EVCHF提示出错了
Error: The type of the actual argument differs from the type of the dummy argument. [EIGENVALUE]
call EVCHF(4, c, 4, eigenvalue, eigenvector, 4)
23 楼
jstzhurj [专家分:4680] 发布于 2010-09-01 14:16:00
program main
use IMSL
implicit none
real*8, parameter::pi=3.14159265
complex*16, parameter:: fi=(0.0, 1.0)
real*8 t,f,w,temp
complex*16 ::c(4,4)
complex*16::eigenvector(4,4)
real*8:: eigenvalue(4)
integer ::i,n,j,p
w=0.0
t=1.0
f=0.25
call hmatr(c)
!求矩阵特征值和特征向量
eigenvalue=eig(c,w=eigenvector)
do i = 1,4
write(*,*) '特征值',eigenvalue(i)
write(*,'(8e20.10)') eigenvalue(i)*eigenvector(:,i)
write(*,'(8e20.10)') matmul(c,eigenvector(:,i))
enddo
contains
subroutine hmatr(c)
integer n0
complex*16:: c(4,4)
c=0.0
n0=3
c(1,1)=w
c(2, 1) = t*exp(fi*(-pi+2.0*pi/3.0*f*(1.5*n0+0.25)))
c(1, 2) = t*exp(-fi*(-pi+2.0*pi/3.0*f*(1.5*n0+0.25)))
c(2, 2) = w
c(2, 3) = t
c(3, 2) = t
c(3, 3) = w
c(3, 4) = t*exp(fi*(-pi+2.0*pi/3.0*f*(1.5*(n0+1)+0.25)))
c(4, 3) = t*exp(-fi*(-pi+2.0*pi/3.0*f*(1.5*(n0+1)+0.25)))
c(4, 4) = w
end subroutine hmatr
end program main
将楼主的程序稍微改动,将排序的一段去掉,验证特征向量特征值的计算是否正确!发现结果完全一致!结论:eig本身没有问题!楼主排序后没有将特征向量对应排序时问题根源所在!
24 楼
jstzhurj [专家分:4680] 发布于 2010-09-01 14:36:00
为了达到排序的目的,程序修改如下:
program main
use IMSL
implicit none
real*8, parameter::pi=3.14159265
complex*16, parameter:: fi=(0.0, 1.0)
real*8 t,f,w,temp
complex*16 ::c(4,4)
complex*16::eigenvector(4,4),eigenvectortmp(4,4)
real*8:: eigenvalue(4)
integer ::i,n,j,p
w=0.0
t=1.0
f=0.25
call hmatr(c)
!求矩阵特征值和特征向量
eigenvalue=eig(c,w=eigenvector)
!特征值特征向量同时排序
do i=1,4
do j=i+1,4
if(eigenvalue(i)>eigenvalue(j)) then
temp=eigenvalue(j)
eigenvalue(j)=eigenvalue(i)
eigenvalue(i)=temp
eigenvectortmp(:,j)=eigenvector(:,j)
eigenvector(:,j)=eigenvector(:,i)
eigenvector(:,i)=eigenvectortmp(:,j)
endif
end do
end do
do i = 1,4
write(*,*) '特征值',eigenvalue(i)
write(*,'(8e20.10)') eigenvalue(i)*eigenvector(:,i)
write(*,'(8e20.10)') matmul(c,eigenvector(:,i))
enddo
contains
subroutine hmatr(c)
integer n0
complex*16:: c(4,4)
c=0.0
n0=3
c(1,1)=w
c(2, 1) = t*exp(fi*(-pi+2.0*pi/3.0*f*(1.5*n0+0.25)))
c(1, 2) = t*exp(-fi*(-pi+2.0*pi/3.0*f*(1.5*n0+0.25)))
c(2, 2) = w
c(2, 3) = t
c(3, 2) = t
c(3, 3) = w
c(3, 4) = t*exp(fi*(-pi+2.0*pi/3.0*f*(1.5*(n0+1)+0.25)))
c(4, 3) = t*exp(-fi*(-pi+2.0*pi/3.0*f*(1.5*(n0+1)+0.25)))
c(4, 4) = w
end subroutine hmatr
end program main
计算结果证明,eig计算的特征值特征向量,验证结果完全自洽!
25 楼
tianhy2010 [专家分:60] 发布于 2010-09-01 14:51:00
[em20][em28][em28][em28][em28][em28][em28][em28][em28][em28][em28]
确实是排序出问题了,看来eig函数是没问题的。特征值排序了,但是特征向量没有跟着动。
可是我需要让特征值排序啊,让它从小到大排列,有没有办法让特征向量跟随特征值变动呢?
能否在对特征值排序的同时,也对特征向量进行排序呢?让它跟着特征值走
do j=1,4*n*m-1
p=j
do i=j+1,4*m*n
if(eigenvalue(i)<eigenvalue(p)) p=i
end do
temp=eigenvalue(j)
eigenvalue(j)=eigenvalue(p)
eigenvalue(p)=temp
ten=eigenvector(:,j)
eigenvector(:,j)=eigenvector(:,p)
eigenvector(:,p)=ten
end do
26 楼
tianhy2010 [专家分:60] 发布于 2010-09-01 15:07:00
特征向量这样排序了。我试了下,还真行!!果然特征向量随着特征值走了
27 楼
jstzhurj [专家分:4680] 发布于 2010-09-01 15:13:00
[quote]特征向量这样排序了。我试了下,还真行!!果然特征向量随着特征值走了[/quote]
最终问题还是出在自己写的程序上!怀疑这,怀疑那,唯独没有从自己的程序上下手!!!转了一圈,回到原点......
28 楼
tianhy2010 [专家分:60] 发布于 2010-09-01 15:19:00
[em6][em6][em6][em1][em1][em1][em21][em21][em21][em21][em21][em22][em22][em22][em22][em22][em57][em57][em57][em57][em57][em58][em58][em58][em58][em58][em59][em59][em59][em59][em59][em59][em62][em62][em62][em62][em62][em62][em52][em52][em52][em52][em52][em52]
29 楼
jstzhurj [专家分:4680] 发布于 2010-09-01 15:24:00
yeg001在8楼,我在11楼都已经提到了特征向量排序的问题![em18][em15][em13][em9]
30 楼
tianhy2010 [专家分:60] 发布于 2010-09-01 15:42:00
[em35][em35][em35][em35][em35][em35][em35][em35][em46][em46][em46][em46][em46][em46][em52][em52][em52][em52]
今年第一次编程
我来回复