choleskey分解的c语法

时间:2017-06-23 07:53:15

标签: c

double *cholesky(double *A, int n) {
    double *L = (double*)calloc(n * n, sizeof(double));
    if (L == NULL)
        exit(EXIT_FAILURE);
    for (int i = 0; i < n; i++)
        for (int j = 0; j < (i+1); j++) {
            double s = 0;
            for (int k = 0; k < j; k++)
                s += L[i * n + k] * L[j * n + k];
            L[i * n + j] = (i == j) ?
                sqrt(A[i * n + i] - s) :
                (1.0 / L[j * n + j] * (A[i * n + j] - s));
        }
        return L;
    }

现在我对这段代码的问题如下,我试图逐步看到,但我有点困惑。

当我写

for(condition)
    for(condition){
        For(k=0;k<j;k++)
            s += L[i * n + k] * L[j * n + k];
        L[i * n + j] = (i == j) ?
            sqrt(A[i * n + i] - s) :
            (1.0 / L[j * n + j] * (A[i * n + j] - s));

    }

这就是我看到的情况:

首先i = 0j = 0;然后我进一步深入到代码中,我们得到了这个:for(k)循环。现在我的第一个问题就是这个问题,因为j=0在第一个实例中这个for循环没有得到评估,因为k小于j

for (int k = 0; k < j; k++)

但是这个for循环下面的kode是如何评估的。 由于L是一个零数组,因此s+=l[0]*l[0]应该等于0,但我根本不知道循环是如何运行的。接下来会对for(k)以下的所有内容进行评估吗?

如果是i==j为真,那么L[i * n + j] = sqrt(A[i * n + i] - s)(在这种情况下等于0)。

现在回到顶部我的巢问题从此开始

for(condition i )
   for(condition j)
for(i=1 )for(j)之前j=0被评估两次之后

没有括号j=i得到评估吗?

真的很感激我能得到的所有帮助。

谢谢,

1 个答案:

答案 0 :(得分:1)

如果添加所有花括号,并将三元运算符转换为if-else语句,则此代码可能更容易理解:

double *cholesky(double *A, int n) {
    double *L = (double*)calloc(n * n, sizeof(double));
    if (L == NULL) {
        exit(EXIT_FAILURE);
    }
    for (int i = 0; i < n; i++) { // loop A
        for (int j = 0; j < (i+1); j++) { // loop B
            double s = 0;
            for (int k = 0; k < j; k++) { // loop C
                s += L[i * n + k] * L[j * n + k];
            }
            // still in loop B
            if (i == j) {
                L[i * n + j] = sqrt(A[i * n + i] - s);
            } else {
                L[i * n + j] = (1.0 / L[j * n + j] * (A[i * n + j] - s));
            }
        }
    }
    return L;
}

代码执行如下:

  1. 循环A 启动并设置i = 0,假设i小于n
  2. 循环B 启动并设置j = 0j小于i+11),以便运行
  3. s = 0
  4. 循环C 启动并设置k = 0,但由于k < j0 < 0)为false,循环C中的代码不运行
  5. 然后循环B 的其余部分执行:

    if (i == j) {
        L[i * n + j] = sqrt(A[i * n + i] - s);
    } else {
        L[i * n + j] = (1.0 / L[j * n + j] * (A[i * n + j] - s));
    }
    

    由于i = 0j = 0L[i * n + j]设置为sqrt(A[i * n + i] - s)

  6. 循环B j增加到1,但由于j < (i+1)1 < 1)为false,因此终止
  7. 循环A i增加到1,假设i小于n则运行
  8. 循环B 启动并设置j = 0j小于i+12),以便运行
  9. s设置为0
  10. 循环C 启动并设置k = 0,但由于k < j0 < 0)为false,循环C中的代码不运行
  11. 循环B 的其余部分运行。 i == j为false,因此L[i * n + j]设置为(1.0 / L[j * n + j] * (A[i * n + j] - s))
  12. 循环B j增加到1,并且由于j < (i+1)1 < 2)为真,所以它会运行
  13. s设置为0
  14. 循环C 启动并设置k = 0,并且由于k < j0 < 1)为真,它运行
  15. s增加L[i * n + k] * L[j * n + k]
  16. 循环C k增加到1,但由于k < j1 < 1)为false,因此终止
  17. 循环B 的其余部分运行。 i == j为真,因此L[i * n + j]设置为sqrt(A[i * n + i] - s)
  18. 循环B j增加到2,但由于j < (i+1)2 < 2)为false,因此终止
  19. 循环A i增加到2,假设i小于n则运行
  20. ...