使用MKL求解矩阵的行列式值与逆

本文介绍了如何利用MKL库在FORTRAN环境下高效地求解矩阵的行列式与逆,提供了具体操作步骤及注意事项。通过LU分解等技术,简化了求解过程,并给出了实例代码供读者参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    在FORTRAN下有很多求矩阵行列式值以及逆的方法,这些方法包括自己写程序求解,使用如IMSL和MKL等下面的库函数求解。一般来说,使用IMSL求解矩阵的行列式值和逆最简单且速度适中,但是IMSL现在属于商业库,如果程序自己用可以通过一些方法来免费使用使用MKL求解矩阵的行列式值与逆,但是若涉及版权,买的话还是挺贵的。使用MKL的话,从在我电脑上的测试来看,速度最快,但是用起来稍微复杂一些,如果你是非商业目的(non-commercial)在Linux下是免费的。(注意非商业目的可能并不包括学术目的,这个可以在Intel的声明中查看)
    对于使用MKL来求解行列式以及矩阵逆实际操作起来并不复杂,但是对于这个方面的中文说明较少(我自己理解是大牛们都不屑与写这么简单的东西),我就把我最近写的一些东西分享出来。有些地方可能是粗浅且错误的,需要自己留意鉴别。
    先说行列式求解,对于这个问题,使用的sgetrf函数,这个函数是对矩阵进行LU分解,函数的命名规则是这样的,s代表single也就是单精度,ge代表一般矩阵,f代表factorization。函数的具体参数如下:

call sgetrf( m, n, a, lda, ipiv, info )

输入参数为以下:
m :代表输入矩阵a的行数n :代表输入矩阵a的列数a :代表输入矩阵lda :就是矩阵a的第一个维度,一般是m输出参数为:a :被经过LU分解后的矩阵覆盖ipiv : 是一个数组,维度一般是max(1,min(mn)),具体英文说明是The pivot indices; for  i  min(mn), row i was interchanged with row ipiv(i).info:执行标示符,成功是0,其他为失败标识,具体查看mkl帮助。    行列式值的计算程序基本上就是在ipiv上做文章,我个人开始猜测它代表的是行之间的交换,交换一次行列式求解时要变号,于是便可以根据这个来进行行列式值的求解。    现在以一个4*4维的矩阵为例,给出求解程序:call sgetrf( n, n, a, n,ipiv,info)res = 1d0do i = 1,4 if(ipiv(i) .ne. i) then  res = -res*a(i,i) else  res = res*a(i,i) end ifend do其中,n=4。    我多次验证过这个程序,没有发现问题,但是也不排除出问题的可能性,使用需谨慎,另外使用的时候最好写个function,把代码封装到function里面,在引用的时候调用这个function就可以了。    现在再说矩阵求逆,我看到大部分矩阵求逆都是使用sgetrf + sgetri的组合来求解的,    在实际应用中我发现,直接求逆时如果lwork这个参数设置不好的话可能得到的结果是错误的,这点我不知道为什么?所以一般来说我使用sgetrf + sgetrs来求解矩阵逆。在这里以n*n矩阵为例来说明下求解过程。    关于sgetrf我在上面说过了,现在来说sgetrs这个函数:
call sgetrs( trans, n, nrhs, a, lda, ipiv, b, ldb, info )


输入参数为以下:
trans :代表求解什么样的方程组,trans = 'N'代表求解A*X = Bn :代表输入矩阵a的秩,一般就是行数nrhs:一般代表B的行数,这里是na :代表输入矩阵lda :就是矩阵a的第一个维度,这里是nldb :就是矩阵b的第一个维度,这里是nipiv:就是上面LU分解后输出的ipiv输出参数为:b :会被求解后的X所覆盖。info:执行标示符,成功是0,其他为失败标识,具体查看mkl帮助。
    在这里,如果我把B设置为单位矩阵,那么X便是A矩阵的逆了,这样最终返回的B便会被X的值也就是A的逆所覆盖了,这样就成功的将A的逆求解出来了。具体的求解程序为:call sgetrf( n, n, a, n,ipiv,info1)call sgetrs( trans, n, nrhs, a, lda, ipiv, b, ldb, info2 )输出的b便是a的逆,记得b要先设置成n*n的单位矩阵。    求解矩阵的逆的时候我强烈建议你将他们封装到一个function中,然后再把这个function放到module中,便于主程序引用。我开始并没有把这两个函数放到function中,而是在程序中直接引用,从而造成了求解结果错误。我不知道这是为什么?可能是数据太大也可能是其他原因?我将这个问题反馈到了Intel论坛,只是现在没有得到答复。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值