zoukankan      html  css  js  c++  java
  • (原)使用mkl中函数LAPACKE_sgesv计算矩阵的逆矩阵

    转载请注明出处:

    http://www.cnblogs.com/darkknightzh/p/5578027.html

    参考文档:mkl的说明文档

    lapack_int LAPACKE_sgesv(int matrix_layout, lapack_int n, lapack_int nrhs, float * a, lapack_int lda, lapack_int * ipiv, float * b, lapack_int ldb);

    该函数计算AX=B的解。简单来说,当B为单位矩阵时,X即为inv(A)。

    输入:

    matrix_layout:矩阵存储顺序,C++中为行优先LAPACK_ROW_MAJOR

    n:线性方程的个数,$nge 0$

    nrhs:矩阵B的列数,$nrhsge 0$

    a:大小max(1, lda*n),包含n*n的系数矩阵A

    b:列优先存储时,大小max(1, ldb* nrhs);行优先存储时,大小max(1, ldb*n);包含n* nrhs的矩阵B

    lda:矩阵a的leading dimension,$ldage max (1,n)$

    ldb:矩阵b的leading dimension;列优先存储时,$ldbge max (1,n)$;行优先存储时,$ldbge max (1,nrhs)$

    输出:

    a:(具体看说明文档)可能会被覆盖

    b:(具体看说明文档)调用此函数时被覆盖

    ippv:(具体看说明文档)大小最小是max(1, n)

    返回值:0成功,其他不成功

    This function returns a value info.

    If info=0, the execution is successful.

    If info = -i, parameter i had an illegal value.

    If info = i, ${{U}_{i,i}}$ (computed in double precision for mixed precision subroutines) is exactly zero. The factorization has been completed, but the factor U is exactly singular, so the solution could not be computed.

    程序:

     1 int SCalcInverseMatrix(float* pDst, const float* pSrc, int dim)
     2 {
     3     int nRetVal = 0;
     4     if (pSrc == pDst)
     5     {
     6         return -1;
     7     }
     8 
     9     int* ipiv = new int[dim * dim];
    10     float* pSrcBak = new float[dim * dim];  // LAPACKE_sgesv会覆盖A矩阵,因而将pSrc备份
    11     memcpy(pSrcBak, pSrc, sizeof(float)* dim * dim);
    12 
    13     memset(pDst, 0, sizeof(float)* dim * dim);
    14     for (int i = 0; i < dim; ++i)
    15     {
    16         // LAPACKE_sgesv函数计算AX=B,当B为单位矩阵时,X为inv(A)
    17         pDst[i*(dim + 1)] = 1.0f;
    18     }
    19 
    20     // 调用LAPACKE_sgesv后,会将inv(A)覆盖到X(即pDst)中
    21     nRetVal = LAPACKE_sgesv(LAPACK_ROW_MAJOR, dim, dim, pSrcBak, dim, ipiv, pDst, dim);
    22 
    23     delete[] ipiv;
    24     ipiv = nullptr;
    25 
    26     delete[] pSrcBak;
    27     pSrcBak = nullptr;
    28 
    29     return nRetVal;
    30 }

    调用:

    1     const int nDim = 3;
    2     float pa[nDim * nDim] = { 1, 2, 3, 6, 5, 4, 7 ,5 ,8 };
    3     float pb[nDim * nDim];
    4 
    5     int nRetVal = SCalcInverseMatrix(pb, pa, nDim);

    结果:

    matlab调用inv后的结果:

    可见在精度允许的范围内,结果一致。

    另一方面,在调用LAPACKE_sgesv之前:

    调用LAPACKE_sgesv之后:

    可见,存储A的缓冲区被覆盖。

  • 相关阅读:
    「分块」学习笔记
    「NOIP 2017」逛公园
    大假期集训模拟赛15
    大假期集训模拟赛14
    大假期集训模拟赛13
    nginx 日志升级
    nginx 日志切割
    nginx 健康检查
    sftp 管理
    Prometheus 学习
  • 原文地址:https://www.cnblogs.com/darkknightzh/p/5578027.html
Copyright © 2011-2022 走看看