关于Fortran中SGESV语法的问题
我对这个子程序有点困惑。我已经阅读了文档,但是我有点搞不清楚IPIV向量到底是做什么的,以及如何准确地设置前导维度。我读到前导维度有助于在数组的每个连续列中找到矩阵元素的起点。例如,假设我们想要解决关于Fortran中SGESV语法的问题,fortran,lapack,Fortran,Lapack,我对这个子程序有点困惑。我已经阅读了文档,但是我有点搞不清楚IPIV向量到底是做什么的,以及如何准确地设置前导维度。我读到前导维度有助于在数组的每个连续列中找到矩阵元素的起点。例如,假设我们想要解决 Ax = B 在哪里 其中sp表示我在主程序中设置的单精度 尺寸是 A(10,10) B(10) 在我的主程序中设置并传递给这个子程序 我应该将子程序设置为 integer :: n,INFO n = size(A,1) IPIV = 0 call SGESV(n,n,A,2*n,IPIV,
Ax = B
在哪里
其中sp表示我在主程序中设置的单精度
尺寸是
A(10,10)
B(10)
在我的主程序中设置并传递给这个子程序
我应该将子程序设置为
integer :: n,INFO
n = size(A,1)
IPIV = 0
call SGESV(n,n,A,2*n,IPIV,B,2*n,INFO)
或
对于IPIV,我应该创建一个大小为10的向量,并用零初始化它
编辑:我用过
call sgesv(n, n, A, n, ipiv, B, n, INFO)
正如建议的那样,但我得到了一个分割错误程序接收信号SIGSEGV:分割错误-无效内存引用
我已经打印了矩阵大小,它们是正确的,矩阵A的大小是100,向量的大小是10
Edit2:所以在我的主循环中,我有一个循环,在我的循环中,它在每次迭代中计算a(10,10)和向量B(10)的矩阵。然后我调用我的子程序来求解这个系统
call solver(A,B)
然而,我得到的分割错误,我不明白,因为尺寸是正确的。(为了检查它,我打印了矩阵和向量的大小,并注释掉了对子例程的调用,它们是100和10)
也许我应该让我的矩阵可分配?但我不认为这有什么问题,因为在每次迭代中,我通过一系列计算来计算矩阵和向量,并覆盖它们
基本上我声明矩阵和向量如下
real(sp) , dimension (10) :: B
real(sp) , dimension (10,10) :: A
然后在我的循环中执行一系列计算,用值填充它们
然后我调用我的子程序
然后用新值重复此操作您正在使用一个旧接口来lapack。请注意我对现代/通用例程的较低回答
旧界面 你可以这样称呼它
呼叫sgesv(n,n,A,n,ipiv,B,n,info)
理由:
- 前导尺寸为
而非n
2n
是一个输出变量s.t。不需要用0初始化它ipiv
现代界面:LAPACK95 只使用提供通用调用的现代接口要容易得多
呼叫gesv(A、B、ipiv=ipiv、info=info)
您不需要指定数据类型(例如不再指定sgesv
)或矩阵维度
确保您需要使用适当的模块
使用lapack95
下面是调用gesv
与sgesv
和dgesv
的通用Lapack95等价物(且更简单)的示例
subroutine test_lapack95(n)
use BLAS95
use LAPACK95
use f95_precision
implicit none
integer, intent(in) :: n
real(float), allocatable :: A(:,:), LU(:,:)
real(float), allocatable :: b(:), x(:)
integer, allocatable :: ipiv(:)
allocate(A(n,n))
allocate(b(n))
allocate(ipiv(n))
! Fill values in A and b
call prepare_values(n, A, b)
LU = A
x = b
call gesv(LU,x,ipiv)
! Solve to A*x=b, for x
end subroutine
不要担心助手函数
prepare_values
,它只需填写A
和b
您应该用代码而不是文字来显示A和b的声明。您好,谢谢您的回复!我现在编辑以向您显示我的声明IPIV
应返回数据透视顺序(索引数组)。虽然A和B是伪参数(带有intent(inout)),但它们在实际调用中是否连续?@Alex请提供一个完整的函数,例如,其中包含一个程序。问题是,我正在尝试使用与您发布的语法完全相同的旧接口,但我得到一个分段错误-->程序接收信号SIGSEGV:分段错误-无效内存引用。@Alex请将您的问题以及错误消息添加到您的问题中。那么我们也许可以告诉你更多。我现在将把它们添加到主要问题中。非常感谢。您应该尽量使代码尽可能短。这将有助于突出重点。
real(sp) , dimension (10) :: B
real(sp) , dimension (10,10) :: A
subroutine test_lapack95(n)
use BLAS95
use LAPACK95
use f95_precision
implicit none
integer, intent(in) :: n
real(float), allocatable :: A(:,:), LU(:,:)
real(float), allocatable :: b(:), x(:)
integer, allocatable :: ipiv(:)
allocate(A(n,n))
allocate(b(n))
allocate(ipiv(n))
! Fill values in A and b
call prepare_values(n, A, b)
LU = A
x = b
call gesv(LU,x,ipiv)
! Solve to A*x=b, for x
end subroutine