Автор работы: Пользователь скрыл имя, 01 Апреля 2012 в 19:49, лабораторная работа
Постановка задачи 3
Ручной счёт и алгоритмы 3
Метод Эйлера 3
Метод Рунге-Кутты 4-го порядка 4
Метод Рунге-Кутты 5-го порядка 5
Метод Адамса 6
Правило Рунге для оценки погрешности 6
Метод прогонки 7
Реализация на языках программирования 9
Реализация на С++ 9
Метод Эйлера 9
Метод Рунге-Кутты 4-го порядка 10
Метод Рунге-Кутты 5-го порядка 11
Метод Адамса 12
Метод прогонки 14
Реализация на Fortran 15
Метод Эйлера 15
Метод Рунге-Кутты 4-го порядка 16
Метод Рунге-Кутты 5-го порядка 17
Метод Адамса 18
Метод прогонки 20
Реализация на SciLab 21
Метод Эйлера 21
Метод Рунге-Кутты 4-го порядка 22
Метод Рунге-Кутты 5-го порядка 23
Метод Адамса 23
Метод прогонки 25
Реализация на Pascal 26
Метод Эйлера 26
Метод Рунге-Кутты 4-го порядка 27
Метод Рунге-Кутты 5-го порядка 28
Метод Адамса 29
Метод прогонки 30
Реализация на Basic 32
Метод Эйлера 32
Метод Рунге-Кутты 4-го порядка 33
Метод Рунге-Кутты 5-го порядка 34
Метод Адамса 35
Метод прогонки 36
Сводная таблица результатов 38
Постановка задачи
Ручной счёт и алгоритмы
Метод Эйлера
Метод Рунге-Кутты 4-го порядка
Метод Рунге-Кутты 5-го порядка
Метод Адамса
Правило Рунге для оценки погрешности
Метод прогонки
Реализация на языках программирования
Реализация на С++
Метод Эйлера
Метод Рунге-Кутты 4-го порядка
Метод Рунге-Кутты 5-го порядка
Метод Адамса
Метод прогонки
Реализация на Fortran
Метод Эйлера
Метод Рунге-Кутты 4-го порядка
Метод Рунге-Кутты 5-го порядка
Метод Адамса
Метод прогонки
Реализация на SciLab
Метод Эйлера
Метод Рунге-Кутты 4-го порядка
Метод Рунге-Кутты 5-го порядка
Метод Адамса
Метод прогонки
Реализация на Pascal
Метод Эйлера
Метод Рунге-Кутты 4-го порядка
Метод Рунге-Кутты 5-го порядка
Метод Адамса
Метод прогонки
Реализация на Basic
Метод Эйлера
Метод Рунге-Кутты 4-го порядка
Метод Рунге-Кутты 5-го порядка
Метод Адамса
Метод прогонки
Сводная таблица результатов
Вывод
Список используемой литературы
Таблица 4. Правило Рунге для оценки погрешности.
,
.
За оценку погрешности решения, вычисленного с шагом , принимаем величину 0.113.
Дано:
,
,
,
,
,
.
Найти численное решение дифференциального уравнения.
Решение:
Необходимые формулы:
, ,
,
,
,
,
,
,
,
,
,
.
Находим :
,
,
,
.
Исходя из полученных данных, можно найти и все остальное.
Результаты соответствующих итераций приведены в таблице 5:
№ итерации | x | y | m | n | c | d |
0 | 1 | 1.3 | -1.97844 | 0.978448 | -0.50544 | -1.26683 |
1 | 1.0625 | 1.25463 | -1.97889 | 0.977537 | -0.67349 | -0.62261 |
2 | 1.125 | 1.21529 | -1.97933 | 0.977895 | -0.75716 | -0.40669 |
3 | 1.1875 | 1.18186 | -1.97974 | 0.978241 | -0.80706 | -0.29787 |
4 | 1.25 | 1.15422 | -1.98015 | 0.978577 | -0.84007 | -0.23187 |
5 | 1.3125 | 1.13227 | -1.98055 | 0.978901 | -0.86341 | -0.18729 |
6 | 1.375 | 1.11595 | -1.98093 | 0.979214 | -0.88069 | -0.15491 |
7 | 1.4375 | 1.1052 | -1.9813 | 0.979517 | -0.98394 | -0.13015 |
8 | 1.5 | 1.1 | -1.98165 | 0.979809 | -0.90435 | -0.11045 |
Таблица 5. Метод прогонки.
Таблица идентификаторов
Идентификаторы | Тип | Значение |
function() | double | Функция для вычисления значения правой части ОДУ |
x0, xN | double | Соответственно, начало и конец промежутка, на котором ищется решение задачи Коши |
h | double | Шаг сетки |
y | double[] | Искомая функция |
dy | double | Приращение функции |
k1, k2, k3, k4,k5 | double | Коэффициенты |
y0 | double | Значение функции в точке x0 |
n | int | Количество разбиений промежутка, на котором требуется решить задачу Коши |
yh, yh2 | double[] | Соответственно, значения искомой функции, вычисленные с сеткой с шагом h и 2h |
funA | double | Коэффициент перед y’’ в краевой задаче |
funB | double | Коэффициент перед y’ в краевой задаче |
funC | double | Коэффициент перед y в краевой задаче |
funF | double | Коэффициент в правой части в краевой задаче |
a, b | double | Соответственно, начало и конец промежутка, на котором ищется решение краевой задачи |
c, d, m, n | double[] | Вспомогательные массивы в методе прогонки |
Файл eiler.cpp
#include<iostream>
#include<cmath>
#include<iomanip>
using namespace std;
double function(double x, double y){
return (1+y)/(1+pow(x,3)*y);
}
double x0, xN, h, y;
double dy = 0.0;
int main(){
cout << "Method eilera" << endl;
cout << "y'= exp(x*y)" << endl;
cout << "Vvedite x0: " ;
cin >> x0;
cout << "Vvedite xN: " ;
cin >> xN;
cout << "Vvedite shag: " ;
cin >> h;
cout << "Vvedite y(0): " ;
cin >> y;
cout << "Result:" << endl;
cout << setw(3) << "x" << setw(10) << "y"<< setw(10) << "dy" << endl;
while(x0 < xN+h){
dy=h*function(x0,y);
cout << setw(3) << x0 << setw(10) << y << setw(10) << dy << endl;
y+=dy;
x0+=h;
}
return 0;
}
Результат работы программы:
Файл RK4.cpp
#include<iostream>
#include<cmath>
using namespace std;
double function(double x, double y){
return exp(x*y);
}
int main()
{
double x0,xN,h,y,k1,k2,k3,k4;
cout << "Vvedite a: ";
cin >> x0;
cout << "Vvedite b: ";
cin >> xN;
cout << "Vvedite shag: ";
cin >> h;
cout << "Vvedite y(0): ";
cin >> y;
double x=x0;
cout << "x\ty" << endl;
while(x < xN+h)
{
cout << x << "\t" << y << endl;
k1 = h*function(x,y);
k2 = h*function(x + h/2, y + k1/2);
k3 = h*function(x + h/2, y + k2/2);
k4 = h*function(x + h, y + k3);
y+=(k1+2*k2+2*k3+k4)/6;
x+=h;
}
return 0;
}
Результат работы программы:
Файл RK5.cpp
#include<iostream>
#include<cmath>
using namespace std;
double function(double x,double y)
{return exp(x*y);}
int main()
{
double x0,xN,h,y,k1,k2,k3,k4,k5;
cout << "Vvedite x0: ";
cin >> x0;
cout << "Vvedite xN: ";
cin >> xN;
cout << "Vvedite shag: ";
cin >> h;
cout << "Vvedite y(0): ";
cin >> y;
double x=x0;
cout << "x\ty"<< endl;
while(x < xN+h)
{
cout << x << "\t" << y << endl;
k1 = h*function(x,y)/3;
k2 = h*function(x + h/3, y + k1)/3;
k3 = h*function(x + h/3, y + k1/2 + k2/2)/3;
k4 = h*function(x + h/2, y + 3*k1/8 + 9*k3/8)/3;
k5 = h*function(x + h, y + 3*k1/2 - 9*k3/2 + 6*k4)/3;
y+=(k1 + 4*k4 + k5)/2;
x+=h;
}
return 0;
}
Результат работы программы:
Файл adams.cpp
#include<iostream>
#include<cmath>
using namespace std;
double function(double x,double y)
{return exp(x*y);}
int main()
{
double x0, xN, h, k1, k2, k3, k4, k5, y, y0, x;
cout << "Vvedite x0: "; cin >> x0;
cout << "Vvedite xN: "; cin >> xN;
cout << "Vvedite shag: "; cin >> h;
cout << "Vvedite y(" << x0 << "): "; cin >> y0;
int n = ceil(fabs(xN-x0)/h);
double *yh = new double[n];
double *yh2 = new double[2*n];
y = y0; x = x0;
for(int i = 0; x <= xN; i++){
yh[i] = y;
k1 = h*function(x,y);
k2 = h*function(x + h/2, y + k1/2);
k3 = h*function(x + h/2, y + k2/2);
k4 = h*function(x + h, y + k3);
y += (k1+2*k2+2*k3+k4)/6;
x += h;
}
int i = 4;
x = x0 + i*h;
while(x <= xN){
yh[i] = yh[i-1] + h*(55*function(x,yh[i-1]) - 59*function(x-h,yh[i-2]) + 37*function(x-2*h,yh[i-3])-9*
x = x+h;
i++;
}
cout << "Result: " << endl;
cout << "y(" << xN << ") = " << yh[n] << endl;
y = y0; x = x0; h = h/2;
for(int i = 0; x <= xN; i++){
yh2[i] = y;
k1 = h*function(x,y);
k2 = h*function(x + h/2, y + k1/2);
k3 = h*function(x + h/2, y + k2/2);
k4 = h*function(x + h, y + k3);
y += (k1+2*k2+2*k3+k4)/6;
x += h;
}
i = 8;
x = x0 + i*h;
while(x <= xN){
yh2[i] = yh2[i-1] + h*(55*function(x,yh2[i-1])-59*
x = x+h;
i++;
}
cout << "eps = " << (yh[n] - yh2[2*n])/(pow(2, 4)-1) << endl;
return 0;
}
Результат работы программы:
где eps – погрешность вычисленного решения.
Файл progon.cpp
#include <iostream>
#include <cmath>
using namespace std;
const double pi = 3.1416;
double funA(double x)
{
return 0.4+2*x+x*x/2;
}
double funB(double x)
{
return pow(x,0.7);
double funC(double x)
{
return -0.95*x*x;
}
double funF(double x)
{
return (pow(x,0.5) + cos(2*x/pi))/funA(x);
}
int main()
{
double a, b, x, h;
int N;
cout << "Vvedite a = "; cin >> a;
cout << "Vvedite b = "; cin >> b;
if (a>=b){ cout << "bad interval" << endl; return -1; }
cout << "Vvedite N = "; cin >> N;
double y[N+1] ,c[N+1], d[N+1], m[N+1], n[N+1];
cout << "Vvedite y(" << a << ") = "; cin >> y[0];
cout << "Vvedite y(" << b << ") = "; cin >> y[N];
h = (b-a)/N;
m[0]=-2+funB(a)*h/funA(a);
n[0]=1-funB(a)*h/funA(a)+funC(
c[0]=1/m[0];
d[0]=-n[0]*y[0]+funF(a)*h*h;
for (int i=1;i<N+1;i++)
{
x=a+i*h;
m[i]=-2+funB(x)*h/funA(x);
n[i]=1-funB(x)*h/funA(x)+funC(
c[i]=1/(m[i]-n[i]*c[i-1]);
d[i]=funF(x)*h*h-n[i]*c[i-1]*
}
for (int i=N;i>1; i--)
{
y[i-1]=c[i-2]*(d[i-2]-y[i]);
}
cout << "x\ty" << endl;
for (int i=0;i<N+1;i++)
{
cout << a+i*h << '\t' <<y[i] << endl;
}
return 0;
}
Результат работы программы:
Файл eiler.f
1 | 2-5 | 6 | 9 72 |
|
|
| program eiler f(x,z)=exp(x*z) real::xk,xN,h,y1,yk,yk12 print *,'Method eilera' print *,'y''=exp(x*y)' print *,'Vvedite x0: ' read *,x0 print *,'Vvedite xN: ' read *,xN print *,'Vvedite shag: ' read *,h print *,'Vvedite y(0): ' read *,y print *,'x ydy' do while(x0<=xN) dy=h*f(x0,y) print *,x0,y,dy y=y+dy x0=x0+h end do end program eiler |
Результат работы программы:
Файл RK4.f
1 | 2-5 | 6 | 9 72 |
|
|
| program RK4 f(x,y)= exp(x*y) real:: x0, xN, h, k1, k2, k3, k4, y print *,'Vvedite x0: ' read *, x0 print *,'Vvedite xN' read *, xN print *,'Vvedite shag: ' read *, h print *,'Vvedite y(0): ' read *, y x = x0 write(*,*) 'x y' do while(x<=xN) write(*,'(f3.1,4x,f8.6)') x ,y k1 = h*f(x,y) k2 = h*f(x + h/2.0, y + k1/2.0) k3 = h*f(x + h/2.0, y + k2/2.0) k4 = h*f(x + h, y + k3) y = y+(k1+2.0*k2+2.0*k3+k4)/6.0 x = x+h end do end program RK4 |
Результат работы программы:
Файл RK5.f
1 | 2-5 | 6 | 9 |
|
|
| program RK5 f(x,y) = exp(x*y) real::x0, xN, h, y, x, k1, k2, k3, k4, k5 print *,'Vvedite x0: ' read *, x0 print *,'Vvedite xN: ' read *, xN print *,'Vvedite shag: ' read *, h print *,'Vvedite y(x0): ' read *, y x=x0 write(*,*) 'x y' do while(x<=xN) write(*,'(f3.1,4x,f8.6)') x, y k1 = h*f(x,y)/3.0 k2 = h*f(x + h/3.0, y + k1)/3.0 k3 = h*f(x + h/3.0, y + k1/2.0 + k2/2.0)/3.0 k4 = h*f(x + h/2.0, y + 3.0*k1/8.0 + 9.0*k3/8)/3.0 k5 = h*f(x + h, y + 3.0*k1/2 - 9.0*k3/2.0 + 6.0*k4)/3.0 y = y+(k1 + 4.0*k4 + k5)/2.0 x = x+h end do end program RK5 |
Информация о работе Методы решения обыкновенных дифференциальных уравнений