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

Нужна помощь в проверки правельности алгоритма - C++

Восстановить пароль Регистрация
 
YouDoItWrong
46 / 46 / 7
Регистрация: 29.10.2011
Сообщений: 154
31.10.2011, 08:51     Нужна помощь в проверки правельности алгоритма #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
class RUNGE_KUTTA {
public:
    int N;
    double t;
    double *K;
    double *KK,*K1,*K2,*K3,*K4;
    RUNGE_KUTTA(int Na) {
        N=Na;
        if(N<1) {
            return;
        }
        K = new double[N];
        KK = new double[N];
        K1 = new double[N];
        K2 = new double[N];
        K3 = new double[N];
        K4 = new double[N];
    }
    ~RUNGE_KUTTA() {
        delete[] K;
        delete[] KK;
        delete[] K1;
        delete[] K2;
        delete[] K3;
        delete[] K4;
    }
    void SET_TERM(double t0, double *K0) {
        t = t0;
        for(int i = 0; i < N; i++) {
            K[i] = K0[i];
        }
    }
    double GET_TIME() {
        return t;
    }
    void F(double t, double *K, double *dY);
    void STEP_IN(double dt) {
        if(dt < 0) {
            return;
        }
        F(t, K, K1);
        for(int i=0; i < N; i++) {
            KK[i] = K[i] + K1[i] * (dt/2.0);
        }
        F(t + dt/2.0, KK, K2);
        for(int i=0; i<N; i++) {
            KK[i] = K[i] + K2[i] * (dt/2.0);
        }
        F(t + dt/ 2.0, KK, K3);
        for(int i=0; i<N; i++) {
            KK[i] = K[i] + K3[i] * (dt);
        }
        F(t + dt, KK, K4);
        for(int i=0; i<N; i++) {
            K[i] = K[i] + dt / 6.0 * (K1[i] + 2.0 * K2[i] + 2.0 * K3[i] + K4[i]);
        }
        t = t + dt;
    }
};
Собственно кто-нибудь может помочь протестировать алгоритм на нескольких функциях, покритиковать код, и проверить правильность его реализации, предложить какие-либо дополнения к коду, заранее спасибо.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
31.10.2011, 08:51     Нужна помощь в проверки правельности алгоритма
Посмотрите здесь:

Нужна помощь C++
Проблема с рандомом + помощь в создании алгоритма C++
C++ Нужна помощь.
C++ Нужна помощь
C++ Помощь в написании алгоритма.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
31.10.2011, 11:13     Нужна помощь в проверки правельности алгоритма #2
Промолчу про стиль именования...

Добавь к конструктору спецификатор explicit.
YouDoItWrong
46 / 46 / 7
Регистрация: 29.10.2011
Сообщений: 154
31.10.2011, 12:02  [ТС]     Нужна помощь в проверки правельности алгоритма #3
Цитата Сообщение от Deviaphan Посмотреть сообщение
Промолчу про стиль именования...
Добавь к конструктору спецификатор explicit.
Done, сам знаю переменные названы ужасно, просто не малейшего представления не имел как их назвать, кроме как названиями из формул, а по работе алгоритма есть какие-либо замечания?
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
31.10.2011, 12:10     Нужна помощь в проверки правельности алгоритма #4
Я имел в виду заглавные буквы. Так обычно макроопределения именуют.
А по алгоритмы сказать нечего, т.к. я не знаю что за алгоритм и кода функции F в листинге нету.
YouDoItWrong
46 / 46 / 7
Регистрация: 29.10.2011
Сообщений: 154
31.10.2011, 12:42  [ТС]     Нужна помощь в проверки правельности алгоритма #5
Цитата Сообщение от Deviaphan Посмотреть сообщение
А по алгоритмы сказать нечего, т.к. я не знаю что за алгоритм и кода функции F в листинге нету.
"Методы Рунге — Кутты — важное семейство численных алгоритмов решения обыкновенных дифференциальных уравнений и их систем. Данные итеративные методы явного и неявного приближённого вычисления были разработаны около 1900 года немецкими математиками К. Рунге и М. В. Куттой.

Формально, методом Рунге — Кутты является модифицированный и исправленный метод Эйлера, они представляют собой схемы второго порядка точности. Существуют стандартные схемы третьего порядка, не получившие широкого распространения. Наиболее часто используется и реализована в различных математических пакетах (Maple, MathCAD, Maxima) стандартная схема четвёртого порядка. Иногда при выполнении расчётов с повышенной точностью применяются схемы пятого и шестого порядков. Построение схем более высокого порядка сопряжено с большими вычислительными трудностями. Методы седьмого порядка должны иметь по меньшей мере девять стадий, в схему восьмого порядка входит 11 стадий. Хотя схемы девятого порядка не имеют большой практической значимости, неизвестно, сколько стадий необходимо для достижения этого порядка точности. Аналогичная задача существует для схем десятого и более высоких порядков."
Пример F, поскольку для различных задач F разная.
C++
1
2
3
4
void F(double t, double *K, double dY[]) { //y''(t) + y(t) = 0 (y'' = 2-ая производная.
        dY[0] = K[1];
        dY[1] = -K[0];
    }
Ну и соответственно использование:
C++
1
2
3
4
5
6
7
8
9
10
int main() {
    RUNGE_KUTTA rk4(2);
    double K0[2] = {0, 1};
    rk4.SET_TERM(0, K0);
    for(int i = 0; i < 10; i++) {
        cout << rk4.GET_TIME() << " " << rk4.K[0] /*Искомое решение*/ << " " << rk4.K[1] /* i - ая производная*/ << endl;
        rk4.STEP_IN(0.01);
    }
    return 0;
}
Добавлено через 4 минуты
При решении этим методом ОДУ N-го порядка входными данными являются:
а) числа:
N - порядок ОДУ
K - число узлов сетки
h - шаг сетки x[k]
x[0], y[0], y'[0], ..., y^(N-1)[0] - начальные условия
б) функция:
f(x, y, y', ..., y^(N-1)) - правая часть ОДУ

В примере который я привел K = 10, h = 0.01, N = 2, а правая часть ничто иное как F(...);
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
31.10.2011, 12:43     Нужна помощь в проверки правельности алгоритма #6
Функцию F следует сделать просто функцией, а не методом класса.
В методе STEP_IN dt нужно на равенство нулю ещё проверять, иначе все шаги одинаковые будут.
YouDoItWrong
46 / 46 / 7
Регистрация: 29.10.2011
Сообщений: 154
31.10.2011, 13:07  [ТС]     Нужна помощь в проверки правельности алгоритма #7
Цитата Сообщение от Deviaphan Посмотреть сообщение
Функцию F следует сделать просто функцией, а не методом класса.
А если F сделать private методом класса? Просто весь класс не будет иметь смысла без F. Я пишу систему стабилизации аппарата, а там нужно решать пару ОДУ, и от этого класса будут наследоваться еще пара классов... И разве не плохо стиль программирования когда ООП сосчитаться с функциональным программирование?
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
31.10.2011, 13:21     Нужна помощь в проверки правельности алгоритма #8
Эту функцию не имеет смысла делать методом класса, т.к. все используемые в ней данные передаются в виде аргументов.

Цитата Сообщение от YouDoItWrong Посмотреть сообщение
поскольку для различных задач F разная
Тебе следует в классе хранить указатель на функцию и назначать её перед использованием. Тогда ты сможешь применять этот класс для решения задач с различной реализацией F.
Т.е. создаёшь в классе указатель на функцию
typedef void (*F)(double t, double *K, double *dY);
F _function;
YouDoItWrong
46 / 46 / 7
Регистрация: 29.10.2011
Сообщений: 154
31.10.2011, 16:52  [ТС]     Нужна помощь в проверки правельности алгоритма #9
Что то точность алгоритма хромает, где может быть ошибка?
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
31.10.2011, 16:56     Нужна помощь в проверки правельности алгоритма #10
Замени деление умножением и попробуй минимизировать число операций, т.е. логику изменить попробуй.
YouDoItWrong
46 / 46 / 7
Регистрация: 29.10.2011
Сообщений: 154
31.10.2011, 17:06  [ТС]     Нужна помощь в проверки правельности алгоритма #11
Может стоит высчитывать среднее квадратичное отклонение от интересующей меня точности, и если точность не достигнута делать двойной пересчет? т.е. Заданный шаг делим на два.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.10.2011, 17:08     Нужна помощь в проверки правельности алгоритма
Еще ссылки по теме:

Нужна помощь C++
Помощь в написании алгоритма C++
C++ Нужна программа пример алгоритма очередь.

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

Или воспользуйтесь поиском по форуму:
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
31.10.2011, 17:08     Нужна помощь в проверки правельности алгоритма #12
Возможно. Но учти, что чем сильнее отличается порядок величин, тем больше будет погрешность.
Yandex
Объявления
31.10.2011, 17:08     Нужна помощь в проверки правельности алгоритма
Ответ Создать тему
Опции темы

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