Интерполяция Лагранжа

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Ответить
Manyak666
Сообщения: 18
Зарегистрирован: 27 мар 2013, 16:23

Добрый день!
Дали задание: построить интерполяционный полином Лагранжа для функции f(x) = 4x - 7sinx на интервале [-2, 3], количество точек, в которых определена функция m = 4. Таблица исходной фунции вычисляется в точках x_i = -2 - i*5/m, i = 0,...,m. Используя полученную таблицу требуется вычислить значения функции, полинома и невязки в точках x_j = -2 - j*5/9, j = 0,...,9.
Программу написал, считает значения полинома, а вот как сделать, чтобы считала невязки, не знаю, может подскажете?
Вот моя программа:

Код: Выделить всё

#include <iostream.h>
#include <conio.h>
#include <stdio.h>
float x[5] = {-2, -0.75, 0.5, 1.75, 3}; 
float y[5] = {-1.64, 1.77, -1.36, 0.11, 11.01}; 
/* Функция, вычисляющая коэффициенты Лагранжа
x - аргумент функции
n - степень многочлена (или число x-ов)
i - номер узла
*/
float L(float xp,int n,int i) {
// числитель и знаменатель 
float Chesl; 
float Znam;
Chesl = 1; Znam = 1;
int k;
// вычисление числителя
for (k = 0; k!= n; k++ ) {
if ( k == i ) continue; 
// убираем множитель x - x(i)
Chesl *= xp - x[k];
}
// вычисление знаменателя
for(k= 0; k!= n;k++) {
if (x[i] == x[k]) continue; 
// убираем, а то ноль в знаменателе
Znam *= x[i] - x[k];
}
return Chesl/Znam; 
}
int main(int argc, char* argv[])
{
// вычисляем степень полинома
int n = sizeof(y)/sizeof(float); 
// начальное значение 
float R = 0; 
// произвольная точка для проверки 
float px = 1;
// вычисляем значение интерполяционного многочлена
for (int i = 0; i != n; i++) { 
R += y[i]*L(px,n,i);
}
printf("Result : %f ",R);
    getch();
// вывод результата
return 0;
}

Надеюсь на вашу помощь, сам ещё плохо знаю С.. Заранее спасибо!
Manyak666
Сообщения: 18
Зарегистрирован: 27 мар 2013, 16:23

Ну что же никто не хочет мне помочь? Вам же не трудно..
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

А вот я и добрался до твоей задачи, Manyak666. Невязка, насколько мне помнится, это разность ординат между исходной функцией и её интерполяционнным многочленом в заданной точке.

Теперь по программе. Наверное стоит сделать отдельную функцию, которая может вычислить значение интерполяционного многочлена в точке x.

Код: Выделить всё

float R(float x)
{
   // вычисляем степень полинома
   int n = sizeof(y)/sizeof(float);
   // начальное значение
   float ret = 0;
   // вычисляем значение интерполяционного многочлена
   for (int i = 0; i != n; i++) {
      ret += y[i]*L(x,n,i);

   return ret;
}
Тогда наш main превратится в:

Код: Выделить всё

int main(int argc, char* argv[])
{
// произвольная точка для проверки
float px = 1;
// вычисляем значение интерполяционного многочлена
printf("Result : %f ",R(px));
    getch();
// вывод результата
return 0;
}
Осталось мелочь. У нас есть интерполяционная функция R(x) и исходная функция f(x) = 4*x - 7*sin(x). Осталось просто вычислить разность этих двух функций в указанных точках и вывести все значения на экран. Предлагаю это сделать самостоятельно. Если не получится - пиши.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Manyak666
Сообщения: 18
Зарегистрирован: 27 мар 2013, 16:23

Эту-то я уже сдал.. три недели, кажется, делал её и сделал.. И вроде немного по-другому получилось.. Сейчас по-вашему сделал, точно так же работает, значит правильно я её отмучил тогда) Сейчас краевая задача - причина моих страданий.. Сижу вот опять над ней..
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

С краевой задачей посложнее будет, я уже подзабыл теорию на неё - всё-таки 10 лет назад окончил университет. Обещаю посмотреть. Может завтра :)
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Manyak666
Сообщения: 18
Зарегистрирован: 27 мар 2013, 16:23

Буду чрезвычайно благодарен! Пока уравнение методом бисекций решил, оказалось просто)
Ответить