Міністерство освіти та науки України
Національний університет “Львівська політехніка”
Звіт
про виконання лабораторної роботи N4
з курсу “Алгоритмічні основи криптології”
на тему: “Основні чисельні методи розв’язування
систем лінійних диференціальних рівнянь ”
Львів – 2004
Мета роботи: вивчити основні чисельні методи розв’язування систем лінійних диференціальних рівнянь.
Завдання: написати програму на мові програмування Сі яка б розв’язувала диференціальне рівняння другого порядку методом Рунге – Кутта - Мерсона, попередньо звівши його до системи диференціальних рівнянь першого порядку.
Диф. рн.
Поч. умови
Проміжок інт.
Крок інт.
Похибка
y’’ – y = sin(x) + cos(2x)
y(0)=1.8
y’(0)=-0.5
[0;2]
0.2
0.001
Блок – схема алгоритму роботи програми1
Текст програми:
Крок сталий:
#include<stdio.h>
#include<math.h>
#include<conio.h>
#define a 0
#define b 2
float f (int i, float x, float y)
{
if(i==1)
return y;
else
return (sin(x)+cos(2*x)+y);
}
void main(void)
{
float k0,k1,k2,k3,k4,z,Rm;
int i;
float h=0.2;
float yp[3],ym1[3],ym12[3],x;
float poch[3];
poch[1]=yp[1]=-0,5;
poch[2]=yp[2]=1,8;
x=a-h;
do
{
z=x;
x+=h;
for(i=1;i<=2;i++)
{
k0=h*f(i,z,yp[i],yp[i-1]);
k1=h*f(i,z+h/3,yp[i]+k0/3,yp[i-1]+k0/3);
k2=h*f(i,z+h/3,yp[i]+k0/6+k1/6,yp[i-1]+k0/6+k1/6);
k3=h*f(i,z+h/2,yp[i]+k0/8+3*k2/8,yp[i-1]+k0/8+3*k2/8);
k4=h*f(i,z+h,yp[i]+k0/2-3*k2/2+2*k3,yp[i-1]+k0/2-3*k2/2+2*k3);
Rm=(-2*k0+9*k2-8*k3+k4)/30;
if(i==1)
ym1[i]=yp[i+1]+(k0+4*k3+k4)/6;
else ym1[i]=yp[i-1]+(k0+4*k3+k4)/6;
}
for(i=1;i<=2;i++)
{
if (i==1)
yp[i+1]=ym1[i];
else
yp[i-1]=ym1[i];
}
printf("x=%2.5f ",x);
for(i=1;i<=2;i++)
printf("y%i=%2.5f ",i,ym1[i]);
printf(" Rm=%f", Rm);
putchar('\n');
}
while (x<=b);
}
Результат виконання програми:
Блок – схема алгоритму роботи програми2
Крок змінний:
#include<stdio.h>
#include<math.h>
#include<conio.h>
#define a 0
#define b 2
#define e 0.002
float f (int i, float x, float y, float y1)
{
if(i==1)
return y;
else return (sin(x)+cos(2*x)+y);
}
void main(void)
{
float k0,k1,k2,k3,k4;
int i,l;
float h=0.2;
float yp[3],ym1[3],ym2[3],Rm;
float x,h1,z,z1,z2,z3,z4;
float p[3];
p[1]=yp[1]=-0,5;
p[2]=yp[2]=1,8;
x=a-h;
while (x<=b)
{
z=x;
z1=yp[1];
z2=yp[2];
x+=h;
for(i=1;i<=2;i++)
{
k0=h*f(i,z,yp[i],yp[i-1]);
k1=h*f(i,z+h/3,yp[i]+k0/3,yp[i-1]+k0/3);
k2=h*f(i,z+h/3,yp[i]+k0/6+k1/6,yp[i-1]+k0/6+k1/6);
k3=h*f(i,z+h/2,yp[i]+k0/8+3*k2/8,yp[i-1]+k0/8+3*k2/8);
k4=h*f(i,z+h,yp[i]+k0/2-3*k2/2+2*k3,yp[i-1]+k0/2-3*k2/2+2*k3); Rm=(-2*k0+9*k2-8*k3+k4)/30;
if(i==1)
ym1[i]=yp[i+1]+(k0+4*k3+k4)/6;
else
ym1[i]=yp[i-1]+(k0+4*k3+k4)/6;
}
for(i=1;i<=2;i++)
{
if (i==1)
yp[i+1]=ym1[i];
else
yp[i-1]=ym1[i];
}
h1=h/2;
for(l=1;l<=2;l++)
{
z+=h/2;
for(i=1;i<=2;i++)
{
k0=h*f(i,z,p[i],p[i-1]);
k1=h*f(i,z+h/3,p[i]+k0/3,p[i-1]+k0/3);
k2=h*f(i,z+h/3,p[i]+k0/6+k1/6,p[i-1]+k0/6+k1/6);
k3=h*f(i,z+h/2,p[i]+k0/8+3*k2/8,p[i-1]+k0/8+3*k2/8);
k4=h*f(i,z+h,p[i]+k0/2-3*k2/2+2*k3,p[i-1]+k0/2-3*k2/2+2*k3); Rm=(-2*k0+9*k2-8*k3+k4)/30;
if(i==1)
ym2[i]=p[i+1]+(k0+4*k3+k4)/6;
else
ym2[i]=p[i-1]+(k0+4*k3+k4)/6;
}
for (i=1;i<=2;i++)
{
if(i==1)
p[i+1]=ym2[i];
else
p[i-1]=ym2[i];
}
}
if (fabs(ym2[1]-ym1[1])<e)
{
printf("x=%2.5f ",x);
for(i=1;i<=2;i++)
printf("y%i=%2.5f ",i,ym1[i]);
for (i=1;i<=2;i++)
printf("poxubka=%2.5f",fabs(ym2[i]-ym1[i]));
putchar('\n');
h=h*5;
}
if (fabs(ym2[1]-ym1[1])>e)
{
x=x-h;
h=h/2;
yp[1]=z1;
yp[2]=z2;
p[1]=z3;
p[2]=z4;
}}}
Результат виконання програми:
Висновок:
Розв’язання систем лінійних диференціальних рівнянь методом Ейлера, Рунге – Кута або методами із змінним кроком інтегрування можна досить легко реалізувати на ЕОМ за допомогою програми в середовищі Сі. Основна перевага використання методу із змінним кроком інтегрування полягає в існуванні можливості розв’язування систем диференціальних рівнянь із заданою похибкою. Розв’язання таких систем на ЕОМ є дуже актуальним, оскільки цей процес є набагато легшим та короткотривалішим ніж розв’язання систем лінійних диференціальних рівнянь вручну.