Метод Эйлера решения скалярной задачи Коши 1-го порядка (Реализация на C++)

C++   7 Июнь 2012  Автор статьи:  

Воспользуемся методом Эйлера для нахождения приближенного решения скалярной задачи Коши 1-го порядка. Под скалярной задачей понимается такая задача, что ее решение — обыкновенная функция, а не вектор-функция.

Рассмотрим следующую задачу

Пример скалярной задачи Коши 1-го порядка

Несложно убедиться, что ее точным решением является функция

Точное решение задачи из примера

В приведенном ниже алгоритме начальные условия и шаг сетки аргумента задается внутри самой программы, тем не менее не представляет трудности осуществить их считывание, например, из файла. Все вычисления проводятся с типом данных double в целях повышения точности вычислений.

Результатом работы программы является таблица из четырех столбцов: абсцисса, значение точного решения в этой точке, значение приближенного аргумента в ней и, наконец, разность между точным и приближенным решениями, т.е. погрешность в данной точке. Именно для подсчета погрешности и интересно знать точное решение исходной задачи. Нетрудно заметить, что в нашем случае погрешность увеличивается по мере отдаления от точки, в которой задано начальное условие задачи Коши, и это справедливо для большинства задач.

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
// Для удобства ввода/вывода в программе
// воспользуемся стандартной библиотекой
#include <iostream>

// Также подключим библиотеку, содержащую
// основные математические функции
#include <cmath>

// Работать будем в стандартном пространстве
// имен, называемом std
using namespace std;

// Следующая функция возвращает значение
// точного решения задачи в точке x;
// она пригодится при оценке погрешности
// метода, но при нахождении приближенного
// решения она не используется
double calculate_y(double x)
{
    return exp(x) * sin(x);
}

// Следующая функция возвращает значение
// правой части исходной задачи по
// заданным аргументам x и y
double calculate_f(double x, double y)
{
    return y + exp(x) * cos(x);
}

int main()
{
    // Задаем границы отрезка, на котором
    // рассматривается исходная задача
    const double a = 0;
    const double b = 1;

    // Задаем начальное условие задачи
    const double y0 = 0;

    // Задаем число точек на отрезке и,
    // соответственно, шаг сетки аргумента
    const int n = 40;
    const double h = (b - a) / n;  

    // Массив x будет хранить сетку аргумента,
    // а массив y - значения приближенного
    // решения в этих точках
    double x[n + 1];
    double y[n + 1];

    // Воспользовавшись начальными условиями,
    // определим первые элементы этих массивов
    x[0] = a;
    y[0] = y0;

    // Применим теперь сам метод Эйлера
    for (int i = 1; i <= n; i++)
    {
        x[i] = x[i - 1] + h;
        y[i] = y[i - 1] + h * calculate_f(x[i - 1], y[i - 1]);
    }

    // Задаем число знаков после запятой,
    // которое мы бы хотели выводить
    cout.precision(8);

    // После этой команды всякое вещественное
    // число будет выводиться с тем числом
    // знаков после запятой, которое было
    // указано выше
    cout.setf(ios::fixed);

    // Выводим 4 столбца: абсцисса, значения
    // точного и приближенного решения в ней
    // и, наконец, погрешность в этой точке
    for (int i = 0; i <= n; i++)
    {
        double error = abs(y[i] - calculate_y(x[i]));

        // Для наглядности столбцы будем выводить
        // через символ табуляции
        cout << x[i] << '\t' << calculate_y(x[i]) << '\t'
             << y[i] << '\t' << error << endl;
    }

    return 0;
}

Научиться программировать

  • на Delphi

  • на Java

  • на C++