Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

Оцените программу: Интерполяция через полином Лагранжа и через сокращённую формулу Ньютона - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Построить график функции http://www.cyberforum.ru/cpp-beginners/thread746141.html
Постройте график функции y = sin2(x)+2 на интервале . Обозначьте оси координат, нарисуйте координатную сетку, укажите цены делений и пределы изменения координат x и y. Оси координат нарисуйте черным...
C++ Вычислить произведение элементов массива, расположенных между первым и вторым нулевыми элементами Вычислить произведение элементов массива, расположенных между первым и вторым нулевыми элементами? Оригинал: Обчислити добуток елементів масиву, розташованих між першим і другим нульовими... http://www.cyberforum.ru/cpp-beginners/thread746119.html
Ошибки в программе C++
Здравствуйте! Помогите, пожалуйста, разобраться с ошибками) #include <iostream.h> #include <conio.h> #include <math.h> class Complex // класс компелексных чисел { double re, im; // целая...
Отличия методов класса от обычных функций C++
Что собой представляет метод в классах? Это такое же как и простая функция или что-то другое? Можно простой пример привести какая разница между методами и функциями!
C++ Метод Хука Дживса(нужна подсказка) http://www.cyberforum.ru/cpp-beginners/thread746086.html
#include <iostream> #include <vector> #include <cmath> using namespace std; double objectiveFunction(vector < vector<double> > &data, int n, int m); void research(vector < vector<double> >...
C++ польская запись Необходима срочная помощь в реализации польской записи на С++ для АРИФМЕТИЧЕСКИХ ВЫРАЖЕНИЙ. УСЛОВИЕ. Необходимо вычислить значение корректного арифметического выражения. Формат файла входных... подробнее

Показать сообщение отдельно
Андрей0792
0 / 0 / 0
Регистрация: 10.04.2011
Сообщений: 16

Оцените программу: Интерполяция через полином Лагранжа и через сокращённую формулу Ньютона - C++

25.12.2012, 22:20. Просмотров 5487. Ответов 9
Метки (Все метки)

Выкладываю программу интерполяции:
-интерполирование через полином Лагранжа;
-интерполирование через сокращённую формулу Ньютона.

Обе формулы есть на Вики
Выставляю на ваш суд. Принимаю предложения по улучшению.

C++
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <iostream>
#include <Windows.h>   // Подключаем 2 библиотеки для русификации программы
#include <iomanip.h>   // Вторая библиотека
 
using namespace std;
 
char   NEWT[256];   //Небольшая штуковинка для использования русского текста
char*  RUS(char*TEXT){
    CharToOem(TEXT,NEWT);
    return NEWT;
}
 
class INTERPOLATION{   // Класс функций для интерполирования
    public:
        double Lagrange();   //Объявляем Лагранжа
        double Newton();   //Объявляем Ньютона
        int i,j,k;
 
        INTERPOLATION(){
            cout << RUS("Введите число вариантов: "); //Вводим количество отрезков между точками(узлами)
            cin  >> variants;
            double step = (2.0/variants); // Число 2.0 получаем из длины отрезка на котором рассматривается функция. Например в моём случае отрезок от -1 до 1, т.е. 2
            OX = new double[variants];
            OY = new double[variants];
            for (i=0; i<variants; i++){
                OX[i] = -1+step*i;
                OY[i] = 1/(1+OX[i]*OX[i]);
            }
 
            cout << "x,y:" << endl;
            for(i=0; i<variants; i++){
                cout << RUS("Точка [") << i+1 << "]=" << OX[i] << " , " << OY[i] << endl;
            }
        }
 
    private:
        double *OX,*OY;
        int variants,n;
};
 
int main(int argc, char *argv[]){
    double x, arg, result=0.0;
 
    INTERPOLATION func;
    cout << func.Lagrange() << endl;
    cout << func.Newton()   << endl;
 
    system("PAUSE");
    return EXIT_SUCCESS;
}
 
double INTERPOLATION::Lagrange(){ // Собственно полином Лагранжа
    double result = 0.0, _x;
 
    cout << RUS("Введите аргумент для полинома Лагранжа: ");
    cin  >> _x;
 
    for(int i=0; i<variants; i++){
        double P = 1.0;
        for(int j=0; j<variants; j++)
            if(j-i)
                P*=(_x-OX[j])/(OX[i]-OX[j]);
        result+=P*OY[i];
    }
 
    cout << RUS("Ответ: ");
    return result;
}
 
double INTERPOLATION::Newton(){ //А это сокращённая формула Ньютона
    double result = OY[0], F, znam, _x;
 
    cout << RUS("Введите аргумент для метода Ньютона:");
    cin  >> _x;
 
    for(i=1; i<variants; i++){
        F=0;
        for(j=0; j<=i; j++){
            znam=1;
            for(k=0; k<=i; k++){
                if (k!=j)
                    znam*=(OX[j]-OX[k]);
            }
            F+=OY[j]/znam;
        }
        for(k=0; k<i; k++)
            F=F*(_x-OX[k]);
        result+=F;
    }
 
    cout << RUS("Ответ: ");
    return result;
}
Добавлено через 2 минуты
Вот ещё интерполяция кубическим сплайном

C++
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <string>
#include <cstdlib>
#include <math.h>
#include <iostream>
#include <Windows.h>
#include <iomanip.h>
 
using namespace std;
 
char   NEWT[256];
char*  RUS(char*TEXT){
    CharToOem(TEXT,NEWT);
    return NEWT;
}
 
class cubic_spline{
    private:
        struct spline{double a, b, c, d, x;};                                   // Структура, описывающая сплайн на каждом сегменте сетки
        spline *splines;                                                        // Сплайн
        std::size_t n;                                                          // Количество узлов сетки
        void clean_memmroy();                                                   // Освобождение памяти
 
    public:
        cubic_spline();                                                         // Конструктор
        ~cubic_spline();                                                        // Деструктор
        void make_spline(const double *x, const double *y, std::size_t n);      // Построение сплайна. x - узлы сетки, должны быть упорядочены по возрастанию, кратные узлы запрещены. y - значения функции в узлах сетки. n - количество узлов сетки
        double f(double x) const;                                               // Вычисление значения интерполированной функции в произвольной точке
};
 
cubic_spline:: cubic_spline():splines(NULL){}
cubic_spline::~cubic_spline(){clean_memmroy();}
 
void cubic_spline::make_spline(const double *x, const double *y, std::size_t n){
    clean_memmroy();
    this->n = n;
    splines = new spline[n];                                                    // Инициализация массива сплайнов
    for (std::size_t i=0; i<n; ++i){
        splines[i].x = x[i];
        splines[i].a = y[i];
    }
    splines[0].c = 0.;
    double *alpha = new double[n-1];                                            // Решение СЛАУ относительно коэффициентов сплайнов c[i] методом прогонки для трехдиагональных матриц
    double *beta = new double[n-1];                                             // Вычисление прогоночных коэффициентов - прямой ход метода прогонки
    double A, B, C, F, h_i, h_i1, z;
    alpha[0] = beta[0] = 0.;
    for (std::size_t i=1; i<n-1; ++i){
        h_i = x[i] - x[i-1], h_i1 = x[i+1] - x[i];
        A = h_i;
        C = 2.*(h_i + h_i1);
        B = h_i1;
        F = 6.*((y[i+1] - y[i])/h_i1 - (y[i] - y[i-1])/h_i);
        z = (A*alpha[i-1] + C);
        alpha[i] = -B/z;
        beta[i]  = (F - A*beta[i-1])/z;
    }
    splines[n-1].c = (F - A*beta[n-2])/(C + A*alpha[n-2]);
 
    for (std::size_t i=n-2; i>0; --i)                                           // Нахождение решения - обратный ход метода прогонки
        splines[i].c = alpha[i]*splines[i+1].c + beta[i];
 
    delete[] beta;                                                              // Освобождение памяти, занимаемой прогоночными коэффициентами
    delete[] alpha;
 
    for (std::size_t i=n-1; i>0; --i){                                          // По известным коэффициентам c[i] находим значения b[i] и d[i]
        double h_i = x[i] - x[i-1];
        splines[i].d = (splines[i].c - splines[i-1].c)/h_i;
        splines[i].b = h_i*(2.*splines[i].c + splines[i-1].c)/6. + (y[i] - y[i-1])/h_i;
    }
}
 
double cubic_spline::f(double x) const{
    if (!splines)
        return std::numeric_limits<double>::quiet_NaN();                        // Если сплайны ещё не построены - возвращаем NaN
 
    spline *s;
    if (x <= splines[0].x)                                                      // Если x меньше точки сетки x[0] - пользуемся первым эл-тов массива
        s = splines + 1;
    else
        if (x >= splines[n-1].x)                                                // Если x больше точки сетки x[n - 1] - пользуемся последним эл-том массива
            s = splines + n-1;
        else{                                                                   // Иначе x лежит между граничными точками сетки - производим бинарный поиск нужного эл-та массива
            std::size_t i=0, j=n-1;
            while (i+1 < j){
                std::size_t k = i+(j-i)/2;
                if (x <= splines[k].x)
                    j = k;
                else
                    i = k;
            }
            s = splines + j;
        }
    double dx = (x-s->x);
    return s->a+(s->b+(s->c/2.+s->d*dx/6.)*dx)*dx;                              // Вычисляем значение сплайна в заданной точке
}
 
void cubic_spline::clean_memmroy(){
    delete[] splines;
    splines = NULL;
}
 
int main(int argc, char *argv[]){
    double x,arg,resultt=0.0;
    double *OX,*OY;
    int variants;
 
    cout << RUS("Введите количество отрезков: ");
    cin  >> variants;
    double step = (2./variants);
    OX = new double[variants];
    OY = new double[variants];
    for (int i=0; i<variants; i++){
        OX[i] = -1+step*i;
        OY[i] = 1/(1+OX[i]*OX[i]);
    }
 
    cout << "x,y:" << endl;
    for(int i=0; i<variants; i++){
        cout << RUS("Аргумент [") << i+1 << "]=" << OX[i] << " , " << OY[i] << endl;
}
 
    cout << RUS("Введите аргумент для кубического сплайна: ");
    cin  >> arg;
 
    cubic_spline Spline;
    Spline.make_spline(OX,OY,variants);
 
    cout << RUS("Ответ: ") << Spline.f(arg) << endl;
 
    system("PAUSE");
    return EXIT_SUCCESS;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru