Алгоритм интерполяции Лагерра, что-то не так с моей реализацией

Это проблема, с которой я боролся в течение недели, возвращаясь, чтобы просто сдаться после потраченных часов …

Я должен найти коэффициенты для следующего полинома Лагерра:

P0(x) = 1

P1(x) = 1 - x

Pn(x) = ((2n - 1 - x) / n) * P(n-1) - ((n - 1) / n) * P(n-2)

Я считаю, что в моей реализации есть ошибка, потому что по какой-то причине коэффициенты, которые я получаю, кажутся слишком большими. Это вывод этой программы:

a1 = -190.234
a2 = -295.833
a3 = 378.283
a4 = -939.537
a5 = 774.861
a6 = -400.612

Описание кода (приведено ниже):

Если вы прокрутите код вниз до части, где я объявляю массив, вы найдете данные x и y.

Функция polynomial просто заполняет массив значениями указанного полинома для определенного x. Это рекурсивная функция. Я считаю, что это работает хорошо, потому что я проверил выходные значения.

Функция Гаусса находит коэффициенты путем выполнения исключения Гаусса для выходного массива. Я думаю, что именно здесь начинаются проблемы. Мне интересно, есть ли в этом коде ошибка или, возможно, мой метод очень точных результатов плох? Я пытаюсь проверить их так:

-190.234 * 1.5 ^ 5 - 295.833 * 1.5 ^ 4 ... - 400.612 = -3017,817625 =/= 2

Код:

#include "stdafx.h"#include <conio.h>
#include <iostream>
#include <iomanip>
#include <math.h>

using namespace std;

double polynomial(int i, int j, double **tab)
{
double n = i;
double **array = tab;
double x = array[j][0];

if (i == 0) {
return 1;
} else if (i == 1) {
return 1 - x;
} else {
double minusone = polynomial(i - 1, j, array);
double minustwo = polynomial(i - 2, j, array);
double result = (((2.0 * n) - 1 - x) / n) * minusone - ((n - 1.0) / n) * minustwo;
return result;
}
}

int gauss(int n, double tab[6][7], double results[7])
{
double multiplier, divider;

for (int m = 0; m <= n; m++)
{
for (int i = m + 1; i <= n; i++)
{
multiplier = tab[i][m];
divider = tab[m][m];

if (divider == 0) {
return 1;
}

for (int j = m; j <= n; j++)
{
if (i == n) {
break;
}

tab[i][j] = (tab[m][j] * multiplier / divider) - tab[i][j];
}

for (int j = m; j <= n; j++) {
tab[i - 1][j] = tab[i - 1][j] / divider;
}
}
}

double s = 0;
results[n - 1] = tab[n - 1][n];
int y = 0;
for (int i = n-2; i >= 0; i--)
{
s = 0;
y++;
for (int x = 0; x < n; x++)
{
s = s + (tab[i][n - 1 - x] * results[n-(x + 1)]);

if (y == x + 1) {
break;
}
}
results[i] = tab[i][n] - s;
}

}int _tmain(int argc, _TCHAR* argv[])
{
int num;
double **array;

array = new double*[5];
for (int i = 0; i <= 5; i++)
{
array[i] = new double[2];
}
//i         0      1       2       3       4       5
array[0][0] = 1.5;  //xi         1.5    2       2.5     3.5     3.8     4.1
array[0][1] = 2;    //yi         2      5       -1      0.5     3       7
array[1][0] = 2;
array[1][1] = 5;
array[2][0] = 2.5;
array[2][1] = -1;
array[3][0] = 3.5;
array[3][1] = 0.5;
array[4][0] = 3.8;
array[4][1] = 3;
array[5][0] = 4.1;
array[5][1] = 7;

double W[6][7]; //n + 1

for (int i = 0; i <= 5; i++)
{
for (int j = 0; j <= 5; j++)
{
W[i][j] = polynomial(j, i, array);
}
W[i][6] = array[i][1];
}

for (int i = 0; i <= 5; i++)
{
for (int j = 0; j <= 6; j++)
{
cout << W[i][j] << "\t";
}
cout << endl;
}

double results[6];
gauss(6, W, results);

for (int i = 0; i < 6; i++) {
cout << "a" << i + 1 << " = " << results[i] << endl;
}

_getch();
return 0;
}

0

Решение

Я считаю, что ваша интерпретация рекурсивного полиномиального поколения либо нуждается в пересмотре, либо слишком умна для меня.

заданный P [0] [5] = {1,0,0,0,0, …}; Р [1] [5] = {1, -1,0,0,0, …};
тогда P [2] является * P [0] + сверткой (P [1], {c, d});
где а = — ((n — 1) / n)
с = (2n — 1) / n и d = — 1 / n

Это можно обобщить: P [n] == a * P [n-2] + conv (P [n-1], {c, d});
На каждом шаге используется умножение полиномов на (c + d * x), которое увеличивает степень на единицу (всего на один …) и добавляет к P [n-1] умноженное на скаляр a.

Тогда, скорее всего, коэффициент интерполяции x находится в диапазоне [0..1].

(свёртка означает, что вы должны реализовать умножение полиномов, что, к счастью, легко …)

              [a,b,c,d]
* [e,f]
------------------
af,bf,cf,df  +
ae,be,ce,de, 0  +
--------------------------
(= coefficients of the final polynomial)
2

Другие решения

Определение P1(x) = x - 1 не реализовано, как указано. У тебя есть 1 - x в расчете.

Я не смотрел дальше.

0

По вопросам рекламы [email protected]