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

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

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 36, средняя оценка - 4.81
Андрей0792
 Аватар для Андрей0792
0 / 0 / 0
Регистрация: 10.04.2011
Сообщений: 16
25.12.2012, 22:20     Оцените программу: Интерполяция через полином Лагранжа и через сокращённую формулу Ньютона #1
Выкладываю программу интерполяции:
-интерполирование через полином Лагранжа;
-интерполирование через сокращённую формулу Ньютона.

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

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;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.12.2012, 22:20     Оцените программу: Интерполяция через полином Лагранжа и через сокращённую формулу Ньютона
Посмотрите здесь:

C++ Интерполяция Лагранжа
C++ Интерполяционный полином Лагранжа
Интерполяция заданной функции второй формулой Ньютона (обратная интерполяция) C++
Интерполяция полиномом Лагранжа C++
C++ Интерполяция Лагранжа
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Dmitriy_M
1297 / 1178 / 106
Регистрация: 20.03.2009
Сообщений: 4,214
Записей в блоге: 11
25.12.2012, 22:43     Оцените программу: Интерполяция через полином Лагранжа и через сокращённую формулу Ньютона #2
Цитата Сообщение от Андрей0792 Посмотреть сообщение
Принимаю предложения по улучшению.
Никому не показывай.
Андрей0792
 Аватар для Андрей0792
0 / 0 / 0
Регистрация: 10.04.2011
Сообщений: 16
25.12.2012, 22:45  [ТС]     Оцените программу: Интерполяция через полином Лагранжа и через сокращённую формулу Ньютона #3
Цитата Сообщение от Dmitriy_M Посмотреть сообщение
Никому не показывай.
Чтож так?
Dmitriy_M
1297 / 1178 / 106
Регистрация: 20.03.2009
Сообщений: 4,214
Записей в блоге: 11
26.12.2012, 10:40     Оцените программу: Интерполяция через полином Лагранжа и через сокращённую формулу Ньютона #4
Цитата Сообщение от Андрей0792 Посмотреть сообщение
Чтож так?
жуткий говнокод.
Андрей0792
 Аватар для Андрей0792
0 / 0 / 0
Регистрация: 10.04.2011
Сообщений: 16
28.12.2012, 00:52  [ТС]     Оцените программу: Интерполяция через полином Лагранжа и через сокращённую формулу Ньютона #5
Цитата Сообщение от Dmitriy_M Посмотреть сообщение
жуткий говнокод.
Хм, а мне показалось или показалось, я что я запостил на форуме для начинающих?
Наверное всётаки на форуме для начинающих.

Я и без вас в курсе что это жопа. Но она хотя бы есть.
Забивать тему пустыми сообщениями нецелесообразно, лучше бы предложили исправления.

Добавлено через 6 минут
В обеих кодах надо изменить задание разбиений на следующее

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
float a,b;
:
:
:
cout << RUS("Введите начало и конец отрезка");
cin >> a; cin >> b;
cout << RUS("Введите количество разбиений: ");
cin  >> variants;
variants++;
double step = (b-a/variants);
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]);
}
Avazart
 Аватар для Avazart
6906 / 5146 / 253
Регистрация: 10.12.2010
Сообщений: 22,639
Записей в блоге: 17
28.12.2012, 01:15     Оцените программу: Интерполяция через полином Лагранжа и через сокращённую формулу Ньютона #6
Ну на вид не так страшно, кроме как того что не освобождается память...
Max Krieg
 Аватар для Max Krieg
0 / 0 / 0
Регистрация: 28.10.2013
Сообщений: 8
24.04.2014, 21:01     Оцените программу: Интерполяция через полином Лагранжа и через сокращённую формулу Ньютона #7
для мэйна: нахрена использовать
C
1
int main(int argc, char *argv[]){...}
??

Ты же не системным программированием занимаешься.
Поэтому такой мэйн бессмысленен.
Пользуйся обычным:
C
1
int main(){...}
Добавлено через 1 минуту
а так, да, код осмысленный и вполне годный. С ресурсами действительно поаккуратней действовать надо, ну и не совсем понятно, для чего ваять код на винде. Поставь линукс, хоть федору, хоть убунту, и не парься. Будет работать гораздо легче.
Dmitriy_M
1297 / 1178 / 106
Регистрация: 20.03.2009
Сообщений: 4,214
Записей в блоге: 11
25.04.2014, 10:12     Оцените программу: Интерполяция через полином Лагранжа и через сокращённую формулу Ньютона #8
Цитата Сообщение от Max Krieg Посмотреть сообщение
Ты же не системным программированием занимаешься.
Причем тут системное программирование? Это прикладная программа.
Max Krieg
 Аватар для Max Krieg
0 / 0 / 0
Регистрация: 28.10.2013
Сообщений: 8
26.04.2014, 13:16     Оцените программу: Интерполяция через полином Лагранжа и через сокращённую формулу Ньютона #9
обычно в системном программировании для системных (или консольных) команд, приложений, утилит используется такой мэйн.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.04.2014, 13:32     Оцените программу: Интерполяция через полином Лагранжа и через сокращённую формулу Ньютона
Еще ссылки по теме:

C++ полином Лагранжа
Интерполяция полиномом Лагранжа C++
C++ Интерполяция методом Ньютона и Лагранжа

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
zss
Модератор
Эксперт С++
 Аватар для zss
5955 / 5560 / 1788
Регистрация: 18.12.2011
Сообщений: 14,209
Завершенные тесты: 1
26.04.2014, 13:32     Оцените программу: Интерполяция через полином Лагранжа и через сокращённую формулу Ньютона #10
Цитата Сообщение от Андрей0792 Посмотреть сообщение
char NEWT[256];
char* RUS(char*TEXT)
{ CharToOem(TEXT,NEWT);
return NEWT; }
Глобальная переменная - это нехорошо.
Можно либо сделать ее локальной статической
C++
1
2
3
4
5
6
char*  RUS(char*TEXT)
{
    static char   NEWT[256];   
    CharToOem(TEXT,NEWT);
    return NEWT;
}
Либо вообще избавиться
C++
1
2
3
4
5
char*  RUS(char*TEXT)
{
   CharToOem(TEXT,TEXT);
    return TEXT;
}
Yandex
Объявления
26.04.2014, 13:32     Оцените программу: Интерполяция через полином Лагранжа и через сокращённую формулу Ньютона
Ответ Создать тему
Опции темы

Текущее время: 00:47. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru