Cholesky分解函数从Matlab到C

时间:2015-09-23 11:50:48

标签: c matlab

我试图将执行cholesky分解的Matlab循环转换为C.我只为第一列得到了正确的结果。

Matlab代码:

M = [5 1.2 0.3 -0.6; 1.2 6 -0.4 0.9; 0.3 -0.4 8 1.7; -0.6 0.9 1.7 10];
n = length( M );
L = zeros( n, n );
for i=1:n
    L(i, i) = sqrt( M(i, i) - L(i, :)*L(i, :)' );

    for j=(i + 1):n
        L(j, i) = ( M(j, i) - L(i, :)*L(j, :)' )/L(i, i);
    end
end

我的C代码:

int  main()
{

    double M[4*4]={5, 1.2, 0.3, -0.6, 1.2, 6, -0.4, 0.9, 0.3, -0.4, 8, 1.7, -0.6, 0.9, 1.7, 10};
    int n=4;
    double L[4*4]={0};
    double sum;
    for (int i=0;i<n;i++){
        sum=0;
        for (int j=0;j<n;j++){
            sum+=L[i*n+j]*L[j*n+i];
            }
    L[i*n+i]=sqrt(M[i*n+i]-sum);

    for (int j=i+1;j<n;j++){
        sum=0;
        for(int k=0;k<n;k++){
            sum+=L[i*n+k]*L[k*n+j];
           }
        L[j*n+i]=(M[j*n+i]-sum)/L[i*n+i];

      }

}
 return 0;

}

Matlab的结果是:

L =

    2.2361         0         0         0
    0.5367    2.3900         0         0
    0.1342   -0.1975    2.8183         0
   -0.2683    0.4368    0.6466    3.0527

但在C中,结果是:

L_c =

    2.2361         0         0         0
    0.5367    2.4495         0         0
    0.1342   -0.1633    2.8284         0
   -0.2683    0.3674    0.6010    3.1623

错误在哪里?

2 个答案:

答案 0 :(得分:1)

检查线

sum+=L[i*n+j]*L[j*n+i];

sum+=L[i*n+k]*L[k*n+j];

我认为这应该是

sum+=L[i*n+j]*L[i*n+j];

sum+=L[i*n+k]*L[j*n+k];

分别。 Matlab代码中的转置只是改变了向量的方向,但没有切换参数或其他东西。

我建议你制作一个计算点积的函数,这样你就可以重用代码了。

答案 1 :(得分:1)

参见守则:

{{1}}