Задача:
Интерполяционный многочлен Лагранжа. Значения функции [latex]y=f\left(x\right)[/latex] заданы таблично в массиве [latex]Y\left(x\right)[/latex] при соответствующих значениях аргумента в упорядоченном массиве [latex]X\left(x\right)[/latex]. Найти значение функции в произвольной точке [latex]x[/latex] по формуле Лагранжа:
[latex]y={L}_{n}\left(x\right)=\sum _{i=1}^{n}{{y}_{i}\prod _{\underset{j\neq i}{j=1}}^{n}{\frac{x-{x}_{j}}{{x}_{i}-{x}_{j}}}}[/latex]
Вводимые значения:
X: | -1 | 0 | 1 | 2 |
Y: | 1 | 2 | 3 | -1 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
#include <iostream> #include <vector> using namespace std; double LP(double x, vector<double> xv, vector<double> yv) { //Lagrange polynomial int size = xv.size(); //Количество точек (для удобства) double sum = 0; //Значение функции for(int i = 0; i < size; i++){ double mul = 1; //Произведение for(int j = 0; j < size; j++){ if(i!=j) mul *= (x - xv[j])/(xv[i]-xv[j]); } sum += yv[i]*mul; } return sum; } int main() { int counter = 0; double a = -3; //Левая грань double b = 3; //Правая грань int fragments = 101; //Разбиение vector<double> xv {}; vector<double> yv {}; double inp; while(cin >> inp) counter++%2 ? yv.push_back(inp) : xv.push_back(inp); //Заполнение for(int i = 0; i < fragments; i++){ double x = a + (b-a)/(fragments-1)*i; printf("%6.3lf\t%6.3lf\n", x, LP(x, xv, yv)); } return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
import java.util.*; import java.lang.*; import java.io.*; class Main { static double LP(double x, double[] xv, double[] yv){ int size = xv.length; double sum = 0; for(int i = 0; i < size; i++){ double mul = 1; for(int j = 0; j < size; j++){ if(i != j){ mul *= (x-xv[j])/(xv[i]-xv[j]); } } sum += yv[i]*mul; } return sum; } static Scanner sc = new Scanner(System.in); public static void main (String[] args) throws java.lang.Exception { int counter = 0; double a = -3; double b = 3; int fragments = 101; ArrayList<Double> xvinp = new ArrayList<Double>(); ArrayList<Double> yvinp = new ArrayList<Double>(); double[] xv; double[] yv; while(sc.hasNext()){ double inp = sc.nextDouble(); if(counter%2 == 0){ xvinp.add(inp); }else{ yvinp.add(inp); } counter++; } xv = new double[xvinp.size()]; yv = new double[yvinp.size()]; for(int i = 0; i < xvinp.size(); i++){ xv[i] = xvinp.get(i); yv[i] = yvinp.get(i); } for(int i = 0; i < fragments; i++){ double x = a + (b-a)/(fragments-1)*i; System.out.println(x + "\t" + LP(x, xv, yv)); } } } |
Идея решения:
Использование отдельной функции, которой надо передать 3 параметра: значение аргумента, массив исходных значений аргумента и массив исходных значений функции при соответствующих аргументах. Эта функция возвращает значение многочлена Лагранжа при подстановки вместо [latex]x[/latex] конкретного значения.
В функции был использован внешний цикл for для вычисления суммы в формуле и внутренний цикл for для вычисления произведения [latex]\prod _{\underset{j\neq i}{j=1}}^{n}{\frac{x-{x}_{j}}{{x}_{i}-{x}_{j}}}[/latex].
В программе мы разбиваем отрезок [-3, 3] на 101 отдельную точку и вычисляем значение полинома Лагранжа для каждой из этих точек. Выводим на экран.
Комментарии: Точки выбраны специально. Мне просто захотелось увидеть, как выглядит график функции, которую мы разбирали на паре (кстати по той же самой теме =) ). График сделан в xls. Векторы выбраны по причине ограниченности массива.
Работает. Очень хорошо, что дали ссылку на описание мат.аппарата задачи.
Зачтено.
Java-версия засчитана, 10 баллов.