对称矩阵求逆用CBLAS / LAPACKç [英] Symmetric Matrix Inversion in C using CBLAS/LAPACK

查看:745
本文介绍了对称矩阵求逆用CBLAS / LAPACKç的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我C语言编写的算法,需要矩阵与向量乘法。我有一个矩阵 问:(W x宽),这是由转乘以一个向量的创建 Ĵ( 1 x宽),与自身和增加单位矩阵 I ,使用标量的缩放的

Q = [(J ^ T)* J + AI]

我接下来要乘Q 的逆是矢量G 以获得向量的 M

M =(Q ^( - 1))。* G

我使用的 cblas 的和的 CLAPACK 的发展我的算法。当矩阵问:使用随机数(float类型)填充,并使用程序倒置的 sgetrf _ 的和的 sgetri _ 的,计算的逆为正确

但是,当矩阵Q是对称,这是当你乘(J ^ T)×j中的情况下,计算出的逆是错的!

我知道阵列的行主(C语言)和列为主(在FORTRAN)格式,同时调用的 LAPACK 的程序从C,但对于一个对称矩阵这不应该是一个问题为A ^ T = A。

我重视我的C函数code下面矩阵求逆。

我肯定有一个更好的办法来解决这个问题。谁能帮我这个?

使用cblas一个解决方案将是巨大的......

感谢。

 无效InverseMatrix_R(浮动*矩阵,INT W)
{
    诠释LDA = W;
    INT IPIV [W]
    INT ERR_INFO;
    INT LWORK = W *宽;
    浮动工作区[LWORK]    // - 计算N矩阵A中的M的LU分解
    sgetrf _(安培; W,放大器; W,矩阵,与放大器; LDA,IPIV,&安培; ERR_INFO);    // - 生成矩阵的逆给予其LU decompsotion
    sgetri _(安培; W,矩阵,与放大器; LDA,IPIV,工作区,和放大器; LWORK,&安培; ERR_INFO);    // - 显示逆矩阵
    PrintMatrix(矩阵,W,W);}无效PrintMatrix(浮动*矩阵,诠释行,诠释科尔姆)
{
    INT I,K;    对于(i = 0; I<排;我++)
    {
        对于(K = 0; K<科尔姆; k ++)
        {
            的printf(%G,矩阵[我*科尔姆+ K]);
        }        的printf(\\ n);
    }
}


解决方案

我不知道BLAS或LAPACK,所以我不知道什么可能导致此行为。

但是,对于给定的形式的矩阵,计算逆是很容易的。造成这种情况的重要事实是

 (J ^ T * j)^ 2 =(J ^ T * j)*(J ^ T * j)= J(1)T *(J * J(1)T)* J =<Ĵ| J&G​​T; *(J ^ T * j)

其中,< U | V> 表示内积(如果组件是真正的 - 规范的双线性的形式复杂的组件,但那么你可能考虑不转,但共轭转,你会回来的内积)。

要概括,

 (J ^ T * j)^ N =(小于Ĵ| J&G​​T;)^(N-1)*(J ^ T * J)对于n> = 1。

让我们表示对称方阵(J ^ T * j)取值和标量<Ĵ| J&G​​T; 。然后,对于一般 A = 0 的足够大的绝对值( | A |>问):

 (A * I + S)^( -  1)= 1 / A *(I + A ^( -  1)* S)^( -  1)
               = 1 / A *(I +Σ(-1)^ K *一个^( - k)的* S ^ k)的
                           K&大于0
               = 1 / A *(I +(Σ(-1)^ K *一个^( - k)的* Q ^(K-1))* S)
                            K&大于0
               = 1 / A *(I - 1 /(A + Q)* S)
               = 1 / A * I - 1 /(A *(A + Q))* S

这公式成立(由分析性)的所有 A 除了 A = 0 A = -q ,因为可以通过计算来验证

 (A * I + S)*(1 / A * I  -  1 /(A *(A + Q))* S)= I + 1 /一个* S  - 1 /(A + q)* S  -  1 /(A *(A + q))* S ^ 2
                                    = I + 1 /一个* S - 1 /(A + Q)* S - Q /(A *(A + Q))* S
                                    = I +((A + Q) - 一 - Q)/(A *(A + Q))* S
                                    = I

使用秒2 = Q * S

即计算也比先查找LU分解更简单和更有效

I am writing an algorithm in C that requires Matrix and Vector multiplications. I have a matrix Q (W x W) which is created by multiplying the transpose of a vector J(1 x W) with itself and adding Identity matrix I, scaled using scalar a.

Q = [(J^T) * J + aI].

I then have to multiply the inverse of Q with vector G to get vector M.

M = (Q^(-1)) * G.

I am using cblas and clapack to develop my algorithm. When matrix Q is populated using random numbers (type float) and inverted using the routines sgetrf_ and sgetri_ , the calculated inverse is correct.

But when matrix Q is symmetrical, which is the case when you multiply (J^T) x J, the calculated inverse is wrong!!.

I am aware of the row-major (in C) and column-major (in FORTRAN) format of arrays while calling lapack routines from C, but for a symmetrical matrix this should not be a problem as A^T = A.

I have attached my C function code for matrix inversion below.

I am sure there is a better way to solve this. Can anyone help me with this?

A solution using cblas would be great...

Thanks.

void InverseMatrix_R(float *Matrix, int W)
{   
    int     LDA = W;
    int     IPIV[W];
    int     ERR_INFO;
    int     LWORK = W * W;
    float   Workspace[LWORK];

    // - Compute the LU factorization of a M by N matrix A
    sgetrf_(&W, &W, Matrix, &LDA, IPIV, &ERR_INFO);

    // - Generate inverse of the matrix given its LU decompsotion
    sgetri_(&W, Matrix, &LDA, IPIV, Workspace, &LWORK, &ERR_INFO);

    // - Display the Inverted matrix
    PrintMatrix(Matrix, W, W);

}

void PrintMatrix(float* Matrix, int row, int colm)
{
    int i,k;

    for (i =0; i < row; i++) 
    {
        for (k = 0; k < colm; k++) 
        {
            printf("%g, ",Matrix[i*colm + k]);
        }

        printf("\n");
    }
}

解决方案

I don't know BLAS or LAPACK, so I have no idea what may cause this behaviour.

But, for matrices of the given form, calculating the inverse is quite easy. The important fact for this is

(J^T*J)^2 = (J^T*J)*(J^T*J) = J^T*(J*J^T)*J = <J|J> * (J^T*J)

where <u|v> denotes the inner product (if the components are real - the canonical bilinear form for complex components, but then you'd probably consider not the transpose but the conjugate transpose, and you'd be back at the inner product).

Generalising,

(J^T*J)^n = (<J|J>)^(n-1) * (J^T*J), for n >= 1.

Let us denote the symmetric square matrix (J^T*J) by S and the scalar <J|J> by q. Then, for general a != 0 of sufficiently large absolute value (|a| > q):

(a*I + S)^(-1) = 1/a * (I + a^(-1)*S)^(-1)
               = 1/a * (I + ∑ (-1)^k * a^(-k) * S^k)
                           k>0
               = 1/a * (I + (∑ (-1)^k * a^(-k) * q^(k-1)) * S)
                            k>0
               = 1/a * (I - 1/(a+q)*S)
               = 1/a*I - 1/(a*(a+q))*S

That formula holds (by analyticity) for all a except a = 0 and a = -q, as can be verified by calculating

(a*I + S) * (1/a*I - 1/(a*(a+q))*S) = I + 1/a*S - 1/(a+q)*S - 1/(a*(a+q))*S^2
                                    = I + 1/a*S - 1/(a+q)*S - q/(a*(a+q))*S
                                    = I + ((a+q) - a - q)/(a*(a+q))*S
                                    = I

using S^2 = q*S.

That calculation is also much simpler and more efficient than first finding the LU decomposition.

这篇关于对称矩阵求逆用CBLAS / LAPACKç的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆