Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用Fortran90中的LAPACK,BLAS计算矩阵的逆_Fortran_Matrix Multiplication_Lapack_Blas_Matrix Inverse - Fatal编程技术网

用Fortran90中的LAPACK,BLAS计算矩阵的逆

用Fortran90中的LAPACK,BLAS计算矩阵的逆,fortran,matrix-multiplication,lapack,blas,matrix-inverse,Fortran,Matrix Multiplication,Lapack,Blas,Matrix Inverse,我不熟悉使用LAPACK/BLAS。我想计算一个方程的解: AU=F 我想知道这部分代码中的逻辑错误是什么。其中,我使用解算器输入大小为((xdiv-1)(ydiv-1)、(xdiv-1)(ydiv-1))的矩阵A。然后,随后求解该方程。U=逆(A)*f 式中,U和f的尺寸相同。(U((xdiv-1)(ydiv-1),1),f((xdiv-1)(ydiv-1),1))。我在执行矩阵求逆时遇到分段错误 这是我的密码: program main double precision, allocatab

我不熟悉使用LAPACK/BLAS。我想计算一个方程的解:

AU=F

我想知道这部分代码中的逻辑错误是什么。其中,我使用解算器输入大小为((xdiv-1)(ydiv-1)、(xdiv-1)(ydiv-1))的矩阵A。然后,随后求解该方程。U=逆(A)*f

式中,U和f的尺寸相同。(U((xdiv-1)(ydiv-1),1),f((xdiv-1)(ydiv-1),1))。我在执行矩阵求逆时遇到分段错误

这是我的密码:

program main
double precision, allocatable :: A(:,:)
double precision, allocatable :: u(:,:), f(:,:)
double precision mesh(2), dx, dy
integer  xdiv, ydiv
 xdiv=55
 ydiv=55
 mesh(1)=.001
 mesh(2)=.001
 dx=mesh(1)
 dy=mesh(2)

allocate (A((xdiv-1)*(ydiv-1),(xdiv-1)*(ydiv-1))) 
allocate (Ainv((xdiv-1)*(ydiv-1),(xdiv-1)*(ydiv-1)))
allocate (u((xdiv-1)*(ydiv-1),1),f((xdiv-1)*(ydiv-1),1))

         do i =1,(xdiv-1)*(ydiv-1)
         A(i,i)=-2.d0*(1.d0/(dx**2)+1.d0/(dy**2))
         enddo
         do i=1,(xdiv-2)
         do j=1,(ydiv-1)
         A(i+(j-1)*(xdiv-1),i+(j-1)*(xdiv-1)+1)=1.d0/(dx**2)
         A(i+(j-1)*(xdiv-1)+1,i+(j-1)*(xdiv-1))=1.d0/(dx**2)
         enddo
         enddo
         do i=1,(xdiv-1)
         do j=1,(ydiv-2)
         A(i+(j-1)*(xdiv-1),i+(j)*(xdiv-1))=1.d0/(dy**2)
         A(i+(j)*(xdiv-1),i+(j-1)*(xdiv))=1.d0/(dy**2)
         enddo
         enddo

        do i=1,(xdiv-1)
         do j=1,(ydiv-1)
       xcoord = (i-1)*mesh(1)
       ycoord = (j-1)*mesh(2)
       xd=sin(2.0*3.14*xcoord)
       yd=sin(2.0*3.14*ycoord)
       f((i-1)*(xdiv-1)+j,1)= 8.0*3.1415*3.1415*xd*yd
         enddo
        enddo
    do i=1,(xdiv-1)*(ydiv-1)
     do j=1,(xdiv-1)*(ydiv-1)
      Ainv(i,j)=A(i,j)
     end do
    end do

 call DGETRF((xdiv-1)*(ydiv-1), (xdiv-1)*(ydiv-1), Ainv,  & 
  (xdiv-1)*(ydiv-1), ipiv, info)

 call DGETRI((xdiv-1)*(ydiv-1), Ainv, (xdiv-1)*(ydiv-1), ipiv, &
  work,(xdiv-1)*(ydiv-1), info)

 call DGEMV(N, (xdiv-1)*(ydiv-1), (xdiv-1)*(ydiv-1), 1.d0, Ainv, &
  (xdiv-1)*(ydiv-1), f, 1.d0, 0.d0, u, 1.d0)

  do i=1,(xdiv-1)*(ydiv-1)
   write(*,*) "u", u(i,1)
  enddo
 end program main
基本上,我计算LU分解,然后将其反转,然后相乘。请帮助我找到错误,并建议更好的方法进行计算(如果有)


注意:变量定义/赋值的某些部分可能显得多余或低效,这是因为这是更大代码的一部分。我只是提取了其中的一部分,以关注矩阵求逆问题。

对于一般平方矩阵的求逆,请查看此函数(使用LAPACK)

此外,您还可以找到其他有用的Fortran子程序和矩阵运算函数

基本上,这遵循与您相同的过程,只是,如某些注释中所述,您传递给LAPACK子例程的参数不正确。查看并修复这些问题,或者直接使用此功能


编辑:请注意,这适用于单精度数据类型。您可以轻松地将其调整为双精度。

对于一般平方矩阵的求逆,请查看此函数(使用LAPACK)

此外,您还可以找到其他有用的Fortran子程序和矩阵运算函数

基本上,这遵循与您相同的过程,只是,如某些注释中所述,您传递给LAPACK子例程的参数不正确。查看并修复这些问题,或者直接使用此功能


编辑:请注意,这适用于单精度数据类型。您可以轻松地将其调整为双精度。

请使用标记fortran处理所有fortran问题。您的代码非常不完整,我们必须了解所有这些变量是如何声明的,我们应该能够编译并测试您的代码。请仔细阅读,并感谢您的意见和建议。我已经添加了fortran标记,并为任何人提供了一个完整的代码来编译和测试。您是否有充分的理由进行因式分解和反转,而不是一次性使用dgesv来完成整个过程?此外,如果您需要帮助,我强烈建议您在上面的代码中使用隐式None-我可以立即看到一个错误,包括这可能会帮助你解决问题。@IanBush不,我自己做分解没有任何具体的原因。谢谢你建议隐式无,你能告诉我错误是什么吗?请使用标记fortran来回答所有fortran问题。您的代码非常不完整,我们必须了解所有这些变量是如何声明的,我们应该能够编译并测试您的代码。请仔细阅读,并感谢您的意见和建议。我已经添加了fortran标记,并为任何人提供了一个完整的代码来编译和测试。您是否有充分的理由进行因式分解和反转,而不是一次性使用dgesv来完成整个过程?此外,如果您需要帮助,我强烈建议您在上面的代码中使用隐式None-我可以立即看到一个错误,包括这可能会帮助你解决问题。@IanBush不,我自己做分解没有任何具体的原因。谢谢你建议隐式无,你能说说错误是什么吗?既然矩阵a是对角占优的,有什么办法可以改进吗?我不确定,对不起,既然矩阵a是对角占优的,有什么办法可以改进吗?对不起,我不确定
  function inv(A) result(Ainv)
    implicit none
    real,intent(in) :: A(:,:)
    real            :: Ainv(size(A,1),size(A,2))
    real            :: work(size(A,1))            ! work array for LAPACK
    integer         :: n,info,ipiv(size(A,1))     ! pivot indices

    ! Store A in Ainv to prevent it from being overwritten by LAPACK
    Ainv = A
    n = size(A,1)
    ! SGETRF computes an LU factorization of a general M-by-N matrix A
    ! using partial pivoting with row interchanges.
    call SGETRF(n,n,Ainv,n,ipiv,info)
    if (info.ne.0) stop 'Matrix is numerically singular!'
    ! SGETRI computes the inverse of a matrix using the LU factorization
    ! computed by SGETRF.
    call SGETRI(n,Ainv,n,ipiv,work,n,info)
    if (info.ne.0) stop 'Matrix inversion failed!'
end function inv