fortran用MKL库求对称矩阵本征问题

31 篇文章 3 订阅
3 篇文章 3 订阅

安装oneAPI(Intel Fortran编译器)

Intel oneAPI Base Toolkit
Intel oneAPI HPC Toolkit
可以选择下载安装或者在线安装,下载的话需要用教育邮箱登陆。

尝试MKL库

参考官方文档Symmetric Eigenproblems
比如:

Fortran

program main
    implicit none
    integer*4,parameter::n=5,lda=5,lwmax=1000
!     .. Local Scalars ..
    INTEGER::INFO, LWORK
!
!     .. Local Arrays ..
    REAL*8::A( LDA, N ),  W( N ), WORK( LWMAX )
    DATA             A/&
       &1.96, 0.00, 0.00, 0.00, 0.00,&
      &-6.49, 3.80, 0.00, 0.00, 0.00,&
      &-0.47,-6.39, 4.17, 0.00, 0.00,&
      &-7.20, 1.50,-1.51, 5.70, 0.00,&
      &-0.65,-6.34, 2.67, 1.80,-7.10/
!
!     .. External Subroutines ..
    EXTERNAL         DSYEV
    EXTERNAL         PRINT_MATRIX
!
!     .. Intrinsic Functions ..
    INTRINSIC        INT, MIN
!
!     .. Executable Statements ..
    WRITE(*,*)'SSYEV Example Program Results'
!     
!     Query the optimal workspace.
!       
    LWORK = -1
    CALL DSYEV( 'Vectors', 'Upper', N, A, LDA, W, WORK, LWORK, INFO )
    LWORK = MIN( LWMAX, INT( WORK( 1 ) ) )
!
!     Solve eigenproblem.
!
    CALL DSYEV( 'Vectors', 'Upper', N, A, LDA, W, WORK, LWORK, INFO )
!
!     Check for convergence.
!
    IF( INFO.GT.0 ) THEN
        WRITE(*,*)'The algorithm failed to compute eigenvalues.'
        STOP
    END IF
!
!     Print eigenvalues.

    !call insert_sort(w,N)
    CALL PRINT_MATRIX( 'Eigenvalues', 1, N, W, 1 )
!      
!     Print eigenvectors.
!
    CALL PRINT_MATRIX( 'Eigenvectors (stored columnwise)', N, N, A,LDA )
    STOP
end program
!
!     End of SSYEV Example.
!
!  =============================================================================
!
!     Auxiliary routine: printing a matrix.
!
subroutine PRINT_MATRIX( DESC, M, N, A, LDA )
    implicit none
    CHARACTER*(*)    DESC
    INTEGER          M, N, LDA
    REAL*8             A( LDA, * )
    !
    INTEGER          I, J
    !
    WRITE(*,*)
    WRITE(*,*) DESC
    DO I = 1, M
        WRITE(*,9998) ( A( I, J ), J = 1, N )
    END DO
    !
    9998 FORMAT( 11(:,1X,e30.20) )
    RETURN
end subroutine

注意编译时后面要加上-mkl,如

ifort test.f90 -o test -mkl

最后的结果为

SSYEV Example Program Results
 
 Eigenvalues
    -0.11065575232626278179E+02    -0.62287466937218827212E+01     0.86402803023585872388E+00     0.88654570265779408800E+01     0.16094836840924127586E+02

 Eigenvectors (stored columnwise)
    -0.29806697142941551704E+00    -0.60751344955327046815E+00     0.40261995251418697395E+00    -0.37448098436165483394E+00     0.48963726915317773436E+00
    -0.50779843411371539119E+00    -0.28796757291700009196E+00    -0.40658568098689418235E+00    -0.35716882040996411618E+00    -0.60525527259440614625E+00
    -0.81606186905410313392E-01    -0.38432041912929776339E+00    -0.65996550612182380835E+00     0.50076383196156670774E+00     0.39914829453170985740E+00
    -0.35892968587850466143E-02    -0.44672977485209214299E+00     0.45528986722532166498E+00     0.62036521460984062060E+00    -0.45637458574365619146E+00
    -0.80412957790481354170E+00     0.44803170564264482856E+00     0.17245847437922906531E+00     0.31076842049946928892E+00     0.16224757660015381999E+00

由于输出的本征值并不总是按从小到大的顺序的,所以有时我们需要一个子程序对本征值数组排序,排序的算法很多,比较简单的如插入排序:

subroutine insert_sort(A,num)
   implicit none
   real*8::A(*),key
   integer*4::num,i,j,k,temp
   !num=size(A)
   do j=1,num
       key=A(j)
       i=j-1
       temp=j
       do k=i,1,-1
           if(A(k)<key)then
               A(k+1)=A(k)
               temp=k
           endif
       enddo
       A(temp)=key
   enddo
end subroutine

C++

类似地

#include <stdio.h>
#include <stdlib.h>
#include <mkl.h>
//extern void dsyev( char* jobz, char* uplo, int* n, double* a, int* lda,
           //     double* w, double* work, int* lwork, int* info );
/* Auxiliary routines prototypes */
#define N 5 
#define LDA N
void print_matrix( char* desc, int m, int n, double* a, int lda );

int main(){
	int n = N, lda = LDA, info, lwork;
	double wkopt;
	double* work;
	/* Local arrays */
	double w[N];
	double a[LDA*N] = {
		1.96,  0.00,  0.00,  0.00,  0.00,
		-6.49,  3.80,  0.00,  0.00,  0.00,
		-0.47, -6.39,  4.17,  0.00,  0.00,
		-7.20,  1.50, -1.51,  5.70,  0.00,
		-0.65, -6.34,  2.67,  1.80, -7.10
	};
	printf( " DSYEV Example Program Results\n" );
    /* Query and allocate the optimal workspace */
    lwork = -1;
    dsyev( "Vectors", "Upper", &n, a, &lda, w, &wkopt, &lwork, &info );
    lwork = (int)wkopt;
    work = (double*)malloc( lwork*sizeof(double) );
    /* Solve eigenproblem */
    dsyev( "Vectors", "Upper", &n, a, &lda, w, work, &lwork, &info );
    /* Check for convergence */
    if( info > 0 ) {
        printf( "The algorithm failed to compute eigenvalues.\n" );
        exit( 1 );
    }
    /* Print eigenvalues */
    print_matrix( "Eigenvalues", 1, n, w, 1 );
    /* Print eigenvectors */
    print_matrix( "Eigenvectors (stored columnwise)", n, n, a, lda );
    /* Free workspace */
    free( (void*)work );
    exit( 0 );
}
void print_matrix( char* desc, int m, int n, double* a, int lda ) {
        int i, j;
        printf( "\n %s\n", desc );
        for( i = 0; i < m; i++ ) {
                for( j = 0; j < n; j++ ) printf( " %6.2f", a[i+j*lda] );
                printf( "\n" );
        }
}

编译时也需要加上-mkl

icc demo1.cpp -o demo1 -mkl

结果为

 DSYEV Example Program Results

 Eigenvalues
 -11.07  -6.23   0.86   8.87  16.09

 Eigenvectors (stored columnwise)
  -0.30  -0.61   0.40  -0.37   0.49
  -0.51  -0.29  -0.41  -0.36  -0.61
  -0.08  -0.38  -0.66   0.50   0.40
  -0.00  -0.45   0.46   0.62  -0.46
  -0.80   0.45   0.17   0.31   0.16
### 回答1: Fortran是一种高级的编程语言,广泛用于科学计算和数值分析。而MKL(Math Kernel Library)是Intel为其处理器提供的一套数学函数库,包含了高效的线性代数运算和矩阵计算函数。 如果要在Fortran中使用MKL求逆,首先需要确保已经正确地安装了MKL,并将其链接到Fortran编译器。 接下来,我们需要定义一个矩阵,并用MKL提供的函数将其求逆。使用MKL求逆可以通过以下步骤完成: 1. 导入MKL库函数。可以使用Fortran的内置`use mkl`语句来导入MKL库函数。 2. 定义矩阵。在Fortran中,我们可以使用多维数组来定义矩阵。 3. 调用MKL的逆函数。MKL提供了多种求逆函数,可以根据具体需求选择适合的函数。最常用的函数是`LAPACK`库中的逆函数。我们可以使用`mkl_lapack_dgetrf`函数对矩阵进行LU分解,然后使用`mkl_lapack_dgetri`函数求解逆矩阵。 4. 输出逆矩阵。可以使用Fortran的内置`print`函数将逆矩阵打印出来。 最后,编译和运行程序即可得到矩阵的逆。 总之,Fortran中可以使用MKL库中的函数来求逆矩阵。使用MKL可以提高计算效率,特别是对于大规模的矩阵运算。但使用MKL需要正确配置和链接,具体步骤可以参考Intel的官方文档或示例代码。 ### 回答2: Fortran是一种计算机编程语言,而MKL是指Intel Math Kernel Library(英特尔数学核心库)。该库提供了一套高性能的数学函数和算法,可以用于进行数值计算和科学计算。 在Fortran中使用MKL库求矩阵的逆是相对简单的。下面是一种可能的实现方法: 1. 首先,引入MKL库。在Fortran程序的开头使用`use mkl`语句来导入MKL库。 2. 定义矩阵并初始化。可以使用Fortran的二维数组来表示矩阵,并使用相应的赋值语句来初始化矩阵中的元素。 3. 使用MKL提供的函数进行逆矩阵计算。MKL库中包含了一些用于矩阵运算的子程序,可以直接调用来计算矩阵的逆。 4. 对于求逆操作,可以使用MKL提供的函数`?getri`,其中`?`代表数据类型(如`dgetri`表示双精度浮点数矩阵的逆)。 5. 调用求逆函数并检查返回值以确保操作成功。可以使用Fortran的`if`语句来检查函数返回的结果,以确定是否成功求得逆矩阵。 6. 输出逆矩阵。可以使用Fortran的输出语句(如`write`语句)将结果打印到屏幕上或保存到文件中。 需要注意的是,在使用MKL求解逆矩阵之前,应确保MKL库已正确安装,并且在编译Fortran程序时链接了MKL库。具体的编译和链接参数可以参考MKL库的文档。 以上就是使用FortranMKL求解逆矩阵的简要步骤。实际操作中可能还需要根据具体情况进行适当调整和优化。 ### 回答3: Fortran是一种编程语言,MKL(Math Kernel Library)是英特尔提供的数学运算库。在Fortran程序中使用MKL库可以方便地进行各种数值计算,包括矩阵的求逆。 要在Fortran中使用MKL库求矩阵的逆,需要进行以下步骤: 1. 导入MKL库。在Fortran程序开头使用`USE mkl`语句导入MKL库。 2. 声明变量和数组。在程序中声明需要用到的变量和数组,包括输入矩阵和输出矩阵。 3. 调用MKL函数。使用MKL库提供的函数进行矩阵求逆的计算。例如使用`DGETRF`函数进行LU分解,再使用`DGETRI`函数进行矩阵的逆运算。 4. 检查返回值。对MKL函数的返回值进行检查,以确保矩阵求逆的计算是否成功。 5. 输出结果。将计算得到的矩阵逆输出到文件或者其他数据结构中,以供后续使用。 总结来说,利用Fortran语言编写程序,在使用MKL库的支持下,我们可以很方便地求解矩阵的逆运算。MKL库提供了一套强大的数学运算函数,可以大大简化数值计算的编程过程,加快计算速度,并且保证计算的准确性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值