2020-03-30 18:01:44 +00:00
|
|
|
unit HyperGeoUnit;
|
|
|
|
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
uses
|
2020-11-16 15:46:13 +00:00
|
|
|
Classes, SysUtils, Forms, Controls, Graphics, StdCtrls, ExtCtrls,
|
|
|
|
FunctionsLib, BasicStatsReportFormUnit;
|
2020-03-30 18:01:44 +00:00
|
|
|
|
|
|
|
type
|
|
|
|
|
|
|
|
{ THyperGeoForm }
|
|
|
|
|
2020-11-16 15:46:13 +00:00
|
|
|
THyperGeoForm = class(TBasicStatsReportForm)
|
2020-03-30 18:01:44 +00:00
|
|
|
SampSizeEdit: TEdit;
|
|
|
|
SampObsEdit: TEdit;
|
|
|
|
PopSizeEdit: TEdit;
|
|
|
|
PopObsEdit: TEdit;
|
|
|
|
ProbXEdit: TEdit;
|
|
|
|
ProbGTEdit: TEdit;
|
|
|
|
ProbLEEdit: TEdit;
|
|
|
|
ProbGEEdit: TEdit;
|
|
|
|
ProbLTEdit: TEdit;
|
2020-11-16 15:46:13 +00:00
|
|
|
SampSizeLabel: TLabel;
|
|
|
|
SampObsLabel: TLabel;
|
|
|
|
PopObsLabel: TLabel;
|
|
|
|
PopSizeLabel: TLabel;
|
2020-03-30 18:01:44 +00:00
|
|
|
Label5: TLabel;
|
|
|
|
Label6: TLabel;
|
|
|
|
Label7: TLabel;
|
|
|
|
Label8: TLabel;
|
|
|
|
Label9: TLabel;
|
|
|
|
private
|
|
|
|
{ private declarations }
|
2020-11-16 15:46:13 +00:00
|
|
|
procedure FisherTable(A,B,C,D, p, SumP: double; AReport: TStrings);
|
|
|
|
|
|
|
|
protected
|
|
|
|
procedure AdjustConstraints; override;
|
|
|
|
procedure Compute; override;
|
|
|
|
function Validate(out AMsg: String; out AControl: TWinControl): Boolean; override;
|
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
public
|
2020-11-16 15:46:13 +00:00
|
|
|
procedure Reset; override;
|
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
var
|
|
|
|
HyperGeoForm: THyperGeoForm;
|
|
|
|
|
2020-11-16 15:46:13 +00:00
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
implementation
|
|
|
|
|
2020-11-16 15:46:13 +00:00
|
|
|
{$R *.lfm}
|
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
uses
|
|
|
|
Math;
|
|
|
|
|
2020-11-16 15:46:13 +00:00
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
{ THyperGeoForm }
|
|
|
|
|
2020-11-16 15:46:13 +00:00
|
|
|
procedure THyperGeoForm.AdjustConstraints;
|
|
|
|
begin
|
|
|
|
inherited;
|
|
|
|
|
|
|
|
ParamsPanel.Constraints.MinHeight := ProbLTEdit.Top + ProbLTEdit.Height +
|
|
|
|
ButtonBevel.Height + CloseBtn.BorderSpacing.Top + CloseBtn.Height;
|
|
|
|
ParamsPanel.Constraints.MinWidth := Max(
|
|
|
|
Max(PopSizeLabel.Width, Label8.Width) + Label8.BorderSpacing.Left + ProbGEEdit.BorderSpacing.Left + ProbGEEdit.Width,
|
|
|
|
4*CloseBtn.Width + 3*CloseBtn.BorderSpacing.Left
|
|
|
|
);;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
procedure THyperGeoForm.Compute;
|
|
|
|
var
|
|
|
|
SampObs, PopObs, SampSize, PopSize: double;
|
|
|
|
A, B, C, D, APlusB, CPlusD: double;
|
|
|
|
ProbX, Prob, SumProb, ProbGE, ProbGT, ProbLT, ProbLE: double;
|
|
|
|
done: boolean;
|
|
|
|
lReport: TStrings;
|
|
|
|
begin
|
|
|
|
lReport := TStringList.Create;
|
|
|
|
try
|
|
|
|
lReport.Add('HYPERGEOMETRIC DISTRIBUTION CALCULATIONS');
|
|
|
|
lReport.Add('Accumulating Values of the distribution');
|
|
|
|
lReport.Add('');
|
|
|
|
|
|
|
|
label5.Enabled := true;
|
|
|
|
label6.Enabled := true;
|
|
|
|
label7.Enabled := true;
|
|
|
|
label8.Enabled := true;
|
|
|
|
label9.Enabled := true;
|
|
|
|
ProbXEdit.Enabled := true;
|
|
|
|
ProbGEEdit.Enabled := true;
|
|
|
|
ProbLTEdit.Enabled := true;
|
|
|
|
ProbLEEdit.Enabled := true;
|
|
|
|
ProbGTEdit.Enabled := true;
|
|
|
|
|
|
|
|
SampObs := StrToFloat(SampObsEdit.Text);
|
|
|
|
PopObs := StrToFloat(PopObsEdit.Text);
|
|
|
|
SampSize := StrToFloat(SampSizeEdit.Text);
|
|
|
|
PopSize := StrToFloat(PopSizeEdit.Text);
|
|
|
|
|
|
|
|
done := false;
|
|
|
|
SumProb := 0.0;
|
|
|
|
|
|
|
|
A := SampObs;
|
|
|
|
B := SampSize - A;
|
|
|
|
C := PopObs;
|
|
|
|
D := PopSize - C;
|
|
|
|
APlusB := A + B;
|
|
|
|
CPlusD := C + D;
|
|
|
|
|
|
|
|
ProbX := combos(A,C) * combos(B,D) / combos(APlusB,CPlusD);
|
|
|
|
ProbXEdit.Text := Format('%.4f', [ProbX]);
|
|
|
|
SumProb := SumProb + ProbX;
|
|
|
|
FisherTable(A,B,C,D,ProbX,SumProb, lReport);
|
|
|
|
|
|
|
|
// get more extreme probabilities
|
|
|
|
while not done do
|
|
|
|
begin
|
|
|
|
if A = APlusB then
|
|
|
|
done := true
|
|
|
|
else
|
|
|
|
begin
|
|
|
|
A := A + 1;
|
|
|
|
B := B - 1;
|
|
|
|
if (A < 0) or (B < 0) or (C < 0) or (D < 0) then done := true;
|
|
|
|
end;
|
|
|
|
if not done then
|
|
|
|
begin
|
|
|
|
Prob := combos(A,C) * combos(B,D) / combos(APlusB,CPlusD);
|
|
|
|
SumProb := SumProb + Prob;
|
|
|
|
FisherTable(A,B,C,D,Prob,SumProb, lReport);
|
|
|
|
lReport.Add('');
|
|
|
|
end;
|
|
|
|
end; // end while not done
|
|
|
|
|
|
|
|
ProbGE := SumProb;
|
|
|
|
ProbGT := SumProb - ProbX;
|
|
|
|
ProbLT := 1.0 - ProbGE;
|
|
|
|
ProbLE := ProbLT + ProbX;
|
|
|
|
ProbGEEdit.Text := Format('%.4f', [ProbGE]);
|
|
|
|
ProbLEEdit.Text := Format('%.4f', [ProbLE]);
|
|
|
|
ProbGTEdit.Text := Format('%.4f', [ProbGT]);
|
|
|
|
ProbLTEdit.Text := Format('%.4f', [ProbLT]);
|
|
|
|
|
|
|
|
FReportFrame.DisplayReport(lReport);
|
|
|
|
finally
|
|
|
|
lReport.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
procedure THyperGeoForm.FisherTable(A,B,C,D, p, SumP: double; AReport: TStrings);
|
|
|
|
begin
|
|
|
|
AReport.Add('Table for Hypergeometric Probabilities');
|
|
|
|
AReport.Add('----------------------------------');
|
|
|
|
AReport.Add(' Row Column ');
|
|
|
|
AReport.Add(' 1 2 ');
|
|
|
|
AReport.Add(' --- ---------- -----------');
|
|
|
|
AReport.Add(' 1 %8.0f %8.0f', [A, B]);
|
|
|
|
AReport.Add(' 2 %8.0f %8.0f', [C, D]);
|
|
|
|
AReport.Add('----------------------------------');
|
|
|
|
AReport.Add('Probability: %8.4f', [p]);
|
|
|
|
AReport.Add('Cumulative Probability: %8.4f', [SumP]);
|
|
|
|
AReport.Add('');
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
procedure THyperGeoForm.Reset;
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
2020-11-16 15:46:13 +00:00
|
|
|
inherited;
|
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
SampSizeEdit.Text := '';
|
|
|
|
SampObsEdit.Text := '';
|
|
|
|
PopSizeEdit.Text := '';
|
|
|
|
PopObsEdit.Text := '';
|
|
|
|
ProbXEdit.Text := '';
|
|
|
|
ProbGEEdit.Text := '';
|
|
|
|
ProbLTEdit.Text := '';
|
|
|
|
ProbLEEdit.Text := '';
|
|
|
|
ProbGTEdit.Text := '';
|
|
|
|
label5.Enabled := false;
|
|
|
|
label6.Enabled := false;
|
|
|
|
label7.Enabled := false;
|
|
|
|
label8.Enabled := false;
|
|
|
|
label9.Enabled := false;
|
|
|
|
ProbXEdit.Enabled := false;
|
|
|
|
ProbGEEdit.Enabled := false;
|
|
|
|
ProbLTEdit.Enabled := false;
|
|
|
|
ProbLEEdit.Enabled := false;
|
|
|
|
ProbGTEdit.Enabled := false;
|
|
|
|
end;
|
|
|
|
|
2020-11-16 15:46:13 +00:00
|
|
|
|
|
|
|
function THyperGeoForm.Validate(out AMsg: String; out AControl: TWinControl): Boolean;
|
|
|
|
var
|
|
|
|
n: Integer;
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
2020-11-16 15:46:13 +00:00
|
|
|
Result := false;
|
|
|
|
|
|
|
|
if (SampSizeEdit.Text = '') or not TryStrToInt(SampSizeEdit.Text, n) or (n <= 0) then
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
2020-11-16 15:46:13 +00:00
|
|
|
AMsg := 'Valid positive integer number required.';
|
|
|
|
AControl := SampSizeEdit;
|
|
|
|
exit;
|
|
|
|
end;
|
2020-03-30 18:01:44 +00:00
|
|
|
|
2020-11-16 15:46:13 +00:00
|
|
|
if (SampObsEdit.Text = '') or not TryStrToInt(SampObsEdit.Text, n) or (n <= 0) then
|
|
|
|
begin
|
|
|
|
AMsg := 'Valid positive integer number required.';
|
|
|
|
AControl := SampObsEdit;
|
|
|
|
exit;
|
|
|
|
end;
|
2020-03-30 18:01:44 +00:00
|
|
|
|
2020-11-16 15:46:13 +00:00
|
|
|
if (PopSizeEdit.Text = '') or not TryStrToInt(PopSizeEdit.Text, n) or (n <= 0) then
|
|
|
|
begin
|
|
|
|
AMsg := 'Valid positive integer number required.';
|
|
|
|
AControl := PopSizeEdit;
|
|
|
|
exit;
|
|
|
|
end;
|
2020-03-30 18:01:44 +00:00
|
|
|
|
2020-11-16 15:46:13 +00:00
|
|
|
if (PopObsEdit.Text = '') or not TryStrToInt(PopObsEdit.Text, n) or (n <= 0) then
|
|
|
|
begin
|
|
|
|
AMsg := 'Valid positive integer number required.';
|
|
|
|
AControl := PopObsEdit;
|
|
|
|
exit;
|
|
|
|
end;
|
2020-03-30 18:01:44 +00:00
|
|
|
|
2020-11-16 15:46:13 +00:00
|
|
|
Result := true;
|
|
|
|
end;
|
2020-03-30 18:01:44 +00:00
|
|
|
|
|
|
|
end.
|
|
|
|
|