Лабораторна робота
Тема:
Розв’язування
диференціальних рівнянь
Мета роботи: Вивчення методів розв’язування диференціальних рівнянь та
засобiв мови Сi для програмування процедур, оволодiння прийомами складання алгоритмiв i програм з пiдпрограмами.
Завдання:
№
вар. | Диференційне рівняння |
Початкові умови | Проміжок інтегрування | Крок інтегрування
15 | y’+4y=6х2+1 | y(0)=1 | [0;1.5] | 0.1
Короткі теоретичні відомості:
Розв’язування диференціального рівняння
Постановка задачі (задача Коші) має вигляд диференціального рівняння з початковими умовами
yР = f(t,y), y = y0 при t = t0. t Є [a, b].
Для її наближеного розв’язання застосовуються так звані однокрокові методи: Ейлера, Ейлера покращений, Ейлера-Коші та Рунге-Кута. Їх суть полягає в тому, що діапазон інтегрування [a, b] ділять на n елементарних відрізків довжиною h. Значення шуканої функції в точці t0=a відомо з початкових умов, а її обчислення в першій і наступних точках аж до точки tn=b виконують за поданими нижче формулами. При цьому h=(b-a)/n, t0 = a, tn = b, ti+1 = ti+h, yi=f(ti), i=0,1,2, ... n.
Алгоритм розв’язування дифрівняння однокроковими методами представляє собою цикл з накопиченням суми.
Метод Ейлера найпростіший, але він має лише перший порядок точності. Геометрично метод представляє собою перехід у кожну наступну точку, починаючи з заданої початковими умовами, вздовж дотичної до точного розв’язку, проведеної з попередньої точки. Цей метод враховує кут нахилу дотичної до кривої точного розв’язку лише в одній крайній точці елементарного відрізка. Ілюстрація першого кроку переходу в точку t1 подана на рисунку 2, де y1* – точне значення шуканої функції в точці t1, e – похибка. Формула Ейлера має такий вигляд: yi+1=yi+hf(xi,yi).
Метод Ейлера покращений має другий порядок точності. На кожному кроці обчислювального процесу знаходять проміжні значення шуканої функції yiп посередині кожного i-го елементарного відрізка (на відстані пів-кроку, тобто при ti+h/2) за методом Ейлера, а проміжні значення використовують для переходу в наступну точку. Геометрично це означає перехід у кожну наступну точку вздовж дотичної, проведеної до кривої точного розв’язку в середній точці. Формули мають такий вигляд:
yiп = yi + hf(ti, yi)/2;
yi+1 = yi + hf(ti+h/2, yiп).
Метод Ейлера-Коші теж має другий порядок точності. Для переходу в кожну наступну точку враховується кут нахилу дотичної до кривої точного розв’язку в обох крайніх точках (тобто в точках ti i ti+1) кожного елементарного відрізка. Для переходу в кожну наступну точку використовують середнє арифметичне значення тангенсів кутів нахилу дотичних до кривої точного розв’язку (похідних) в крайніх точках. Тут теж обчислюють проміжні значення. Формули мають такий вигляд:
yiп = yi + hf(ti, yi);
yi+1 = yi + h[f(ti+h, yiп) + f(ti, yi)]/2.
Метод Рунге-Кута має четвертий порядок точності. На кожному кроці циклічного обчислювального процесу знаходять допоміжні коефіцієнти a, b, c, d. Формули мають такий вигляд:
a = f(ti, yi);
b = f(ti+h/2, yi + ha/2);
c = f(ti+h/2, yi + hb/2);
d = f(ti+h, yi + hc);
yi+1 = yi + h(a + 2b + 2c + d)/6.
Ідентифікація змінних:
Змінна | a |
b | Крок | y0 |
y’ | Номер
елементу
Ідентифікатор | a | b | h | y0 | y_ | func(x,у) | і
Програма:
#include<math.h>
/*Глобальнi змiннi*/
const float a=0,b=1.5,h=0.1,y0=1;
float func(float,float);
/*Функцiя*/
float func(float x,float y)
{
float y_;
y_=6*pow(x,2)+1-4*y;
return y_;
}
/*Головна програма*/
main()
{
ejler();
ejler_p();
ejler_k();
runge_k();
}
/*Метод Ейлера*/
ejler()
{
int i=0;
float x,y=y0;
clrscr();
printf("Метод Ейлера\n");
for(x=a;x<=b+h;x+=h)
{
printf("x[%i]=%.1f >>> y[%i]=%.4f\n",i,x,i,y);
y+=h*func(x,y);
i++;
}
getch();
return;
}
/*Метод Ейлера покращений*/
ejler_p()
{
int i=0;
float x,y=y0,yp;
clrscr();
printf("Метод Ейлера покращений\n");
for(x=a;x<=b+h;x+=h)
{
printf("x[%i]=%.1f >>> y[%i]=%.4f\n",i,x,i,y);
yp=y+h*func(x,y)/2;
y+=h*func(x+h/2,yp);
i++;
}
getch();
return;
} |
/*Метод Ейлера-Кошi*/
ejler_k()
{
int i=0;
float x,y=y0,yp;
clrscr();
printf("Метод Ейлера-Кошi\n");
for(x=a;x<=b+h;x+=h)
{
printf("x[%i]=%.1f >>> y[%i]=%.4f\n",i,x,i,y);
yp=y+h*func(x,y)/2;
y+=h*(func(x+h,yp)+func(x,y))/2;
i++;
}
getch();
return;
}
/*Метод Рунге-Кута*/
runge_k()
{
int i=0;
float x,y=y0,A,B,C,D;
clrscr();
printf("Метод Рунге-Кута\n");
for(x=a;x<=b+h;x+=h)
{
printf("x[%i]=%.1f >>> y[%i]=%.4f\n",i,x,i,y);
A=func(x,y);
B=func(x+h/2,y+h*A/2);
C=func(x+h/2,y+h*B/2);
D=func(x+h,y+h*C);
y+=h*(A+2*B+2*C+D)/6;
i++;
}
getch();
return;
}
Чорнові результати:
Метод Ейлера
x[0]=0.0 >>> y[0]=1.0000
x[1]=0.1 >>> y[1]=0.7000
x[2]=0.2 >>> y[2]=0.5260
x[3]=0.3 >>> y[3]=0.4396
x[4]=0.4 >>> y[4]=0.4178
x[5]=0.5 >>> y[5]=0.4467
x[6]=0.6 >>> y[6]=0.5180
x[7]=0.7 >>> y[7]=0.6268
x[8]=0.8 >>> y[8]=0.7701
x[9]=0.9 >>> y[9]=0.9460
x[10]=1.0 >>> y[10]=1.1536
x[11]=1.1 >>> y[11]=1.3922
x[12]=1.2 >>> y[12]=1.6613
x[13]=1.3 >>> y[13]=1.9608
x[14]=1.4 >>> y[14]=2.2905
x[15]=1.5 >>> y[15]=2.6503 |
Метод Ейлера покращений
x[0]=0.0 >>> y[0]=1.0000
x[1]=0.1 >>> y[1]=0.7615
x[2]=0.2 >>> y[2]=0.6101
x[3]=0.3 >>> y[3]=0.5276
x[4]=0.4 >>> y[4]=0.5015
x[5]=0.5 >>> y[5]=0.5233
x[6]=0.6 >>> y[6]=0.5873
x[7]=0.7 >>> y[7]=0.6897
x[8]=0.8 >>> y[8]=0.8277
x[9]=0.9 >>> y[9]=0.9995
x[10]=1.0 >>> y[10]=1.2040
x[11]=1.1 >>> y[11]=1.4402
x[12]=1.2 >>> y[12]=1.7076
x[13]=1.3 >>> y[13]=2.0059
x[14]=1.4 >>> y[14]=2.3347
x[15]=1.5 >>> y[15]=2.6939 | Метод Ейлера-Кошi
x[0]=0.0 >>> y[0]=1.0000
x[1]=0.1 >>> y[1]=0.7330
x[2]=0.2 >>> y[2]=0.5735
x[3]=0.3 >>> y[3]=0.4937
x[4]=0.4 >>> y[4]=0.4755
x[5]=0.5 >>> y[5]=0.5077
x[6]=0.6 >>> y[6]=0.5830
x[7]=0.7 >>> y[7]=0.6965
x[8]=0.8 >>> y[8]=0.8454
x[9]=0.9 >>> y[9]=1.0276
x[10]=1.0 >>> y[10]=1.2421
x[11]=1.1 >>> y[11]=1.4879
x[12]=1.2 >>> y[12]=1.7647
x[13]=1.3 >>> y[13]=2.0720
x[14]=1.4 >>> y[14]=2.4097
x[15]=1.5 >>> y[15]=2.7776 |
Метод Рунге-Кута
x[0]=0.0 >>> y[0]=1.0000
x[1]=0.1 >>> y[1]=0.7546
x[2]=0.2 >>> y[2]=0.6003
x[3]=0.3 >>> y[3]=0.5170
x[4]=0.4 >>> y[4]=0.4912
x[5]=0.5 >>> y[5]=0.5137
x[6]=0.6 >>> y[6]=0.5786
x[7]=0.7 >>> y[7]=0.6818
x[8]=0.8 >>> y[8]=0.8205
x[9]=0.9 >>> y[9]=0.9929
x[10]=1.0 >>> y[10]=1.1979
x[11]=1.1 >>> y[11]=1.4345
x[12]=1.2 >>> y[12]=1.7022
x[13]=1.3 >>> y[13]=2.0007
x[14]=1.4 >>> y[14]=2.3296
x[15]=1.5 >>> y[15]=2.6890
Систематизовані результати:
№
елем. | х | у
Ейлера | Ейлера покращений | Ейлера-Кошi | Рунге-Кута
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | 0.0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1.0
1.1
1.2
1.3
1.4
1.5 | 1.0000
0.7000
0.5260
0.4396
0.4178
0.4467
0.5180
0.6268
0.7701
0.9460
1.1536
1.3922
1.6613
1.9608
2.2905
2.6503 | 1.0000
0.7615
0.6101
0.5276
0.5015
0.5233
0.5873
0.6897
0.8277
0.9995
1.2040
1.4402
1.7076
2.0059
2.3347
2.6939 | 1.0000
0.7330
0.5735
0.4937
0.4755
0.5077
0.5830
0.6965
0.8454
1.0276
1.2421
1.4879
1.7647
2.0720
2.4097
2.7776 | 1.0000
0.7546
0.6003
0.5170
0.4912
0.5137
0.5786
0.6818
0.8205
0.9929
1.1979
1.4345
1.7022
2.0007
2.3296
2.6890
Висновок: Я вивчив методи розв’язування диференціальних рівнянь та засоби мови Сi для програмування процедур, оволодiв прийомами складання алгоритмiв i програм з пiдпрограмами.
Блок-схема
/*Метод Ейлера*/ |
/*Метод Ейлера покращений*/ |
/*Метод Ейлера-Кошi*/ | /*Метод Рунге-Кута*/
/*Головна програма*/
/*Функцiя*/