Улучшение подпрограммы Fortran - PullRequest
0 голосов
/ 29 октября 2019

Я построил подпрограмму в Фортране, и она работает нормально и правильно, но на это уходит больше времени, чем нужно.

Есть идеи, как мне улучшить эту подпрограмму? Может быть, изменение способа объявления параметров или удаление некоторых ненужных do.

ZGESV и ZGEEV являются подпрограммами от Лапака для решения линейных сложных систем (например: A * x = B).

Subroutine arnoldi(m,n,A,B,sigma,eig,INFO)
implicit none

integer, intent(in) :: n, m
integer, intent(out)    :: INFO
complex(8), intent(in)  :: sigma
complex(8), dimension(m), intent(out)   :: eig
complex(8), dimension(n,n), intent(in)  :: A,B

! Argumentos
integer :: i, j, LDVL, LDVR, one
integer ::  LWORK
integer, dimension(n) :: IPIV
complex(8), dimension(n) :: r, q
complex(8), dimension(n,n) :: C
complex(8), dimension (m,m) :: VL,VR 
complex(8), dimension(6*(m+1)) :: WORK
complex(8), dimension(m+1,m) :: h
complex(8), dimension(n,m+1) :: v
complex(8), dimension(m,m) :: hh
real(8), dimension(8*(m+1)) :: RWORK
character :: JOBVL, JOBVR

! Lapack
JOBVL = 'N'
JOBVR = 'N'
LWORK = 6*(m+1) 
LDVL = 2*(m+1)
LDVR = 2*(m+1)
one = 1

! Arnoldi
q = dcmplx(1.0d0,0.0d0)
q = q/norm2(zabs(q))
v(:,1) = q

C = A - sigma*B

do i = 1,m

    r = Matmul(B,v(:,i))

    CALL ZGESV(n,one,C,n,IPIV,r,n,INFO)

    do j = 1,i
            h(j,i) = dot_product(v(:,j),r)
            r = r - v(:,j)*h(j,i)
    end do

    if (i.lt.n) then 
            h(i+1,i) = norm2(zabs(r))
        if (zabs(h(i+1,i)).lt.1.0d-7) exit
            v(:,i+1) = r/h(i+1,i)
    end if

end do



do i = 1,m

    do j = 1,m
            HH(i,j) = h(i,j)
    end do

end do

CALL ZGEEV(JOBVL,JOBVR,m,HH,m,eig,VL,LDVL,VR,LDVR,WORK,LWORK,RWORK,INFO)

! Autovalores
do i=1,m
   eig(i) = dcmplx(1.0d0,0.0d0)/eig(i) + sigma
end do

end subroutine
...