База научных работ, курсовых, рефератов! Lcbclan.ru Курсовые, рефераты, скачать реферат, лекции, дипломные работы

Программная реализация модального управления для линейных стационарных систем

Программная реализация модального управления для линейных стационарных систем

Курсовая работа:

«Программная реализация модального управления для линейных стационарных систем»

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

1. Для объекта управления с математическим описанием

[pic], (1) [pic]- задано, где [pic] - n-мерный вектор состояния, [pic],

[pic]- начальный вектор состояния,

[pic]- скалярное управление,

[pic]- матрица действительных коэффициентов,

[pic]- матрица действительных коэффициентов, найти управление в функции переменных состояния объекта, т.е.

[pic], (2) где[pic]- матрица обратной связи, такое, чтобы замкнутая система была устойчивой.
2. Корни характеристического уравнения замкнутой системы

[pic] (3) должны выбираться по усмотрению (произвольно) с условием устойчивости системы (3).


Задание:

1. Разработать алгоритм решения поставленной задачи.
2. Разработать программу решения поставленной задачи с интерактивным экранным интерфейсом в системах Borland Pascal, Turbo Vision, Delphi - по выбору.
3. Разработать программу решения систем дифференциальных уравнений (1) и
(3) с интерактивным экранным интерфейсом.
4. Разработать программу графического построения решений систем (1) и (3) с интерактивным экранным интерфейсом.

Введение

Наряду с общими методами синтеза оптимальных законов управления для стационарных объектов всё большее применение находят методы, основанные на решении задачи о размещении корней характеристического уравнения замкнутой системы в желаемое положение. Этого можно добиться надлежащим выбором матрицы обратной связи по состоянию. Решение указанной задачи является предметом теории модального управления (термин связан с тем, что корням характеристического уравнения соответствуют составляющие свободного движения, называемые модами).

Алгоритм модального управления.

Соглашения:
. Задаваемый объект управления математически описывается уравнением

[pic], (1) где [pic] и [pic] - матрицы действительных коэффициентов,

[pic] - n-мерный вектор состояния

[pic]- скалярное управление,

[pic] - порядок системы (1).
. Обратная связь по состоянию имеет вид

[pic], (2) где[pic]- матрица обратной связи.
. Система с введенной обратной связью описывается уравнением

[pic] (3)
. Характеристическое уравнение системы (1) имеет вид

[pic] (4)
. Характеристическое уравнение системы (3) с задаваемыми (желаемыми) корнями [pic]имеет вид

[pic] (5)

Алгоритм:
1. Для исходной системы (1) составляем матрицу управляемости

[pic]
2. Обращаем матрицу [pic], т.е. вычисляем [pic].
Если [pic] не существует (т.е. матрица [pic] - вырожденная), то прекращаем вычисления: полное управление корнями характеристического уравнения (5) не возможно.
3. Вычисляем матрицу [pic]
4. Составляем матрицу

[pic]
5. Вычисляем матрицу, обратную матрице [pic], т.е. [pic]
6. Вычисляем матрицу [pic] - матрицу [pic] в канонической форме фазовой переменной:

[pic] где [pic]- коэффициенты характеристического уравнения (4).
Матрица [pic] в канонической форме имеет вид

[pic]
7. Составляем вектор [pic] , элементам которого являются коэффициенты характеристического уравнения (4), т.е. [pic], [pic], где [pic] - элементы матрицы [pic].
8. Находим коэффициенты характеристического уравнения (5) (см. пояснения) и составляем из них вектор [pic].
9. Вычисляем вектор [pic].
[pic] - искомая матрица обратной связи системы (3), но она вычислена для системы, матрицы которой заданы в канонической форме фазовой переменной
([pic] и [pic]).
10. Для исходной системы (3) матрица обратной связи получается по формуле

[pic]
Матрица [pic] - искомая матрица обратной связи.

Пояснения к алгоритму:
В данной работе рассматривается случай, когда управление единственно и информация о переменных состояния полная. Задача модального управления тогда наиболее просто решается, если уравнения объекта заданы в канонической форме фазовой переменной.
Так как управление выбрано в виде линейной функции переменных состояния
[pic], где [pic] является матрицей строкой [pic]. В таком случае уравнение замкнутой системы приобретает вид [pic]. Здесь

[pic]

[pic]
Характеристическое уравнение такой замкнутой системы будет следующим

[pic]
Поскольку каждый коэффициент матрицы обратной связи [pic] входит только в один коэффициент характеристического уравнения, то очевидно, что выбором коэффициентов [pic] можно получить любые коэффициенты характеристического уравнения, а значит и любое расположение корней.
Если же желаемое характеристическое уравнение имеет вид

[pic], то коэффициенты матрицы обратной связи вычисляются с помощью соотношений:

[pic]
Если при наличии одного управления нормальные уравнения объекта заданы не в канонической форме (что наиболее вероятно), то, в соответствии с пунктами
№1-6 алгоритма, от исходной формы с помощью преобразования [pic] или [pic] нужно перейти к уравнению [pic] в указанной канонической форме.
Управление возможно, если выполняется условие полной управляемости (ранг матрицы управляемости M должен быть равен n). В алгоритме об управляемости системы судится по существованию матрицы [pic]: если она существует, то ранг матрицы равен ее порядку (n). Для объекта управления с единственным управлением матрица [pic] оказывается также единственной.
Для нахождения коэффициентов [pic] характеристического уравнения (5), в работе используется соотношения между корнями [pic] и коэффициентами
[pic] линейного алгебраического уравнения степени n:

[pic], (k = 1, 2, ... , n) где многочлены [pic]- элементарные симметрические функции, определяемые следующим образом:

[pic],

[pic],

[pic],

...

[pic] где Sk - сумма всех [pic] произведений, каждое из которых содержит k сомножителей xj с несовпадающими коэффициентами.

Программная реализация алгоритма.

Текст программной реализации приведен в ПРИЛОЖЕНИИ №1. Вот несколько кратких пояснений.
. Программа написана на языке Object Pascal при помощи средств Delphi 2.0, и состоит из следующих основных файлов:

KursovayaWork.dpr

MainUnit.pas

SubUnit.pas

Matrix.pas

Operates.pas

HelpUnit.pas

OptsUnit.pas
. KursovayaWork.dpr - файл проекта, содержащий ссылки на все формы проекта и инициализирующий приложение.
. В модуле MainUnit.pas находится описание главной формы приложения, а также сконцентрированы процедуры и функции, поддерживаюшие нужный интерфейс программы.
. Модули SubUnit.pas и Operates.pas содержат процедуры и функции, составляющие смысловую часть программной реализации алгоритма, т.е. процедуры решения задачи модально управления, процедуры решения систем дифференциальных уравнений, процедуры отображения графиков решений систем и т.д. Там также находятся процедуры отображения результатов расчетов на экран.
. В модуле Matrix.pas расположено описание класса TMatrix - основа матричных данных в программе.
. Модули HelpUnit.pas и OptsUnit.pas носят в программе вспомогательный характер.
. Для решения систем дифференциальных уравнений использован метод Рунге-
Кутта четвертого порядка точности с фиксированным шагом. Метод был позаимствован из пакета программ NumToolBox и адаптирован под новую модель матричных данных.
. Обращение матриц производится методом исключения по главным диагональным элементам (метод Гаусса). Этот метод так же был позаимствован из
NumToolBox и соответствующе адаптирован.

Пориложение.

program KursovayaWork;

uses

Forms,

MainUnit in 'MainUnit.pas' {Form_Main},

OptsUnit in 'OptsUnit.pas' {Form_Options},

SubUnit in 'SubUnit.pas',

Matrix in 'Matrix.pas',

Operates in 'Operates.pas',

HelpUnit in 'HelpUnit.pas' {Form_Help};

{$R *.RES}

begin

Application.Initialize;

Application.Title := 'Модальное управление';

Application.CreateForm(TForm_Main, Form_Main);

Application.CreateForm(TForm_Options, Form_Options);

Application.CreateForm(TForm_Help, Form_Help);

Application.Run; end. unit MainUnit;

interface

uses

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

ComCtrls, Tabnotbk, Menus, StdCtrls, Spin, ExtCtrls, Buttons, Grids,

OleCtrls, VCFImprs, GraphSvr, ChartFX {, ChartFX3};

type

TForm_Main = class(TForm)

BevelMain: TBevel;

TabbedNotebook_Main: TTabbedNotebook;

SpinEdit_Dim: TSpinEdit;

BitBtn_Close: TBitBtn;

BitBtn_Compute: TBitBtn;

StringGrid_Ap0: TStringGrid;

StringGrid_Anp0: TStringGrid;

StringGrid_Roots: TStringGrid;

StringGrid_Kpp0: TStringGrid;

StringGrid_Bp0: TStringGrid;

RadioGroup_RootsType: TRadioGroup;

Label_A1p0: TLabel;

Label_Ap0: TLabel;

Label_mBp0: TLabel;

Label_Roots: TLabel;

Label_Kpp0: TLabel;

BevelLine: TBevel;

Label_Dim: TLabel;

StringGrid_Ap1: TStringGrid;

StringGrid_Bp1: TStringGrid;

Label_Ap1: TLabel;

Label_Bp1: TLabel;

StringGrid_Kpp1: TStringGrid;

Label_Kpp1: TLabel;

StringGrid_InCond: TStringGrid;

Label_InCond: TLabel;

Label_U: TLabel;

Edit_U: TEdit;

BitBtn_Options: TBitBtn;

BitBtn_Help: TBitBtn;

StringGrid_ABKpp1: TStringGrid;

Label_ABKpp1: TLabel;

Edit_W: TEdit;

Label_w: TLabel;

RadioGroupChart: TRadioGroup;

ChartFX: TChartFX;

LabelW1: TLabel;

StringGrid_Solve1: TStringGrid;

StringGrid_Solve2: TStringGrid;

Label1: TLabel;

Label2: TLabel;

Label3: TLabel; procedure BitBtn_CloseClick(Sender: TObject); procedure BitBtn_OptionsClick(Sender: TObject); procedure BitBtn_ComputeClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure SpinEdit_DimChange(Sender: TObject); procedure StringGrid_RootsSetEditText(Sender: TObject; ACol,

ARow: Longint; const Value: string); procedure RadioGroup_RootsTypeClick(Sender: TObject); procedure TabbedNotebook_MainChange(Sender: TObject; NewTab: Integer; var AllowChange: Boolean); procedure StringGrid_SetEditText(Sender: TObject; ACol,

ARow: Longint; const Value: string); procedure BitBtn_HelpClick(Sender: TObject); procedure RadioGroupChartClick(Sender: TObject); private procedure FillFixedCellsInAllGrids; procedure FillCellsInAllGrids; public procedure BindGrids; procedure UnBindGrids; end;

var

Form_Main: TForm_Main;

implementation

uses Matrix, SubUnit, OptsUnit, Operates, CFXOCX2, HelpUnit;

const

DefOptions = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goColSizing, goEditing, goAlwaysShowEditor, goThumbTracking];
{$R *.DFM}

procedure TForm_Main.FillFixedCellsInAllGrids; var

Order : TOrder; i: byte;

Str: string; begin

Order := SpinEdit_Dim.Value; for i := 1 to Order do begin

Str := IntToStr(i);

StringGrid_Ap0.Cells[0, i] := Str;

StringGrid_Ap0.Cells[i, 0] := Str;

StringGrid_Bp0.Cells[0, i] := Str;

StringGrid_ANp0.Cells[i, 0] := Str;

StringGrid_ANp0.Cells[0, i] := Str;

StringGrid_Roots.Cells[i, 0] := Str;

StringGrid_Kpp0.Cells[i, 0] := Str;

StringGrid_Ap1.Cells[0, i] := Str;

StringGrid_Ap1.Cells[i, 0] := Str;

StringGrid_Bp1.Cells[0, i] := Str;

StringGrid_ABKpp1.Cells[i, 0] := Str;

StringGrid_ABKpp1.Cells[0, i] := Str;

StringGrid_InCond.Cells[i, 0] := Str;

StringGrid_Kpp1.Cells[i, 0] := Str;

StringGrid_Solve1.Cells[i, 0] := 'X' + IntToStr(i);

StringGrid_Solve2.Cells[i, 0] := 'X' + IntToStr(i);

StringGrid_Solve1.Cells[0, 0] := 'Время';

StringGrid_Solve2.Cells[0, 0] := 'Время'; end; end;

procedure TForm_Main.FillCellsInAllGrids; var

Order : TOrder; i, j : byte; begin

Order := SpinEdit_Dim.Value; for i := 1 to Order do for j := 1 to Order do begin

StringGrid_Ap0.Cells[j, i] := '0';

StringGrid_Ap0.Cells[i, i] := '1';

StringGrid_Bp0.Cells[1, i] := '0';

StringGrid_Roots.Cells[i, 1] := '-1';

StringGrid_Roots.Cells[i, 2] := '0';

StringGrid_Kpp0.Cells[i, 1] := '0';

StringGrid_Ap1.Cells[j, i] := '0';

StringGrid_Ap1.Cells[i, i] := '1';

StringGrid_Bp1.Cells[1, i] := '0';

StringGrid_ABKpp1.Cells[j, i] := '0';

StringGrid_ABKpp1.Cells[i, i] := '1';

StringGrid_InCond.Cells[i, 1] := '0';

StringGrid_Kpp1.Cells[i, 1] := '0'; end;

FillFixedCellsInAllGrids;

StringGrid_Roots.Cells[0, 1] := 'Re';

StringGrid_Roots.Cells[0, 2] := 'Im';

StringGrid_Bp1.Cells[1, 0] := '1';

StringGrid_Bp0.Cells[1, 0] := '1'; end;

procedure TForm_Main.BindGrids; begin

CopyGrid(StringGrid_Ap1, StringGrid_Ap0);

CopyGrid(StringGrid_Bp1, StringGrid_Bp0);

CopyGrid(StringGrid_Kpp1, StringGrid_Kpp0);

StringGrid_Ap1.Options := DefOptions - [goEditing];

StringGrid_Bp1.Options := DefOptions - [goEditing];

StringGrid_Kpp1.Options := DefOptions - [goEditing]; end;

procedure TForm_Main.UnBindGrids; begin

StringGrid_Ap1.Options := DefOptions;

StringGrid_Bp1.Options := DefOptions;

StringGrid_Kpp1.Options := DefOptions; end;

procedure TForm_Main.BitBtn_CloseClick(Sender: TObject); begin

Close; end;

procedure TForm_Main.BitBtn_OptionsClick(Sender: TObject); var

V0, V1, V2, V3: LongInt;

LS: TCheckBoxState; begin with Form_Options do begin

V0 := SpinEdit0.Value;

V1 := SpinEdit1.Value;

V2 := SpinEdit2.Value;

V3 := SpinEdit3.Value;

LS := CheckBox_Link.State;

ShowModal; if ModalResult = mrCancel then begin

SpinEdit0.Value := V0;

SpinEdit1.Value := V1;

SpinEdit2.Value := V2;

SpinEdit3.Value := V3;

CheckBox_Link.State := LS; end else if ((SpinEdit0.Value V0) or (SpinEdit1.Value V1)) or

((SpinEdit2.Value V2) or (SpinEdit3.Value V3)) then begin

BitBtn_Compute.Enabled := True; case BitBtn_Compute.Tag of

4, 5 :BitBtn_Compute.Tag := BitBtn_Compute.Tag - 4;

6, 7 :BitBtn_Compute.Tag := BitBtn_Compute.Tag - 4;

8, 9 :BitBtn_Compute.Tag := BitBtn_Compute.Tag - 8;

10, 11 :BitBtn_Compute.Tag := BitBtn_Compute.Tag - 8;

12, 13 :BitBtn_Compute.Tag := BitBtn_Compute.Tag - 12;

14, 15 :BitBtn_Compute.Tag := BitBtn_Compute.Tag - 12; end; end; end; end;

procedure TForm_Main.BitBtn_ComputeClick(Sender: TObject); begin

BitBtn_Compute.Enabled := False; if Form_Options.CheckBox_Link.State = cbChecked then BindGrids; case TabbedNotebook_Main.PageIndex of

0 : begin

ComputeFromPage0;

BitBtn_Compute.Tag := BitBtn_Compute.Tag + 1; end;

1 : begin

ComputeFromPage1;

ShowChart(Succ(RadioGroupChart.ItemIndex));

BitBtn_Compute.Tag := BitBtn_Compute.Tag + 14; end;

2 : begin

ComputeFromPage2;

BitBtn_Compute.Tag := BitBtn_Compute.Tag + 4; end;

3 : begin

ComputeFromPage3;

BitBtn_Compute.Tag := BitBtn_Compute.Tag + 8; end; end; end;

procedure TForm_Main.FormCreate(Sender: TObject); const

FirstColWidth = 20; begin

StringGrid_Ap0.ColWidths [0] := FirstColWidth;

StringGrid_Anp0.ColWidths [0] := FirstColWidth;

StringGrid_Bp0.ColWidths [0] := FirstColWidth;

StringGrid_Roots.ColWidths [0] := FirstColWidth;

StringGrid_Ap1.ColWidths [0] := FirstColWidth;

StringGrid_ABKpp1.ColWidths [0] := FirstColWidth;

StringGrid_Bp1.ColWidths [0] := FirstColWidth;

StringGrid_Kpp0.ColWidths [0] := FirstColWidth;

StringGrid_Kpp1.ColWidths [0] := FirstColWidth;

StringGrid_InCond.ColWidths [0] := FirstColWidth;

FillCellsInAllGrids;

BindGrids; end;

procedure TForm_Main.SpinEdit_DimChange(Sender: TObject); var

Order: byte; begin

Order := Succ(SpinEdit_Dim.Value);

StringGrid_Ap0.ColCount := Order;

StringGrid_Ap0.RowCount := Order;

StringGrid_Anp0.ColCount := Order;

StringGrid_Anp0.RowCount := Order;

StringGrid_Bp0.RowCount := Order;

StringGrid_Roots.ColCount := Order;

StringGrid_Kpp0.ColCount := Order;

StringGrid_Ap1.ColCount := Order;

StringGrid_Ap1.RowCount := Order;

StringGrid_Bp1.RowCount := Order;

StringGrid_ABKpp1.ColCount := Order;

StringGrid_ABKpp1.RowCount := Order;

StringGrid_InCond.ColCount := Order;

StringGrid_Kpp1.ColCount := Order;

FillFixedCellsInAllGrids;

BitBtn_Compute.Enabled := True; end;

procedure TForm_Main.StringGrid_RootsSetEditText(Sender: TObject; ACol,

ARow: Longint; const Value: string); var

Val : string; begin if (ARow = 2) and (Value '') then begin

Val := StringGrid_Roots.Cells [ACol, ARow]; if StrToFloat (Value) 0 then

StringGrid_Roots.Cells[Succ(ACol),ARow]:=FloatToStr(-
StrToFloat(Value)); if StrToFloat (Value) = 0 then

StringGrid_Roots.Cells [Succ(ACol),ARow] := FloatToStr(0); end; end;

procedure TForm_Main.RadioGroup_RootsTypeClick(Sender: TObject); var

Order: TOrder; j: byte;

NHalf: byte;

StartAlfa, NAlfa, dAlfa: Float;

W: Float; begin

Order := SpinEdit_Dim.Value;

W := StrToFloat (Edit_W.Text); case RadioGroup_RootsType.ItemIndex of

0 :StringGrid_Roots.Options := DefOptions;

1 :begin for j := 1 to Order do begin

StringGrid_Roots.Cells [j, 1] := FloatToStr (-W);

StringGrid_Roots.Cells [j, 2] := '0';

StringGrid_Roots.Options := DefOptions - [goEditing]; end end;

2 :begin dAlfa := Pi / Order;

StartAlfa := Pi/2 - dAlfa/2;

NHalf := Order div 2; for j := 1 to NHalf do begin

NAlfa := StartAlfa + dAlfa * j;

StringGrid_Roots.Cells [j, 1] := FloatToStr (Cos (NAlfa) *
W);

StringGrid_Roots.Cells [Order - Pred (j), 1] := FloatToStr
(Cos (-NAlfa) * W);

StringGrid_Roots.Cells [j, 2] := FloatToStr (Sin (NAlfa) *
W);

StringGrid_Roots.Cells [Order - Pred (j), 2] := FloatToStr
(Sin (-NAlfa) * W); end; if Odd (Order) then begin

StringGrid_Roots.Cells [NHalf +1, 1] := FloatToStr (-W);

StringGrid_Roots.Cells [NHalf +1, 2] := '0'; end;

StringGrid_Roots.Options := DefOptions - [goEditing]; end; end;

end;

procedure TForm_Main.TabbedNotebook_MainChange(Sender: TObject;

NewTab: Integer; var AllowChange: Boolean); begin with BitBtn_Compute do case NewTab of

0 :begin

SpinEdit_Dim.Enabled := True; if Tag in [1, 3, 5, 7, 9, 11, 13, 15] then Enabled := False else Enabled := True;

BitBtn_Compute.Caption := 'Рассчитать модальное управление'; end;

1 :begin

SpinEdit_Dim.Enabled := True; if Tag in [2, 3, 6, 7, 10, 11, 14, 15] then Enabled := False else Enabled := True;

BitBtn_Compute.Caption := 'Решить системы дифф. уравнений '; if Form_Options.CheckBox_Link.State = cbChecked then BindGrids; end;

2 :begin

SpinEdit_Dim.Enabled := False; if Tag in [4, 5, 6, 7, 12, 13, 14, 15] then Enabled := False else Enabled := True;

BitBtn_Compute.Caption := 'Обновить результаты решений '; end;

3 :begin

SpinEdit_Dim.Enabled := False; if Tag in [8, 9, 10, 11, 12, 13, 14, 15] then Enabled := False else Enabled := True;

BitBtn_Compute.Caption := 'Обновить диаграмму решения '; end; end; end;

procedure TForm_Main.StringGrid_SetEditText(Sender: TObject; ACol,

ARow: Longint; const Value: string); begin if not BitBtn_Compute.Enabled then case TabbedNotebook_Main.PageIndex of

0 :if Form_Options.CheckBox_Link.State = cbChecked then

BitBtn_Compute.Tag := BitBtn_Compute.Tag - 3 else

BitBtn_Compute.Tag := BitBtn_Compute.Tag - 1;

1 :BitBtn_Compute.Tag := BitBtn_Compute.Tag - 2; end;

BitBtn_Compute.Enabled := True; end;

procedure TForm_Main.BitBtn_HelpClick(Sender: TObject); begin

Form_Help.ShowModal; end;

procedure TForm_Main.RadioGroupChartClick(Sender: TObject); begin case RadioGroupChart.ItemIndex of

0 :ShowChart(1);

1 :ShowChart(2); end; end;

end. unit SubUnit;

interface

uses

SysUtils, Matrix, Operates, Grids;

procedure CopyGrid(AGrid, BGrid: TStringGrid); procedure LoadMatrixSolveFromStrGrd (AMatrix: TMatrix; AGrid:
TStringGrid); procedure ComputeFromPage0; procedure ComputeFromPage1; procedure ComputeFromPage2; procedure ComputeFromPage3; procedure ShowChart(NumberOfChart: Byte);

implementation

uses

MainUnit, OptsUnit, CFXOCX2;

procedure CopyGrid(AGrid, BGrid: TStringGrid); var i, j: LongInt; begin

AGrid.ColCount := BGrid.ColCount;

AGrid.RowCount := BGrid.RowCount; for j := 0 to AGrid.ColCount do for i := 0 to AGrid.RowCount do

AGrid.Cells[j, i] := BGrid.Cells[j, i]; end;

function CropStr (Str: String): String; var i: Byte;

Str_1: String;
Begin for i := Length(Str) downto 1 do if Str [i] = ' ' then Str := Copy(Str, 1, i-1) else Break;

Str_1 := Str; for i := 1 to Length(Str) do if Str[i] = ' ' then Str_1 := Copy(Str, i+1, Length(Str) - i) else Break;

CropStr := Str_1;
End;

procedure LoadMatrixFromStrGrd (AMatrix: TMatrix; AGrid: TStringGrid); var i, j: Word; begin

AMatrix.Resize (Pred(AGrid.ColCount), Pred(AGrid.RowCount)); for i := 1 to AMatrix.RowCount do for j := 1 to AMatrix.ColCount do begin if CropStr(AGrid.Cells[j, i]) = '' then AGrid.Cells[j, i] := '0';

AMatrix[j ,i] := StrToFloat(AGrid.Cells[j, i]) end end;

procedure OutPutMatrixToStrGrd (AMatrix: TMatrix; AGrid: TStringGrid); var i, j: Word; begin

AGrid.ColCount := Succ(AMatrix.ColCount);

AGrid.RowCount := Succ(AMatrix.RowCount); for i := 1 to AMatrix.RowCount do for j := 1 to AMatrix.ColCount do begin

AGrid.Cells[j, 0] := IntToStr (j);

AGrid.Cells[0, i] := IntToStr (i);

AGrid.Cells[j, i] := FloatToStrF(AMatrix[j ,i],ffGeneral,5,3); end end;

procedure OutPutMatrixSolveToStrGrd (AMatrix: TMatrix; AGrid:
TStringGrid); var i, j, k: Word; begin

AGrid.ColCount := AMatrix.ColCount;

AGrid.RowCount := Succ(AMatrix.RowCount); for i := 1 to AMatrix.RowCount do for j := 1 to AMatrix.ColCount do begin if j = AMatrix.ColCount then k := 0 else k := j;

AGrid.Cells[j, 0] := 'X' + IntToStr (j);

AGrid.Cells[k, i] := FloatToStrF(AMatrix[j ,i],ffGeneral,5,3); end;

AGrid.Cells[0, 0] := 'Время'; end;

procedure LoadMatrixSolveFromStrGrd (AMatrix: TMatrix; AGrid:
TStringGrid); var i, j, k: Word; begin

AMatrix.Resize (AGrid.ColCount, Pred(AGrid.RowCount)); for i := 1 to AMatrix.RowCount do for j := 0 to AMatrix.ColCount do begin if j = 0 then k := AMatrix.ColCount else k := j; if CropStr(AGrid.Cells[j, i]) = '' then AGrid.Cells[j, i] := '0';

AMatrix[k ,i] := StrToFloat(AGrid.Cells[j, i]) end end;

procedure ComputeFromPage0; var

Order : TOrder; i, j : byte;

K : ShortInt; mDummy1, mDummy2, mA, mB, mKp, mM, mN, mN1: TMatrix; cvRoots: TComplexVector; begin with Form_Main do begin

Order := SpinEdit_Dim.Value;

mA := TMatrix.Create(Order, Order); mB := TMatrix.Create(1, Order); mM := TMatrix.Create(Order, Order); mDummy1 := TMatrix.Create(Order, Order); mN1 := TMatrix.Create(Order, 1); mN := TMatrix.Create(Order, Order); mDummy2 := TMatrix.Create(Order, Order); mKp := TMatrix.Create(Order, 1);

LoadMatrixFromStrGrd (mA, StringGrid_Ap0);

LoadMatrixFromStrGrd (mB, StringGrid_Bp0);

for j := 1 to Order do begin mDummy1.Assign(mA); mDummy1.NthPower(j - 1); mDummy1.MultFromRight(mB); for i := 1 to Order do mM[j, i] := mDummy1[1, i]; end;

if not mM.Inverse then

Raise ESingularMatrix.Create('Система неполностью управляема:' +

'матрица M - вырожденная !!!'#10 +

'Измените значения коэффициентов матриц А и B');

mN1.SetNull; mN1[Order, 1] := 1; mN1.MultFromRight(mM);

for i := 1 to Order do begin mDummy2.Assign(mA); mDummy2.NthPower(i-1); mDummy1.Assign(mN1); mDummy1.MultFromRight(mDummy2); for j := 1 to Order do mN[j, i] := mDummy1[j, 1]; end;

mDummy1.Assign(mN); if not mDummy1.Inverse then

Raise ESingularMatrix.Create('Не могу обратить матрицу N !!!'#10 +

'(не разбрасывайтесь порядками коэффициентов матриц)'); mA.MultFromLeft(mN); mA.MultFromRight(mDummy1);

OutPutMatrixToStrGrd(mA, StringGrid_Anp0);

cvRoots.Dim := Order; for j := 1 to Order do begin cvRoots.Data[j].Re := StrToFloat(StringGrid_Roots.Cells[j, 1]); cvRoots.Data[j].Im := StrToFloat(StringGrid_Roots.Cells[j, 2]); end;

for j := 1 to Order do begin if Odd (j) then K := -1 else K := +1; mKp[Order-Pred(j), 1] := - mA[Order-Pred(j), Order] -

K * SymmetricalFunction(cvRoots, j); end; mKp.MultFromRight(mN);

OutPutMatrixToStrGrd (mKp, StringGrid_Kpp0);

mDummy1.Free; mDummy2.Free; mA.Free; mB.Free; mKp.Free; mM.Free; mN.Free; mN1.Free; end; end;

procedure ComputeFromPage1; var

Order: TOrder; mA, mB, mABKp, mInCond, mKp: TMatrix; mSolutionValues: TMatrix;

LowerLimit, UpperLimit, NumReturn, NumIntervals: Word; begin with Form_Main do begin

Order := SpinEdit_Dim.Value;

mA := TMatrix.Create(Order, Order); mB := TMatrix.Create(1, Order); mKp := TMatrix.Create(Order, 1); mInCond := TMatrix.Create(Order, 1);

LoadMatrixFromStrGrd(mA, StringGrid_Ap1);

LoadMatrixFromStrGrd(mB, StringGrid_Bp1);

LoadMatrixFromStrGrd(mKp, StringGrid_Kpp1);

LoadMatrixFromStrGrd(mInCond, StringGrid_InCond);

mABKp := TMatrix.Create(Order, Order); mABKp.Assign(mB); mABKp.MultFromRight(mKp); mABKp.AddMatrix(mA);

OutPutMatrixToStrGrd(mABKp, StringGrid_ABKpp1);

mB.MultConst(StrToFloat(Edit_U.Text));

with Form_Options do begin

LowerLimit := SpinEdit0.Value;

UpperLimit := SpinEdit1.Value;

NumReturn := SpinEdit2.Value;

NumIntervals := SpinEdit3.Value; end;

mSolutionValues := TMatrix.Create(1, 1);

try

DiffSystemSolve (mA, mB,

LowerLimit, UpperLimit, mInCond,

NumReturn, NumIntervals, mSolutionValues);

OutPutMatrixSolveToStrGrd(mSolutionValues, StringGrid_Solve1);

mSolutionValues.ReSize(1, 1);

DiffSystemSolve (mABKp, mB,

LowerLimit, UpperLimit, mInCond,

NumReturn, NumIntervals, mSolutionValues);

OutPutMatrixSolveToStrGrd(mSolutionValues, StringGrid_Solve2);

except on EO: EOverflow do begin

EO.Message := 'Не буду считать !!!'#10 +

'С уменьшите разброс коэффициентов в матрицах'#10
+

'либо измените опции (уменьшите их pls.)';

Raise; end; end;

mA.Free; mB.Free; mABKp.Free; mInCond.Free; mKp.Free; mSolutionValues.Free; end; end;

procedure ShowChart(NumberOfChart: Byte); var

Order, Serie: TOrder;

NumReturn, Point: Word; mSolutionValues: TMatrix;

procedure SetAdm; const

Divisor = 3.4E+38; var i, j: LongInt;

Greatest, Least: Float; begin

Greatest := mSolutionValues[1, 1];

Least := Greatest; for j := 1 to Order do for i := 1 to NumReturn do begin if mSolutionValues[j, i] > Greatest then Greatest := mSolutionValues[j, i]; if mSolutionValues[j, i] < Least then Least := mSolutionValues[j, i]; end;

Form_Main.ChartFX.Adm[CSA_MAX] := Greatest;

Form_Main.ChartFX.Adm[CSA_MIN] := Least;

Form_Main.ChartFX.Title[CHART_TOPTIT] := 'Y = Y '' * '; end;

begin with Form_Main do begin

Order := SpinEdit_Dim.Value;

NumReturn := Form_Options.SpinEdit2.Value; mSolutionValues := TMatrix.Create(1, 1);

ComputeFromPage1; case NumberOfChart of

1 :begin

LoadMatrixSolveFromStrGrd(mSolutionValues,
StringGrid_Solve1);

SetAdm;

ChartFX.OpenDataEx(Cod_Values, Order, Pred(NumReturn)); for Serie := 1 to Order do begin

ChartFX.SerLeg[Pred(Serie)] := 'X ' + IntToStr(Serie);

ChartFX.ThisSerie := Pred(Serie); for Point := 0 to Pred(NumReturn) do

ChartFX.Value[Point] := mSolutionValues[Serie,
Succ(Point)]; end;

ChartFX.CloseData(Cod_Values);

{

ChartFX.OpenDataEx(Cod_XValues, Order, Pred(NumReturn)); for Serie := 1 to Order do begin

ChartFX.ThisSerie := Pred(Serie); for Point := 0 to Pred(NumReturn) do

ChartFX.XValue[Point] := mSolutionValues[1,
Succ(Point)]; end;

ChartFX.CloseData(Cod_XValues);

} end;

2 :begin

LoadMatrixSolveFromStrGrd(mSolutionValues,
StringGrid_Solve2);

SetAdm;

ChartFX.OpenDataEx(Cod_Values, Order, Pred(NumReturn)); for Serie := 1 to Order do begin

ChartFX.SerLeg[Pred(Serie)] := 'X ' + IntToStr(Serie);

ChartFX.ThisSerie := Pred(Serie); for Point := 0 to Pred(NumReturn) do

ChartFX.Value[Point] := mSolutionValues[Serie,
Succ(Point)]; end;

ChartFX.CloseData(Cod_Values); end; end; mSolutionValues.Free; end; end;

procedure ComputeFromPage2; begin

ComputeFromPage1; end;

procedure ComputeFromPage3; begin case Form_Main.RadioGroupChart.ItemIndex of

0 :ShowChart(1);

1 :ShowChart(2); end; end;

end. unit Matrix;

interface

uses SysUtils;

type

Float = Extended;

EMatrixOperatingError = class (Exception);

const

NearlyZero = 1E-15;

type

TMatrix = class (TObject) private

DataPtr: Pointer;

FCols, FRows: Word; function GetCell (ACol, ARow: Word): Float; procedure SetCell (ACol, ARow: Word; AValue: Float); function GetItem (NumItem: LongInt): Float; procedure SetItem (NumItem: LongInt; AValue: Float); procedure SwitchRows (FirstRow, SecondRow: Word); public constructor Create (NCols, NRows: Word); destructor Destroy; override; procedure Assign (AMatrix: TMatrix); procedure ReSize (NewCols, NewRows: Word); procedure SetNull; procedure SetSingle; procedure SetNegative; procedure AddConst (AConst: Float); procedure AddMatrix (AMatrix: TMatrix); procedure MultConst (MConst: Float); procedure MultFromRight (MMatrix: TMatrix); procedure MultFromLeft (MMatrix: TMatrix); procedure NthPower (Power: Word); procedure Transpose; function Inverse: Boolean; function Determinant: Float; function Rang: Float; property ColCount: Word read FCols; property RowCount: Word read FRows; property Cells [ACol, ARow: Word]: Float read GetCell write SetCell; default; property Items [NumItem: LongInt]: Float read GetItem write SetItem; end;

implementation

uses Windows;

function IncPtr (p: Pointer; i: LongInt): Pointer; asm push EBX mov EBX,EAX add EBX,EDX mov EAX,EBX pop EBX end;

function TMatrix.GetCell (ACol, ARow: Word): Float; var

CellPtr: ^Float; begin

CellPtr := IncPtr(DataPtr, (FRows * Pred(ACol) + Pred(ARow)) *
SizeOf(Float));

Result := CellPtr^; end;

procedure TMatrix.SetCell (ACol, ARow: Word; AValue: Float); var

CellPtr: ^Float; begin

CellPtr := IncPtr(DataPtr, (FRows * Pred(ACol) + Pred(ARow)) *
SizeOf(Float));

CellPtr^ := AValue; end;

function TMatrix.GetItem (NumItem: LongInt): Float; var

CellPtr: ^Float; begin

CellPtr := IncPtr(DataPtr, Pred(NumItem) * SizeOf(Float));

Result := CellPtr^; end;

procedure TMatrix.SetItem (NumItem: LongInt; AValue: Float); var

CellPtr: ^Float; begin

CellPtr := IncPtr(DataPtr, Pred(NumItem) * SizeOf(Float));

CellPtr^ := AValue; end;

procedure TMatrix.SwitchRows (FirstRow, SecondRow: Word); var i: Word;

Buffer: Float; begin for i := 1 to FCols do begin

Buffer := GetCell(i, FirstRow);

SetCell(i, FirstRow, GetCell(i, SecondRow));

SetCell(i, SecondRow, Buffer); end; end;

constructor TMatrix.Create (NCols, NRows: Word); begin inherited Create;

FCols := NCols;

FRows := NRows;

DataPtr := AllocMem(FCols * FRows * SizeOf(Float)); end;

destructor TMatrix.Destroy; begin

FreeMem(DataPtr); inherited Destroy; end;

procedure TMatrix.Assign (AMatrix: TMatrix); var

NewMatrixSize: LongInt; begin

NewMatrixSize := AMatrix.ColCount * AMatrix.RowCount * SizeOf(Float);

ReAllocMem(DataPtr, NewMatrixSize);

CopyMemory(DataPtr, AMatrix.DataPtr, NewMatrixSize);

FCols := AMatrix.ColCount;

FRows := AMatrix.RowCount end;

procedure TMatrix.ReSize (NewCols, NewRows: Word); var

NewMatrixSize: LongInt; begin

NewMatrixSize := NewCols * NewRows * SizeOf(Float);

ReAllocMem(DataPtr, NewMatrixSize);

FCols := NewCols;

FRows := NewRows; end;

procedure TMatrix.SetNull; begin

ZeroMemory (DataPtr, FCols * FRows * SizeOf(Float)); end;

procedure TMatrix.SetSingle; var i: Word; begin if FCols FRows then

Raise EMatrixOperatingError.Create ('Единичная матрица должна быть '+

'квадратной') else begin

SetNull; for i := 1 to FCols do SetCell (i, i, 1); end; end;

procedure TMatrix.SetNegative; var i: LongInt; begin for i := 1 to FCols * FRows do SetItem(i, - GetItem(i)); end;

procedure TMatrix.AddConst (AConst: Float); var i: LongInt; begin for i := 1 to FCols * FRows do SetItem (i, GetItem(i) + AConst); end;

procedure TMatrix.AddMatrix (AMatrix: TMatrix); var i: LongInt; begin for i := 1 to FCols * FRows do SetItem (i, GetItem(i) + AMatrix.Items
[i]); end;

procedure TMatrix.MultConst (MConst: Float); var i: LongInt; begin for i := 1 to FCols * FRows do SetItem (i, GetItem(i) * MConst); end;

procedure TMatrix.MultFromRight (MMatrix: TMatrix); var j, i, k: Word;

DummyRes: Float;

DummyMatrix: TMatrix; begin

DummyMatrix := TMatrix.Create (MMatrix.ColCount, FRows); if FCols MMatrix.RowCount then

Raise EMatrixOperatingError.Create ('Перемножаемые матрицы должны быть '+

'соответствующей размерности') else for i := 1 to FRows do for j := 1 to MMatrix.ColCount do begin

DummyRes := 0; for k := 1 to FCols do

DummyRes := DummyRes + Cells[k, i] * MMatrix[j, k];

DummyMatrix[j, i] := DummyRes; end;

Assign(DummyMatrix);

DummyMatrix.Free; end;

procedure TMatrix.MultFromLeft (MMatrix: TMatrix); var j, i, k: Word;

DummyRes: Float;

DummyMatrix: TMatrix; begin

DummyMatrix := TMatrix.Create (FCols, MMatrix.RowCount); if MMatrix.ColCount FRows then

Raise EMatrixOperatingError.Create ('Перемножаемые матрицы должны быть '+

'соответствующей размерности') else for i := 1 to MMatrix.ColCount do for j := 1 to FCols do begin

DummyRes := 0; for k := 1 to MMatrix.ColCount do

DummyRes := DummyRes + MMatrix[k, i] * Cells[j, k];

DummyMatrix[j, i] := DummyRes; end;

Assign(DummyMatrix);

DummyMatrix.Free; end;

procedure TMatrix.NthPower (Power: Word); var i: Word;

DummyMatrix: TMatrix; begin

DummyMatrix := TMatrix.Create (FCols, FRows);

DummyMatrix.Assign (Self); if FCols FRows then

Raise EMatrixOperatingError.Create ('Возводимая в степень матрица должна '+

'быть квадратной') else case Power of

0 : SetSingle;

1 : begin end; else for i := 2 to Power do MultFromRight (DummyMatrix); end;

DummyMatrix.Free; end;

procedure TMatrix.Transpose; var i, j: Word;

Dummy: Float; begin if FCols FRows then

Raise EMatrixOperatingError.Create ('Транспонируемая матрица должна быть '+

'квадратной') else for i := 1 to FCols do for j := 1 to FRows do if j > i then begin

Dummy := GetCell(j, i);

SetCell(j, i, GetCell(i, j));

SetCell(i, j, Dummy); end end;

function TMatrix.Inverse: Boolean; var

DummyMatrix: TMatrix;

Divisor, Multiplier: Float;

Row, RefRow, NewRow, Term: Word;

Singular: Boolean; begin

Singular := False;

DummyMatrix := TMatrix.Create (FCols, FRows); if (FCols FRows) or (FCols = 0) then

Raise EMatrixOperatingError.Create ('Инвертируемая матрица должна быть '+

'квадратной и ненулевого размера'); if FCols = 1 then if ABS(GetItem(1)) < NearlyZero then Singular := True else DummyMatrix.Items[1] := 1 / GetItem(1); if FCols > 1 then begin

DummyMatrix.SetSingle;

RefRow := 0; repeat

Inc(RefRow); if ABS(Cells[RefRow, RefRow]) < NearlyZero then begin

Singular := TRUE;

NewRow := RefRow; repeat

Inc(NewRow); if ABS(Cells[RefRow, NewRow]) > NearlyZero then begin

SwitchRows(NewRow, RefRow);

DummyMatrix.SwitchRows(NewRow, RefRow);

Singular := False; end; until (not Singular) or (NewRow >= FCols); end; if not Singular then begin

Divisor := Cells[RefRow, RefRow]; for Term := 1 to FCols do begin

SetCell(Term, RefRow, GetCell(Term, RefRow)/Divisor);

DummyMatrix[Term, RefRow] := DummyMatrix[Term,
RefRow]/Divisor; end; for Row := 1 to FCols do if (Row RefRow) and (ABS(Cells[RefRow, Row]) >
NearlyZero) then begin

Multiplier := - Cells[RefRow, Row] / Cells[RefRow,
RefRow]; for Term := 1 to FCols do begin

SetCell(Term, Row, GetCell(Term, Row) +

Multiplier * GetCell(Term,
RefRow));

DummyMatrix[Term, Row] := DummyMatrix[Term, Row] +

Multiplier * DummyMatrix[Term,
RefRow]; end end; end; until Singular or (RefRow >= FCols); end;

Assign(DummyMatrix);

DummyMatrix.Free; if not Singular then Result := True else Result := False; end;

function TMatrix.Determinant: Float; begin

Result := 0; end;

function TMatrix.Rang: Float; begin

Result := 0; end;

end. unit Operates;

interface

uses Matrix, Grids, SysUtils;

const

MaxArraySize = 30;

type

Float = Extended;

TOrder = 1..MaxArraySize;

ESingularMatrix = class (Exception);

type

TComplex = record

Re, Im : Float; end;

TComplexVector = record

Data : array [1..MaxArraySize] of TComplex;

Dim : TOrder; end;

function SymmetricalFunction (Roots: TComplexVector; K: byte): Float; procedure DiffSystemSolve (matrixA, matrixB: TMatrix;

LowerLimit,

UpperLimit: Float;

InitialValues: TMatrix;

NumReturn,

NumIntervals: Word;

SolutionValues: TMatrix);

implementation

function SymmetricalFunction (Roots: TComplexVector; K: byte): Float; var

Z: TComplex;

function SummComplex (FirstNC, SecondNC: TComplex): TComplex; begin

Result.Re := FirstNC.Re + SecondNC.Re;

Result.Im := FirstNC.Im + SecondNC.Im; end;

function MultComplex (FirstNC, SecondNC: TComplex): TComplex; begin

Result.Re := FirstNC.Re * SecondNC.Re - FirstNC.Im * SecondNC.Im;

Result.Im := FirstNC.Re * SecondNC.Im + FirstNC.Im * SecondNC.Re; end;

function DivComplex (FirstNC, SecondNC: TComplex): TComplex; var

Z: Float; begin

Z := Sqr(SecondNC.Re) + Sqr(SecondNC.Im);

Result.Re := (FirstNC.Re * SecondNC.Re + FirstNC.Im * SecondNC.Im) / Z;

Result.Im := (FirstNC.Im * SecondNC.Re - FirstNC.Re * SecondNC.Im) / Z; end;

function CombinationSumm (LowLimit, HighLimit, K: byte): TComplex; var i: byte; begin

Result.Re := 0;

Result.Im := 0; if LowLimit = HighLimit then Result := Roots.Data[LowLimit] else for i := LowLimit to HighLimit - K + 1 do if K = 1 then Result := SummComplex(Result, Roots.Data [i]) else Result := SummComplex(Result,

MultComplex(Roots.Data [i],

CombinationSumm(i + 1,

HighLimit, K-
1)));

end; begin

Z := CombinationSumm(1, Roots.Dim, K);

Result := Z.Re; end;

procedure DiffSystemSolve (matrixA, matrixB: TMatrix;

LowerLimit, UpperLimit: Float;

InitialValues: TMatrix;

NumReturn, NumIntervals: Word;

SolutionValues: TMatrix); type

Ptr = ^Data;

Data = record

Values: TMatrix;

Next: Ptr; end; var

ValuesStack: Ptr;

Spacing, HalfSpacing: Float;

Index, Term: Word;

F1, F2, F3, F4,

CurrentValues,

TempValues: TMatrix;

NumEquations, NumTimeCol: Word;

function TargetALL (matrixA, mayrixB: TMatrix; Values: TMatrix; KRow:
Word): Float; var j: Word; begin try

Result := matrixB.Items[KRow]; for j := 1 to NumEquations do

Result := Result + matrixA[j, KRow] * Values.Items[j]; except on EO: EOverflow do EO.Message := 'Не буду считать !!!'#10 +

'С уменьшите разброс коэффициентов в матрице А'#10 +

'либо измените опции (уменьшите их pls.)'; end; end;

procedure Push (var ValuesStack: Ptr;

CurrentValues: TMatrix); var

NewNode : Ptr; begin

New(NewNode);

NewNode^.Values := TMatrix.Create(NumTimeCol, 1);

NewNode^.Values.Assign(CurrentValues);

NewNode^.Next := ValuesStack;

ValuesStack := NewNode; end; { procedure Push }

procedure Pop (var ValuesStack: Ptr;

CurrentValues: TMatrix); var

OldNode : Ptr; begin

OldNode := ValuesStack;

ValuesStack := OldNode^.Next;

CurrentValues.Assign(OldNode^.Values);

OldNode^.Values.Free;

Dispose(OldNode); end; { procedure Pop }

procedure GetValues(NumReturn, NumIntervals: Word; var ValuesStack: Ptr;

SolutionValues: TMatrix); var

Index, Term: Integer; j: Word;

CurrValues: TMatrix; begin

SolutionValues.ReSize(NumTimeCol, Succ(NumReturn));

CurrValues := TMatrix.Create(NumTimeCol, 1);

Term := NumIntervals; for Index := NumReturn downto 0 do begin

Pop(ValuesStack, CurrValues);

Dec(Term); while (Term / NumIntervals >= Index / NumReturn) and (Term >= 0) do begin

Pop(ValuesStack, CurrValues);

Dec(Term); end; for j := 1 to NumTimeCol do

SolutionValues[j, Succ(Index)] := CurrValues.Items[j]; end;

CurrValues.Free; end; { procedure GetValues }

procedure Step(Spacing: Float; CurrentValues: TMatrix; F: TMatrix); var i : byte; begin for i := 1 to NumEquations do

F.Items[i] := Spacing * TargetALL (matrixA, matrixB, CurrentValues, i); end; { procedure Step }

begin

NumEquations := matrixA.RowCount;

NumTimeCol := Succ(NumEquations);

ValuesStack := nil;

Spacing := (UpperLimit - LowerLimit) / NumIntervals;

CurrentValues := TMatrix.Create(1, 1);

CurrentValues.Assign(InitialValues);

CurrentValues.ReSize(NumTimeCol, 1);

CurrentValues.Items[NumTimeCol] := LowerLimit;

TempValues := TMatrix.Create(NumTimeCol, 1);

F1 := TMatrix.Create(NumTimeCol, 1);

F2 := TMatrix.Create(NumTimeCol, 1);

F3 := TMatrix.Create(NumTimeCol, 1);

F4 := TMatrix.Create(NumTimeCol, 1);

Push(ValuesStack, CurrentValues);

HalfSpacing := Spacing / 2; for Index := 1 to NumIntervals do begin

{ First step - calculate F1 }

Step(Spacing, CurrentValues, F1);

TempValues.Items[NumTimeCol] := CurrentValues.Items[NumTimeCol] +
HalfSpacing; for Term := 1 to NumEquations do

TempValues.Items[Term] := CurrentValues.Items[Term] + 0.5 *
F1.Items[Term];

{ 2nd step - calculate F2 }

Step(Spacing, TempValues, F2); for Term := 1 to NumEquations do

TempValues.Items[Term] := CurrentValues.Items[Term] + 0.5 *
F2.Items[Term];

{ Third step - calculate F3 }

Step(Spacing, TempValues, F3);

TempValues.Items[NumTimeCol] := CurrentValues.Items[NumTimeCol] +
Spacing; for Term := 1 to NumEquations do

TempValues.Items[Term] := CurrentValues.Items[Term] +
F3.Items[Term];

{ Fourth step - calculate F4[1]; first equation }

Step(Spacing, TempValues, F4);

{ Combine F1, F2, F3, and F4 to get }

{ the solution at this mesh point }

CurrentValues.Items[NumTimeCol] := CurrentValues.Items[NumTimeCol]
+ Spacing; for Term := 1 to NumEquations do

CurrentValues.Items[Term] := CurrentValues.Items[Term] +

(F1.Items[Term] + 2 * F2.Items[Term]
+

2 * F3.Items[Term] +
F4.Items[Term]) /6;

Push(ValuesStack, CurrentValues); end;

GetValues(NumReturn, NumIntervals, ValuesStack, SolutionValues);

F1.Free;

F2.Free;

F3.Free;

F4.Free;

CurrentValues.Free;

TempValues.Free; end;

end. unit HelpUnit;

interface

uses

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

StdCtrls, ExtCtrls, Buttons;

type

TForm_Help = class(TForm)

BitBtn1: TBitBtn;

Bevel1: TBevel;

Label1: TLabel;

Label2: TLabel;

Label3: TLabel;

Label4: TLabel;

Label5: TLabel;

Label6: TLabel;

Label7: TLabel; private

{ Private declarations } public

{ Public declarations } end;

var

Form_Help: TForm_Help;

implementation

{$R *.DFM}

end. unit OptsUnit;

interface

uses

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

StdCtrls, Spin, Buttons, ExtCtrls;

type

TForm_Options = class(TForm)

CheckBox_Link: TCheckBox;

SpinEdit1: TSpinEdit;

SpinEdit2: TSpinEdit;

SpinEdit3: TSpinEdit;

Label_UpLimit: TLabel;

Label_PointsNumber: TLabel;

Label_Intervals: TLabel;

Label_1: TLabel;

BitBtn_Ok: TBitBtn;

BitBtn_Cancel: TBitBtn;

SpinEdit0: TSpinEdit;

Label1: TLabel;

Bevel1: TBevel; procedure SpinEdit0Change(Sender: TObject); procedure SpinEdit2Change(Sender: TObject); procedure CheckBox_LinkClick(Sender: TObject); private

{ Private declarations } public

{ Public declarations } end;

var

Form_Options: TForm_Options;

implementation

uses MainUnit, SubUnit;

{$R *.DFM}

procedure TForm_Options.SpinEdit0Change(Sender: TObject); begin

SpinEdit1.MinValue := Succ(SpinEdit0.Value); if SpinEdit1.Value < SpinEdit1.MinValue then SpinEdit1.Value:=
SpinEdit1.MinValue; end;

procedure TForm_Options.SpinEdit2Change(Sender: TObject); begin

SpinEdit3.MinValue := SpinEdit2.Value; if SpinEdit3.Value < SpinEdit3.MinValue then SpinEdit3.Value:=
SpinEdit3.MinValue; end;

procedure TForm_Options.CheckBox_LinkClick(Sender: TObject); begin if CheckBox_Link.State = cbChecked then Form_Main.BindGrids else Form_Main.UnBindGrids end;

end.


мвмв

Наш опрос
Как Вы оцениваете работу нашего сайта?
Отлично
Не помог
Реклама
 
Авторское мнение может не совпадать с мнением редакции портала
Перепечатка материалов без ссылки на наш сайт запрещена