使用克拉姆-施密特可能会失去精度

Possible loss of precision with Gram-Schmidt

本文关键字:失去 精度 施密特      更新时间:2023-10-16

我有一个在循环中使用Gram-Schmidt的代码。我想尽可能减少对这个算法的调用次数,但问题是,尽管在调用之前和之后得到相同的结果,但当我使用这些值打印一些操作的结果时,它们是不同的。例如,在下面的代码中,abs(muGS[k][0]) - abs(before2)的结果应该是0或非常接近0,因为该变量的打印值(在调用之前和之后)是相同的。然而,事实并非如此。muGS是一个二重矩阵,它的值通常在0到1之间。

int k = 1;
double before2;
while(k < end) {
    before2 = muGS[k][0];
    gramSchmidt(b, muGS, cGS, k);
    //prints for debug
    if (abs(muGS[k][0]) - abs(before2) > 0.1) {
        if (abs(muGS[k][0]) - abs(before2) > 0.1)  {
            cout << "1 muGS[k] diff:" << abs(muGS[k][0]) - abs(before2) << endl;
            cout << "1 muGS[k] before:" << muGS[k][0] << endl;
            cout << "1 muGS[k] after:" << muGS[k][0] << endl;
            cout << "1 muGS[k] mult before:" << before2 * before2 << endl;
            cout << "1 muGS[k] mult after:" << muGS[k][0] * muGS[k][0] << endl;
            cout << "1 muGS[k] abs before:" << abs(before2) << endl;
            cout << "1 muGS[k] abs after:" << abs(muGS[k][0]) << endl;
        }
        getchar();
    }
    for (i = k-1; i >= 0; i--) {
        for (j = 0; j < i; j++) {
            muGS[k][j] -= round(muGS[k][i]) * muGS[i][j];
        }
    }
    //some other operations that don't change the value of muGS
    k++;
}
输出:

1 muGS[k] diff:0.157396
1 muGS[k] before:0.288172
1 muGS[k] after:0.288172
1 muGS[k] mult before:0.0171023
1 muGS[k] mult after:0.083043
1 muGS[k] abs before:0.130776
1 muGS[k] abs after:0.288172

另一个现象是before2的绝对值与before2的绝对值相差很大。有没有可能我失去了一些精度或者为什么会发生这种情况?

谢谢

没有精度损失。你的代码中有一个错误:

        cout << "1 muGS[k] before:" << muGS[k][0] << endl;
        cout << "1 muGS[k] after:" << muGS[k][0] << endl;

在前后打印相同的值。但应该是:

        cout << "1 muGS[k] before:" << before2 << endl;
        cout << "1 muGS[k] after:" << muGS[k][0] << endl;