unit LCPerformance;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, Basic2, Classifier, StdCtrls, ExtCtrls, ComCtrls;

type
  TLcPerformanceForm = class(TBasicForm2)
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Bevel1: TBevel;
    Label4: TLabel;
    Label5: TLabel;
    Bevel2: TBevel;
    TimeLabel: TLabel;
    CountLabel: TLabel;
    Bevel3: TBevel;
    CasesPerSecondLabel: TLabel;
    ClassesEdit: TEdit;
    DAttributesEdit: TEdit;
    FAttributesEdit: TEdit;
    LearnEdit: TEdit;
    TestEdit: TEdit;
    GroupBox1: TGroupBox;
    Label6: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    Label9: TLabel;
    Label10: TLabel;
    Label11: TLabel;
    Label12: TLabel;
    LinearClassifier: TLinearClassifier;
    LearnButton: TButton;
    ClassifyButton: TButton;
    procedure LearnButtonClick(Sender: TObject);
    procedure ClassesEditChange(Sender: TObject);
    procedure ClassifyButtonClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure DAttributesEditChange(Sender: TObject);
    procedure FAttributesEditChange(Sender: TObject);
    procedure LearnEditChange(Sender: TObject);
    procedure TestEditChange(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  LcPerformanceForm: TLcPerformanceForm;

implementation

{$R *.dfm}

procedure TLCPerformanceForm.ClassesEditChange(Sender: TObject);
begin
      try
      StrToInt(ClassesEdit.Text);
      except
             ClassesEdit.Text := '50';   
      end;
end;

procedure TLCPerformanceForm.LearnButtonClick(Sender: TObject);
var i,j,ClassCount: integer;
    ad: array of integer;
    af: array of double;
    ATime: TDateTime;
    Hour, Min, Sec, MSec: Word;
begin
        LinearClassifier.Clear;
        SetLength(ad, LinearClassifier.DiscreteAttributeCount);
        SetLength(af, LinearClassifier.FloatAttributeCount);
        Randomize;
        for i := 0 to Length(ad)-1 do ad[i] := Random(10);
        for i := 0 to Length(af)-1 do af[i] := Random(10);
        TimeLabel.Caption := '';
        CasesPerSecondLabel.Caption := '';
        ATime := Now;
        j := StrToInt(LearnEdit.Text);
        ClassCount := StrToInt(ClassesEdit.Text);
        for i := 0 to j-1 do
        begin
             LinearClassifier.LearnIndex(Random(ClassCount),ad,af);
             if i mod 1000 = 0 then
             begin
                  CountLabel.Caption := 'Learned cases = ' + IntToStr(i);
                  Update;
             end;
        end;
        ATime := Now - ATime;
        TimeLabel.Caption := 'Time: '  + FormatDateTime('hh:nn:ss:zz',ATime);
        CountLabel.Caption := 'Learned cases = ' + LearnEdit.Text;
        DecodeTime(ATime, Hour, Min, Sec, MSec);
        CasesPerSecondLabel.Caption := FormatFloat('0',StrToInt(LearnEdit.Text)/(Min*60+Sec+MSec*0.001))  + ' Cases/second';
end;

procedure TLCPerformanceForm.DAttributesEditChange(Sender: TObject);
begin
        try
        LinearClassifier.DiscreteAttributeCount := StrToInt(DAttributesEdit.Text)
        except
              DAttributesEdit.Text := '25';
        end;
end;

procedure TLCPerformanceForm.FAttributesEditChange(Sender: TObject);
begin
        try
        LinearClassifier.FloatAttributeCount := StrToInt(FAttributesEdit.Text);
        except
              FAttributesEdit.Text := '25';
        end;
end;

procedure TLCPerformanceForm.LearnEditChange(Sender: TObject);
begin
        try
        StrToInt(LearnEdit.Text);
        except
              LearnEdit.Text := '10000';
        end;
end;

procedure TLCPerformanceForm.TestEditChange(Sender: TObject);
begin
        try
        StrToInt(TestEdit.Text);
        except
              TestEdit.Text := '10000';
        end;

end;

procedure TLCPerformanceForm.ClassifyButtonClick(Sender: TObject);
var i,j: integer;
    ad: array of integer;
    af: array of double;
    ATime: TDateTime;
    Hour, Min, Sec, MSec: Word;
begin
        if LinearClassifier.Classes.Count <> StrToInt(ClassesEdit.Text) then raise Exception.Create('Learn first!');
        SetLength(ad, LinearClassifier.DiscreteAttributeCount);
        SetLength(af, LinearClassifier.FloatAttributeCount);
        Randomize;
        for i := 0 to Length(ad)-1 do ad[i] := Random(10);
        for i := 0 to Length(af)-1 do af[i] := Random(10);
        TimeLabel.Caption := '';
        CasesPerSecondLabel.Caption := '';
        ATime := Now;
        j := StrToInt(TestEdit.Text);
        for i := 0 to j-1 do
        begin
             LinearClassifier.Classify(ad,af);
             if i mod 1000 = 0 then
             begin
                  CountLabel.Caption := 'Classified cases = ' + IntToStr(i);
                  Update;
             end;
        end;
        ATime := Now - ATime;
        TimeLabel.Caption := 'Time: '  + FormatDateTime('hh:nn:ss:zzz',ATime);
        CountLabel.Caption := 'Classified cases = ' + TestEdit.Text;
        DecodeTime(ATime, Hour, Min, Sec, MSec);
        CasesPerSecondLabel.Caption := FormatFloat('0',StrToInt(TestEdit.Text)/(Min*60+Sec + MSec/1000))  + ' Cases/second';
end;

procedure TLCPerformanceForm.FormCreate(Sender: TObject);
begin
  With RichEdit1.Lines, RichEdit1 do
  begin
    Clear;
    Add('This example tests the performance of the "linear classifier". ' +
        'The speed of learning and classification is high enough to make use ' +
        'of clustering algorithms uneccessary (too slow and not real time).' +
        'Press the "learn examples" button to measure the speed of learming. Press the '+
        '"classify examples" button to measure the speed of classifying. You can also ' +
        'change the learn and classify parameters to see how the algorithm scales.');
  end;
  TButton(Self.Owner.FindComponent('btnHelp')).Enabled := false;
end;

initialization
   RegisterClass(TLcPerformanceForm);

end.
