МIНIСТЕРСТВО ОСВIТИ І НАУКИ УКРАЇНИ
Лабораторна робота
Тема: “Розв’язання диференціальних рівнянь”
Мета: вивчення засобiв мови Сi та оволодiння прийомами складання алгоритмiв i програм для розвязування диференційних рівнянь.
Завдання: розвязати диференціальне рівняння y’’+4y’=6x2+1 на проміжку [0;1.5] з кроком 0.1. Початкові умови y(0)=1, y’(0)=0.
Теоретичні відомості:
Розв’язування диференціального рівняння
Постановка задачі (задача Коші) має вигляд диференціального рівняння з початковими умовами
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.
Програма складена мовою Сі:
# include<stdio.h>
# include<bios.h>
# include<graphics.h>
float x,h=0.1,yb[21],y[2],z[2],f[2];
int i,j;
/*Побудова графiка*/
void grafik()
{
int j,i,gmode,gdriver=DETECT;
initgraph(&gdriver,&gmode,"\BGI");
fprintf(stdout,"\ngrafik\n");
for(i=0;i<20;i++)
line(10*i+100,300-100*yb[i],10*(i+1)+100,300-100*yb[i+1]);
line(100,200,500,200);
line(100,300,500,300);
line(100,100,100,500);
outtextxy(80,200,"1");
outtextxy(80,300,"0");
bioskey(0);
closegraph();
return;
}
void Ejler()
{ void systema(void);
x=0;
y[0]=0;
y[1]=1;
yb[0]=0;
for(i=0;i<=20;i++)
{
for(j=0;j<2;j++)z[j]=y[j];
systema();
for(j=0;j<2;j++)y[j]=z[j]+h*f[j];
yb[i]=y[1];
x+=h;
}
return;
}
void Ejler-pokraschenuj(void)
{ void systema(void);
x=0;
y[0]=0;
y[1]=1;
yb[0]=0;
for(i=0;i<=20;i++)
{
for(j=0;j<2;j++)z[j]=y[j];
systema();
for(j=0;j<2;j++)y[j]=z[j]+h*f[j]/2;
systema();
for(j=0;j<2;j++)y[j]=z[j]+h*f[j];
yb[i]=y[1];
x+=h;
}
return;
}
void Ejler-Koshi()
{void systema(void);
float a[4];
x=0;
y[0]=0;
y[1]=1;
yb[0]=0;
for(i=0;i<=20;i++)
{for(j=0;j<2;j++)z[j]=y[j];
systema();
for(j=0;j<2;j++){a[j]=f[j];y[j]=z[j]+h*a[j];}
systema();
for(j=0;j<2;j++){y[j]=z[j]+h*(a[j]+f[j])/2;}
yb[i]=y[1];
}
return;
}
void Runge-Kuta()
{float a[4],b[4],c[4],d[4];
void systema(void);
y[0]=0;
y[1]=1;
yb[0]=0;
for(i=0;i<=20;i++)
{for(j=0;j<2;j++)z[j]=y[j];
systema();
for(j=0;j<2;j++){a[j]=f[j]*h;y[j]=z[j]+a[j]/2;}
systema();
for(j=0;j<2;j++){b[j]=f[j]*h;y[j]=z[j]+b[j]/2;}
systema();
for(j=0;j<2;j++){c[j]=f[j]*h;y[j]=z[j]+c[j];}
systema();
for(j=0;j<2;j++){d[j]=f[j]*h;y[j]=z[j]+(a[j]+2*(b[j]+c[j])+d[j])/6;}
yb[i]=y[1];
}
return;
}
/* Система дифрiвнянь */
void systema(void)
{
f[0]=6*x*x+1-4*y[0];
f[1]=y[0];
return;
}
void prin()
{
printf("%f\t%f\t%f\t%f\t%f\n",yb[0],yb[1],yb[2],yb[3],yb[4]);
printf("%f\t%f\t%f\t%f\t%f\n",yb[5],yb[6],yb[7],yb[8],yb[9]);
printf("%f\t%f\t%f\t%f\t%f\n",yb[10],yb[11],yb[12],yb[13],yb[14]);
printf("%f\t%f\t%f\t%f\t%f\n",yb[15],yb[16],yb[17],yb[18],yb[19]);
}
/* Головна програма */
void main()
{
Ejler();
Printf(”Метод Ейлера\n ”);
prin();
bioskey(0);
grafik();
Ejler-pokraschenuj();
Printf(”Метод Ейлера-покращений\n ”);
prin();
bioskey(0);
grafik();
Ejler-Koshi();
Printf(”Метод Ейлера-Коші\n ”);
prin();
bioskey(0);
grafik();
Runge-Kuta();
Printf(”Метод Рунге-Кута \n ”);
prin();
bioskey(0);
grafik();
}
Результат виконання програми
Метод Ейлера
Метод Ейлера-покращений
Метод Ейлера-Коші
Метод Рунге-Кута
Висновки: виконавши лабораторну роботу, я вивчив засоби мови Сi та прийомами складання алгоритмiв i програм, для розвязування диференціального рівняння.