Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Архив1 / docx57 / Лабораторная работа6

.docx
Скачиваний:
20
Добавлен:
01.08.2013
Размер:
44.09 Кб
Скачать

Лабораторная работа №6

Численные методы решения задачи Коши

Студента группы ПВ-22

Воробьева Романа Викторовика

Вариант № 3

1.Найти точное решение задачи Коши

Задача Коши:

Точное решение:

i

0

1.570796

0

1

1.770796

0.196

2

1.970796

0.3684

3

2.170796

0.4952

4

2.370796

0.5574

5

2.570796

0.5403

2. Вычислить «вручную» y(x+0.2) четырьмя методами : Эйлера, Эйлера-Коши, модифицированного Эйлера, Рунге-Кутты сначала с шагом h=0.2 , а затем с шагом h=0.1. Сравнить y(x+0.2) со значением y(x+0.2) точного решения.

4. Описать в модуле функции, каждая из которых возвращает приближенное значение с точностью Ɛ задачи Коши в точке x с оценкой точности по принципу Рунге, реализующие методы Эйлера, Эйлера-Коши, модифицированного Эйлера, Рунге-Кутты.

Описание структур данных

Подпрограммы для вычисления приближенных значений задачи Коши позволяют находить приближенные значения для разного количества точек n. Поэтому для передачи массивов e, et, em, ek, rk будем использовать указатели на них. Структура данных на языке С:

typedef float* mas;

Модуль реализующий методы Эйлера, Эйлера-Коши, модифицированного Эйлера, Рунге-Кутты:

#include "stdafx.h"

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

typedef float* mas;

#pragma once

/*

Спецификация подпрограмм:

  1. Заголовок: void “function”( float (*f)(float x, float y), float a, float h, float e, float y0, mas y, unsigned k )

  2. Назначение: Находит приближенные решения задачи Коши (*f)(float x,float y) с точностью e, для k точек с шагом h, начиная с =a и . Решения записываются в массив по адресу y.

  3. Входные параметры: (*f)(), a, h, e, y0,k.

  4. Выходные параметры: y.

*/

void Euler(float (*f)(float x,float y),float a,float h,float e,float y0, mas y,unsigned k)

{

float x,e1,h1,y1,y2,x1;

int i;

y[0]=y0;

e1=e;

x=a;

h1=h;

for (i=1;i<=k;i++)

{

y1=y[i-1]+h*(*f)(x,y[i-1]);

y2=y1;

do

{

y1=y2;

h1/=2;

x1=x+h1;

y2=y[i-1]+h*(*f)(x1,y[i-1]);

}

while (fabs(y1-y2)>e1);

x=x+h;

y[i]=y1;

}

}

void Euler_Cauchy(float (*f)(float x,float y),float a,float h,float e,float y0, mas y,unsigned k)

{

float x,x1,f1,f2,h1,e1,y1,y2;

int i;

x=a;

e1=e*3;

y[0]=y0;

h1=h;

for (i=1; i<=k; i++)

{

y1=y[i-1]+h/2*((*f)(x,y[i-1])+(*f)(x+h,y[i-1]+h*(*f)(x,y[i-1])));

y2=y1;

do

{

y1=y2;

h1/=2;

x1=x+h1;

y2=y[i-1]+h/2*((*f)(x1,y[i-1])+(*f)(x1+h,y[i-1]+h*(*f)(x1,y[i-1])));

}

while (fabs(y2-y1)>e1);

x=x+h;

y[i]=y2;

}

}

void Euler_modif(float (*f)(float x,float y),float a,float h,float e,float y0, mas y,unsigned k)

{

float x,x1,f1,f2,h1,e1,y1,y2;

int i;

x=a;

e1=e*3;

h1=h;

y[0]=y0;

for (i=1; i<=k; i++)

{

y1=y[i-1]+h*(*f)(x+h/2,y[i-1]+h/2*(*f)(x,y[i-1]));

y2=y1;

do

{

y1=y2;

h1/=2;

x1=x+h1;

y2=y[i-1]+h*(*f)(x1+h/2,y[i-1]+h/2*(*f)(x1,y[i-1]));

}

while (abs(y2-y1)>e1);

x=x+h;

y[i]=y2;

}

}

void Runge_Kutta(float (*f)(float x,float y),float a,float h,float e,float y0, mas y,unsigned k)

{

float x,x1,y1,y2,h1,e1,m1,m2,m3,m4;

int i;

x=a;

e1=e*15;

h1=h;

y[0]=y0;

for (i=1; i<=k; i++)

{

m1=h*((*f)(x,y[i-1]));

m2=h*(*f)(x+h/2,y[i-1]+m1/2);

m3=h*(*f)(x+h/2,y[i-1]+m2/2);

m4=h*(*f)(x+h,y[i-1]+m3);

y1=y[i-1]+(m1+2*m2+2*m3+m4)/6;

y2=y1;

do

{

y1=y2;

h1/=2;

x1=x+h1;

m1=h*(*f)(x1,y[i-1]);

m2=h*(*f)(x1+h/2,y[i-1]+m1/2);

m3=h*(*f)(x1+h/2,y[i-1]+m2/2);

m4=h*(*f)(x1+h,y[i-1]+m3);

y2=y[i-1]+(m1+2*m2+2*m3+m4)/6;

}

while (fabs(y2-y1)>e1);

x=x+h;

y[i]=y2;

}

}

using namespace System;

namespace Ch_met_resh_z_Koshi {

public ref class Class1

{// TODO: здесь следует добавить свои методы для этого класса.};

}

5.Составить программу для вычисления точного и приближенных значений решения задачи Коши с точностью Ɛ на промежутке [a,b] с шагом с использованием всех функций, описанных в модуле.

#include "stdafx.h"

#include <iostream>

#include "Ch_met_resh_z_Koshi.h"

using namespace System;

using namespace std;

const float pi=1.570796;

float task_Koshi(float x, float y)

{

return sin(x)+y/tan(x);

}

void exact_decision(float x, mas y,unsigned n,float h)

{

for(int i=0;i<=n;i++)

{

y[i]=(x-pi)*sin(x);

x=x+h;

}

}

int main(array<System::String ^> ^args)

{

float a, b, E, y0, x0, h;

int n;

mas e,et, em, ek, rk;

printf("input a: ");

scanf("%f", &a);

printf("input b: ");

scanf("%f", &b);

printf("input n: ");

scanf("%i", &n);

h=(b-a)/n;

e=GetMem(n);

et=GetMem(n);

em=GetMem(n);

ek=GetMem(n);

rk=GetMem(n);

printf("input x0: ");

scanf("%f", &x0);

printf("input y0: ");

scanf("%f", &y0);

printf("input E: ");

scanf("%f", &E);

exact_decision(a,et,n,h);

Euler(task_Koshi,a,h,E,y0,e,n);

Euler_Cauchy(task_Koshi,a,h,E,y0,ek,n);

Euler_modif(task_Koshi,a,h,E,y0,em,n);

Runge_Kutta(task_Koshi,a,h,E,y0,rk,n);

printf("\n%3s %6s %7s %8s %7s %8s %8s\n","i","x","yt","ye","yek","ym","rk");

for (int i=0; i<=n; i++)

printf("%3i %7.2f %8.4f %8.4f %7.4f %8.4f %8.4f \n",i,x0+i*h,et[i],e[i],ek[i],em[i],rk[i]);

FreeMem(e);

FreeMem(et);

FreeMem(em);

FreeMem(ek);

FreeMem(rk);

system("pause");

return 0;

}

6.Результат работы в виде таблицы: