Пример: найти численное решение дифференциального уравнения
d3x/dt3 = 2,5 d2x/dt2 + 5 dx/dt + 2x
на интервале от t0=0 c до t1=10 c с шагом h=0,02 при начальных условиях
x0 = 1, dx0 /dt = 0, d2x0/dt2 = 0.
Решение выводить на каждом пятом шаге интегрирования (101 точка вывода).
Вывести графики переменной x(t), ее первой и второй производной.
Представим исходной уравнение в форме Коши:
dx0/dt(t) = x1(t);
dx1/dt(t) = x2(t);
dx2/dt(t) = -2x0(t) – 5x1(t) - 2,5x2(t).
Головная программа:
#include <stdio.h>
#include <math.h>
#include <conio.h>
void Runge_Kutt_4(int n, float h, float t0, float t1, int s1, float x[n], float out[][n+1], int *k);
void graphics_diffur_koshi(int n, int k, int amplituda, char path[], float out[][n+1]);
int main(int argc, char **argv)
{
int n; // порядок системы уравнений
float h; // шаг интегрирования
float t0, t1; // начальное и конечное время
// интегрирования
int s1; // количество шагов на один вывод решения
int k; // количество точек вывода
int amplituda; // амплитуда графиков функций в позициях
char path[30]="E:/User/graphics.txt"; // полный путь
// к текстовому файлу для вывода данных, например,
// d:/user/out.txt
int i, j; // рабочие переменные
printf("\n Porjadok sistemy uravn. n=");
scanf("%d", &n);
float x[n]; // вектор начальных условий
float out[500][n+1]; // матрица выходных данных:
// количество строк – количество
// точек вывода: (t1-t0)/(h*s1) +1
// нулевой столбец - текущее время,
// остальные n столбцов - вектор решения
printf("\n Nachalnoe vremja integrir.: t0=");
scanf("%f", &t0);
printf("\n Konechnoe vremja integrir.: t1=");
scanf("%f", &t1);
printf("\n Shag integrir.: h=");
scanf("%f", &h);
printf("\n Kol-vo shagov na odin vyvod reshenija s1=");
scanf("%d", &s1);
printf("\n Max amplituda grafikov amplituda=");
scanf("%d", &lituda);
printf("\n Vvedite nachaln. uslovija (%d znachenij):\n", n);
for (i=0; i<n; i++)
scanf("%f", &x[i]);
printf("\n");
Runge_Kutt_4(n, h, t0, t1, s1, x, out, &k);
printf("\nTochek vyvoda - %d\n", k);
printf("\n------------------------------------------");
printf("\n t x dx/dt d(dx/dt)/dt");
printf("\n------------------------------------------\n");
for (i=0; i<k; i++)
{
for (j=0; j<n+1; j++)
printf ("%10.5f", out[i][j]);
printf("\n");
}
printf("\n");
// обращение к функции вывода графиков
Graphics_diffur_koshi(n, k, amplituda, path, out);
Return 0;
}
Описание правых частей системы уравнений:
void pr_chasti(float x[], float p[])
{
p[0]=x[1];
p[1]=x[2];
p[2]=-2.0*x[0]-5.0*x[1]-2.5*x[2];
}
Результат решения задачи:
Результаты, сохраненные в выходном файле:
---------------------------------------------------------------------------
| t | g r a p h i c s
---------------------------------------------------------------------------
| 0.00000 | 2 1*
| 0.10000 | 2 1*
| 0.20000 | 2 1 *
| 0.30000 | 2 1 *
| 0.40000 |2 1 *
| 0.50000 |2 1 *
| 0.60000 |2 1 *
| 0.70000 | 2 1 *
| 0.80000 | 2 1 *
| 0.90000 | 1 2 *
| 1.00000 | 1 2 *
| 1.10000 | 1 2 *
| 1.20000 |1 2 *
| 1.30000 |1 2 *
| 1.40000 |1 *2
| 1.50000 |1 * 2
| 1.60000 |1 * 2
| 1.70000 | 1 * 2
| 1.80000 | 1 * 2
| 1.90000 | 1 * 2
| 2.00000 | 1 * 2
| 2.10000 | 1 * 2
| 2.20000 | 1 * 2
| 2.30000 | 1* 2
| 2.40000 | * 1 2
| 2.50000 | * 1 2
| 2.60000 | * 1 2
| 2.70000 | * 1 2
| 2.80000 | * 1 2
| 2.90000 | * 1 2
| 3.00000 | * 1 2
| 3.10000 | * 1 2
| 3.20000 | * 1 2
| 3.30000 | * 1 2
| 3.40000 | * 12
| 3.50000 | * 21
| 3.60000 | * 2 1
| 3.70000 | * 2 1
| 3.80000 | * 2 1
| 3.90000 | * 2 1
| 4.00000 | * 2 1
| 4.10000 | * 2 1
| 4.20000 | * 2 1
| 4.30000 | * 2 1
| 4.40001 | * 2 1
| 4.50001 | * 2 1
| 4.60001 | * 2 1
| 4.70001 | * 2 1
| 4.80001 | * 2 1
| 4.90002 | * 2 1
| 5.00002 | * 2 1
| 5.10002 | * 2 1
| 5.20002 | * 2 1
| 5.30003 | * 2 1
| 5.40003 | * 2 1
| 5.50003 | * 2 1
| 5.60003 | * 2 1
| 5.70004 | * 2 1
| 5.80004 | * 2 1
| 5.90004 | * 2 1
| 6.00004 | * 2 1
| 6.10004 | * 2 1
| 6.20005 | * 2 1
| 6.30005 | * 2 1
| 6.40005 | * 2 1
| 6.50005 | * 2 1
| 6.60006 | * 2 1
| 6.70006 | * 2 1
| 6.80006 | * 2 1
| 6.90006 |* 2 1
| 7.00007 |* 2 1
| 7.10007 |* 2 1
| 7.20007 |* 2 1
| 7.30007 |* 2 1
| 7.40007 |* 2 1
| 7.50008 |* 2 1
| 7.60008 |* 2 1
| 7.70008 |* 2 1
| 7.80008 |* 2 1
| 7.90009 |* 2 1
| 8.00009 |* 2 1
| 8.10009 |* 2 1
| 8.20009 |* 2 1
| 8.30009 |* 2 1
| 8.40010 |* 2 1
| 8.50010 |* 2 1
| 8.60010 |* 2 1
| 8.70010 |* 2 1
| 8.80011 |* 2 1
| 8.90011 |* 2 1
| 9.00011 |* 2 1
| 9.10011 |* 2 1
| 9.20012 |* 2 1
| 9.30012 |* 2 1
| 9.40012 |* 2 1
| 9.50012 |* 2 1
| 9.60012 |* 2 1
| 9.70013 |* 2 1
| 9.80013 |* 2 1
| 9.90013 |* 2 1
| 10.00013 |* 2
Символы, используемые для вывода графиков:
“ * ” выходная переменная x(t),
“ 1 ” ее первая производная,
“ 2 ” ее вторая производная.
Вывод графиков функций
В головной программе необходимо:
1. описать прототип функции:
void graphics(int n, int k, int amplituda, char path[], float out[][n+1]);
2. ввести значение переменной n – количество графиков (n<10),
3. ввести значение переменных x0, x1 – начальное и конечное значение аргумента,
4. ввести значение переменной h – шаг вывода графиков,
5. описать массив out[k][n+1] – выходной массив:
количество строк – количество точек вывода k=(x1- x0)/h + 1,
нулевой столбец – значение аргумента,
остальные столбцы – исходные данные для построения графиков,
6. ввести значение переменой amplituda - амплитуда графиков функций в позициях (в текстовом файле),
7. ввести строку path[30] - полный путь к текстовому файлу для вывода данных, например, d:/user/out.txt,
8. обратиться к программе вывода графиков: