m :代表输入矩阵a的行数n :代表输入矩阵a的列数a :代表输入矩阵lda :就是矩阵a的第一个维度,一般是m输出参数为:a :被经过LU分解后的矩阵覆盖ipiv : 是一个数组,维度一般是max(1,min(m, n)),具体英文说明是The
pivot indices; for 1 ≤i≤min(m, n), row iwas
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论坛,只是现在没有得到答复。