unit GraphUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, Spin, StdCtrls,MaticeUnit,Math, Vcl.Buttons;

type
  TGraphForm = class(TForm)
    Image1: TImage;
    SpinButton1: TSpinButton;
    Edit1: TEdit;
    SpinButton5: TSpinButton;
    Edit2: TEdit;
    SpinButton2: TSpinButton;
    Edit3: TEdit;
    SpinButton3: TSpinButton;
    Edit4: TEdit;
    BitBtn1: TBitBtn;
    Button1: TButton;
    Edit5: TEdit;
    SpinButton4: TSpinButton;
    SpeedButton1: TSpeedButton;
    Label1: TLabel;
    Button2: TButton;
    Panel1: TPanel;
    Button3: TButton;
    constructor Create(Prumer: TMatice); overload;

    procedure Body;
    procedure Histogram;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure SpinButton1UpClick(Sender: TObject);
    procedure SpinButton1DownClick(Sender: TObject);
    procedure SpinButton5DownClick(Sender: TObject);
    procedure SpinButton5UpClick(Sender: TObject);
    procedure SpinButton2DownClick(Sender: TObject);
    procedure SpinButton2UpClick(Sender: TObject);
    procedure SpinButton3DownClick(Sender: TObject);
    procedure SpinButton4UpClick(Sender: TObject);
    procedure KresliFunkci(a, b, c, d, e: Double; y: TMatice);
    procedure FormCreate(Sender: TObject);
    procedure Edit1Change(Sender: TObject);
    procedure KresliOsy;
    procedure NelderMead(a, b, c, d, e: Double; x, y: TMatice);
    procedure Gradient(a, b, c, d, e: Double; x, y: TMatice);
    procedure Newton(a, b, c, d, e: DOuble; x, y: TMatice);
    procedure Button1Click(Sender: TObject); //metoda pro zjištění param, a,b,c,d
    function UcelovaFunkce(a, b, c, d, e: Double; x, y: TMatice):Double;
    procedure SpinButton4DownClick(Sender: TObject);
    procedure SpinButton3UpClick(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
    moc: Double;
    PrumerneHue: TMatice;
    HistoMat: TMatice;
    bHisto: Boolean;
  public
    { Public declarations }
    constructor Create (Prumer, HistoMatice: TMatice); overload;
  end;

const dc = 0.01;
  epsilon1 = 0.1;
  epsilon2 = 1E-10;
  h = 0.001;
var
  Pos0X, Pos0Y: Integer;
  ScaleX, ScaleY: Double;
  GraphForm: TGraphForm;
  function GetX(I:Integer):Double; //Vraci x-ovou souřadnici puvodni ze zobrazene
  function GetY(J:Integer):Double; //Vraci y-ovou souřadnici puvodni ze zobrazene
  function GetI(X:Double):Integer; //Vraci x-ovou souřadnici zobrazenou
  function GetJ(Y:Double):Integer; //Vraci y-ovou souřadnici zobrazenou
  function Maximum6(a, b, c, d, e, f: Double): Double;
  function Minimum6(a, b, c, d, e, f: Double): Double;
  function Minimum4(a, b, c, d: Double): Double;
  function Norma(g: Array of Double): Double;
  function TransfX(X: Double): Double; //Transformace x-ové souřadnice pro lepší výpočet funkce
  function TransfY(Y: Double): Double; //Transformace y-ové souřadnice pro lepší výpočet funkce
  function InvTransfX(X: Double): Double; //Transformace x-ové souřadnice pro lepší výpočet funkce
  function InvTransfY(Y: Double): Double; //Transformace y-ové souřadnice pro lepší výpočet funkce
  function Funkce(a, b, c, d, e, x: Double): Double;
  function InvFunkce(a, b, c, d, e, y: Double): Double;

implementation

uses DateUtils;

{$R *.dfm}
function Funkce(a, b, c, d, e, x: Double): Double;
begin
  Result := c * Power((ArcTan(a * x + b)/Pi+0.5), e) + d;
end;

function InvFunkce(a, b, c, d, e, y: Double): Double;
begin
  Result := ((Tan((Power((y - d)/c, 1/e) - 0.5)*Pi)) - b)/a;
end;

function Norma(g: Array of Double): Double;
var
  i: Integer;
begin
  Result := 0;
  for i := Low(g) to High(g) do
    Result := Result + sqr(g[i]);
  Result := sqrt(Result);
end;

function GetX(I:Integer):Double;
begin

end;

function GetY(J:Integer):Double;
begin

end;

function GetI(X:Double):Integer;
begin
  Result := Round(Pos0X + ScaleX*X*3);
end;

function GetJ(Y:Double):Integer;
begin
  Result := Round(Pos0Y - ScaleY*Y);
end;

function TransfX(X: Double): Double;
begin
  Result := (X - 20)/3;
end;

function TransfY(Y: Double): Double;
begin
  Result := Y/30;
end;

function InvTransfX(X: Double): Double;
begin
  Result := (X*3) + 20;
end;

function InvTransfY(Y: Double): Double;
begin
  Result := Y * 30;
end;

function Maximum6(a, b, c, d, e, f: Double): Double;
var MaxCislo: Double;
begin
  MaxCislo := a;
  if MaxCislo < b then MaxCislo := b;
  if MaxCislo < c then MaxCislo := c;
  if MaxCislo < d then MaxCislo := d;
  if MaxCislo < e then MaxCislo := e;
  if MaxCislo < f then MaxCislo := f;

  Result := MaxCislo;
end;

function Minimum6(a, b, c, d, e, f: Double): Double;
var MinCislo: Double;
begin
  MinCislo := a;
  if MinCislo > b then MinCislo := b;
  if MinCislo > c then MinCislo := c;
  if MinCislo > d then MinCislo := d;
  if MinCislo > e then MinCislo := e;
  if MinCislo > f then MinCislo := f;
  
  Result := MinCislo;
end;

function Minimum4(a, b, c, d: Double): Double;
var MinCislo: Double;
begin
  MinCislo := a;
  if MinCislo > b then MinCislo := b;
  if MinCislo > c then MinCislo := c;
  if MinCislo > d then MinCislo := d;
  Result := MinCislo;
end;

procedure TGraphForm.Body;
var i,j:integer;
    ce,dc:double;
    maxi: integer;
begin
  j:=1;
  ce := 0;
  Image1.Canvas.Pen.Color:=clBlue;
  Image1.Canvas.Brush.Color:= clWhite;
  //Image1.Canvas.MoveTo(15,Image1.Height-20);
  for i := 0 to PrumerneHue.m-1 do
    for j := 0 to PrumerneHue.n-1 do begin
      Image1.Canvas.MoveTo(GetI(TransfX(i+1)) - 5, GetJ(PrumerneHue.elem[i,j]));
      Image1.Canvas.LineTo(GetI(TransfX(i+1)) + 6, GetJ(PrumerneHue.elem[i,j]));
      Image1.Canvas.MoveTo(GetI(TransfX(i+1)), GetJ(PrumerneHue.elem[i,j]) - 5);
      Image1.Canvas.LineTo(GetI(TransfX(i+1)), GetJ(PrumerneHue.elem[i,j]) + 6);
    end;
//  while (j<=PrumerneHue.m) do begin
//    Image1.Canvas.MoveTo(GetI(TransfX(j)) - 5, GetJ(PrumerneHue.elem[j - 1,0]));
//    Image1.Canvas.LineTo(GetI(TransfX(j)) + 6, GetJ(PrumerneHue.elem[j - 1,0]));
//    Image1.Canvas.MoveTo(GetI(TransfX(j)), GetJ(PrumerneHue.elem[j - 1,0]) - 5);
//    Image1.Canvas.LineTo(GetI(TransfX(j)), GetJ(PrumerneHue.elem[j - 1,0]) + 6);
//    Inc(j);
//  end;
  for i:=0 to PrumerneHue.m do
    Image1.Canvas.TextOut(GetI(TransfX(i)) - 3, GetJ(0) + 1, IntToStr(i));
  maxi := Round(InvTransfY(PrumerneHue.Maximum));
  j := 5;
  while (j <= maxi+10) do begin
    Image1.Canvas.TextOut(1, GetJ(TransfY(j)), FloatToStr(j));
    Image1.Canvas.MoveTo(10, GetJ(TransfY(j)));
    Image1.Canvas.LineTo(20, GetJ(TransfY(j)));
    j := j + 5;
  end;
  KresliFunkci(StrToFloat(Edit1.Text), StrToFloat(Edit2.Text), StrToFloat(Edit3.Text), StrToFloat(Edit4.Text), STrToFloat(Edit5.Text), PrumerneHue);
  Image1.Refresh;
end;

procedure TGraphForm.FormActivate(Sender: TObject);
var
  i: Integer;
begin
  if bHisto then begin
    for i:= 0 to Panel1.ControlCount - 1 do begin
      if Panel1.Controls[i] is TEdit then
        Panel1.Controls[i].Enabled := False
      else if (Panel1.Controls[i] is TSpinButton) or (Panel1.Controls[i] is TButton) or (Panel1.Controls[i] is TSpeedButton) then
        Panel1.Controls[i].Visible := False;
    end;
    Image1.Picture := nil;
    Histogram;
    Body;
  end else begin
    Image1.Picture := nil;
    Body;
  end;
end;

procedure TGraphForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action:=caFree;
end;

procedure TGraphForm.SpinButton1UpClick(Sender: TObject);
begin
  Edit1.Text:=FloatToStr(StrToFloat(Edit1.Text)+1);
  Image1.Picture := nil;
  Body;
end;

procedure TGraphForm.SpinButton1DownClick(Sender: TObject);
begin
    Edit1.Text:=FloatToStr(StrToFloat(Edit1.Text)-1);
    Image1.Picture := nil;
    Body;
end;

procedure TGraphForm.SpinButton5DownClick(Sender: TObject);
begin
  Edit5.Text:=FloatToStr(StrToFloat(Edit5.Text)-0.1);
  Image1.Picture := nil;
  Body;
end;

procedure TGraphForm.SpinButton5UpClick(Sender: TObject);
begin
  Edit5.Text:=FloatToStr(StrToFloat(Edit5.Text)+0.1);
  Image1.Picture := nil;
  Body;
end;

function TGraphForm.UcelovaFunkce(a, b, c, d, e: Double; x, y: TMatice): Double;
var
  i: Integer;
  j: Integer;
begin
  Result := 0;
  for i := 0 to y.m - 1 do
    Result := Result + sqr(y.elem[i, 0] - Funkce(a, b, c, d, e, x.elem[i, 0]));
end;

procedure TGraphForm.SpinButton2DownClick(Sender: TObject);
begin
  Edit2.Text:=FloatToStr(StrToFloat(Edit2.Text)-1);
  Image1.Picture := nil;
  Body;
end;

procedure TGraphForm.SpinButton2UpClick(Sender: TObject);
begin
  Edit2.Text:=FloatToStr(StrToFloat(Edit2.Text)+1);
  Image1.Picture := nil;
  Body;
end;

procedure TGraphForm.SpinButton3DownClick(Sender: TObject);
begin
  Edit3.Text:=FloatToStr(StrToFloat(Edit3.Text)-1);
  Image1.Picture := nil;
  Body;
end;

procedure TGraphForm.SpinButton3UpClick(Sender: TObject);
begin
  Edit3.Text:=FloatToStr(StrToFloat(Edit3.Text)+1);
  Image1.Picture := nil;
  Body;
end;

procedure TGraphForm.SpinButton4UpClick(Sender: TObject);
begin
  Edit4.Text:=FloatToStr(StrToFloat(Edit4.Text)+1);
  Image1.Picture := nil;
  Body;
end;

procedure TGraphForm.SpinButton4DownClick(Sender: TObject);
begin
  Edit4.Text:=FloatToStr(StrToFloat(Edit4.Text)-1);
  Image1.Picture := nil;
  Body;
end;

procedure TGraphForm.KresliFunkci(a, b, c, d, e: Double; y: TMatice);
var i, j:integer;
    ce,apar,bpar,cpar,dpar:double;
begin
  KresliOsy;
  Image1.Canvas.Pen.Color := clRed;
  ce:=-y.m;
  Image1.Canvas.MoveTo(GetI(ce),GetJ(Funkce(a, b, c, d, e, ce)));
  while (ce<=y.m) do begin
    ce:=ce+dc;
    Image1.Canvas.LineTo(GetI(ce), GetJ(Funkce(a, b, c, d, e, ce)));
  end;
end;

procedure TGraphForm.KresliOsy;
begin
  Image1.Canvas.Pen.Color := clBlack;
  Image1.Canvas.MoveTo(0, Pos0Y);
  Image1.Canvas.LineTo(Image1.Width - 1, Image1.Height - 20);
  Image1.Canvas.MoveTo(15, 0);
  Image1.Canvas.LineTo(15, Image1.Height - 1);
  Image1.Canvas.TextOut(15 - 3, Image1.Height - 20 + 1, '0');
  Image1.Repaint;
end;

procedure TGraphForm.NelderMead(a, b, c, d, e: Double; x, y: TMatice);
var
  f: Array[1..6] of Double;
  i, j, k, worst: Integer;
  SBody: Array[1..6,1..5] of Double;
  PBody: Array[1..4,1..5] of Double;
  fW, fB, nas, fNew, Rozdil, RozdilPred: Double;
  W, T, SmerVec, fP: Array[1..5] of Double;
  Graf: TGraphForm;
  mr: TModalResult;
  delta: Double;
const
  nasobky: Array[1..4] of Double = (0.5, 1.5, 2, 3);
begin
  SpeedButton1.Down := True;
  fW := 0; fNew := 0;
  for i := 1 to 4 do
    for j := 1 to 4 do
      PBody[i, j] := 0;
  f[1] := 0; f[2] := 0; f[3] := 0; f[4] := 0; f[5] := 0; f[6]:= 0;
  delta := 0.05;
  SBody[1,1] := a; SBody[1,2] := b; SBody[1,3] := c; SBody[1,4] := d; SBody[1,5] := e;
  SBody[2,1] := a + delta; SBody[2,2] := b; SBody[2,3] := c; SBody[2,4] := d; SBody[2,5] := e;
  SBody[3,1] := a; SBody[3,2] := b + delta; SBody[3,3] := c; SBody[3,4] := d; SBody[3,5] := e;
  SBody[4,1] := a; SBody[4,2] := b; SBody[4,3] := c + delta; SBody[4,4] := d; SBody[4,5] := e;
  SBody[5,1] := a; SBody[5,2] := b; SBody[5,3] := c; SBody[5,4] := d + delta; SBody[5,5] := e;
  SBody[6,1] := a; SBody[6,2] := b; SBody[6,3] := c; SBody[6,4] := d; SBody[6,5] := e+ delta;
  for j := 1 to 6 do
    f[j] := UcelovaFunkce(SBody[j,1], SBody[j,2], SBody[j,3], SBody[j,4], SBody[j,5], x, y);
  Rozdil := 100;
  RozdilPred := 1000;
  k := 0;
  while (abs(RozdilPred - Rozdil) > epsilon2) and SpeedButton1.Down do begin
    fW := Maximum6(f[1],f[2],f[3],f[4],f[5], f[6]);
    for i := 1 to 6 do begin
      if fW = f[i] then begin
        for j := 1 to 5 do begin
          W[j] := SBody[i,j];
          T[j] := 0;
        end;
        worst := i;
        BREAK;
      end;
    end;
    for i := 1 to 5 do begin
      for j := 1 to 6 do begin
        if j <> worst then begin
          T[i] := T[i] + SBody[j, i];
        end;
      end;
      T[i] := T[i]/4;
      SmerVec[i] := T[i] - W[i];
    end;

    i := 1;
    for nas in nasobky do begin
      fP[i] := 0;
      for j := 1 to 5 do begin
        PBody[i, j] := W[j] + (smerVec[j] * nas);
      end;
      Inc(i);
    end;
    for j := 0 to 5 do
      fP[j] := UcelovaFunkce(PBody[j,1], PBody[j,2], PBody[j,3], PBody[j,4], PBody[j,5], x, y);
    fNew := Minimum4(fP[1],fP[2],fP[3],fP[4]);
    for i := 1 to 4 do begin
      if fNew = fP[i] then begin
        for j := 1 to 5 do begin
          SBody[worst,j] := PBody[i,j];
        end;
        f[worst] := fNew;
        BREAK;
      end;
    end;
    f[1] := 0; f[2] := 0; f[3] := 0; f[4] := 0; f[5] := 0;
    for j := 1 to 6 do
      f[j] := UcelovaFunkce(SBody[j,1], SBody[j,2], SBody[j,3], SBody[j,4], SBody[j,5], x, y);
    fB := Minimum6(f[1],f[2],f[3],f[4],f[5],f[6]);
    for i := 1 to 5 do begin
      if fB = f[i] then begin
        a := SBody[i,1];
        b := SBody[i,2];
        c := SBody[i,3];
        d := SBody[i,4];
        e := SBody[i,5];
        BREAK;
      end;
    end;
    Label1.Caption := FloatToStr(fB);
    Edit1.Text := FloatToStr(a);
    Edit2.Text := FloatToStr(b);
    Edit3.Text := FloatToStr(c);
    Edit4.Text := FloatToStr(d);
    Edit5.Text := FloatToStr(e);
    Image1.Picture := nil;
    Body;
    Application.ProcessMessages;
    RozdilPred := Rozdil;
    Rozdil := abs(fW - fB);
    Inc(k);
  end; //while
  ShowMessage(IntToStr(k) + #13#10 + FloatToStr(RozdilPred-Rozdil));
  SpeedButton1.Down := False;
end;

procedure TGraphForm.Newton(a, b, c, d, e: DOuble; x, y: TMatice);
var
  fk, xmin,
  aN, bN, cN, dN, eN: Double;
  Hes, g, dk: TMatice;
  ge:Array[1..5] of Double;
  i, k: Integer;
begin
  SpeedButton1.Down := True;
  Hes := TMatice.Create(5, 5);
  g := TMatice.Create(5, 1);
  dk := TMatice.Create(5, 1);
  g.elem[0, 0] := (-1)*(UcelovaFunkce(a + h, b, c, d, e, x, y)-UcelovaFunkce(a - h, b, c, d, e, x, y))/(2*h);
  g.elem[1, 0] := (-1)*(UcelovaFunkce(a, b + h, c, d, e, x, y)-UcelovaFunkce(a, b - h, c, d, e, x, y))/(2*h);
  g.elem[2, 0] := (-1)*(UcelovaFunkce(a, b, c + h, d, e, x, y)-UcelovaFunkce(a, b, c - h, d, e, x, y))/(2*h);
  g.elem[3, 0] := (-1)*(UcelovaFunkce(a, b, c, d + h, e, x, y)-UcelovaFunkce(a, b, c, d - h, e, x, y))/(2*h);
  g.elem[4, 0] := (-1)*(UcelovaFunkce(a, b, c, d, e + h, x, y)-UcelovaFunkce(a, b, c, d, e - h, x, y))/(2*h);

  Hes.elem[0, 0] := (UcelovaFunkce(a + h, b, c, d, e, x, y)-2*UcelovaFunkce(a, b, c, d, e, x, y)+UcelovaFunkce(a - h, b, c, d, e, x, y))/(h*h);
  Hes.elem[0, 1] := (UcelovaFunkce(a + h, b, c, d, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a+h, b-h, c, d, e, x, y)+UcelovaFunkce(a, b-h, c, d, e, x, y))/(h*h);
  Hes.elem[0, 2] := (UcelovaFunkce(a + h, b, c, d, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a+h, b, c-h, d, e, x, y)+UcelovaFunkce(a, b, c-h, d, e, x, y))/(h*h);
  Hes.elem[0, 3] := (UcelovaFunkce(a + h, b, c, d, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a+h, b, c, d-h, e, x, y)+UcelovaFunkce(a, b, c, d-h, e, x, y))/(h*h);
  Hes.elem[0, 4] := (UcelovaFunkce(a + h, b, c, d, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a+h, b, c, d, e-h, x, y)+UcelovaFunkce(a, b, c, d, e-h, x, y))/(h*h);
  Hes.elem[1, 0] := (UcelovaFunkce(a, b+h, c, d, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a-h, b+h, c, d, e, x, y)+UcelovaFunkce(a-h, b, c, d, e, x, y))/(h*h);
  Hes.elem[1, 1] := (UcelovaFunkce(a, b+h, c, d, e, x, y)-2*UcelovaFunkce(a, b, c, d, e, x, y)+UcelovaFunkce(a, b - h, c, d, e, x, y))/(h*h);
  Hes.elem[1, 2] := (UcelovaFunkce(a, b+h, c, d, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a, b+h, c-h, d, e, x, y)+UcelovaFunkce(a, b, c-h, d, e, x, y))/(h*h);
  Hes.elem[1, 3] := (UcelovaFunkce(a, b+h, c, d, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a, b+h, c, d-h, e, x, y)+UcelovaFunkce(a, b, c, d-h, e, x, y))/(h*h);
  Hes.elem[1, 4] := (UcelovaFunkce(a, b+h, c, d, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a, b+h, c, d, e-h, x, y)+UcelovaFunkce(a, b, c, d, e-h, x, y))/(h*h);
  Hes.elem[2, 0] := (UcelovaFunkce(a, b, c+h, d, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a-h, b, c+h, d, e, x, y)+UcelovaFunkce(a-h, b, c, d, e, x, y))/(h*h);
  Hes.elem[2, 1] := (UcelovaFunkce(a, b, c+h, d, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a, b-h, c+h, d, e, x, y)+UcelovaFunkce(a, b-h, c, d, e, x, y))/(h*h);
  Hes.elem[2, 2] := (UcelovaFunkce(a, b, c+h, d, e, x, y)-2*UcelovaFunkce(a, b, c, d, e, x, y)+UcelovaFunkce(a, b, c-h, d, e, x, y))/(h*h);
  Hes.elem[2, 3] := (UcelovaFunkce(a, b, c+h, d, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a, b, c+h, d-h, e, x, y)+UcelovaFunkce(a, b, c, d-h, e, x, y))/(h*h);
  Hes.elem[2, 4] := (UcelovaFunkce(a, b, c+h, d, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a, b, c+h, d, e-h, x, y)+UcelovaFunkce(a, b, c, d, e-h, x, y))/(h*h);
  Hes.elem[3, 0] := (UcelovaFunkce(a, b, c, d+h, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a-h, b, c, d+h, e, x, y)+UcelovaFunkce(a-h, b, c, d, e, x, y))/(h*h);
  Hes.elem[3, 1] := (UcelovaFunkce(a, b, c, d+h, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a, b-h, c, d+h, e, x, y)+UcelovaFunkce(a, b-h, c, d, e, x, y))/(h*h);
  Hes.elem[3, 2] := (UcelovaFunkce(a, b, c, d+h, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a, b, c-h, d+h, e, x, y)+UcelovaFunkce(a, b, c-h, d, e, x, y))/(h*h);
  Hes.elem[3, 3] := (UcelovaFunkce(a, b, c, d + h, e, x, y)-2*UcelovaFunkce(a, b, c, d, e, x, y)+UcelovaFunkce(a, b, c, d-h, e, x, y))/(h*h);
  Hes.elem[3, 4] := (UcelovaFunkce(a, b, c, d+h, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a, b, c, d+h, e-h, x, y)+UcelovaFunkce(a, b, c, d, e-h, x, y))/(h*h);
  Hes.elem[4, 0] := (UcelovaFunkce(a, b, c, d, e+h, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a-h, b, c, d, e+h, x, y)+UcelovaFunkce(a-h, b, c, d, e, x, y))/(h*h);
  Hes.elem[4, 1] := (UcelovaFunkce(a, b, c, d, e+h, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a, b-h, c, d, e+h, x, y)+UcelovaFunkce(a, b-h, c, d, e, x, y))/(h*h);
  Hes.elem[4, 2] := (UcelovaFunkce(a, b, c, d, e+h, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a, b, c-h, d, e+h, x, y)+UcelovaFunkce(a, b, c-h, d, e, x, y))/(h*h);
  Hes.elem[4, 3] := (UcelovaFunkce(a, b, c, d, e+h, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a, b, c, d-h, e+h, x, y)+UcelovaFunkce(a, b, c, d-h, e, x, y))/(h*h);
  Hes.elem[4, 4] := (UcelovaFunkce(a, b, c, d, e+h, x, y)-2*UcelovaFunkce(a, b, c, d, e, x, y)+UcelovaFunkce(a, b, c, d, e-h, x, y))/(h*h);

  for i := 0 to 4 do
    ge[i+1]:= g.elem[i, 0];

  k := 0;
  while (Norma(ge) >= epsilon2) and SpeedButton1.Down do begin

    fk := UcelovaFunkce(a, b, c, d, e, x, y);
    Label1.Caption := FloatToStr(fk);

    dk := Hes.GEM(g);

    a := a + dk.elem[0, 0];
    b := b + dk.elem[1, 0];
    c := c + dk.elem[2, 0];
    d := d + dk.elem[3, 0];
    e := e + dk.elem[4, 0];

    g.elem[0, 0] := -(UcelovaFunkce(a + h, b, c, d, e, x, y)-UcelovaFunkce(a - h, b, c, d, e, x, y))/(2*h);
    g.elem[1, 0] := -(UcelovaFunkce(a, b + h, c, d, e, x, y)-UcelovaFunkce(a, b - h, c, d, e, x, y))/(2*h);
    g.elem[2, 0] := -(UcelovaFunkce(a, b, c + h, d, e, x, y)-UcelovaFunkce(a, b, c - h, d, e, x, y))/(2*h);
    g.elem[3, 0] := -(UcelovaFunkce(a, b, c, d + h, e, x, y)-UcelovaFunkce(a, b, c, d - h, e, x, y))/(2*h);
    g.elem[4, 0] := -(UcelovaFunkce(a, b, c, d, e + h, x, y)-UcelovaFunkce(a, b, c, d, e - h, x, y))/(2*h);

    Hes.elem[0, 0] := (UcelovaFunkce(a + h, b, c, d, e, x, y)-2*UcelovaFunkce(a, b, c, d, e, x, y)+UcelovaFunkce(a - h, b, c, d, e, x, y))/(h*h);
    Hes.elem[0, 1] := (UcelovaFunkce(a + h, b, c, d, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a+h, b-h, c, d, e, x, y)+UcelovaFunkce(a, b-h, c, d, e, x, y))/(h*h);
    Hes.elem[0, 2] := (UcelovaFunkce(a + h, b, c, d, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a+h, b, c-h, d, e, x, y)+UcelovaFunkce(a, b, c-h, d, e, x, y))/(h*h);
    Hes.elem[0, 3] := (UcelovaFunkce(a + h, b, c, d, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a+h, b, c, d-h, e, x, y)+UcelovaFunkce(a, b, c, d-h, e, x, y))/(h*h);
    Hes.elem[0, 4] := (UcelovaFunkce(a + h, b, c, d, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a+h, b, c, d, e-h, x, y)+UcelovaFunkce(a, b, c, d, e-h, x, y))/(h*h);
    Hes.elem[1, 0] := (UcelovaFunkce(a, b+h, c, d, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a-h, b+h, c, d, e, x, y)+UcelovaFunkce(a-h, b, c, d, e, x, y))/(h*h);
    Hes.elem[1, 1] := (UcelovaFunkce(a, b+h, c, d, e, x, y)-2*UcelovaFunkce(a, b, c, d, e, x, y)+UcelovaFunkce(a, b - h, c, d, e, x, y))/(h*h);
    Hes.elem[1, 2] := (UcelovaFunkce(a, b+h, c, d, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a, b+h, c-h, d, e, x, y)+UcelovaFunkce(a, b, c-h, d, e, x, y))/(h*h);
    Hes.elem[1, 3] := (UcelovaFunkce(a, b+h, c, d, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a, b+h, c, d-h, e, x, y)+UcelovaFunkce(a, b, c, d-h, e, x, y))/(h*h);
    Hes.elem[1, 4] := (UcelovaFunkce(a, b+h, c, d, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a, b+h, c, d, e-h, x, y)+UcelovaFunkce(a, b, c, d, e-h, x, y))/(h*h);
    Hes.elem[2, 0] := (UcelovaFunkce(a, b, c+h, d, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a-h, b, c+h, d, e, x, y)+UcelovaFunkce(a-h, b, c, d, e, x, y))/(h*h);
    Hes.elem[2, 1] := (UcelovaFunkce(a, b, c+h, d, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a, b-h, c+h, d, e, x, y)+UcelovaFunkce(a, b-h, c, d, e, x, y))/(h*h);
    Hes.elem[2, 2] := (UcelovaFunkce(a, b, c+h, d, e, x, y)-2*UcelovaFunkce(a, b, c, d, e, x, y)+UcelovaFunkce(a, b, c-h, d, e, x, y))/(h*h);
    Hes.elem[2, 3] := (UcelovaFunkce(a, b, c+h, d, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a, b, c+h, d-h, e, x, y)+UcelovaFunkce(a, b, c, d-h, e, x, y))/(h*h);
    Hes.elem[2, 4] := (UcelovaFunkce(a, b, c+h, d, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a, b, c+h, d, e-h, x, y)+UcelovaFunkce(a, b, c, d, e-h, x, y))/(h*h);
    Hes.elem[3, 0] := (UcelovaFunkce(a, b, c, d+h, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a-h, b, c, d+h, e, x, y)+UcelovaFunkce(a-h, b, c, d, e, x, y))/(h*h);
    Hes.elem[3, 1] := (UcelovaFunkce(a, b, c, d+h, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a, b-h, c, d+h, e, x, y)+UcelovaFunkce(a, b-h, c, d, e, x, y))/(h*h);
    Hes.elem[3, 2] := (UcelovaFunkce(a, b, c, d+h, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a, b, c-h, d+h, e, x, y)+UcelovaFunkce(a, b, c-h, d, e, x, y))/(h*h);
    Hes.elem[3, 3] := (UcelovaFunkce(a, b, c, d + h, e, x, y)-2*UcelovaFunkce(a, b, c, d, e, x, y)+UcelovaFunkce(a, b, c, d-h, e, x, y))/(h*h);
    Hes.elem[3, 4] := (UcelovaFunkce(a, b, c, d+h, e, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a, b, c, d+h, e-h, x, y)+UcelovaFunkce(a, b, c, d, e-h, x, y))/(h*h);
    Hes.elem[4, 0] := (UcelovaFunkce(a, b, c, d, e+h, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a-h, b, c, d, e+h, x, y)+UcelovaFunkce(a-h, b, c, d, e, x, y))/(h*h);
    Hes.elem[4, 1] := (UcelovaFunkce(a, b, c, d, e+h, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a, b-h, c, d, e+h, x, y)+UcelovaFunkce(a, b-h, c, d, e, x, y))/(h*h);
    Hes.elem[4, 2] := (UcelovaFunkce(a, b, c, d, e+h, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a, b, c-h, d, e+h, x, y)+UcelovaFunkce(a, b, c-h, d, e, x, y))/(h*h);
    Hes.elem[4, 3] := (UcelovaFunkce(a, b, c, d, e+h, x, y)-UcelovaFunkce(a, b, c, d, e, x, y)-UcelovaFunkce(a, b, c, d-h, e+h, x, y)+UcelovaFunkce(a, b, c, d-h, e, x, y))/(h*h);
    Hes.elem[4, 4] := (UcelovaFunkce(a, b, c, d, e+h, x, y)-2*UcelovaFunkce(a, b, c, d, e, x, y)+UcelovaFunkce(a, b, c, d, e-h, x, y))/(h*h);

    for i := 0 to 4 do
      ge[i+1]:= g.elem[i, 0];


    Edit1.Text := FloatToStr(a);
    Edit2.Text := FloatToStr(b);
    Edit3.Text := FloatToStr(c);
    Edit4.Text := FloatToStr(d);
    Edit5.Text := FloatToStr(e);
    Image1.Picture := nil;
    Body;
    Application.ProcessMessages;
    Inc(k);
  end;
  //ShowMessage(IntToStr(k) + #13#10 + FloatToStr(Norma(ge)));
  SpeedButton1.Down := False;
end;

procedure TGraphForm.FormCreate(Sender: TObject);
begin
  moc:=(RoundTo(PrumerneHue.Maximum,-2));
  moc := RoundTo(moc + 1/moc, -2);
  ScaleX := RoundTo((Image1.Width-15)/(PrumerneHue.m+1), -2);
  ScaleY := RoundTo((Image1.Height-20)/moc, -2);
  Pos0X := Round(ScaleX*20) + 15;
  Pos0Y := Image1.Height - 20;
  KresliOsy;
end;

procedure TGraphForm.Gradient(a, b, c, d, e: Double; x, y: TMatice);
var
  f, fa, fb, fc, xa, xb, xc, xmin,
  aN, bN, cN, dN, eN: Double;
  g: Array[1..5] of Double; //gradient
  ge, gen: Double;
  k: Integer;
begin
  SpeedButton1.Down := True;
//  a := 1;
//  b := 0;
//  c := 1;
//  d := 0;
//  e := 1;

  g[1] := (UcelovaFunkce(a + h, b, c, d, e, x, y)-UcelovaFunkce(a - h, b, c, d, e, x, y))/(2*h);
  g[2] := (UcelovaFunkce(a, b + h, c, d, e, x, y)-UcelovaFunkce(a, b - h, c, d, e, x, y))/(2*h);
  g[3] := (UcelovaFunkce(a, b, c + h, d, e, x, y)-UcelovaFunkce(a, b, c - h, d, e, x, y))/(2*h);
  g[4] := (UcelovaFunkce(a, b, c, d + h, e, x, y)-UcelovaFunkce(a, b, c, d - h, e, x, y))/(2*h);
  g[5] := (UcelovaFunkce(a, b, c, d, e + h, x, y)-UcelovaFunkce(a, b, c, d, e - h, x, y))/(2*h);
  k := 0;
  while (Norma(g) >= epsilon1) and SpeedButton1.Down  do begin
    xa := 0;
    fa := UcelovaFunkce(a, b, c, d, e, x, y);
    Label1.Caption := FloatToStr(fa);
    xb := 0.005;
    aN := a - (g[1]*xb);
    bN := b - (g[2]*xb);
    cN := c - (g[3]*xb);
    dN := d - (g[4]*xb);
    eN := e - (g[5]*xb);
    fb := UcelovaFunkce(aN, bN, cN, dN, eN, x, y);

    xc := 0.01;
    aN := a - (g[1]*xc);
    bN := b - (g[2]*xc);
    cN := c - (g[3]*xc);
    dN := d - (g[4]*xc);
    eN := e - (g[5]*xc);
    fc := UcelovaFunkce(aN, bN, cN, dN, eN, x, y);

    xmin := (1/2)*((sqr(xa)*(fb-fc)+sqr(xb)*(fc-fa)+sqr(xc)*(fa-fb))/(xa*(fb-fc)+xb*(fc-fa)+xc*(fa-fb)));

    a := a - (g[1]*xmin);
    b := b - (g[2]*xmin);
    c := c - (g[3]*xmin);
    d := d - (g[4]*xmin);
    e := e - (g[5]*xmin);

    g[1] := (UcelovaFunkce(a + h, b, c, d, e, x, y)-UcelovaFunkce(a - h, b, c, d, e, x, y))/(2*h);
    g[2] := (UcelovaFunkce(a, b + h, c, d, e, x, y)-UcelovaFunkce(a, b - h, c, d, e, x, y))/(2*h);
    g[3] := (UcelovaFunkce(a, b, c + h, d, e, x, y)-UcelovaFunkce(a, b, c - h, d, e, x, y))/(2*h);
    g[4] := (UcelovaFunkce(a, b, c, d + h, e, x, y)-UcelovaFunkce(a, b, c, d - h, e, x, y))/(2*h);
    g[5] := (UcelovaFunkce(a, b, c, d, e + h, x, y)-UcelovaFunkce(a, b, c, d, e - h, x, y))/(2*h);

    Edit1.Text := FloatToStr(a);
    Edit2.Text := FloatToStr(b);
    Edit3.Text := FloatToStr(c);
    Edit4.Text := FloatToStr(d);
    Edit5.Text := FloatToStr(e);
    Image1.Picture := nil;
    Body;
    Application.ProcessMessages;
    Inc(k);
  end;
  //ShowMessage(IntToStr(k) + #13#10 + FloatToStr(Norma(g)));
  SpeedButton1.Down := False;
end;

procedure TGraphForm.Histogram;
var i,j:integer;
    ce,dc:double;
    maxi: double;
begin
  j:=0;
  Image1.Canvas.Pen.Color := clAqua;
  Image1.Canvas.Brush.Color:= clAqua;
  //Image1.Canvas.MoveTo(15,Image1.Height-20);
  maxi := HistoMat.Maximum;
  maxi := (moc-1/moc)/maxi;

  while (j<=HistoMat.m-1) do begin
    Image1.Canvas.Rectangle(GetI(TransfX(j))-5, GetJ((HistoMat.elem[j,0])*maxi),
                              GetI(TransfX(j)) + 5, GetJ(0));
    Inc(j);
  end;
  Image1.Refresh;
end;

procedure TGraphForm.Button1Click(Sender: TObject);
var
  i: Integer;
  vec, Prum: TMatice;
  j, c: Integer;
begin
  vec := TMatice.Create(PrumerneHue.m, 1);
  for i := 0 to vec.m - 1 do
    vec.elem[i, 0] := TransfX(i + 1);
  Prum := TMatice.Create(PrumerneHue.m, 1);
  for i := 0 to PrumerneHue.m-1 do begin
    c := 0;
    for j := 0 to PrumerneHue.n-1 do begin
      Prum.elem[i, 0] := Prum.elem[i, 0] + PrumerneHue.elem[i, j];
      Inc(c);
    end;
    Prum.elem[i, 0] := Prum.elem[i, 0]/c;
  end;
  Gradient(StrToFloat(Edit1.Text),StrToFloat(Edit2.Text),StrToFloat(Edit3.Text),StrToFloat(Edit4.Text), StrToFloat(Edit5.Text), vec, Prum);
end;

procedure TGraphForm.Button2Click(Sender: TObject);
var
  i, j, c: Integer;
  vec, Prum: TMatice;
begin
  vec := TMatice.Create(PrumerneHue.m, 1);
  for i := 0 to vec.m - 1 do
    vec.elem[i, 0] := TransfX(i + 1);
  Prum := TMatice.Create(PrumerneHue.m, 1);
  for i := 0 to PrumerneHue.m-1 do begin
    c := 0;
    for j := 0 to PrumerneHue.n-1 do begin
      Prum.elem[i, 0] := Prum.elem[i, 0] + PrumerneHue.elem[i, j];
      Inc(c);
    end;
    Prum.elem[i, 0] := Prum.elem[i, 0]/c;
  end;
  Newton(StrToFloat(Edit1.Text),StrToFloat(Edit2.Text),StrToFloat(Edit3.Text),StrToFloat(Edit4.Text), StrToFloat(Edit5.Text), vec, Prum);
end;

procedure TGraphForm.Button3Click(Sender: TObject);
var
  i, j, c: Integer;
  vec, Prum: TMatice;
begin
  vec := TMatice.Create(PrumerneHue.m, 1);
  for i := 0 to vec.m - 1 do
    vec.elem[i, 0] := TransfX(i + 1);
  Prum := TMatice.Create(PrumerneHue.m, 1);
  for i := 0 to PrumerneHue.m-1 do begin
    c := 0;
    for j := 0 to PrumerneHue.n-1 do begin
      Prum.elem[i, 0] := Prum.elem[i, 0] + PrumerneHue.elem[i, j];
      Inc(c);
    end;
    Prum.elem[i, 0] := Prum.elem[i, 0]/c;
  end;
  NelderMead(StrToFloat(Edit1.Text),StrToFloat(Edit2.Text),StrToFloat(Edit3.Text),StrToFloat(Edit4.Text), StrToFloat(Edit5.Text), vec, Prum);
end;

constructor TGraphForm.Create(Prumer, HistoMatice: TMatice);
var
  i, j: Integer;
begin
  inherited Create(nil);
  PrumerneHue := TMatice.Create(Prumer.m, Prumer.n);
  for i := 0 to PrumerneHue.m - 1 do
    for j := 0 to PrumerneHue.n - 1 do
      PrumerneHue.elem[i,j] := TransfY(Prumer.elem[i,j]);
  HistoMat := TMatice.Create(HistoMatice.m, HistoMatice.n);
  for i := 0 to HistoMat.m - 1 do
    for j := 0 to HistoMat.n - 1 do
      HistoMat.elem[i,j] := HistoMatice.elem[i,j];
  bHisto := True;
end;

constructor TGraphForm.Create(Prumer: TMatice);
var
  i, j: Integer;
begin
  inherited Create(nil);
  PrumerneHue := TMatice.Create(Prumer.m, Prumer.n);
  for i := 0 to PrumerneHue.m - 1 do
    for j := 0 to PrumerneHue.n - 1 do
      PrumerneHue.elem[i,j] := TransfY(Prumer.elem[i,j]);
  bHisto := False;
end;

procedure TGraphForm.Edit1Change(Sender: TObject);
begin
  //Body(PrumerneHue);
end;
end.
