unit InverseMtx;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Basic2, StdCtrls, ExtCtrls, ComCtrls, MtxVec, Grids, Buttons;

type
  TInvMtx = class(TBasicForm2)
    TrackBar1: TTrackBar;
    Label1: TLabel;
    Label2: TLabel;
    StringGrid1: TStringGrid;
    Button1: TBitBtn;
    Button2: TBitBtn;
    Button3: TButton;
    Label3: TLabel;
    StringGrid2: TStringGrid;
    Label4: TLabel;
    procedure TrackBar1Change(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure StringGrid1SetEditText(Sender: TObject; ACol, ARow: Integer;
      const Value: String);
    procedure FormDestroy(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    DimMtx : Integer;
    A,B, C: TMtx;
    procedure bthHelpClick(Sender: TObject);
    { Private declarations }
  public
    { Public declarations }
  end;

var
  InvMtx: TInvMtx;

implementation

{$R *.DFM}

Uses MtxVecEdit;

const INVHELP = 4890;

procedure TInvMtx.bthHelpClick(Sender: TObject);
begin
     Application.HelpContext(INVHELP);
end;

procedure TInvMtx.TrackBar1Change(Sender: TObject);
begin
  DimMtx := TTrackBar(Sender).Position;
  Label2.Caption := IntToStr(DimMtx);
  Button2.Enabled := false;
  Button3.Enabled := false;
end;

procedure TInvMtx.FormCreate(Sender: TObject);
begin
  inherited;
  With RichEdit1.Lines, RichEdit1 do
  begin
    Clear;
    Add('Calculating the inverse matrix is a peace of '
      + 'cake. It can be done with just one function call :');
    Add('');
    SelAttributes.Name := 'Courier New';
    Add('A.Inv;');
    Add('');
    Add('The Inv method optionally accepts the matrix type '
      + 'parameter. Depending of matrix type (symmetric, '
      + 'triangular, etc..)  optimized methods will be used '
      + 'to calculate the inverse matrix.');
  end;
  CreateIt(A,B,C);
  TrackBar1Change(TrackBar1);
  with TButton(Self.Owner.FindComponent('btnHelp')) do
  begin
       OnClick := bthHelpClick;
       Enabled := true;
  end;
  Button1Click(Self);
end;

procedure TInvMtx.Button1Click(Sender: TObject);
begin
  A.Size(DimMtx,DimMtx);
  { Resize StringGrid1 to A size}
  StringGrid1.RowCount := DimMtx;
  StringGrid1.ColCount := DimMtx;
  StringGrid2.RowCount := DimMtx;
  StringGrid2.ColCount := DimMtx;
  A.RandUniform(-5,5);
  {Write A to StringGrid1 }
  A.ValuesToGrid(StringGrid1,0,0,'0.0000',false);
  Button2.Enabled := true;
  Button3.Enabled := false;
end;

procedure TInvMtx.Button2Click(Sender: TObject);
begin
  { resize B to match the size of A }
  B.Size(A);
  { copy values for StringGrid1 }
  B.GridToValues(StringGrid1,B.Complex,false);
  { calculate the inverse }
  B.AutoMtxType := true;
  B.Inv;
  {show the inverse matrix in StringGrid1 }
  B.ValuesToGrid(StringGrid2,0,0,'0.0000',false);
  Button3.Enabled := true;
end;

procedure TInvMtx.StringGrid1SetEditText(Sender: TObject; ACol,
  ARow: Integer; const Value: String);
begin
  try
     StrToFloat(Value);
  except
  end;
end;

procedure TInvMtx.FormDestroy(Sender: TObject);
begin
  FreeIt(A,B,C);
  TButton(Self.Owner.FindComponent('btnHelp')).OnClick := nil;
  inherited;
end;

procedure TInvMtx.Button3Click(Sender: TObject);
begin
  C.Mul(A,B);
  ViewValues(C,'A*A-1 = ?',true);
end;

initialization
   RegisterClass(TInvMtx);

end.
