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

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

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Построить график функции http://www.cyberforum.ru/cpp-beginners/thread746141.html
Постройте график функции y = sin2(x)+2 на интервале . Обозначьте оси координат, нарисуйте координатную сетку, укажите цены делений и пределы изменения координат x и y. Оси координат нарисуйте черным цветом, координатную сетку – серым, а график функции – красным. Помогите ребята) тут пацан просил помочь ему) а тут какая то непонятность сам пишу на C# а с C++ не могу что то разобрать в VS)
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> > &data, double step, int n); void main() {
C++ польская запись Необходима срочная помощь в реализации польской записи на С++ для АРИФМЕТИЧЕСКИХ ВЫРАЖЕНИЙ. УСЛОВИЕ. Необходимо вычислить значение корректного арифметического выражения. Формат файла входных данных: Корректное арифметическое выражение ( знаки: +, -, *, /, (, ); возможны отрицательные числа). Также нужна отдельная реализация для sin, cos, tg, sqrt, ln. Все числа целые. подробнее

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

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

25.12.2012, 22:20. Просмотров 5201. Ответов 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;
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru