Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <math.h>
- #include <vector>
- #include <Windows.h>
- #include <stdlib.h>
- #include <fstream>
- #include <string.h>
- using namespace std;
- const double PI = 3.1415926535897932384626433832795;
- typedef double(*functiontype)(double x);
- typedef struct Node
- {
- double x, y;
- } Node;
- typedef double(*method)(double x, Node *Array, int Count);
- typedef struct Interval
- {
- double InitialNode, EndNode;
- } Interval;
- int Factorial(int n)
- { // Факториал
- int x = 1;
- for (int i = 1; i <= n; i++)
- {
- x *= i;
- }
- return x;
- }
- double Myfunc(double x)
- {
- return (x*x);
- }
- double exponenta(double x)
- { // Экспонента
- return exp(x);
- }
- void ValueUniformTable(functiontype* f, Node* Array, double Initial, double End, int Count) // Передаем массив в который все будет записано
- { // Создание равномерной таблицы значений
- double step = abs(Initial - End) / (Count - 1);
- Array[0].x = Initial;
- Array[0].y = (*f)(Array[0].x);
- for (int i = 1; i < Count; i++)
- {
- Array[i].x = Array[i - 1].x + step;
- Array[i].y = (*f)(Array[i].x);
- }
- }
- double DividedDifference(int i, Node* Array) //Не понимаем алгоритм
- { // Разделенная разность
- double DD = 0;
- for (int j = 0; j <= i; j++)
- {
- double tmp = 1;
- for (int k = 0; k <= i; k++)
- {
- if (k != j)
- tmp *= Array[j].x - Array[k].x;
- }
- DD += Array[j].y / tmp;
- }
- return DD;
- }
- void ValueChebyshevTable(functiontype* f, Node* Array, double Initial, double End, int Count)
- { // Создание таблицы Чебышевских значений
- for (int i = 0; i < Count; i++)
- {
- Array[i].x = ((End + Initial) / 2)
- + ((End - Initial) / 2) * cos(((2 * i + 1) * PI) / (2 * (Count + 1)));
- Array[i].y = (*f)(Array[i].x);
- }
- }
- void get_koef_polynom(double* mas, double* res, int n, int k) // k - кол во скобок для раскрытия (сколько надо, напр в ньютоне нужно не все), n - максимальное кол-во скобок
- {
- int i;
- double* anx = new double[k+1];
- double* ann = new double[k+1];
- res[0] = mas[0];
- res[1] = 1;
- int j;
- for (j = 0; j <= k; j++)
- {
- anx[j] = 0.0;
- }
- for (j = 0; j < k; j++)
- {
- ann[j] = 0.0;
- }
- for (i = 1; i < k; i++)
- for (j = 0; j <= i + 1; j++) //Спросить у Антона работу алгоритма
- {
- anx[j + 1] = res[j];
- ann[j] = res[j] * mas[i];
- res[j] = anx[j] + ann[j];
- }
- }
- //Возвращает число, возведенное в cтепень i
- double get_degree(double x, int degree) {
- int i;
- double y = x;
- if (degree == 0)
- return 1;
- for (i = 0; i < degree - 1; i++)
- y *= x;
- return y;
- }
- double round(double x) {
- if (x < 0.0000000001)
- x = 0.0;
- return x;
- }
- // Полином Лагранжа в точке
- double PolynomLG_dot(double x, Node *Array, int Count)
- {
- double Polynom = 0;
- for (int i = 0; i < Count; i++)
- { // Счетчик по функциям l_i
- double Li = 1;
- for (int j = 0; j < Count; j++)
- { // Счетчик по x_j
- if (i != j) Li *= (x - Array[j].x) / (Array[i].x - Array[j].x);
- }
- Polynom += Array[i].y * Li;
- }
- return Polynom;
- }
- //Полином Ньютона в точке
- double PolynomN_dot(double x, Node *Array, int Count)
- {
- double Result = Array[0].y, dd;
- for (int i = 1; i < Count; i++)
- {
- dd = 0.0;
- dd = DividedDifference(i, Array);
- for (int k = 0; k < i; k++) dd = dd * (x - Array[k].x);
- Result += dd; // Домножаем разделенную разность на скобки (x-x[0])...(x-x[i-1])
- }
- return Result;
- }
- //То же самое но значение считает сразу вточке
- void table_in_file2(Node* MyArray, Node* Array, int MyCount, int Count, string file_name, string file_name_error, string method_name) {
- int k, j;
- double y_value, x_value;
- ofstream fout(file_name); //Лежит таблица от интерполяции (по заданным точкам) по выбранному методу для графика (точки сами выбрали)
- ofstream pogr(file_name_error);
- method Func = PolynomN_dot;
- if (method_name == "Lagrange")
- method Func = PolynomLG_dot;
- for (k = 0; k < MyCount; k++) {
- x_value = MyArray[k].x;
- fout << x_value << " ";
- pogr << x_value << " ";
- y_value = Func(x_value, Array, Count);
- fout << y_value << endl;
- pogr << abs(y_value - MyArray[k].y) << endl;
- }
- fout.close();
- }
- void orig_table_in_file(Node* Array, int Count) { // Функция берет таблицу иксов и игриков, количество точек в которых считаем знач полинома (мб убрать) и коэфф полинома,
- // По итоге имеем файл с 2 столбацами: х и у, по которому гну пло
- int k;
- double y_value, x_value;
- ofstream fout("D:/Original_graphic.txt");
- for (k = 0; k < Count; k++) { //n иксов подставляев в полином степени n-1
- x_value = Array[k].x;
- fout << x_value << " ";
- y_value = Array[k].y;
- fout << y_value << endl;
- }
- fout.close();
- }
- double W(double x, int n, Node* Array)
- { // Полином вида: (x - x1) * (x - x2) * ... * (x - xn)
- double w = 1;
- for (int i = 1; i <= n; i++)
- {
- w *= x - Array[i].x;
- }
- return w;
- }
- void ApproximateError(functiontype *Function, double Initial, double End, Node *Array, int Count)
- { // Приближенная погрешность
- for (double x = Initial; x <= End; x += 0.01f)
- {
- abs(MaxВerivative * W(x, Count, Array) / Factorial(Count + 1));
- }
- }
- void PolynomLG(Node* Array, int Count, double* &mas_coeff_polynom) //Заполняет массив коэффициентами интерполяционного полинома
- {
- int i, j, l, p, z, c;
- double* tmp_massiv_coeff = new double[Count]; // Хранит коэффиценты Li
- double* brackets_massiv = new double[Count - 1]; //Для раскрытия (x-x0)...(x-xn), умноженных на коэффициент
- double k;
- for (j = 0; j < Count; j++)
- {
- mas_coeff_polynom[j] = 0.0;
- }
- for (i = 0; i < Count; i++)
- {
- c = 0; //Счетчик для числителя, т.к. иначе при счете по P будет дырка в массиве и get_koef_polynom не сможет посчитать (т.е. с делает сдвиг на 1 ячейку)
- for (j = 0; j < Count - 1; j++)
- {
- brackets_massiv[j] = 0.0;
- tmp_massiv_coeff[j] = 0.0;
- }
- tmp_massiv_coeff[Count - 1] = 0.0;
- k = Array[i].y;
- for (p = 0; p < Count; p++)
- {
- if (p != i)
- {
- k *= 1.0 / (Array[i].x - Array[p].x);
- brackets_massiv[c] = 0.0 - Array[p].x;
- c++;
- }
- }
- get_koef_polynom(brackets_massiv, tmp_massiv_coeff, Count - 1, Count - 1); //Раскрываем все скобки из возможных (по Лагранжу так)
- for (i = 0; j < Count; j++)
- {
- mas_coeff_polynom[j] += tmp_massiv_coeff[j] * k;
- }
- }
- }
- void PolynomN(Node* Array, int Count, double* &mas_coeff_polynom)
- {
- int j;
- double dd;
- double* tmp_massiv_coeff = new double[Count]; // массив А0...An конечных коэфф для одного шага цикла сколько точек, столько и коэфф
- double* brackets_massiv = new double[Count - 1]; //массив X0,,,Хn
- int i;
- for (int j = 0; j < Count - 1; j++)
- {
- mas_coeff_polynom[j] = 0.0;
- brackets_massiv[j] = 0.0;
- }
- mas_coeff_polynom[Count - 1] = 0.0;
- for (int j = 0; j < Count - 1; j++)
- { //Кладем все иксы
- brackets_massiv[j] = 0.0 - Array[j].x;
- }
- mas_coeff_polynom[0] = Array[0].y; // 0 индекс хранит свободный член итого многочлена
- for (i = 1; i < Count; i++)
- {
- for (j = 0; j < Count; j++)
- {
- tmp_massiv_coeff[j] = 0.0;
- }
- dd = DividedDifference(i, Array); //Ищем итую РР
- get_koef_polynom(brackets_massiv, tmp_massiv_coeff, Count - 1, i); //Возвращает кф при перемножении (х-Х0)...(х-Хi+1)
- for (j = 0; j < Count; j++)
- {
- mas_coeff_polynom[j] += tmp_massiv_coeff[j] * dd;
- }
- }
- }
- double DFunc(functiontype* func, double x,
- int n) //возварщает проивзодную нго порядка как константу типа дабл
- { // Производная функции
- double h = 0.00001;
- if (n == 1)
- {
- return ((*func)(x + h) - (*func)(x)) / h;
- }
- else
- {
- return (DFunc(func, x + h, n - 1) - DFunc(func, x, n - 1)) / h;
- }
- }
- double test(functiontype* func, double x, int n, long double h)
- { // Производная функции
- h = 0.0001;
- while (n > 1)
- {
- return (test(func, x + h, n - 1, h / pow(10, -2))
- - test(func, x - h, n - 1, h / pow(10, -2)))
- / 2 * h;
- }
- if (n == 1)
- {
- return ((*func)(x + h) - (*func)(x - h)) / 2 * h;
- }
- }
- int main()
- {
- setlocale(LC_ALL, "RUS");
- //ПОСТРОЕНИЕ ДАННЫХ
- Interval Interval;
- int CountNodes, MyNodes = 100;
- functiontype Func = &Myfunc;
- cout << "Enter the interval: " << endl;
- cin >> Interval.InitialNode >> Interval.EndNode;
- cout << "Enter the number of nodes: " << endl;
- cin >> CountNodes;
- double* mas_coeff_polynomNew = new double[CountNodes];
- double* mas_coeff_polynomLag = new double[CountNodes];
- Node *ArrayUniformNodes = new Node[CountNodes];// Массив с равномерными // узлами
- Node *Graph_ArrayUniformNodes = new Node[MyNodes];
- Node* ArrayChebyshevNodes = new Node[CountNodes]; // Массив с Чебышевскими узлами
- Node *Graph_ArrayformNodes = new Node[100]; //Массив где будет много точек для построение ориг графика
- ValueUniformTable(&Func, ArrayUniformNodes, Interval.InitialNode, Interval.EndNode, CountNodes); // Заполнение таблицы равномерных значений
- ValueUniformTable(&Func, Graph_ArrayUniformNodes, Interval.InitialNode, Interval.EndNode, MyNodes);
- ValueChebyshevTable(&Func, ArrayChebyshevNodes, Interval.InitialNode, Interval.EndNode, CountNodes); // Заполнение таблицы Чебышевских значений
- cout << endl;
- //PolynomLG(ArrayUniformNodes, CountNodes, mas_coeff_polynom);
- cout << endl;
- //PolynomN(ArrayUniformNodes, CountNodes,mas_coeff_polynom);
- //Запись точек в файл для построения
- table_in_file2(Graph_ArrayUniformNodes, ArrayUniformNodes, MyNodes, CountNodes, "D:/Lagrange.txt", "D:/Pogr_Lagrange.txt", "Lagrange");
- table_in_file2(Graph_ArrayUniformNodes, ArrayUniformNodes, MyNodes, CountNodes, "D:/Newton.txt", "D:/Pogr_Newton.txt", "Newton");
- orig_table_in_file(Graph_ArrayUniformNodes, MyNodes);
- // Приближенная погрешность
- //ApproximateError(&Func, Interval.InitialNode, Interval.EndNode, ArrayUniformNodes, CountNodes);
- //system("pause");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement