У вас вопросы?
У нас ответы:) SamZan.net

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

Работа добавлена на сайт samzan.net:

Поможем написать учебную работу

Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.

Предоплата всего

от 25%

Подписываем

договор

Выберите тип работы:

Скидка 25% при заказе до 28.12.2024

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

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

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

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

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

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

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

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

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

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

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

,               (2)

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

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

          (3)

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

Задание:

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

2. Разработать программу решения поставленной задачи с интерактивным экранным интерфейсом в системах Borland Pascal, Turbo Vision, 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. Вот несколько кратких пояснений.

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




1. ОКНО В МИР РЕБЕНКА МОДЕЛЬ ПСИХОЛОГИЧЕСКОЙ ПОМОЩИ СЕМЬЕ В
2. Я хочу сегодня ввести всех в курс кто сегодня пришел вопервых здравствуйте мои дорогие коллеги.html
3. Профессиональные вредности и отравления
4. реферату- Аскетизм у релігійному житті Стародавнього РимуРозділ- Релігія Аскетизм у релігійному житті Стар
5. Надзор и контроль в области трудовых отношений
6. тема и ее уровни Принципы организации БС БС ~ это основанная на экон
7. Курсовая работа- Психологический портрет врача
8. 1] СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ И ЛИТЕРАТУРЫ [6] Подготовка дипломной работы к защите и защита
9. Технологические процессы технического обслуживания автомобильного транспорта
10. Право на жизнь, свободу и личную неприкосновенность
11. Курсовой проект по учебной дисциплине
12. Программа развития Национального исследовательского университета ~ Высшей школы экономики НИУ ВШЭ на пер
13. Расчет кривошипного механизма
14. Тема 1.1.1. 1. Купляпродажа
15. Разработка в педагогике проблемы целей воспитания
16. реферат дисертації на здобуття наукового ступеня доктора історичних наук.
17. Социология управления
18. Реферат- Автоматизированное проектирование СБИС на базовых матричных кристаллах
19. Понятие деятельности в социальной теории
20. Наука, библия и моррисианство