16219

РЕШЕНИЕ ДИФФЕРЕНЦИАЛЬНЫХ УРАВНЕНИЙ ПЕРВОГО ПОРЯДКА

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

Информатика, кибернетика и программирование

Лабораторная работа №7 Решение дифференциальных уравнений первого порядка Цель лабораторной работы: Изучить принципы создания класса для решения дифференциальных уравнений первого порядка. Постановка задачи: Разработать класс решения дифференциальных уравнен...

Русский

2013-06-20

80 KB

5 чел.

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

Решение дифференциальных уравнений первого порядка

Цель лабораторной работы: Изучить принципы создания класса для решения дифференциальных уравнений первого порядка.

Постановка задачи:

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

Краткие теоретические сведения:

Дифференциальным уравнением первого порядка называется уравнение вида F(x,y,у')=0 или у'=f(x,y). Функция y(x), при подстановке которой уравнение обращается в тождество, называется решением дифференциального уравнения.

Рассмотрим несколько численных методов решения дифференциальных уравнений первого порядка. Описание численных методов приводится для уравнения в виде у'=f(x,y).

  1.  Метод Эйлера.

Рассмотрим два варианта вывода расчетных формул

y1=y0+h*f(x0,y0)

x1=x0+h

Расчетные формулы для 1-го шага

yi+1=yi+h*f(xi,yi)

xi+1=xi*h

Расчетные формулы для i-го шага


  1.  Модифицированный метод Эйлера (вариант 2).

уi+1i+(h/2)[f(xi,yi)+f(xi,+h,yi+hf(xi,yi))],

xi+1=xi+h.

  1.  Метод Рунге-Кутта четвертого порядка.

уi+1=уi+(k1+2k2+2k3+k4)/6,

k1=hf(xi,yi),

k2=hf(xi+h/2, yi+k1/2),

k3=hf(xi+h/2, yi+k2/2),

k4=hf(xi+h, yi+k3),

xi+1=xi+h,

где уi+1i - значения искомой функции в точках xi+1, xi соответственно, индекс i показывает номер шага интегрирования, h - шаг интегрирования. Начальные условия при численном интегрировании учитываются на нулевом шаге: i=0, x=x0, y=y0.

Текст программы:

// основная программа

unit UMainForm;

interface

uses

 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

 Dialogs, StdCtrls, ExtCtrls, ComCtrls, TeeProcs, TeEngine, Chart, Series,

 Buttons, BubbleCh, Grids, DiffEquation;

type

 TForm1 = class(TForm)

   EditMin: TEdit;

   EditMax: TEdit;

   Label1: TLabel;

   Label2: TLabel;

   Label3: TLabel;

   Panel1: TPanel;

   Label4: TLabel;

   Bevel1: TBevel;

   DisplayChart: TChart;

   Series1: TLineSeries;

   SpeedButton1: TSpeedButton;

   Panel4: TPanel;

   RadioGroupEquation: TRadioGroup;

   Table: TStringGrid;

   Label5: TLabel;

   Panel2: TPanel;

   EditH: TEdit;

   Label6: TLabel;

   Panel3: TPanel;

   GroupBox1: TGroupBox;

   CheckBox1: TCheckBox;

   CheckBox2: TCheckBox;

   CheckBox3: TCheckBox;

   Series2: TLineSeries;

   Series3: TLineSeries;

   procedure SpeedButton1Click(Sender: TObject);

   procedure RadioGroupEquationClick(Sender: TObject);

   procedure GroupBox1Click(Sender: TObject);

   procedure CheckBoxesClick(Sender: TObject);

   procedure FormCreate(Sender: TObject);

 private

   { Private declarations }

 public

   { Public declarations }

 end;

var

 Form1: TForm1;

 Diff:TDifferentia;

implementation

{$R *.dfm}

procedure TForm1.SpeedButton1Click(Sender: TObject);

var

 Method:TMethod;

begin

if Assigned(Diff) then

 diff.Free;

if CheckBox1.Checked=true then Method[0]:=1 else Method[0]:=0;

if CheckBox2.Checked=true then Method[1]:=1 else Method[1]:=0;

if CheckBox3.Checked=true then Method[2]:=1 else Method[2]:=0;

case (RadioGroupEquation.ItemIndex) of

 0:Diff:=TDifferentia.Create(StrToFloat(EditMin.Text),StrToFloat(EditMax.Text),Method,StrToFloat(EditH.Text),DisplayChart,Table);

 1:Diff:=TDifferentia1.Create(StrToFloat(EditMin.Text),StrToFloat(EditMax.Text),Method,StrToFloat(EditH.Text),DisplayChart,Table);

 2:Diff:=TDifferentia2.Create(StrToFloat(EditMin.Text),StrToFloat(EditMax.Text),Method,StrToFloat(EditH.Text),DisplayChart,Table);

end;

end;

procedure TForm1.RadioGroupEquationClick(Sender: TObject);

begin

//  ShowMessage('Для вычисления значений нажмите кнопку "РАССЧИТАТЬ"');

end;

procedure TForm1.GroupBox1Click(Sender: TObject);

begin

 ShowMessage('Для вычисления значений нажмите кнопку "РАССЧИТАТЬ"');

end;

procedure TForm1.CheckBoxesClick(Sender: TObject);

begin

 Diff.Method[(Sender as TCheckBox).Tag]:=ord((Sender as TCheckBox).Checked);

end;

procedure TForm1.FormCreate(Sender: TObject);

begin

 SpeedButton1.Click;

end;

end.

unit DiffEquation;

interface

Uses Chart, Grids, Classes, SysUtils;

Type

 TArrayList = array [0..2] of TList;

 TPoint = Record

     x:Extended;

     y:Extended;

   end;

 PPoint=^TPoint;

 TMethod=array [0..2] of byte;

 TDifferentia = class

   private

     FMin:Extended;  // мин. граница промежутка

     FMax:Extended;  // макс. граница промежутка

     FH:Extended;    // шаг вычисления

     FN:Integer;     // количество итераций

     FMethod:TMethod;    // метод вычисления

     FChart:TChart;  // область отображения

     FTable:TStringGrid;  // таблица для значений

     PD:PPoint;

     FResult:TArrayList;

     procedure DrawF(AResult:TList;series:Byte);

     procedure FillTable(AResult:TList; ARow:Byte);

{     procedure SetMin(newMin:Extended);

     procedure SetMax(newMax:Extended);

     procedure SetMethod(newMetod:Byte);}

   public

     constructor Create(AMin,AMax:Extended; AMethod:TMethod; AH:Extended; AChart:TChart; ATable:TStringGrid); overload;

     function F(x0,y0:Extended):Extended;  virtual;

     property Min:Extended read FMin write FMin;

     property Max:Extended read FMax write FMax;

//     property Method:Byte read FMethod write FMethod;

     property Chart:TChart read FChart write FChart;

     property Table:TStringGrid read FTable write FTable;

     procedure Calculate;

     procedure Calc_Ejler;

     procedure Calc_Modify_Ejler;

     procedure Calc_Runge_Kutta;

     function GetMethod(ind: integer): byte;

     procedure SetMethod(ind: integer;ANew: byte);

     procedure OutPut;

     property Method[ind: integer]: byte read GetMethod write SetMethod;

  end;

 TDifferentia1 = class (TDifferentia)

   public

     function F(x0,y0:Extended):Extended;     override;

 end;

 TDifferentia2 = class (TDifferentia)

   public

     function F(x0,y0:Extended):Extended;     override;

 end;

implementation

function TDifferentia.GetMethod(ind:  integer): byte;

begin

 Result:=FMethod[ind];

end;

procedure TDifferentia.SetMethod(ind: integer;ANew: byte);

begin

 FMethod[ind]:=ANew;

 Self.OutPut;

end;

function TDifferentia1.F(x0,y0:Extended):Extended;

begin

 Result:=(1-2*x0)/(y0*y0);

 Result:=FH*Result;

end;

function TDifferentia2.F(x0,y0:Extended):Extended;

begin

 Result:=sin(x0)-y0;

 Result:=FH*Result;

end;

constructor TDifferentia.Create(AMin,AMax:Extended; AMethod:TMethod; AH:Extended; AChart:TChart; ATable:TStringGrid);

begin

 FMin:=AMin;

 FMax:=AMax;

 FH:=AH;

 FN:=round((FMax-FMin)/FH)+1;

 FMethod:=AMethod;

 FChart:=AChart;

 FTable:=ATable;

 Calculate;

 OutPut;

end;

function TDifferentia.F(x0,y0:Extended):Extended;

begin

 Result:=3*x0-2*y0+5;

 Result:=FH*Result;

end;

procedure TDifferentia.Calculate;

begin

 Calc_Ejler;

 Calc_Modify_Ejler;

 Calc_Runge_Kutta;

end;

procedure TDifferentia.Calc_Ejler;

var

 i:Integer;

 x:Extended;

 y0,y:Extended; // y0 предыдущее значение

begin

 FResult[0]:=TList.Create;

 x:=FMin;

 y0:=1;

 for i:=1 to FN do

  begin

    new(PD);

    y:=y0+F(x-FH,y0);

    y0:=y;

    PD^.x:=x;

    PD^.y:=y;

    x:=x+FH;

    FResult[0].Add(PD);

  end;

end;

procedure TDifferentia.Calc_Modify_Ejler;

var

 i:integer;

 x:Extended;

 y0,y:Extended;

begin

 FResult[1]:=TList.Create;

 x:=FMin;

 y0:=1;

 for i:=1 to FN do

   begin

     new(PD);

     y:=y0+f((x+FH/2),(y0+f(x,y0)/2));

     y0:=y;

     PD^.x:=x;

     PD^.y:=y;

     x:=x+FH;

     FResult[1].Add(PD);

   end;

end;

procedure TDifferentia.Calc_Runge_Kutta;

var

  k1,k2,k3,k4:Extended;

  y0,y:Extended;

  x:Extended;

  i:integer;

begin

 FResult[2]:=TList.Create;

 x:=FMin;

 y0:=1;

 for i:=1 to FN do

   begin

     new(PD);

     k1:=f(x,y0);

     k2:=f(x+FH/2, y0+k1/2);

     k3:=f(x+FH/2, y0+k2/2);

     k4:=f(x+FH, y0+k3);

     y:=y0+(k1+2*k2+2*k3+k4)/6;

     y0:=y;

     PD^.x:=x;

     PD^.y:=y;

     x:=x+FH;

     FResult[2].Add(PD);

   end;

end;

procedure TDifferentia.DrawF(AResult:TList;series:Byte);

var

 i:integer;

begin

FChart.Series[series].Clear;

     for  i:=0 to AResult.Count-1 do

     begin

       new(PD);

       PD:=AResult[i];

       FChart.Series[series].AddXY(PD^.x, PD^.y);

     end;

end;

procedure TDifferentia.OutPut;

var

 i:integer;

 x:Extended;

begin

FTable.Rows[0].Clear;

FTable.Rows[1].Clear;

FTable.Rows[2].Clear;

FTable.Rows[3].Clear;

FChart.Series[0].Clear;

FChart.Series[1].Clear;

FChart.Series[2].Clear;

if ((FMethod[0]=1)or(FMethod[1]=1)or(FMethod[2]=1)) then

  if (Assigned(FChart))and(Assigned(FTable)) then

   begin

     FTable.Cells[0,0]:='   X ';

     FTable.ColCount:=2;

     x:=FMin;

     for i:=1 to FN do

          begin

            FTable.ColCount:=FTable.ColCount+1;

            FTable.Cells[i,0]:=FloatToStr(x);

            x:=x+FH;

          end;

     FTable.ColCount:=Table.ColCount-1;

     if FMethod[0]=1 then

         begin

           FTable.Cells[0,1]:='   Y1 ';

           DrawF(FResult[0],0);

           FillTable(FResult[0],1);

         end;

     if FMethod[1]=1 then

         begin

           FTable.Cells[0,2]:='   Y2 ';

           DrawF(FResult[1],1);

           FillTable(FResult[1],2);

         end;

     if FMethod[2]=1 then

          begin

           FTable.Cells[0,3]:='   Y3';

           DrawF(FResult[2],2);

           FillTable(FResult[2],3);

          end;

   end;

end;

procedure TDifferentia.FillTable(AResult:TList; ARow:Byte);

var

i:integer;

begin

for  i:=0 to AResult.Count-1 do      // y - столбцы

     begin

       new(PD);

       PD:=AResult.Items[i];

       FTable.Cells[i+1,ARow]:=FloatToStr(PD^.y);

       //Dispose(PD);

     end;

end;

end.


Результаты работы программы:

Вывод: В результате выполнения данной лабораторной работы были изучить принципы создания класса для решения дифференциальных уравнений первого порядка.

Был разработан класс, который позволяет вычислять дифференциальные уравнения первого порядка четырьмя различными методами:  Эйлера, усовершенствованный метод Эйлера и методом Рунге-Кутта четвертого порядка. Программа отображает результаты работы в виде графика и таблицы.


 

А также другие работы, которые могут Вас заинтересовать

4246. Аудит як форма фінансового контролю та складова адміністративно-правової інфраструктури детінізації економічних відносин в Україні 1.15 MB
  Аудит як форма фінансового контролю та складова адміністративно-правової інфраструктури детінізації економічних відносин в Україні Актуальність теми дослідження. Трансформаційний стан економічних відносин в Україні характеризується рядом кільк...
4247. Функції. Багатовимірні масиви 30.63 KB
  Тема: Функції. Багатовимірні масиви. Мета: навчитись проводити обробку багатовимірних масивів та рядків мовою програмування С. Завдання Написати функцію, що повертає номер матриці тривимірного масиву, яка містить найбільший елемент. Програма...
4248. Функції. Багатовимірні масиви. Обробка двовимірних масивів 102.75 KB
  Функції. Багатовимірні масиви. Обробка двовимірних масивів. Мета: навчитись проводити обробку одновимірних масивів та рядків мовою програмування С. Завдання Дано матрицю 9х9. Зробити її дзеркальне відображення відносно головної діагоналі. Програма...
4249. Статичні одновимірні масиви. Оператори роботи з рядками. Обробка одновимірних масивів та рядків 414.18 KB
  Оператори роботи з рядками. Обробка одновимірних масивів та рядків. Мета: навчитись проводити обробку одновимірних масивів та рядків мовою програмування С. Завдання 1. Задано рядок. Перевірити чи він складається із підряд...
4250. Статичні одновимірні масиви. Оператори роботи з рядками. Обробка одновимірних масивів та рядків. Практична робота 141.61 KB
  Статичні одновимірні масиви. Оператори роботи з рядками. Обробка одновимірних масивів та рядків. Мета: навчитись проводити обробку одновимірних масивів та рядків мовою програмування С. Завдання 1. Задано цілочисельний масив розміру N. Назвемо серією...
4251. Оператори циклу. Програмування циклічних алгоритмів 130.19 KB
  Оператори циклу. Програмування циклічних алгоритмів. Мета: навчитись програмувати циклічні алгоритми з використанням операторів циклу з параметром, перед- та післяумовою мовою програмування С. Завдання 1. Скласти програму табулювання функції y=f(x) ...
4252. Учебно-методическое пособие по курсу экономико-математические методы и модели. Линейное программирование 1.17 MB
  В учебно-методическом пособии рассмотрены вопросы построения математических моделей основных типов задач линейного программирования и способы их решения средствами табличного редактора Microsoft Excel, приведены примеры решения или рекомендации к ре...
4253. Программирование для Microsoft Windows с использованием Visual C++ и библиотеки классов MFC 1.17 MB
  Введение Изучение программирования на Си++ для современных операционных систем семейства MSWindows сопряжено со сложностями, связанными с большим количеством технических подробностей устройства приложения и операционной системы, а также вопрос...
4254. Проект модернизации привода конвертера ОАО ЗСМК. ККЦ – 1 1.38 MB
  Введение Впервые возможность применения кислорода для производства стали рассматривали в своих работах в 1872 году Д.К. Чернов, а затем в 1899 году Д.И. Менделеев. В 1933 году советский инженер Н.И. Мозговой предложил применение чистого кислорода...