从 Matlab 到 C 的 Cholesky 分解函数

标签 c matlab

我尝试将执行乔列斯基分解的 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

哪里出错了?

最佳答案

检查线路

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代码中的转置只是改变 vector 的方向,但不会改变参数或其他东西。

我建议您创建一个计算点积的函数,以便您可以重用代码。

关于从 Matlab 到 C 的 Cholesky 分解函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32738836/

相关文章:

matlab - 自动将图像和图表与共享 x 轴对齐

matlab - 给定四分位数,我如何使用 MATLAB、matplotlib、gnuplot 或其他一些软件包绘制盒须?

matlab - Matlab 中的平滑颜色图

c - 在 C 中递归期间数组会发生什么?

c - printf 中不带引号的数字参数有什么作用?

c - 生成的依赖项与生成的文件

matlab - 在 Matlab 中使用互相关进行 3D 模板匹配

c - 使用泰勒级数逼近 sin(x) 直到项的绝对值低于某个实值

c - while 循环内的 scanf() 错误处理?

创建定制的 S 功能 block ,并使用实时车间生成相同的 C 代码