![]() |
|
|
Курсовая работа: Программа для решения дифференциальных уравнений первого порядка методом Рунге-Кутта2.2 Основные задачи Программа обеспечивает решение следующих задач: − ввод исходных данных; − решение ОДУ и вывод результата решения в численном и аналитическом виде; − обнуление результатов решения ОДУ; − контроль корректности ввода исходных данных и вывод на экран сообщение о содержании ошибки с рекомендацией по её устранению; − контроль возникновения в процессе вычислений ошибки «деление на ‘0’» и вывод на экран соответствующего сообщения о содержании ошибки с рекомендацией по её устранению. 2.3 Входные и выходные данные Входными данными для программы являются: − начальное условие решения ОДУ − у'(х0) = у0., − начальное и конечное значения отрезка, в пределах которого находится решение ОДУ; −величина шага дифференцирования, −формула образцовой функции. Выходными данными программы являются: − массив (х1 ,у1 ; х2 ,у2;…; хi ,уi) − решений выбранного дифференциального уравнения на заданном интервале; − график функции, которая, будучи подставленной, в исходное образцовое уравнение, обращает его в тождество и одновременно удовлетворяет начальному условию. 3. ПРОЕКТИРОВАНИЕ 3.1 Выделение основных объектов ПО − Объект класса TRKutta (Form1) – главная окно программы. − Объект класса TRngeKutta (Form2) – окно вывода графика функции-решения ДУ. − Объект класса TSpravka (Form3) – окно «О программе». − Объект класса TRungeKutta – координатная плоскость и график функции; 3.2 Описание полей и методов Класс TRKutta (родительский класс TForm) Поля класса: x1 - значение x1(начало отрезка); x2 - значение x2(конец отрезка); yc - начальные значения (Y0) для передачи в графический модуль; xc - начальные значения (х0)для передачи в графический модуль; y - значение Y(x1); h – зачение величины шага вычислений; f - значение функции при начальных условиях zx - массив значений аргумента; zy - массив значений функции; line_arr - размерность массивa; Методы класса: procedure Button1Click – вычисление значений функции – решения ОДУ; procedure Button2Click – очистка полей ввода/вывода данных; procedure Button3Click - вывод окна ГРАФИК; procedure Button4Click - выход из программы; procedure RadioGroup1Click - выбор образцовой функции; procedure Button5Click - активация ввода образцовых функций; procedure Button6Click - деактивация ввода образцовых функций; procedure N7Click - вывод информации о программе; Класс TRungeKutta (родительский класс TObject) Поля класса x0,y0 - координаты начала координатных осей; dx,dy - шаг координатной сетки (в пикселях) y1,y2,xP,xL - засечки по оси Y и X dlx,dly - шаг меток (оцифровки) линий сетки по X и Y cross - счетчик неоцифрованных линий сетки dcross - количество неоцифрованных линий между оцифрованными razm – размер массивов; uzx - Динамический массив координат-X uzy - Динамический массив координат-Y uxc,uyc - Оцифровка по осям mx, my - масштабы по осям X и Y; BaseMasht_X,BaseMasht_Y - МАХ значения элементов в массивах Методы класса function MaxAbsElementArray – определяет MAX элемент массива по модулю; procedure UstanovkaParametrov – вычисляет исходные параметры необходимые для построения декартовой плоскости; procedure KoordPloskost – вычерчивает координатную плоскость; Конструктор constructor TRungeKutta.CreateGr - создание объекта (график функции, координатная сетка, координатные оси) Класс Form2 (родительский класс TForm) Поле класса (private) RungeKutta - переменная-объект класса TRungeKutta ; Методы класса procedure N4Click - вывод графика функции в окне 'График'; procedure N5Click - закрытие окна 'График'; Класс Form3 (родительский класс TForm) Метод класса procedure Button1Click – процедура вывода информации о программе 3.3 Иерархия классов на основе выделенных объектов 4. ОСНОВНЫЕ ФОРМЫ И КОМПОНЕНТЫ, ИСПОЛЬЗУЕМЫЕ ДЛЯ РЕАЛИЗАЦИИ ПРОГРАММЫ. ОСНОВНЫЕ АЛГОРИТМИЧЕСКИЕ РЕШЕНИЯ РЕЗУЛЬТАТЫ РАБОТЫ ПРОГРАММЫ
РУКОВОДСТВО Теоретический материал 1. Решение дифференциальных уравнений Пусть дано дифференциальное уравнение первого порядка: у' = f(x) и начальное условие его решения: у'(х0) = у0.. Тогда решить уравнение — это значит найти такую функцию у — φ(х), которая, будучи подставленной, в исходное уравнение, обратит его в тождество и одновременно будет удовлетворено начальное условие. Задача отыскания функции у = φ (х) называется в математике задачей Коши. При решении дифференциального уравнения порядка n задача Коши формулируется следующим образом. Дано дифференциальное уравнение порядка n: у(n) = f(x, y, у'’,…,yn-1) Необходимо найти такую функцию у = φ (х), которая, будучи подставленной в исходное уравнение, обратит его в тождество и одновременно будут удовлетворены следующие п начальных условий: у(х0) = у0 у'(х0) = у'0 . . . уn-1(х0) = уn-10 4.1 Метод Рунге-Кутта Метод Рунге-Кутта обладает более высокой точностью, чем методы Эйлера за счет снижения методических ошибок. Идея метода состоит в следующем. По методу Эйлера решение дифференциального уравнения первого порядка определяется из соотношения: yi+1 = yi + Δyi; где Δyi = hf (хi, yi) = hу' (хi, yi). Тогда приращение Δyi, может быть найдено путем интегрирования: Или окончательно Вычислим теперь интеграл по методу прямоугольников: yi+1 = yi + (xi+1 - xi)f(xi, yi) = yi + hf(xi, yi). Из полученного выражения видно, что вычисление интеграла по методу прямоугольников приводит к формуле Эйлера. Вычислим интеграл по формуле трапеций: yi+1 = yi +0,5h(f(xi, yi)+ f(xi+1, yi+1)) Из выражения видно, что оно совпадает с расчетной формулой усовершенствованного метода Эйлера-Коши. Для получения более точного решения дифференциального уравнения следует воспользоваться более точными методами вычисления интеграла. В методе Рунге-Кутта искомый интеграл представляется в виде следующей конечной суммы: где Pi — некоторые числа, зависящие от q ; Ki(h) — функции, зависящие от вида подынтегральной функции f(x,y) и шага интегрирования h, вычисляемые по следующим формулам: K1(h) = hf(x, y); K2(h) = hf(x + a2h, y + β21K1(h)); K3(h) = hf(x + a3h, y + β 31K1(h) + β 32K2(h)); Kn(h) = hf(x + aqh, , y + β q1K1(h) + ... + β q,q-1Kq-1(h)). Значения p, α, β получают из соображений высокой точности вычислений. Формулы Рунге-Кутта третьего порядка (q= 3) имеют следующий вид: K1=hf(xi, yi); K2=hf(xi + 0,5h, yi+0,5 K1); K3=hf(xi+h, yi+K1+2K2). Наиболее часто используется метод Рунге-Кутта четвертого порядка, для которого расчетные формулы имеют следующий вид: K1=hf(xi, yi); K2=hf(xi + 0,5h, yi+0,5 K1); K3=hf(xi+0,5h, yi+0,5K2). K3=hf(xi+h, yi+K3). Формулы Рунге-Кутта имеют погрешности порядка h q+1 . Погрешность метода Рунге-Кутта четвертого порядка имеет порядок h5 4.2 Описание программы ” РЕШЕНИЕ ОДУ “ Программа ”Решение ОДУ“ достаточно проста в использовании. При запуске программы открывается главное окно программы (рис. 4), с установленными по умолчанию начальными условиями в полях ввода. Назначение элементов ввода данных. 1. Поля X1, X2, Y(x1), H предназначены для ввода начального и конечного значений отрезка, на котором ищется решение дифференциального уравнения, значения функции при аргументе равном Х1 и величины шага дифференцирования; 2. В поле dY выводится формула дифференциального уравнения 1-й степени, выбранная для решения; 3. В поле dY(x1,y1) выводится значение производной в исходной точке. Рис.4 Назначение элементов управления и контроля. 1. При нажатии кнопки EXAMPLE активируются “радиокнопки” выбора уравнений; 2. Щелчком “радиокнопки” выбирается соответствующее ей уравнение, вид формулы контролируется по её отображению в поле dY ; 3. Щелчком по кнопке ВЫЧИСЛИТЬ находятся приближенные решения выбранного дифференциального уравнения на заданном интервале; 4. Решения дифференциального уравнения в виде пар значений X - Y выводятся в поля X и Y; (рис. 5.) По окончании вычислений активируются кнопка ГРАФИК и пункт меню ГРАФИК главного окна системы. Рис.5 4.3 Назначение элементов графического окна программы Вход в графическое окно осуществляется с помощью кнопок ГРАФИК на главной форме или пункт меню ГРАФИК (рис. 6). С помощью кнопки ВЫЧЕРТИТЬ на координатную плоскость выводится график функции – решение дифференциального уравнения на заданном интервале. рис.6 4.4 Реакция программы при возникновении ошибок При вводе пользователем ошибочных данных (отсутствии начальных условий, некорректных значений переменных) программа выдает сообщение об ошибке (рис.7 а, б) рис.7а. рис.7б. рис 7а Рис.7б Версия DELPHI 4.5 Перечень компонент DELPHI использованных в программе В Form1 использованы компоненты: - Edit1.text, Edit2.text, Edit3.text, Edit4.text – для ввода начальных условий дифференциального уравнения - Memo4.TMemo – для вывода формулы уравнения; - Memo1.TMemo, Memo2.TMemo - для вывода результатов вычислений; - Memo3.TMemo – для вывода значения производной в точке (Х0,Y0) - ScrollBars ssVertical в свойствах Memo1.TMemo, Memo2.TMemo; - Button1 “Вычислить”, Button2 “Очистить”, Button3 “График”, Button4 “Выход”, Button5 “Example”, Button6 “UnExample”; - Label1.TLabel - Label9.TLabel – для отображения назначения компонентов Memo и Edit; - RadioGroup – для выбора вида уравнения; - MainMenu ; В Form2 использованы компоненты: - MainMenu - для построения графика; В Form3 использованы компоненты: - Panel1.T Panel – для размещения информации о программе; - Label1.TLabel – Label14.TLabel – для отображения информации о программе; - Button1.T Button “OK” – для выхода из окна 5. ТЕХНИЧЕСКИЕ ХАРАКТЕРИСТИКИ И ТРЕБОВАНИЯ К ПО Технические характеристики Программа работает в среде операционных систем Windows 9х, NT. Требования к ПО Минимальные системные требования a процессор Intel 486 с рабочей частотой 66 MHz и выше; b) операционная система Windows 95, 98, NT 4.0, 2000, XP; с) 16 Мбайт оперативной памяти (или более); d) 3 Мбайт свободного пространства на жёстком диске. 6. ТЕКСТ ПРОГРАММЫ Код программы unit RKt; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, CheckLst, ComCtrls, ExtCtrls,math, Menus; type TRKutta = class(TForm) Label2: TLabel; Label3: TLabel; Label5: TLabel; Label6: TLabel; Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Edit4: TEdit; Memo1: TMemo; Memo2: TMemo; Button1: TButton; Button2: TButton; Label4: TLabel; Label7: TLabel; Button3: TButton; Button4: TButton; Label9: TLabel; RadioGroup1: TRadioGroup; Button5: TButton; Memo3: TMemo; Button6: TButton; MainMenu1: TMainMenu; N1: TMenuItem; N3: TMenuItem; N4: TMenuItem; Example1: TMenuItem; UnExample1: TMenuItem; N5: TMenuItem; N7: TMenuItem; N2: TMenuItem; N9: TMenuItem; N8: TMenuItem; Label1: TLabel; Memo4: TMemo; Label8: TLabel; Label10: TLabel; Label11: TLabel; Label12: TLabel; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); procedure RadioGroup1Click(Sender: TObject); procedure Button5Click(Sender: TObject); procedure Button6Click(Sender: TObject); procedure N7Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var RKutta: TRKutta; x1,x2,yc,xc,y,h:extended; line_arr:integer; // размерность массивa f:real; // значение функции при начальных условиях zx:array of real; zy:array of real; implementation uses RungeKutta, Spravka; {$R *.DFM} procedure TRKutta.Button1Click(Sender: TObject); var k1,k2,k3,k4:extended; t:integer; begin Memo1.Clear; Memo2.Clear; memo1.Enabled:=true; memo2.Enabled:=true; Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=False; //Проверка возможности ввода начальных условий и инициализация переменных try // инструкции, которые могут вызвать исключение (ошибку) x1:=StrToFloat(Edit1.Text); //инициализация(ввод) x1(начало отрезка) xc:=StrToFloat(Edit1.Text); //передача начальных условий (х0)в графический модуль x2:=StrToFloat(Edit2.Text); //инициализация(ввод) x2(конец отрезка) y:=StrToFloat(Edit3.Text); //инициализация(ввод) Y(x1) yc:=StrToFloat(Edit3.Text); //передача начальных условий (Y0)в графический модуль h:=StrToFloat(Edit4.Text); //инициализация(ввод) H -величины шага вычислений //определение размера массивов содержащего значения аргумента и функции line_arr:=round(abs((x2-x1)/h))+1; //Установка размера динамических массивов zx, zy SetLength(zx, line_arr); SetLength(zy, line_arr); t:=0; // счётчик while x1<x2 do begin zx[t]:=x1; zy[t]:=y; k1:=h*f; if (y+(k1/2))=0 then begin showmessage ('Деление на 0!'+#13+' Измените h'); break; end; k2:=h*((y+(k1/2))-(2*(x1+(h/2)))/(y+(k1/2))); if (y+(k2/2))=0 then begin showmessage ('Деление на 0!'+#13+' Измените h'); break; end; k3:=h*((y+(k2/2))-(2*(x1+(h/2)))/(y+(k2/2))); if (y+k3)=0 then begin showmessage ('Деление на 0!'+#13+' Измените h');break; end; k4:=h*(y+k3-2*(x1+(h/2)))/(y+k3); x1:=x1+h; y:=y+(1/6)*(k1+2*k2+2*k3+k4); t:=t+1; Memo1.Lines.Add('x['+floattostr(t)+']='+floattostr(x1)); Memo2.Lines.Add('y['+floattostr(t)+']='+floattostr(y)); end; except on EConvertError do // невозможно преобразовать строку символов в число begin MessageDlg('Некорректные значения переменных',mtError,[mbOk],0); exit; end; end; if ((y+(k1/2))=0) or ((y+(k2/2))=0) or((y+k3)=0) then begin Button3.Enabled:=False; N3.Enabled:=False; end else begin Button3.Enabled:=True; N3.Enabled:=True; end;end; //------------------------------------------------------------------------------ procedure TRKutta.Button2Click(Sender: TObject); begin memo1.Clear; MEMO2.Clear; MEMO3.Clear; memo4.Clear; edit1.Clear; edit2.Clear; edit3.Clear; edit4.Clear; end; //------------------------------------------------------------------------------ {Процедура вывода окна ГРАФИК} procedure TRKutta.Button3Click(Sender: TObject); begin Button3.enabled:=false; N3.Enabled:=false; Form2.ShowModal; end; //------------------------------------------------------------------------------ {Процедура выхода из программы} procedure TRKutta.Button4Click(Sender: TObject); begin Close; end; //------------------------------------------------------------------------------ {Процедура выбора образцовой функции} procedure TRKutta.RadioGroup1Click(Sender: TObject); var x_rg,y_rg:extended; begin try y_rg:=strtofloat(edit3.Text); //ввод Y(x1) x_rg:=strtofloat(edit1.Text); //ввод X1 {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=0 then begin if x_rg=0 then begin ShowMessage('введите X1 неравное 0'); RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end else begin Memo3.clear; Memo4.Clear; Memo4.Lines.Add(' -(y+1)/x '); вывод формулы функции в окно "dY" f:=-(y_rg+1)/x_rg; //вычисление значения dY Memo3.lines.Add(''+floattostr(f)); //вывод значения dY в окно "dY(x1,y1)" // сброс радиокнопки (с целью корретного вычисления // значения dy(x1,y1) при вводе других данных) Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=1 then begin if y_rg=0 then begin ShowMessage('введите Y(x1) неравное 0'); RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end else begin Memo4.Clear; Memo4.Lines.Add('x*(x^2-1)/(x^2+1)*y '); f:=x_rg*(power(x_rg,2)-1)/(power(x_rg,2)+1)*y_rg; Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=2 then begin if x_rg=0 then begin ShowMessage('введите X1 неравное 0'); RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end else begin Memo3.Clear; Memo4.Clear; Memo4.Lines.Add('(x*cos(y/x))^2+y)/x '); f:=x_rg*(POWER(cos(y_rg/x_rg),2)+y_rg)/x_rg; Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=3 then begin if x_rg=0 then begin ShowMessage('введите X1 неравное 0'); RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end else begin Memo3.Clear; Memo4.Clear; Memo4.Lines.Add('2*x*sin(x)+y*ctg(x) '); f:=2*x_rg*sin(x_rg)+y_rg*cot(x_rg); Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=4 then begin Memo3.Clear; Memo4.Clear; Memo4.Lines.Add('((e^y)+cos(x) '); f:=(exp(y_rg))+cos(x_rg); Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=5 then begin Memo3.Clear; Memo4.Clear; Memo4.Lines.Add('e^(x+y) '); f:=exp(y_rg+x_rg); Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=6 then begin if ((x_rg<=0) and (y_rg>=0))or((x_rg>=0) and (y_rg<=0)) then begin ShowMessage('X1 / Y(X1) не должны быть <=0'); RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end else begin Memo4.Clear; Memo4.Lines.Add('(y/x)ln(y/x) '); f:=(y_rg/x_rg)*ln(y_rg/x_rg); Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=7 then begin if x_rg=0 then begin ShowMessage('введите X1 неравное 0'); RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end else begin Memo4.Clear; Memo4.Lines.Add(' sin(y/x)+y/x '); f:=sin(y_rg/x_rg)+y_rg/x_rg; Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=8 then begin Memo4.Clear; Memo4.Lines.Add(' 6x-sin(x) '); f:=6*x_rg-sin(x_rg); Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=9 then begin Memo4.Clear; Memo4.Lines.Add(' x+2y '); f:=x_rg+2*y_rg; Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=10 then begin Memo4.Clear; Memo4.Lines.Add(' e^x-y '); f:=exp(x_rg)-y_rg; Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=11 then begin if x_rg=0 then begin ShowMessage('введите X1 не равное 0'); RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end else begin Memo4.Clear; Memo4.Lines.Add(' y*ctg(x) '); f:=cot(x_rg)*y_rg; Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=12 then begin if x_rg=0 then begin ShowMessage('введите X1 не равное 0'); RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end else begin Memo4.Clear; Memo4.Lines.Add('(e^x-y)/x '); f:=(exp(x_rg)-y_rg)/x_rg; Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=13 then begin if x_rg*y_rg<0 then begin ShowMessage('введите X1*Y(X1) >= 0'); RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end else begin Memo4.Clear; Memo4.Lines.Add('(x*y)^(1/2) '); f:=power(x_rg*y_rg,1/2); Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=14 then begin Memo4.Clear; Memo4.Lines.Add(' x+y '); f:=x_rg+y_rg; Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=15 then begin Memo4.Clear; Memo4.Lines.Add(' x*y '); f:=x_rg*y_rg; Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=16 then begin Memo4.Clear; Memo4.Lines.Add('e^(x*y) '); f:=exp(x_rg*y_rg); Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=17 then begin Memo4.Clear; Memo4.Lines.Add('(e^x*y) '); f:=exp(x_rg)*y_rg; Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=18 then begin Memo4.Clear; Memo4.Lines.Add('(x^2)*y '); f:=power(x_rg,2)*y_rg; Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=19 then begin Memo4.Clear; Memo4.Lines.Add('-2*x+(2+x+x^2)*y^2 '); f:=-2*x_rg+(2+x_rg+power(x_rg,2))*power(y_rg,2); Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=20 then begin Memo4.Clear; Memo4.Lines.Add('-x*y+(x+1)*y^2 '); f:=-x_rg*y_rg+(x_rg+1)*power(y_rg,3); Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=21 then begin Memo4.Clear; Memo4.Lines.Add(' x^2*y^2 '); f:=power(x_rg,2)*power(y_rg,2); Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=22 then begin Memo4.Clear; Memo4.Lines.Add(' e^(x-y) '); f:=exp(x_rg-y_rg); Memo3.clear; Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=23 then begin if (x_rg=-y_rg) then begin ShowMessage('введите Y(x1)неравное X1'); RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end else begin Memo4.Clear; Memo4.Lines.Add('(x-(y/2))/(x+y) '); f:=(x_rg-0.5*y_rg)/(x_rg+y_rg); Memo3.clear; Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=24 then begin Memo4.Clear; Memo4.Lines.Add('(x+1)*(y+1) '); f:=(x_rg+1)*(y_rg+1); Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=25 then begin Memo4.Clear; Memo4.Lines.Add('x*e^(y) '); f:=x_rg*exp(y_rg); Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=26 then begin if (2*x_rg=-y_rg) then begin ShowMessage('введите Y(x1) неравное -2*X1'); RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end else begin Memo4.Clear; Memo4.Lines.Add('(x+1)/(2*x+y) '); f:=(x_rg+1)/(2*x_rg+y_rg); Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=27 then begin if (x_rg=0)or(y_rg=0) then begin ShowMessage('введите Y(x1) неравное 0'); RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end else begin Memo4.Clear; Memo4.Lines.Add('((x+1)*(y^2))/x*y '); f:=((x_rg+1)*power(y_rg,2))/x_rg*y_rg; Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=28 then begin if (x_rg=-y_rg) then begin ShowMessage('введите Y(x1) неравное -X1'); RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end else begin Memo4.Clear; Memo4.Lines.Add('(3.4-x*y)/(x+y) '); f:=(3.4-x_rg*y_rg)/(x_rg+y_rg); Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=29 then begin if y_rg=0 then begin ShowMessage('введите Y(x1) не равное 0'); RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end else begin Memo4.Clear; Memo4.Lines.Add('y-2x/y '); f:=y_rg-2*x_rg/y_rg; Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; end; {------------------------------------------------------------------------------} if RadioGroup1.ItemIndex=30 then begin if y_rg=0 then begin ShowMessage('введите Y(x1) не равное 0'); RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end else begin Memo4.Clear; Memo4.Lines.Add(' x/y '); f:=x_rg/y_rg; Memo3.lines.Add(''+floattostr(f)); Button1.Enabled:=True; RadioGroup1.Enabled:=False; RadioGroup1.ItemIndex:=31; end; end {------------------------------------------------------------------------------} except on EConvertError do // невозможно преобразовать строку символов в число begin MessageDlg('Некорректные значения переменных',mtError,[mbOk],0); exit; end; end; end; //------------------------------------------------------------------------------ {Активация ввода образцовых функций} procedure TRKutta.Button5Click(Sender: TObject); begin memo4.clear; memo3.clear; RadioGroup1.Enabled:=True; memo1.clear;memo2.Clear;memo3.clear; memo3.lines.Add(''+floattostr(f)); end; //------------------------------------------------------------------------------ {Деактивация ввода образцовых функций} procedure TRKutta.Button6Click(Sender: TObject); begin RadioGroup1.Enabled:=False; Memo3.lines.Add(''+floattostr(f)); end; //------------------------------------------------------------------------------ {Вывод информации о программе} procedure TRKutta.N7Click(Sender: TObject); begin Form3.ShowModal; end; //------------------------------------------------------------------------------ end. {====================================================} unit RngeKutta; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs,StdCtrls,Rkt,Menus; type TRungeKutta=class(TObject) constructor CreateGr(var hzx:array of real;var hzy:array of real;var lin_arr:integer); private { Private declarations } public { Public declarations } x0,y0:integer; //координаты начала координатных осей, 2*x0,2*y0 - высота // и ширина области вывода координатной сетки dx,dy:integer; // шаг координатной сетки (в пикселях) y1,y2,xP,xL:integer;// засечки по оси Y и X dlx,dly:real; // шаг меток (оцифровки) линий сетки по X и Y cross:integer; // счетчик неоцифрованных линий сетки dcross:integer; // количество неоцифрованных линий между оцифрованными BaseMasht_X,BaseMasht_Y:extended; //МАХ значения элементов в массивах razm:integer; uzx:array of real; //Динамический массив координат-X uzy:array of real; //Динамический массив координат-Y uxc,uyc:extended; // Оцифровка по осям mx,my:extended; function MaxAbsElementArray(arr:array of real;razmer:integer):real; procedure UstanovkaParametrov(); procedure KoordPloskost; end; TForm2 = class(TForm) MainMenu1: TMainMenu; N4: TMenuItem; N5: TMenuItem; procedure N4Click(Sender: TObject); procedure N5Click(Sender: TObject); private { Private declarations } RungeKutta:TRungeKutta; //Объявление переменной - объекта класса public { Public declarations } end; var Form2: TForm2; implementation {$R *.dfm} function TRungeKutta.MaxAbsElementArray(arr:array of real;razmer:integer):real; var i:integer; max:real; begin i:=1; max:=arr[1]; while i<>razmer do begin i:=i+1; if abs(arr[i])>max then begin max:=abs(arr[i]); end; end; MaxAbsElementArray:=max; end; //------------------------------------------------------------------------------ procedure TRungeKutta.UstanovkaParametrov(); begin //определение max абсолютного значения функции (ордината) BaseMasht_Y:=MaxAbsElementArray(uzy,razm)+1; //определение max абсолютного значения аргумента функции (абсцисса) BaseMasht_X:=MaxAbsElementArray(uzx,razm); y0:=round(Form2.ClientHeight/2); // оси начинаются в точке (X0,Y0) x0:=round(Form2.ClientWidth/2); dcross:=1; // помечать линии сетки X: 1 - каждую; // 2 - через одну; // 3 - через две; dlx:=round(BaseMasht_X)/10; // вес меток оси X dly:=round(BaseMasht_Y)/10; // вес меток оси Y , dx:=round(x0/10); // шаг координатной сетки в пикселях dy:=round(y0/10); // шаг координатной сетки в пикселях mx:=round(x0/round(BaseMasht_X)+1);//вычисление масштаба по оси X my:=round(y0/round(BaseMasht_Y)+1);//вычисление масштаба по оси Y end; //------------------------------------------------------------------------------ procedure TRungeKutta.KoordPloskost; begin uxc:=0; uyc:=0; with form2.Canvas do begin cross:=dcross; //------------------------------------------------------------------------------ //Нанесение засечек и оцифровка координатных осей I,II квадрантов // засечки и оцифровка по оси X xP:=x0; xL:=x0; repeat MoveTo(xP,y0-2);LineTo(xP,y0+2); // засечка MoveTo(xL,y0-2);LineTo(xL,y0+2); // засечка cross:=cross-1; if cross = 0 then //оцифровка begin TextOut(xP-8,y0+3,FloatToStr(uxc)); TextOut(xL-8,y0+3,FloatToStr(-uxc)); cross:=dcross; uxc:=uxc+dlx; end; Pen.Style:=psDot; MoveTo(xP,2*y0);LineTo(xP,-2*y0); // линия сетки MoveTo(xL,2*y0);LineTo(xL,-2*y0); Pen.Style:=psSolid; xP:=xP+dx; xL:=xL-dx; until (xP>2*x0); //------------------------------------------------------------------------------ //Нанесение засечек и оцифровка координатных осей III, IV квадрантов // засечки, и оцифровка по оси Y y1:=y0-dy; y2:=y0+dy; repeat MoveTo(x0-2,y1);LineTo(x0+2,y1); // засечка MoveTo(x0-2,y2);LineTo(x0+2,y2); uyc:=uyc+dly; TextOut(x0-20,y1,FloatToStr(uyc)); // оцифровка TextOut(x0-20,y2,FloatToStr(-uyc)); Pen.Style:=psDot; MoveTo(10,y1);LineTo(2*x0-10,y1); // линия сетки MoveTo(10,y2);LineTo(2*x0-10,y2); Pen.Style:=psSolid; y2:=y2+dy; y1:=y1-dy; until (y2>2*y0); //------------------------------------------------------------------------------ MoveTo(x0,2*y0); LineTo(x0,0); // ось Y MoveTo(0,y0); LineTo(2*x0,y0); // ось X end; end; //----------------------------------------------------------------------------- //создание объекта (график функции, координатная сетка, координатные оси) constructor TRungeKutta.CreateGr(var hzx:array of real;var hzy:array of real;var lin_arr:integer); var n:integer; begin SetLength(uzx,lin_arr); //Установка размера массива uzx SetLength(uzy,lin_arr); //Установка размера массива uzy razm:= lin_arr; for n:=0 to lin_arr do begin uzx[n]:=hzx[n]; //инициализация массива uzx uzy[n]:=hzy[n]; //инициализация массива uzy end; UstanovkaParametrov; KoordPloskost; for n:=0 to (lin_arr-1) do begin form2.canvas.Pixels[(x0+ROUND(uzx[n]*mx)),(y0-round((uzy[n]*my)))]:=clRed; end; end; //------------------------------------------------------------------------------ {Процедура N4Click выводит график функции в установленном масштабе в окне 'График' } procedure TForm2.N4Click(Sender: TObject); begin form2.Canvas.FillRect(Rect(0,0,ClientWidth,ClientHeight)); TRungeKutta.CreateGr(zx,zy,line_arr); end; //------------------------------------------------------------------------------ {Процедура N5Click закрывает окно вывода графика функции - результата решния ДУ } procedure TForm2.N5Click(Sender: TObject); begin close; end; end. {====================================================} Unit Spravka; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls; type TForm3 = class(TForm) Panel1: TPanel; Label1: TLabel; Button1: TButton; Label2: TLabel; Label3: TLabel; Label4: TLabel; Label5: TLabel; Label7: TLabel; Label8: TLabel; Label9: TLabel; Label10: TLabel; Label6: TLabel; Label11: TLabel; Label12: TLabel; Label13: TLabel; Label14: TLabel; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form3: TForm3; implementation {$R *.dfm} //------------------------------------------------------------------------------ {Ввывод информации о программе} procedure TForm3.Button1Click(Sender: TObject); begin Caption := 'OK'; ModalResult := mrOK; OnClick := Button1Click; end; end. {===============================================} 7. РЕШЕНИЕ ДИФФЕРЕНЦИАЛЬНОГО УРАВНЕНИЯ Y = Y−2X/Y МЕТОДОМ РУНГЕ – КУТТА В СРЕДЕ EXCEL дифференциальное уравнение программирование 2. Решение дифференциального уравнения Y = Y−2X/Y программой «РЕШЕНИЕ ОДУ» показано на рис. 5 и рис. 6.(стр. 22 - 23 ) ВЫВОД Программа «Решение ОДУ» решает заданные дифференциальные уравнения первой степени с достаточно высокой степенью точности. |
Страницы: 1, 2
![]() |
||
НОВОСТИ | ![]() |
![]() |
||
ВХОД | ![]() |
|
Рефераты бесплатно, реферат бесплатно, курсовые работы, реферат, доклады, рефераты, рефераты скачать, рефераты на тему, сочинения, курсовые, дипломы, научные работы и многое другое. |
||
При использовании материалов - ссылка на сайт обязательна. |