多步后C发散的拉格朗日插值算法

时间:2018-04-18 20:08:10

标签: c algorithm linear-interpolation

我有一个拉格朗日插值算法,经过许多时间步后开始发散,我似乎无法弄清楚为什么。快速回顾一下,如果我有两个阵列

int x[11] = {0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}
int y[11] = {0,  2,  4,  6,  8, 10, 12, 14, 16, 18,  20}

并且我在算法中输入了15的x值,输出(即插值的y值)应为3.以下算法使插值正确,但随着循环增量输入最终输出开始发散。我不确定是什么导致了分歧。代码创建两个从-100到+100的整数数组,并根据递增的x输入插值。值开始匹配,但大约55左右,插值的y值开始发散。代码如下。任何见解将不胜感激。

#include <stdio.h>

#define SIZE 201

int main()
{
    double x[SIZE], y[SIZE], value, sum, factor[SIZE];
    for (int i = 0; i < SIZE; i++)
    {
        x[i] = -100 + i;
    }
    for (int i = 0; i < SIZE; i++)
    {
        y[i] = -100 + i;
    }
    value = 0.0;
    while (1)
    {   
        sum = 0.0;  
        printf("Input is: %lf\n", value);
        for(int i = 0; i < SIZE; i++)
        {
            factor[i] = 1.0;
            for(int j = 0; j < SIZE; j++)
            {
                if(i != j)
                {
                    factor[i] = factor[i] * (value - x[j])/(x[i] - x[j]);
                }   
            }
            sum = sum + factor[i] * y[i];
         }
         printf("Output is: %lf\n", sum);
//       if ((value - sum) > 0.01) break;
         if (value < 100) value += 0.001;
         else break;
    }
    return 0;
}

1 个答案:

答案 0 :(得分:2)

给定N个样本,拉格朗日多项式的度数为N,在您的情况下为200.这是一个相当大的度数,对于value足够大的中间数结果(即factor)开始表现得非常不稳定。我在外循环的每次迭代之后打印factor,这就是我在我的机器上的代码(代码在value处分开62.1):

    Input is: 62.100000
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000002
        -0.000010
        0.000047
        -0.000212
        0.000916
        -0.003834
        0.015558
        -0.061214
        0.233667
        -0.865800
        3.115490
        -10.892598
        37.019453
        -122.351630
        393.413839
        -1231.176112
        3751.320027
        -11132.603776
        32188.920849
        -90709.929863
        249216.884601
        -667734.556134
        1745251.075381
        -4451006.398268
        11079451.201015
        -26924437.939740
        63892139.532124
        -148088119.614110
        335320733.480250
        -741923910.135582
        1604370277.576735
        -3391407192.476863
        7009154161.161494
        -14165714298.372702
        28000907070.092331
        -54142322716.578796
        102423636122.796417
        -189594810732.400879
        343460854643.929565
        -608991796878.604858
        1057024952593.679688
        -1796190002106.606201
        2988571833231.810547
        -4869319260810.958008
        7769844431032.450195
        -12143392562153.164062
        18590594785582.515625
        -27881222667878.292969
        40966915113033.500000
        -58978430272092.585938
        83200365623915.609375
        -115016713573880.578125
        155822462931701.031250
        -206899948714767.906250
        269263745978734.968750
        -343484172924072.000000
        429506076055356.812500
        -526485323131795.875000
        632668952077638.500000
        -745344926690223.250000
        860883054405210.375000
        -974879663742953.625000
        1082405867199472.750000
        -1178344322529343.250000
        1257784740974879.500000
        -1316436663535827.500000
        1351011674779421.000000
        -1359527880018181.000000
        1341497535715305.750000
        -1297973187760748.750000
        1231446261994579.000000
        -1145611653890577.250000
        1045029162299372.250000
        -934724762872858.125000
        819779917571950.250000
        -704954924193421.250000
        594383648437451.875000
        -491363855983359.125000
        398252366806871.062500
        -316460003024013.937500
        246529925760965.156250
        -188275766805651.375000
        140953330916004.437500
        -103441104978326.546875
        74409294797142.390625
        -52463275136077.218750
        36253867741005.359375
        -24552698830046.890625
        16295359517452.095703
        -10597930155882.712891
        6753701701870.307617
        -4216931244837.877441
        2579609371842.192871
        -1545902253614.920410
        907502140862.699341
        -521815325006.697205
        293869684950.453308
        -162078786010.080200
        87537719445.039368
        -46294138480.248749
        23970808358.990040
        -12151499571.568396
        6030219319.167710
        -2929269302.567177
        1392763710.430415
        -648125926.103312
        295175902.544337
        -131559694.388017
        57381635.324659
        -24492187.039684
        10230449.673919
        -4182126.956840
        1673313.368037
        -655394.261464
        251347.530884
        -94414.677824
        34753.964878
        -12544.686326
        4444.407825
        -1547.546444
        530.612164
        -179.651152
        60.317931
        -20.218974
        6.844738
        -2.391284
        0.904560
        -0.429040
        1.136162
        0.029430
        -0.003145
        0.000450
        -0.000070
        0.000011
        -0.000002
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000000
        -0.000000
        0.000000
        -0.000000
    Output is: 67.164298

很抱歉粘贴量。

您可以看到代码以非常大的factor s(例如155822462931701.031250)运行,而sum保持在1左右。这会导致由于规范化而导致精度下降。随着value的增长,精度的损失会放大。

底线是,天真的拉格朗日插值在数值上不稳定。查看Notes