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


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

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

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

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

, (1) – задано,

Где – n-мерный вектор состояния, ,

– начальный вектор состояния,

– скалярное управление,

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

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

Найти управление в функции переменных состояния объекта, т. е.

, (2)

Где– матрица обратной связи, такое, чтобы замкнутая система была устойчивой.

2. Корни характеристического уравнения замкнутой системы

(3)

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

Задание:

1. Разработать алгоритм решения поставленной задачи.

2. Разработать программу решения поставленной задачи с интерактивным экранным интерфейсом в системах BorlandPascal, TurboVision, Delphi – по выбору.

3. Разработать программу решения систем дифференциальных уравнений (1) и (3) с интерактивным экранным интерфейсом.

4. Разработать программу графического построения решений систем (1) и (3) с интерактивным экранным интерфейсом.

Введение

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

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

Соглашения:

– Задаваемый объект управления математически описывается уравнением

, (1)

Где и – матрицы действительных коэффициентов,

– n-мерный вектор состояния

– скалярное управление,

– порядок системы (1).

– Обратная связь по состоянию имеет вид

, (2)

Где– матрица обратной связи.

– Система с введенной обратной связью описывается уравнением

(3)

– Характеристическое уравнение системы (1) имеет вид

(4)

– Характеристическое уравнение системы (3) с задаваемыми (желаемыми) корнями Имеет вид

(5)

Алгоритм:

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

2. Обращаем матрицу , т. е. вычисляем .

Если не существует (т. е. матрица – вырожденная), то прекращаем вычисления: полное управление корнями характеристического уравнения (5) не возможно.

3. Вычисляем матрицу

4. Составляем матрицу

5. Вычисляем матрицу, обратную матрице , т. е.

6. Вычисляем матрицу – матрицу в канонической форме фазовой переменной:

Где – коэффициенты характеристического уравнения (4).

Матрица в канонической форме имеет вид

7. Составляем вектор , элементам которого являются коэффициенты характеристического уравнения (4), т. е. , ,

Где – элементы матрицы .

8. Находим коэффициенты характеристического уравнения (5) (см. пояснения) и составляем из них вектор .

9. Вычисляем вектор .

– искомая матрица обратной связи системы (3), но она вычислена для системы, матрицы которой заданы в канонической форме фазовой переменной ( и ).

10. Для исходной системы (3) матрица обратной связи получается по формуле

Матрица – искомая матрица обратной связи.

Пояснения к алгоритму:

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

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

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

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

Если же желаемое характеристическое уравнение имеет вид

,

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

Если при наличии одного управления нормальные уравнения объекта заданы не в канонической форме (что наиболее вероятно), то, в соответствии с пунктами №1-6 алгоритма, от исходной формы с помощью преобразования Или Нужно перейти к уравнению в указанной канонической форме.

Управление возможно, если выполняется условие полной управляемости (ранг матрицы управляемости M должен быть равен n ). В алгоритме об управляемости системы судится по существованию матрицы : если она существует, то ранг матрицы равен ее порядку (n ). Для объекта управления с единственным управлением матрица оказывается также единственной.

Для нахождения коэффициентов характеристического уравнения (5), в работе используется соотношения между корнями и коэффициентами линейного алгебраического уравнения степени n :

, (k = 1, 2, … , n )

Где многочлены – элементарные симметрические функции, определяемые следующим образом:

,

,

,

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

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

Текст программной реализации приведен в ПРИЛОЖЕНИИ №1. Вот несколько кратких пояснений.

– Программа написана на языке ObjectPascal при помощи средств 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.



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