解决“近乎”Hermitian线性系统

时间:2017-08-02 02:54:30

标签: parallel-processing cuda linear-algebra gpu-programming

所以我需要求解线性系统(A + i * mu * I)x = b,其中A是密集的Hermitian矩阵(6x6复数),mu是一个真正的标量,我是单位矩阵。< / p>

显然,如果mu = 0,我应该使用Cholesky并完成它。虽然非零mu,但矩阵不再是Hermitian而且Cholesky失败了。

可能的解决方案:

  1. 使用Cholesky求解普通算子并乘以共轭
  2. 直接使用LU分解解决
  3. 这是一个时间紧迫的性能程序,我需要最有效的方法。关于最优方法的任何想法,或者是否有解决上述移位的Hermitian系统的特定方法?

    这将部署在CUDA内核中,我将并行解决许多线性系统,例如,每个线程一个。这意味着我需要一种最小化线程差异的解决方案。鉴于系统规模较小,可以忽略旋转而不会出现太多问题:这会消除线程分歧的可能来源。我已经实现了一个就地的Cholesky常规方法,虽然它工作正常,但在双精度方面表现并不是很好。

1 个答案:

答案 0 :(得分:1)

我不能保证下面方法的稳定性,但是如果您的矩阵条件相当好,那么可能值得一试。

我们要解决

A*X = B

如果我们选出第一行和第一行,请说

A = ( a y )
    ( z A_ )
X = ( x )
    ( X_)
B = ( b )
    ( B_ )

要求是

a*x + y*X_ = b
z*x + A_*X_ = B_

所以

x = (b - y*X_ )/a
(A_ - zy/a) * X_ = B_ - (b/a)z

解决方案分两个阶段进行。首先使用第二个等式来变换A和b,然后使用第二个等式来形成解x。

在C:

static  void    nhsol( int dim, complx* A, complx* B, complx* X)
{
int i, j, k;
complx      a, fb, fa;
complx* z;
complx* acol;
    // update A and B
    for( i=0; i<dim; ++i)
    {   z = A + i*dim;
        a = z[i];
        // update B
        fb = B[i]/a;
        for( j=i+1; j<dim; ++j)
        {   B[j] -=  fb*z[j];
        }
        // update A
        for( k=i+1; k<dim; ++k)
        {   acol = A + k*dim;
            fa = acol[i]/a;
            for( j=i+1; j<dim; ++j)
            {   acol[j] -= fa*z[j];
            }
        }
    }
    // compute x
    i = dim-1;
    X[i] = B[i] / A[i+dim*i];
    while( --i>=0)
    {
    complx  s = B[i];
        for( j=i+1; j<dim; ++j)
        {   s -= A[i+j*dim]*X[j];
        }
        X[i] = s/A[i+i*dim];
    }
}

,其中

typedef _Complex double complx;

如果代码空间不在前提,则可能需要展开循环。就个人而言,我会通过编写一个程序来完成这项工作,该程序的唯一工作就是编写代码。