wrong eigenvectors using zgeev.f - fortran

I'm trying to diagonalize a non-hermitian matrix using the subroutine zgeev in lapack. But checking the right eigenvectors and the left eigenvectors it is possible to see that they are incorrect. Does anyone know why? I checked the eigenvalues and they are corrects.
program complex_diagonalization
implicit none
integer,parameter :: N=4
integer::i,j
integer, parameter:: LWMAX=1000
integer,parameter :: LDA=N,LDVL=N,LDVR=N
real(kind=8),parameter::q=-dsqrt(3.0d0)
integer :: INFO,LWORK
real(kind=8) :: RWORK(2*N)
complex*16 :: B(LDA,N),VL(LDVL,N),VR(LDVR,N),W(N),WORK(2*N)
external::zgeev
!matrix defining
B(1,1)=0.0d0; B(1,2)=-1.0d0; B(1,3)=0.0d0; B(1,4) =0.0d0
B(2,1)=0.0d0; B(2,2)=0.0d0; B(2,3)=-2.0d0; B(2,4) =0.0d0
B(3,1)=-1.0d0; B(3,2)=0.0d0; B(3,3)=0.0d0; B(3,4) =q
B(4,1)=0.0d0; B(4,2)=q; B(4,3)=0.0d0; B(4,4) =0.0d0
LWORK=-1
CALL ZGEEV('V','V',N,B,LDA,W,VL,LDVL,VR,LDVR,WORK,LWORK,RWORK,INFO)
LWORK=Max(LWMAX,INT(WORK(1)))
CALL ZGEEV('V','V',N,B,LDA,W,VL,LDVL,VR,LDVR,WORK,2*N,RWORK,INFO)
IF( INFO.GT.0 ) THEN
WRITE(*,*)'The algorithm failed to compute eigenvalues.'
STOP
END IF
!eigenvalues
do i=1,N
WRITE(*,*)W(i)
enddo
write(*,*)
write(*,*)
! eigenvalues and right eigenvectors
do i=1,N
write(*,*) 'eigenvalue->', w(i)
write(*,*)
WRITE(*,*) 'right eigvector->', (VR(i,j),j=1,N)
write(*,*)
ENDDO
write(*,*)
write(*,*)
!eigenvalues and left eigenvectors
do i=1,N
WRITE(*,*) 'eigenvalue->', w(i)
write(*,*)
WRITE(*,*) 'left eigvector->', (Vl(i,j),j=1,N)
write(*,*)
ENDDO
end
This is the result for eigenvalues and eigenvectors
(-2.00000000000000,-1.110223024625157E-016)
(1.00000000000000,1.73205080756888)
(1.00000000000000,-1.73205080756888)
(0.000000000000000E+000,0.000000000000000E+000)
eigenvalue-> (-2.00000000000000,-1.110223024625157E-016)
right eigvector-> (0.288675134594813,8.847089727481716E-017)
(-0.144337567297406,-0.250000000000000) (-0.144337567297406,-0.250000000000000)
(0.866025403784438,0.000000000000000E+000)
eigenvalue-> (1.00000000000000,1.73205080756888)
right eigvector-> (0.577350269189626,2.289834988289385E-016)
(-0.288675134594813,0.500000000000000)
(0.577350269189626,0.000000000000000E+000)
(0.000000000000000E+000,0.000000000000000E+000)
eigenvalue-> (1.00000000000000,-1.73205080756888)
right eigvector-> (0.577350269189626,0.000000000000000E+000)
(0.577350269189626,0.000000000000000E+000)
(-0.288675134594813,0.500000000000000)
(0.000000000000000E+000,0.000000000000000E+000)
eigenvalue-> (0.000000000000000E+000,0.000000000000000E+000)
right eigvector-> (0.500000000000000,2.463307335887066E-016)
(-0.250000000000000,-0.433012701892219) (-0.250000000000000,-0.433012701892219)
(-0.500000000000000,0.000000000000000E+000)
eigenvalue-> (-2.00000000000000,-1.110223024625157E-016)
left eigvector-> (0.288675134594813,2.949029909160572E-017)
(-0.144337567297406,-0.250000000000000) (-0.144337567297406,-0.250000000000000)
(0.866025403784438,0.000000000000000E+000)
eigenvalue-> (1.00000000000000,1.73205080756888)
left eigvector-> (0.577350269189626,3.157196726277789E-016)
(-0.288675134594813,0.500000000000000)
(0.577350269189626,0.000000000000000E+000)
(0.000000000000000E+000,0.000000000000000E+000)
eigenvalue-> (1.00000000000000,-1.73205080756888)
left eigvector-> (0.577350269189626,0.000000000000000E+000)
(0.577350269189626,0.000000000000000E+000)
(-0.288675134594813,0.500000000000000)
(0.000000000000000E+000,0.000000000000000E+000)
eigenvalue-> (0.000000000000000E+000,0.000000000000000E+000)
left eigvector-> (0.500000000000000,1.491862189340054E-016)
(-0.250000000000000,-0.433012701892219) (-0.250000000000000,-0.433012701892219)
(-0.500000000000000,0.000000000000000E+000)
Even the right eigenvectors doesn't satisfy the condition H*v(j)=lambda(j)*v(j).

Related

Integral of 1D array in Fortran

The task is to write the code for calculating integral of the polynomial function. the function id displayed in the image I attached. I wrote the code and it compiled and the answer came out. However, it is completely different with the analytical solution. The code:
program rectangularApproximation
write(*,*) "Input values of a ,b and eps"
read(*,*) a,b,eps
1 continue
n=1000
h=(b-a)/n
s=0.0
do i=1,n
x=a+h*i
s=s+f(x)*h
enddo
sprev=s
n=10*n
h=(b-a)/n
s=0.0
do i=1,n
x=a+h*i
s=s+f(x)*h
enddo
snext=s
if (abs(sprev-snext)<eps) then
write(*,*) snext,n
stop
end if
goto 1
write(*,*) s
end
real function f(x)
implicit none
real, intent(in) :: x
integer :: i
real, dimension(8) :: numbers
numbers = (/1,3,1,4,2,3,0,1 /)
do i = 1,8
f = f + numbers(i) * x**(numbers(i))
end do
end function
The result obtained by running the code is 588189248 (the interval (a,b) is (1,2) and i chose epsillon=0.001) Analytical solution is following :
The answer of analytical solution is 169.256 . What could have gone wrong in my code?
Your polynomial code is wrong:
do i = 1,8
f = f + numbers(i) * x**(numbers(i))
end do
That should be
do i = 1,8
f = f + numbers(i) * x**i
end do

MPI_WTIME is not giving me speedup as required

Program Main
implicit none
include 'mpif.h'
!Define parameters
integer::my_rank,p2,n2,ierr,source
integer, parameter :: n=3,m=3,o=m*n
real(kind=8) aaa(n),ddd(n),bbb(n),ccc(n),xxx(n),b(m,n),start, finish
integer i, j
real h
real(kind=8),dimension(:),allocatable::sol1
h=0.25
b=0
do i=1,m
b(i,i)=1/(1.2**i)
b(i,i-1)=-b(i,i)
enddo
call MPI_INIT(ierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD,p2,ierr)
call MPI_COMM_RANK(MPI_COMM_WORLD,my_rank,ierr)
allocate(sol1(o))
start=MPI_WTIME()
do i=1,n
aaa(i)=-1/h**2
bbb(i)=2/h**2+b(my_rank+1,my_rank+1)
ccc(i)=-1/h**2
ddd(i)=1/h**2
enddo
call thomas(aaa,bbb,ccc,ddd,xxx,n)
finish=MPI_WTIME()
print*, finish-start
write(*,*) xxx, my_rank
call MPI_GATHER(xxx,n, MPI_REAL, sol1,n,MPI_REAL8,0, MPI_COMM_WORLD,ierr)
print*,sol1
call MPI_FINALIZE(ierr)
end program main
subroutine thomas(ld,md,ud,rh,solution,n)
implicit none
integer,parameter :: r8 = kind(1.d0)
integer,intent(in) :: n
real(r8),dimension(n),intent(in) :: ld,md,ud,rh
real(r8),dimension(n),intent(out) :: solution
real(r8),dimension(n) :: P,Q
real(r8) :: m
integer i
P(1) = ud(1)/md(1)
Q(1) = rh(1)/md(1)
do i = 2,n
m = md(i)-p(i-1)*ld(i)
P(i) = ud(i)/m
Q(i) = (rh(i)-Q(i-1)*ld(i))/m
end do
solution(n) = Q(n)
do i = n-1, 1, -1
solution(i) = Q(i)-P(i)*solution(i+1)
end do
end subroutine thomas
Here I used MPI_WTIME() to find the execution time. It seems like when I increase the number of processor than I am not getting the speedup. In this code I have m=3 (I make m equal equal to no of processor). I run with mpirun -np 3 sp.exe). Now I change say m=10 and run with mpirun -np 10 sp.exe. I should get the less time, isn't it? or I am missing something here. The community helped me before with some issues and now I am getting another issue. I would really appreciate the help if somebody would point out something.Isn't the chunk of code starting with do loop done by invidual processors( which I want)?

I want to make a matrix(6,6) but it shows me other values (serves for newtonian interpolation)

First, I calculated the lower triangle and the main diagonal values with the formula: f(i,j)=(f(i,j-1))-(f(i-1,j-1))/(x(i)- x(i-j), I made the matrix(6,6) so i can have the main diagonal from it, which values are defined with b in the code and shown as "Cosntante" in the promt.
Then i did the interpolation defined as p in the code and shown as " El valor aproximado de f() es:" in the promt.
program p4
use ISO_C_Binding
implicit none
real :: x(6), y(6), b(6), xi, p
integer :: i, j, n, m, k
real, dimension(6,6) :: f=c_float
f=0
x=[1.6, 2.0, 2.5, 3.2, 4.0, 4.5]
y=[2, 8, 14, 15, 8, 2]
n=SIZE(x)
do i=1,n
f(i,1)=y(i)
end do
do i=1,n
f(i,2:n)=0
end do
do j=2,n
do i=j,n
f(i,j)=(f(i,j-1))-(f(i-1,j-1))/(x(i)- x(i-j))
end do
end do
do i=1,n
write(*,*) F(i,:)
end do
do i=1,n
b(i)=f(i,i)
write(*,*) "Constante b[",i,"]=",b(i)
end do
xi=2.8
m=size(x)-1
p=b(m)
do k=2,m+1
p=(b(m-k))+(xi-((x(m-k))*p))
end do
write(*,*) "El valor aproximado de f(",xi,") es:",p
pause
end program p4
it shows me the next values (these are the values i get in ForceFortran):
And it should show me (these are the values i get in Python):
What should i do?

I want to show a 4*5 matrix and my program is no error,but when I run it show me the program stop work

my program display no error but it can't work?
program hw4
dimension a(i,j)
real a
common i,j
integer i,j
do i=1,4,1
do j=1,5,1
a(1,1)=0
a(1,2)=1
a(1,3)=2
a(1,4)=3
a(1,5)=25
a(2,1)=1
a(2,2)=1
a(2,3)=1
a(2,4)=1
a(2,5)=12
a(3,1)=2
a(3,2)=0
a(3,3)=3
a(3,4)=1
a(3,5)=19
a(4,1)=3
a(4,2)=4
a(4,3)=0
a(4,4)=6
a(4,5)=41
write(*,*) a(i,j)
enddo
enddo
stop
end
I expect it will show 4*5 matrix,but now it will show me the program stop work message
Firstly, your matrix "a" must have constant shape i.e. dimensions "i" and "j" must be explicitly defined.
Secondly, your nested loop sets matrix values every loop. Try putting it before the loop.
Something like:
program hw4
implicit none
integer, parameter :: ni=4, nj=5
real, dimension(ni,nj) :: a
integer :: i, j
! Set matrix values here
a(1,1) = 0
! ...
do i = 1, ni, 1
do j = 1, nj, 1
write(*,*) a(i,j)
end do
end do
end program hw4
Kind regards

Unclassifiable statement in an equation in Fortran

So far my code is working properly except I am now getting a compiler error error like this:
std =std +((x(I) -xbar))**2)
1
Error: Unclassifiable statement at (1)
Here is my code:
program cardata
implicit none
real, dimension(291) :: x
intEGER I,N
double precision date, odometer, fuel
real :: std=0
real :: xbar=0
open(unit=10, file="car.dat", FOrm="FORMATTED", STATUS="OLD", ACTION="READ")
read(10,*) N
do I=1,N
read(10,*) x(I)
xbar= xbar +x(I)
enddo
xbar = xbar/N
DO I =1,N
std =std +((x(I) -xbar))**2
enddo
std = SQRT((std / (N - 1)))
print*,'mean:',xbar
print*, 'std deviation:',std
close(unit=10)
end program cardata
I am fairly new to this, any input will be greatly appreciated.
Count the parentheses.
std =std +((x(I) -xbar))**2)
There are three of these: (
There are four of these: )
Since this is likely a course I will help you how to debug.
Basically start with some write statements... Check your answers...
program cardata
implicit none
...
read(10,*) N
WRITE(*,*)' I read N as ',N
WRITE(*,*)'XBar starts as ', Xbar
do I=1,N
...
! was XBAr ever set to start at 0!
xbar= xbar +x(I)
...
WRITE(*,*)'Syd starts as ',Std
DO I =1,N
std =std +((x(I) -xbar))**2
enddo
WRITE(*,*)'Std starts is now ',Std,' and n =',N
! What do we do if N=1 or is Std is negative?
WRITE(*,*)'SQRT(Std)=', SQRT(Std)
std = SQRT((std / (N - 1)))
...
At some point You will determine that X is a column, and it is the first column. What is the second column? Y?