собственные значения и собственные векторы с использованием библиотек mkl lapack в Фортране - PullRequest
1 голос
/ 06 июля 2011

Я пытаюсь вычислить собственные значения и собственные векторы матриц разных размеров. Я использую кусок очень простого кода на Fortran90 и собираю его, ссылаясь на соответствующие библиотеки Lapack, включенные в пакет Intel MKL, доступный на моей машине, который работает в Ubuntu. Код "matrix_diag_01.f90" прикрепляется в конце сообщения. «Случайный» модуль включает в себя «запускаемый» генератор случайных чисел из Numeric Recipes. Код хорошо компилируется с использованием

ifort -I $(MKLPATH) -o matrix_diag_01 matrix_diag_01.f90 
      random.f90 $(MKLPATH)libmkl_lapack95.a -Wl,--start-group  
      $(MKLPATH)libmkl_intel_lp64.a $(MKLPATH)libmkl_lapack.a 
      $(MKLPATH)libmkl_intel_thread.a $(MKLPATH)libmkl_core.a
       -Wl,--end-group -lguide -lpthread

Исполняемый файл прекрасно работает, когда указаны маленькие матрицы. Однако для матриц размером 3000x3000 это вызывает странное поведение. Сначала выдает эту ошибку

MKL ERROR : Parameter 8 was incorrect on entry to SSYEVD

Однако в вызове SSYEVD есть только 3 параметра. Во-вторых, он возвращает собственные векторы, но не собственные значения. Я проверил, скомпилировав в другой машине с большим объемом памяти, но результат был тот же.

Может кто-нибудь помочь, пожалуйста?

Спасибо!

PROGRAM matrix_diag_01

USE random

IMPLICIT NONE

INTERFACE 
   SUBROUTINE diag(mat,n)
      INTEGER n
      REAL,DIMENSION(n,n) :: mat
   END SUBROUTINE
END INTERFACE 

INTEGER n,i,j,iseed
REAL, DIMENSION(:), ALLOCATABLE  :: w
REAL, DIMENSION(:,:), ALLOCATABLE :: mat

write (*,*) ' Please enter size of matrix'
read (*,*) n
write (*,*) ' Please type seed'
read (*,*) iseed

allocate (mat(n,n))

do i = 1,n
   do j = 1,n
      mat(i,j) = ran(iseed)
   end do
end do

call diag(mat,n)

stop
END
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
SUBROUTINE diag(mat,n)

  USE mkl95_lapack
  USE mkl95_precision

  IMPLICIT NONE

  CHARACTER(len=1) :: jobz = 'V'

  INTEGER n,i

  REAL,DIMENSION(n,n) :: mat
  REAL,DIMENSION(:,:),ALLOCATABLE :: matt,a
  REAL,DIMENSION(:),ALLOCATABLE :: w

  allocate (matt(n,n),a(n,n),w(n))

  matt = mat*transpose(mat)
  a = sqrt(matt)
  open (unit=7,file="matrix.dat",status="unknown")
  do i = 1,n
     write (7,100) a(i,:)
  end do
  close (unit=7)

  call syevd(a,w,jobz)

  open (unit=8,file="eig_val.dat",status="unknown")
  do i = 1,n
     write (8,100) w(i)
  end do
  close (unit=8)

  open (unit=9,file="eig_vec.dat",status="unknown")
  do i = 1,n
     write (9,100) a(i,:)
  end do
  close (unit=9)

  return
 100 format(5000f16.5)
end

1 Ответ

2 голосов
/ 06 июля 2011

Если вы посмотрите на источник функции, которую вы вызываете, она сама выполнит следующий вызов: http://software.intel.com/sites/products/documentation/hpc/mkl/lapack/mkl_lapack_examples/ssyevd_ex.f.htm

 LWORK = MIN( LWMAX, INT( WORK( 1 ) ) )

 CALL SSYEVD( 'Vectors', 'Upper', N, A, LDA, W, WORK, LWORK,
         $             IWORK, LIWORK, INFO )

Предположительно, параметр LWORK неверен.

...