2020-03-30 18:01:44 +00:00
|
|
|
// Use file "cansas.laz" for testing
|
|
|
|
|
|
|
|
unit CompareDistUnit;
|
|
|
|
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
uses
|
|
|
|
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
|
2020-09-29 13:49:25 +00:00
|
|
|
StdCtrls, Buttons, ExtCtrls, ComCtrls,
|
|
|
|
FunctionsLib, Globals, GraphLib, DataProcs, MainDM, MainUnit,
|
|
|
|
BasicStatsFormUnit, ReportFrameUnit, ChartFrameUnit;
|
2020-03-30 18:01:44 +00:00
|
|
|
|
|
|
|
type
|
2020-09-30 10:19:19 +00:00
|
|
|
TCompareTo = (ctTheoreticalDistrib, ctVariable);
|
|
|
|
TCompareDist = (cd_Normal, cd_t, cd_ChiSq, cd_F, cd_Poisson);
|
2020-03-30 18:01:44 +00:00
|
|
|
|
|
|
|
{ TCompareDistFrm }
|
|
|
|
|
2020-09-29 13:49:25 +00:00
|
|
|
TCompareDistFrm = class(TBasicStatsForm)
|
2020-03-30 18:01:44 +00:00
|
|
|
Bevel1: TBevel;
|
2020-09-30 10:19:19 +00:00
|
|
|
DF1Edit: TEdit;
|
|
|
|
DF2Edit: TEdit;
|
|
|
|
DistGroup: TGroupBox;
|
|
|
|
DF1Label: TLabel;
|
|
|
|
DF2Label: TLabel;
|
2020-09-29 13:49:25 +00:00
|
|
|
PageControl1: TPageControl;
|
|
|
|
ParamsSplitter: TSplitter;
|
2020-09-30 10:19:19 +00:00
|
|
|
NormalDistChk: TRadioButton;
|
|
|
|
FreqChartPage: TTabSheet;
|
|
|
|
tDistChk: TRadioButton;
|
|
|
|
ChiSqDistChk: TRadioButton;
|
|
|
|
FDistChk: TRadioButton;
|
|
|
|
PoissonDistChk: TRadioButton;
|
2020-09-29 13:49:25 +00:00
|
|
|
ReportPage: TTabSheet;
|
2020-09-30 10:19:19 +00:00
|
|
|
CumFreqChartPage: TTabSheet;
|
2020-09-29 13:49:25 +00:00
|
|
|
Notebook: TNotebook;
|
2020-09-30 10:19:19 +00:00
|
|
|
BarPlotBtn: TSpeedButton;
|
2020-09-29 13:49:25 +00:00
|
|
|
LinePlotBtn: TSpeedButton;
|
|
|
|
TheoreticalDistPage: TPage;
|
|
|
|
VariablePage: TPage;
|
|
|
|
ParamsPanel: TPanel;
|
2020-03-30 18:01:44 +00:00
|
|
|
BothChk: TCheckBox;
|
2020-09-29 13:49:25 +00:00
|
|
|
OptionsGroup: TGroupBox;
|
2020-03-30 18:01:44 +00:00
|
|
|
ResetBtn: TButton;
|
|
|
|
ComputeBtn: TButton;
|
|
|
|
CloseBtn: TButton;
|
|
|
|
CompareGroup: TRadioGroup;
|
|
|
|
VarOneEdit: TEdit;
|
|
|
|
VarTwoEdit: TEdit;
|
|
|
|
Label2: TLabel;
|
|
|
|
Label3: TLabel;
|
|
|
|
Var1InBtn: TBitBtn;
|
|
|
|
Var1OutBtn: TBitBtn;
|
|
|
|
Var2InBtn: TBitBtn;
|
|
|
|
Var2OutBtn: TBitBtn;
|
|
|
|
Label1: TLabel;
|
|
|
|
VarList: TListBox;
|
2020-09-29 10:36:56 +00:00
|
|
|
procedure CloseBtnClick(Sender: TObject);
|
2020-03-30 18:01:44 +00:00
|
|
|
procedure CompareGroupClick(Sender: TObject);
|
|
|
|
procedure ComputeBtnClick(Sender: TObject);
|
|
|
|
procedure FormActivate(Sender: TObject);
|
|
|
|
procedure FormCreate(Sender: TObject);
|
2020-09-30 10:19:19 +00:00
|
|
|
procedure DistChange(Sender: TObject);
|
2020-03-30 18:01:44 +00:00
|
|
|
procedure ResetBtnClick(Sender: TObject);
|
|
|
|
procedure Var1InBtnClick(Sender: TObject);
|
|
|
|
procedure Var1OutBtnClick(Sender: TObject);
|
|
|
|
procedure Var2InBtnClick(Sender: TObject);
|
|
|
|
procedure Var2OutBtnClick(Sender: TObject);
|
2020-09-29 13:49:25 +00:00
|
|
|
procedure VarListDblClick(Sender: TObject);
|
|
|
|
procedure VarListSelectionChange(Sender: TObject; {%H-}User: boolean);
|
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
private
|
2020-09-29 13:49:25 +00:00
|
|
|
FReportFrame: TReportFrame;
|
2020-09-30 10:19:19 +00:00
|
|
|
FCumFreqChartFrame: TChartFrame;
|
|
|
|
FFreqChartFrame: TChartFrame;
|
2020-03-30 18:01:44 +00:00
|
|
|
FAutoSized: Boolean;
|
2020-09-30 10:19:19 +00:00
|
|
|
CompareTo: TCompareTo;
|
|
|
|
CompareDist: TCompareDist;
|
|
|
|
procedure CalcFreq(XValues, FreqValues, CumFreqValues: DblDyneVec;
|
|
|
|
AMin, AMax: Double; ANumIntervals, ANumCases: Integer; DF1: Integer = -1;
|
|
|
|
DF2: Integer = -1);
|
|
|
|
procedure CalcTheoreticalDist(XValues, FreqValues, CumFreqValues: DblDyneVec;
|
|
|
|
ANumIntervals, ANumCases: Integer; out AName: String);
|
|
|
|
procedure Plot(AChartFrame: TChartFrame; Y1Values, Y2Values: DblDyneVec;
|
|
|
|
AName1, AName2: String);
|
2020-03-30 18:01:44 +00:00
|
|
|
procedure UpdateBtnStates;
|
2020-09-30 10:19:19 +00:00
|
|
|
procedure UpdateDF1;
|
|
|
|
function Validate(ANumCases: Integer;
|
|
|
|
out AMsg: String; out AControl: TWinControl): Boolean;
|
2020-09-29 13:49:25 +00:00
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
public
|
2020-09-29 13:49:25 +00:00
|
|
|
procedure Reset; override;
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
|
2020-09-29 13:49:25 +00:00
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
var
|
|
|
|
CompareDistFrm: TCompareDistFrm;
|
|
|
|
|
2020-09-29 13:49:25 +00:00
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
implementation
|
|
|
|
|
2020-09-29 13:49:25 +00:00
|
|
|
{$R *.lfm}
|
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
uses
|
2020-09-28 14:05:34 +00:00
|
|
|
Math,
|
2020-09-30 10:19:19 +00:00
|
|
|
TACustomSeries, TASeries,
|
2020-09-28 14:05:34 +00:00
|
|
|
Utils, MathUnit;
|
2020-03-30 18:01:44 +00:00
|
|
|
|
|
|
|
|
2020-09-29 13:49:25 +00:00
|
|
|
{ TCompareDistFrm }
|
2020-03-30 18:01:44 +00:00
|
|
|
|
2020-09-30 10:19:19 +00:00
|
|
|
procedure TCompareDistFrm.CalcFreq(XValues, FreqValues, CumFreqValues: DblDyneVec;
|
|
|
|
AMin, AMax: Double; ANumIntervals, ANumCases: Integer; DF1: Integer = -1;
|
|
|
|
DF2: Integer = -1);
|
|
|
|
var
|
|
|
|
dx: Double;
|
|
|
|
i: Integer;
|
|
|
|
|
|
|
|
procedure Calc(AProb1, AProb2: Double);
|
|
|
|
begin
|
|
|
|
FreqValues[i] := abs(AProb2 - AProb1) * ANumCases;
|
|
|
|
end;
|
|
|
|
|
|
|
|
begin
|
|
|
|
dx := (AMax - AMin) / ANumIntervals;
|
|
|
|
for i := 0 to ANumIntervals do
|
|
|
|
XValues[i] := AMin + i * dx;
|
|
|
|
|
|
|
|
for i := 0 to ANumIntervals - 1 do
|
|
|
|
case CompareDist of
|
|
|
|
cd_Normal:
|
|
|
|
Calc(NormalDist(XValues[i]), NormalDist(XValues[i+1]));
|
|
|
|
cd_t:
|
|
|
|
Calc(0.5 * ProbT(XValues[i], DF1), 0.5 * ProbT(XValues[i+1], DF1));
|
|
|
|
cd_ChiSq:
|
|
|
|
Calc(ChiSquaredProb(XValues[i], DF1), ChiSquaredProb(XValues[i+1], DF1));
|
|
|
|
cd_F:
|
|
|
|
Calc(ProbF(XValues[i], DF1, DF2), ProbF(XValues[i+1], DF1, DF2));
|
|
|
|
cd_Poisson:
|
|
|
|
Calc(PoissonCDF(round(XValues[i]), DF1), PoissonCDF(round(XValues[i+1]), DF1));
|
|
|
|
// Calc(PoissonPDF(round(XValues[i]), DF1), 0);
|
|
|
|
end;
|
|
|
|
|
|
|
|
CumFreqValues[0] := FreqValues[0];
|
|
|
|
for i := 1 to ANumIntervals - 1 do
|
|
|
|
CumFreqValues[i] := CumFreqValues[i-1] + FreqValues[i];
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
procedure TCompareDistFrm.CalcTheoreticalDist(XValues, FreqValues, CumFreqValues: DblDyneVec;
|
|
|
|
ANumIntervals, ANumCases: Integer; out AName: String);
|
|
|
|
var
|
|
|
|
min, max: Double;
|
|
|
|
DF1: Integer = -1;
|
|
|
|
DF2: Integer = -1;
|
|
|
|
a: Double;
|
|
|
|
begin
|
|
|
|
if TryStrToFloat(DF1Edit.Text, a) then
|
|
|
|
DF1 := round(a);
|
|
|
|
if TryStrToFloat(DF2Edit.Text, a) then
|
|
|
|
DF2 := round(a);
|
|
|
|
|
|
|
|
case CompareDist of
|
|
|
|
cd_Normal:
|
|
|
|
begin
|
|
|
|
min := -3.0;
|
|
|
|
max := 3.0;
|
|
|
|
AName := 'Normal dist';
|
|
|
|
end;
|
|
|
|
cd_t:
|
|
|
|
begin
|
|
|
|
min := -3.0;
|
|
|
|
max := 3.0;
|
|
|
|
AName := 't dist';
|
|
|
|
end;
|
|
|
|
cd_ChiSq:
|
|
|
|
begin
|
|
|
|
min := 0.0;
|
|
|
|
max := 20.0;
|
|
|
|
AName := 'Chi-sq dist';
|
|
|
|
end;
|
|
|
|
cd_F:
|
|
|
|
begin
|
|
|
|
min := 0.0;
|
|
|
|
max := 2.0;
|
|
|
|
AName := 'F dist';
|
|
|
|
end;
|
|
|
|
cd_Poisson:
|
|
|
|
; // will be handled separately
|
|
|
|
end;
|
|
|
|
|
|
|
|
CalcFreq(XValues, FreqValues, CumFreqValues, min, max, ANumIntervals, ANumCases, DF1, DF2);
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(*
|
|
|
|
if NormalDistChk.Checked then // normal distribution curve
|
|
|
|
begin
|
|
|
|
name2 := 'Normal';
|
|
|
|
min2 := -3.0;
|
|
|
|
max2 := 3.0;
|
|
|
|
range2 := max2 - min2;
|
|
|
|
incrsize2 := range2 / noints;
|
|
|
|
Xvalue2[0] := min2;
|
|
|
|
Xvalue2[noints] := max2;
|
|
|
|
for i := 1 to noInts do
|
|
|
|
begin
|
|
|
|
Xvalue2[i-1] := min2 + (i-1) * incrSize2;
|
|
|
|
Xvalue2[i] := min2 + (i) * incrSize2;
|
|
|
|
prob1 := probz(abs(Xvalue2[i-1]));
|
|
|
|
prob2 := probz(abs(Xvalue2[i]));
|
|
|
|
if prob1 > prob2 then
|
|
|
|
Var2Freq[i-1] := round((prob1 - prob2) * nCases)
|
|
|
|
else
|
|
|
|
Var2Freq[i-1] := round((prob2 - prob1) * nCases)
|
|
|
|
end;
|
|
|
|
Cumfreq2[0] := Var2Freq[0];
|
|
|
|
for i := 1 to noints do
|
|
|
|
Cumfreq2[i] := Cumfreq2[i-1] + Var2Freq[i];
|
|
|
|
end
|
|
|
|
end;
|
|
|
|
*)
|
|
|
|
|
2020-09-29 13:49:25 +00:00
|
|
|
procedure TCompareDistFrm.CloseBtnClick(Sender: TObject);
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
2020-09-29 13:49:25 +00:00
|
|
|
Close;
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
procedure TCompareDistFrm.CompareGroupClick(Sender: TObject);
|
|
|
|
begin
|
2020-09-30 10:19:19 +00:00
|
|
|
CompareTo := TCompareTo(CompareGroup.ItemIndex);
|
2020-09-29 13:49:25 +00:00
|
|
|
Notebook.PageIndex := CompareGroup.ItemIndex;
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
|
2020-09-29 10:36:56 +00:00
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
procedure TCompareDistFrm.ComputeBtnClick(Sender: TObject);
|
|
|
|
var
|
2020-09-30 10:19:19 +00:00
|
|
|
var1Freq: DblDyneVec = nil; // could be IntDyneVec, but simpler charting this way
|
|
|
|
var2Freq: DblDyneVec = nil;
|
|
|
|
xValue1: DblDyneVec = nil;
|
|
|
|
xValue2: DblDyneVec = nil;
|
|
|
|
cumfreq1: DblDyneVec = nil;
|
|
|
|
cumfreq2: DblDyneVec = nil;
|
|
|
|
i, j, k, col1, col2, nCases, noInts: integer;
|
|
|
|
min1, max1, min2, max2, range1, range2, value: double;
|
|
|
|
incrSize1, incrSize2, {%H-}KS: double;
|
|
|
|
cellVal, name1, name2: string;
|
2020-03-30 18:01:44 +00:00
|
|
|
msg: String;
|
2020-09-30 10:19:19 +00:00
|
|
|
C: TWinControl;
|
2020-03-30 18:01:44 +00:00
|
|
|
lReport: TStrings;
|
|
|
|
begin
|
2020-09-30 10:19:19 +00:00
|
|
|
SetLength(var1Freq, NoCases + 1);
|
|
|
|
SetLength(var2Freq, NoCases + 1);
|
|
|
|
SetLength(xValue1, NoCases + 1);
|
|
|
|
SetLength(xValue2, NoCases + 1);
|
|
|
|
SetLength(cumfreq1, NoCases + 1);
|
|
|
|
SetLength(cumfreq2, NoCases + 1);
|
2020-03-30 18:01:44 +00:00
|
|
|
|
|
|
|
// Get columns of the variables
|
|
|
|
col1 := 0;
|
|
|
|
for i := 1 to NoVariables do
|
2020-09-30 10:19:19 +00:00
|
|
|
if VarOneEdit.Text = OS3MainFrm.DataGrid.Cells[i, 0] then col1 := i;
|
|
|
|
|
|
|
|
col2 := 0;
|
|
|
|
if CompareTo = ctVariable then
|
|
|
|
for i := 1 to NoVariables do
|
|
|
|
if VarTwoEdit.Text = OS3MainFrm.DataGrid.Cells[i, 0] then col2 := i;
|
2020-03-30 18:01:44 +00:00
|
|
|
|
2020-09-30 10:19:19 +00:00
|
|
|
// Check existence of required variables
|
2020-03-30 18:01:44 +00:00
|
|
|
msg := '';
|
|
|
|
case CompareTo of
|
2020-09-30 10:19:19 +00:00
|
|
|
ctTheoreticalDistrib:
|
|
|
|
if col1 = 0 then
|
|
|
|
msg := 'Variable not specified.';
|
|
|
|
ctVariable:
|
|
|
|
if col1 = 0 then
|
|
|
|
msg := 'Variable One is not specified.'
|
|
|
|
else if col2 = 0 then
|
|
|
|
msg := 'Variable Two is not specified.';
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
if msg <> '' then
|
|
|
|
begin
|
2020-05-10 23:10:20 +00:00
|
|
|
ErrorMsg(msg);
|
2020-03-30 18:01:44 +00:00
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
|
2020-09-30 10:19:19 +00:00
|
|
|
// Get min and max values for variable in col1, as well as true number of cases
|
|
|
|
min1 := Infinity;
|
|
|
|
max1 := -Infinity;
|
|
|
|
nCases := 0;
|
2020-03-30 18:01:44 +00:00
|
|
|
for j := 1 to NoCases do
|
|
|
|
begin
|
2020-09-30 10:19:19 +00:00
|
|
|
if not ValidValue(j, col1) then continue;
|
|
|
|
value := StrToFloat(OS3MainFrm.DataGrid.Cells[col1, j]);
|
2020-03-30 18:01:44 +00:00
|
|
|
if value > max1 then max1 := value;
|
|
|
|
if value < min1 then min1 := value;
|
2020-09-30 10:19:19 +00:00
|
|
|
inc(nCases);
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
|
2020-09-30 10:19:19 +00:00
|
|
|
// Validate
|
|
|
|
if not Validate(nCases, msg, C) then begin
|
|
|
|
C.SetFocus;
|
|
|
|
ErrorMsg(msg);
|
|
|
|
end;
|
|
|
|
|
|
|
|
// Get number of intervals
|
|
|
|
noInts := NoCases - 1; // wp: why NoCases here, and not nCases?
|
|
|
|
if noInts > 20 then noints := 20;
|
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
range1 := max1 - min1 + 1.0;
|
2020-09-30 10:19:19 +00:00
|
|
|
incrSize1 := range1 / noInts;
|
2020-03-30 18:01:44 +00:00
|
|
|
name1 := VarOneEdit.Text;
|
|
|
|
|
2020-09-30 10:19:19 +00:00
|
|
|
// Repeat for variable 2 (if Compare To is selected as "Another variable")
|
|
|
|
if CompareTo = ctVariable then
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
2020-09-30 10:19:19 +00:00
|
|
|
min2 := Infinity;
|
|
|
|
max2 := -Infinity;
|
2020-03-30 18:01:44 +00:00
|
|
|
for j := 1 to NoCases do
|
|
|
|
begin
|
2020-09-30 10:19:19 +00:00
|
|
|
if not ValidValue(j, col2) then continue;
|
|
|
|
value := StrToFloat(OS3MainFrm.DataGrid.Cells[col2, j]);
|
2020-03-30 18:01:44 +00:00
|
|
|
if value > max2 then max2 := value;
|
|
|
|
if value < min2 then min2 := value;
|
|
|
|
end;
|
|
|
|
range2 := max2 - min2 + 1.0;
|
2020-09-30 10:19:19 +00:00
|
|
|
incrSize2 := range2 / noInts;
|
2020-03-30 18:01:44 +00:00
|
|
|
name2 := VarTwoEdit.Text;
|
|
|
|
end;
|
|
|
|
|
2020-09-30 10:19:19 +00:00
|
|
|
// Get frequency of cases in each interval
|
2020-03-30 18:01:44 +00:00
|
|
|
for j := 1 to noints+1 do
|
2020-09-30 10:19:19 +00:00
|
|
|
var1Freq[j-1] := 0;
|
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
for j := 1 to NoCases do
|
|
|
|
begin
|
2020-09-30 10:19:19 +00:00
|
|
|
if not ValidValue(j, col1) then continue;
|
|
|
|
value := StrToFloat(OS3MainFrm.DataGrid.Cells[col1, j]);
|
|
|
|
for k := 1 to noInts do
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
2020-09-30 10:19:19 +00:00
|
|
|
if (value >= min1 + (k-1) * incrSize1) and (value < min1 + k * incrSize1) then
|
|
|
|
var1Freq[k-1] := var1Freq[k-1] + 1;
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
end;
|
2020-09-30 10:19:19 +00:00
|
|
|
|
|
|
|
cumFreq1[0] := var1Freq[0];
|
|
|
|
for j := 1 to noInts+1 do
|
|
|
|
xValue1[j-1] := min1 + (j-1) * incrSize1;
|
|
|
|
for j := 1 to noInts do
|
|
|
|
cumFreq1[j] := cumFreq1[j-1] + var1Freq[j];
|
|
|
|
|
|
|
|
// Repeat for 2nd variable, if required
|
|
|
|
if CompareTo = ctVariable then
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
2020-09-30 10:19:19 +00:00
|
|
|
for j := 1 to noInts+1 do
|
|
|
|
var2Freq[j-1] := 0;
|
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
for j := 1 to NoCases do
|
|
|
|
begin
|
2020-09-30 10:19:19 +00:00
|
|
|
if not ValidValue(j, col2) then continue;
|
|
|
|
value := StrToFloat(OS3MainFrm.DataGrid.Cells[col2, j]);
|
|
|
|
for k := 1 to noInts do
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
2020-09-30 10:19:19 +00:00
|
|
|
if (value >= min2 + (k-1) * incrsize2) and (value < min2 + k * incrsize2) then
|
|
|
|
var2Freq[k-1] := var2Freq[k-1] + 1;
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
end;
|
2020-09-30 10:19:19 +00:00
|
|
|
|
|
|
|
cumfreq2[0] := var2Freq[0];
|
|
|
|
for j := 1 to noInts+1 do
|
|
|
|
xValue2[j-1] := min2 + (j-1) * incrSize2;
|
|
|
|
for j := 1 to noInts do
|
|
|
|
cumFreq2[j] := cumFreq2[j-1] + var2Freq[j];
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
|
2020-09-30 10:19:19 +00:00
|
|
|
// Get theoretical distribution frequencies for selected distribution, if required.
|
|
|
|
if CompareDist = cd_Poisson then
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
2020-09-30 10:19:19 +00:00
|
|
|
CalcFreq(xValue2, var2Freq, cumFreq2, min1, min2, noInts, nCases, StrToInt(DF1Edit.Text));
|
|
|
|
name2 := 'Poisson';
|
|
|
|
end
|
|
|
|
else
|
|
|
|
CalcTheoreticalDist(xValue2, var2Freq, cumFreq2, noInts, nCases, name2);
|
|
|
|
|
|
|
|
(*
|
|
|
|
|
|
|
|
|
|
|
|
if CompareTo = ctTheoreticalDistrib then
|
|
|
|
begin
|
|
|
|
if NormalDistChk.Checked then // normal distribution curve
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
|
|
|
name2 := 'Normal';
|
|
|
|
min2 := -3.0;
|
|
|
|
max2 := 3.0;
|
|
|
|
range2 := max2 - min2;
|
|
|
|
incrsize2 := range2 / noints;
|
|
|
|
Xvalue2[0] := min2;
|
|
|
|
Xvalue2[noints] := max2;
|
2020-09-30 10:19:19 +00:00
|
|
|
for i := 1 to noInts do
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
2020-09-30 10:19:19 +00:00
|
|
|
Xvalue2[i-1] := min2 + (i-1) * incrSize2;
|
|
|
|
Xvalue2[i] := min2 + (i) * incrSize2;
|
2020-03-30 18:01:44 +00:00
|
|
|
prob1 := probz(abs(Xvalue2[i-1]));
|
|
|
|
prob2 := probz(abs(Xvalue2[i]));
|
|
|
|
if prob1 > prob2 then
|
2020-09-30 10:19:19 +00:00
|
|
|
Var2Freq[i-1] := round((prob1 - prob2) * nCases)
|
2020-03-30 18:01:44 +00:00
|
|
|
else
|
2020-09-30 10:19:19 +00:00
|
|
|
Var2Freq[i-1] := round((prob2 - prob1) * nCases)
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
Cumfreq2[0] := Var2Freq[0];
|
|
|
|
for i := 1 to noints do
|
|
|
|
Cumfreq2[i] := Cumfreq2[i-1] + Var2Freq[i];
|
|
|
|
end
|
|
|
|
else
|
2020-09-30 10:19:19 +00:00
|
|
|
if tDistChk.Checked then // t-distribution
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
|
|
|
name2 := 't-Dist.';
|
|
|
|
min2 := -3.0;
|
|
|
|
max2 := 3.0;
|
2020-09-30 10:19:19 +00:00
|
|
|
df1 := nCases - 1;
|
2020-03-30 18:01:44 +00:00
|
|
|
range2 := max2 - min2;
|
|
|
|
incrsize2 := range2 / noints;
|
|
|
|
Xvalue2[0] := min2;
|
|
|
|
Xvalue2[noints] := max2;
|
2020-09-30 10:19:19 +00:00
|
|
|
for i := 1 to noInts do
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
2020-09-30 10:19:19 +00:00
|
|
|
Xvalue2[i-1] := min2 + (i-1) * incrSize2;
|
|
|
|
Xvalue2[i] := min2 + (i) * incrSize2;
|
2020-03-30 18:01:44 +00:00
|
|
|
prob1 := 0.5 * probt(Xvalue2[i-1],df1);
|
|
|
|
prob2 := 0.5 * probt(Xvalue2[i],df1);
|
|
|
|
if prob1 > prob2 then
|
2020-09-30 10:19:19 +00:00
|
|
|
Var2Freq[i-1] := round((prob1-prob2) * nCases)
|
2020-03-30 18:01:44 +00:00
|
|
|
else
|
2020-09-30 10:19:19 +00:00
|
|
|
Var2Freq[i-1] := round((prob2-prob1) * nCases)
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
Cumfreq2[0] := Var2Freq[0];
|
2020-09-30 10:19:19 +00:00
|
|
|
for i := 1 to noInts do
|
2020-03-30 18:01:44 +00:00
|
|
|
Cumfreq2[i] := Cumfreq2[i-1] + Var2Freq[i];
|
|
|
|
end
|
|
|
|
else
|
2020-09-30 10:19:19 +00:00
|
|
|
if ChiSqDistChk.Checked then // chi squared distribution
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
|
|
|
cellval := InputBox('Deg. Freedom 1 Entry','DF 1','');
|
|
|
|
df1 := StrToInt(cellval);
|
2020-09-30 10:19:19 +00:00
|
|
|
name2 := 'Chi Sq';
|
2020-03-30 18:01:44 +00:00
|
|
|
min2 := 0.0;
|
|
|
|
max2 := 20.0;
|
|
|
|
range2 := max2 - min2;
|
2020-09-30 10:19:19 +00:00
|
|
|
incrSize2 := range2 / noInts;
|
|
|
|
xValue2[0] := min2;
|
|
|
|
xValue2[noInts] := max2;
|
2020-03-30 18:01:44 +00:00
|
|
|
for i := 1 to noints do
|
|
|
|
begin
|
2020-09-30 10:19:19 +00:00
|
|
|
Xvalue2[i-1] := min2 + (i-1) * incrSize2;
|
|
|
|
Xvalue2[i] := min2 + (i) * incrSize2;
|
2020-03-30 18:01:44 +00:00
|
|
|
prob1 := chisquaredprob(Xvalue2[i-1],df1);
|
|
|
|
prob2 := chisquaredprob(Xvalue2[i],df1);
|
|
|
|
if prob1 > prob2 then
|
2020-09-30 10:19:19 +00:00
|
|
|
Var2Freq[i-1] := round((prob1-prob2) * nCases)
|
2020-03-30 18:01:44 +00:00
|
|
|
else
|
2020-09-30 10:19:19 +00:00
|
|
|
Var2Freq[i-1] := round((prob2-prob1) * nCases)
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
2020-09-30 10:19:19 +00:00
|
|
|
cumfreq2[0] := var2Freq[0];
|
2020-03-30 18:01:44 +00:00
|
|
|
for i := 1 to noints do
|
2020-09-30 10:19:19 +00:00
|
|
|
cumfreq2[i] := cumfreq2[i-1] + var2Freq[i];
|
2020-03-30 18:01:44 +00:00
|
|
|
end
|
|
|
|
else
|
2020-09-30 10:19:19 +00:00
|
|
|
if FDistChk.Checked then // F distribution
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
|
|
|
// get degrees of freedom
|
|
|
|
cellval := InputBox('Deg. Freedom 1 Entry','DF 1','');
|
|
|
|
df1 := StrToInt(cellval);
|
|
|
|
cellval := InputBox('Deg. Freedom 2 Entry','DF 2','');
|
|
|
|
df2 := StrToInt(cellval);
|
|
|
|
name2 := 'F Dist.';
|
|
|
|
min2 := 0.0;
|
|
|
|
max2 := 3.0;
|
|
|
|
range2 := max2 - min2;
|
|
|
|
incrsize2 := range2 / noints;
|
|
|
|
Xvalue2[0] := min2;
|
|
|
|
Xvalue2[noints] := max2;
|
2020-09-30 10:19:19 +00:00
|
|
|
for i := 1 to noInts do
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
2020-09-30 10:19:19 +00:00
|
|
|
Xvalue2[i-1] := min2 + (i-1) * incrSize2;
|
|
|
|
Xvalue2[i] := min2 + (i) * incrSize2;
|
2020-09-28 14:05:34 +00:00
|
|
|
prob1 := ProbF(Xvalue2[i-1],df1,df2);
|
|
|
|
prob2 := ProbF(Xvalue2[i],df1,df2);
|
2020-03-30 18:01:44 +00:00
|
|
|
if prob1 > prob2 then
|
2020-09-30 10:19:19 +00:00
|
|
|
Var2Freq[i-1] := round((prob1-prob2) * nCases)
|
2020-03-30 18:01:44 +00:00
|
|
|
else
|
2020-09-30 10:19:19 +00:00
|
|
|
Var2Freq[i-1] := round((prob2-prob1) * nCases)
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
2020-09-30 10:19:19 +00:00
|
|
|
cumfreq2[0] := Var2Freq[0];
|
|
|
|
for i := 1 to noInts do
|
|
|
|
cumfreq2[i] := cumfreq2[i-1] + var2Freq[i];
|
2020-03-30 18:01:44 +00:00
|
|
|
end
|
|
|
|
else
|
2020-09-30 10:19:19 +00:00
|
|
|
if PoissonDistChk.Checked then // Poisson distribution
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
|
|
|
name2 := 'Poisson';
|
|
|
|
mean := 0; // use as parameter a in pdf call
|
|
|
|
min2 := min1;
|
|
|
|
max2 := max1;
|
|
|
|
if max2 > 13 then
|
|
|
|
begin
|
2020-05-10 23:10:20 +00:00
|
|
|
ErrorMsg('Value > 13 found. Factorial too large - exiting.');
|
2020-03-30 18:01:44 +00:00
|
|
|
exit;
|
|
|
|
end;
|
2020-09-30 10:19:19 +00:00
|
|
|
for i := 1 to nCases do
|
|
|
|
mean := mean + StrToFloat(OS3MainFrm.DataGrid.Cells[col1, i]);
|
|
|
|
mean := mean / nCases;
|
2020-03-30 18:01:44 +00:00
|
|
|
cellval := IntToStr(round(mean));
|
2020-09-30 10:19:19 +00:00
|
|
|
cellval := InputBox('Parameter Entry (mean)', 'DF 1', cellval);
|
2020-03-30 18:01:44 +00:00
|
|
|
degfree := StrToFloat(cellval);
|
|
|
|
range2 := max2 - min2;
|
2020-09-30 10:19:19 +00:00
|
|
|
incrsize2 := range2 / noInts;
|
2020-03-30 18:01:44 +00:00
|
|
|
// Xvalue2[0] := min2;
|
|
|
|
Xvalue2[noints] := max2;
|
|
|
|
for i := 1 to noints do
|
|
|
|
begin
|
2020-09-30 10:19:19 +00:00
|
|
|
Xvalue2[i-1] := min2 + (i-1) * incrSize2;
|
|
|
|
Xvalue2[i] := min2 + (i) * incrSize2;
|
2020-03-30 18:01:44 +00:00
|
|
|
poisson_pdf ( round(Xvalue2[i-1]), degfree, prob1 );
|
|
|
|
// prob1 := (Xvalue2[i-1],df1);
|
|
|
|
// prob2 := chisquaredprob(Xvalue2[i],df1);
|
|
|
|
// if prob1 > prob2 then
|
2020-09-30 10:19:19 +00:00
|
|
|
Var2Freq[i-1] := round((prob1) * nCases);
|
2020-03-30 18:01:44 +00:00
|
|
|
// else Var2Freq[i-1] := round((prob2-prob1) * Ncases)
|
|
|
|
end;
|
2020-09-30 10:19:19 +00:00
|
|
|
cumfreq2[0] := var2Freq[0];
|
|
|
|
for i := 1 to noInts do
|
|
|
|
cumfreq2[i] := cumfreq2[i-1] + var2Freq[i];
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2020-09-30 10:19:19 +00:00
|
|
|
*)
|
2020-03-30 18:01:44 +00:00
|
|
|
lReport := TStringList.Create;
|
|
|
|
try
|
|
|
|
lReport.Add('DISTRIBUTION COMPARISON by Bill Miller');
|
|
|
|
lReport.Add('');
|
|
|
|
lReport.Add('%10s %10s %10s %10s %10s %10s', [
|
|
|
|
name1, name1, name1, name2, name2, name2
|
|
|
|
]);
|
|
|
|
lReport.Add('%10s %10s %10s %10s %10s %10s', [
|
2020-05-10 10:49:11 +00:00
|
|
|
'X1 Value', 'Frequency', 'Cum. Freq.', 'X2 Value', 'Frequency', 'Cum. Freq.'
|
2020-03-30 18:01:44 +00:00
|
|
|
]);
|
2020-09-30 10:19:19 +00:00
|
|
|
lReport.Add('---------- ---------- ---------- ---------- ---------- ----------');
|
2020-03-30 18:01:44 +00:00
|
|
|
for i := 1 to noints do
|
2020-09-30 10:19:19 +00:00
|
|
|
lReport.Add('%10.3f %10.0f %10.3f %10.3f %10.0f %10.3f', [
|
2020-05-10 10:49:11 +00:00
|
|
|
XValue1[i-1], Var1Freq[i-1], Cumfreq1[i-1], XValue2[i-1], Var2Freq[i-1], Cumfreq2[i-1]
|
2020-03-30 18:01:44 +00:00
|
|
|
]);
|
2020-09-30 10:19:19 +00:00
|
|
|
lReport.Add('');
|
2020-03-30 18:01:44 +00:00
|
|
|
cellval := 'D';
|
2020-09-30 10:19:19 +00:00
|
|
|
KS := KolmogorovTest(noInts, Cumfreq1, noInts, Cumfreq2, cellVal, lReport);
|
2020-03-30 18:01:44 +00:00
|
|
|
// lReport.Add('Kolmogorov-Smirnov statistic := %5.3f', [KS]);
|
|
|
|
|
2020-09-29 13:49:25 +00:00
|
|
|
FReportFrame.DisplayReport(lReport);
|
2020-03-30 18:01:44 +00:00
|
|
|
finally
|
|
|
|
lReport.Free;
|
|
|
|
end;
|
|
|
|
|
|
|
|
// plot the cdfs
|
2020-09-30 10:19:19 +00:00
|
|
|
Plot(FCumFreqChartFrame, cumFreq1, cumFreq2, VarOneEdit.Text, name2);
|
|
|
|
|
|
|
|
if BothChk.Checked then
|
|
|
|
Plot(FFreqChartFrame, var1Freq, var2Freq, VarOneEdit.Text, name2);
|
|
|
|
|
|
|
|
FreqChartPage.TabVisible := BothChk.Checked;
|
|
|
|
|
|
|
|
(*
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
xtitle := 'Red = ' + VarOneEdit.Text + ' Blue = ' + name2;
|
|
|
|
cellval := 'Plot of Cumulative Distributions';
|
2020-09-29 13:49:25 +00:00
|
|
|
{
|
2020-03-30 18:01:44 +00:00
|
|
|
if LinesChk.Checked then
|
|
|
|
GraphFrm.barwideprop := 1.0
|
|
|
|
else
|
|
|
|
GraphFrm.barwideprop := 0.5;
|
2020-09-29 13:49:25 +00:00
|
|
|
}
|
2020-03-30 18:01:44 +00:00
|
|
|
GraphFrm.nosets := 2;
|
|
|
|
GraphFrm.nbars := noints+1;
|
|
|
|
GraphFrm.Heading := cellval;
|
|
|
|
GraphFrm.XTitle := xtitle;
|
|
|
|
GraphFrm.YTitle := 'Frequency';
|
|
|
|
SetLength(GraphFrm.Ypoints,2,noints+1);
|
|
|
|
SetLength(GraphFrm.Xpoints,1,noints+1);
|
|
|
|
for k := 1 to noints+1 do
|
|
|
|
begin
|
|
|
|
GraphFrm.Ypoints[0,k-1] := Cumfreq1[k-1];
|
|
|
|
GraphFrm.Ypoints[1,k-1] := CumFreq2[k-1];
|
|
|
|
GraphFrm.Xpoints[0,k-1] := k;
|
|
|
|
end;
|
|
|
|
GraphFrm.AutoScaled := true;
|
2020-09-29 13:49:25 +00:00
|
|
|
{
|
2020-03-30 18:01:44 +00:00
|
|
|
if LinesChk.Checked then
|
|
|
|
GraphFrm.GraphType := 6 // 3d lines
|
|
|
|
else
|
|
|
|
GraphFrm.GraphType := 8; // 3D points
|
2020-09-29 13:49:25 +00:00
|
|
|
}
|
2020-03-30 18:01:44 +00:00
|
|
|
GraphFrm.BackColor := clYellow;
|
|
|
|
GraphFrm.WallColor := clBlue;
|
|
|
|
GraphFrm.FloorColor := clGray;
|
|
|
|
GraphFrm.ShowLeftWall := true;
|
|
|
|
GraphFrm.ShowRightWall := true;
|
|
|
|
GraphFrm.ShowBottomWall := true;
|
|
|
|
GraphFrm.ShowBackWall := true;
|
|
|
|
GraphFrm.ShowModal;
|
|
|
|
GraphFrm.Xpoints := nil;
|
|
|
|
GraphFrm.Ypoints := nil;
|
|
|
|
|
|
|
|
if BothChk.Checked then // plot the frequencies
|
|
|
|
begin
|
|
|
|
xtitle := 'Red = ' + VarOneEdit.Text + ' Blue = ' + name2;
|
|
|
|
cellval := 'Plot of Cumulative Distributions';
|
2020-09-29 13:49:25 +00:00
|
|
|
{
|
2020-03-30 18:01:44 +00:00
|
|
|
if LinesChk.Checked then
|
|
|
|
GraphFrm.BarWideProp := 1.0
|
|
|
|
else
|
|
|
|
GraphFrm.BarWideProp := 0.5;
|
2020-09-29 13:49:25 +00:00
|
|
|
}
|
2020-03-30 18:01:44 +00:00
|
|
|
GraphFrm.nosets := 2;
|
|
|
|
GraphFrm.nbars := noints+1;
|
|
|
|
GraphFrm.Heading := cellval;
|
|
|
|
GraphFrm.XTitle := xtitle;
|
|
|
|
GraphFrm.YTitle := 'Frequency';
|
|
|
|
SetLength(GraphFrm.Ypoints,2,noints+1);
|
|
|
|
SetLength(GraphFrm.Xpoints,1,noints+1);
|
|
|
|
for k := 1 to noints+1 do
|
|
|
|
begin
|
|
|
|
GraphFrm.Ypoints[0,k-1] := Var1Freq[k-1];
|
|
|
|
GraphFrm.Ypoints[1,k-1] := Var2Freq[k-1];
|
|
|
|
GraphFrm.Xpoints[0,k-1] := k;
|
|
|
|
end;
|
|
|
|
GraphFrm.AutoScaled := true;
|
2020-09-29 13:49:25 +00:00
|
|
|
{
|
2020-03-30 18:01:44 +00:00
|
|
|
if LinesChk.Checked then
|
|
|
|
GraphFrm.GraphType := 6 // 3d lines
|
|
|
|
else
|
|
|
|
GraphFrm.GraphType := 8; // 3D points
|
2020-09-29 13:49:25 +00:00
|
|
|
}
|
2020-03-30 18:01:44 +00:00
|
|
|
GraphFrm.BackColor := clYellow;
|
|
|
|
GraphFrm.WallColor := clBlue;
|
|
|
|
GraphFrm.FloorColor := clGray;
|
|
|
|
GraphFrm.ShowLeftWall := true;
|
|
|
|
GraphFrm.ShowRightWall := true;
|
|
|
|
GraphFrm.ShowBottomWall := true;
|
|
|
|
GraphFrm.ShowBackWall := true;
|
|
|
|
GraphFrm.ShowModal;
|
|
|
|
GraphFrm.Xpoints := nil;
|
|
|
|
GraphFrm.Ypoints := nil;
|
|
|
|
end;
|
2020-09-30 10:19:19 +00:00
|
|
|
*)
|
2020-03-30 18:01:44 +00:00
|
|
|
|
|
|
|
// clean up
|
|
|
|
Cumfreq2 := nil;
|
|
|
|
Cumfreq1 := nil;
|
|
|
|
XValue1 := nil;
|
|
|
|
XValue2 := nil;
|
|
|
|
Var2Freq := nil;
|
|
|
|
Var1Freq := nil;
|
|
|
|
end;
|
|
|
|
|
2020-09-29 13:49:25 +00:00
|
|
|
|
2020-09-30 10:19:19 +00:00
|
|
|
procedure TCompareDistFrm.DistChange(Sender: TObject);
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
2020-09-30 10:19:19 +00:00
|
|
|
DF1Edit.Visible := CompareDist <> cd_Normal;
|
|
|
|
DF1Label.Visible := DF1Edit.Visible;
|
|
|
|
DF1Label.Caption := 'D.F.';
|
|
|
|
|
|
|
|
DF2Edit.Visible := CompareDist = cd_F;
|
|
|
|
DF2Label.Visible := DF2Edit.Visible;
|
|
|
|
|
|
|
|
if NormalDistChk.Checked then
|
|
|
|
CompareDist := cd_Normal
|
|
|
|
else if tDistChk.Checked then
|
|
|
|
begin
|
|
|
|
CompareDist := cd_t;
|
|
|
|
UpdateDF1;
|
|
|
|
end
|
|
|
|
else if ChiSqDistChk.Checked then
|
|
|
|
CompareDist := cd_ChiSq
|
|
|
|
else if FDistChk.Checked then
|
|
|
|
begin
|
|
|
|
CompareDist := cd_F;
|
|
|
|
DF1Label.Caption := 'D.F. 1';
|
|
|
|
end
|
|
|
|
else if PoissonDistChk.Checked then
|
|
|
|
begin
|
|
|
|
CompareDist := cd_Poisson;
|
|
|
|
DF1Label.Caption := 'Mean';
|
|
|
|
UpdateDF1;
|
|
|
|
end else
|
|
|
|
raise Exception.Create('Distribution not supported.');
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
|
2020-09-29 13:49:25 +00:00
|
|
|
|
|
|
|
procedure TCompareDistFrm.FormActivate(Sender: TObject);
|
|
|
|
var
|
|
|
|
w: Integer;
|
|
|
|
begin
|
|
|
|
if FAutoSized then
|
|
|
|
exit;
|
|
|
|
|
|
|
|
w := MaxValue([ResetBtn.Width, ComputeBtn.Width, CloseBtn.Width]);
|
|
|
|
ResetBtn.Constraints.MinWidth := w;
|
|
|
|
ComputeBtn.Constraints.MinWidth := w;
|
|
|
|
CloseBtn.Constraints.MinWidth := w;
|
|
|
|
|
|
|
|
Notebook.AutoSize := true;
|
|
|
|
ParamsPanel.Constraints.MinWidth := Max(
|
|
|
|
3*w + 2*CloseBtn.BorderSpacing.Left,
|
|
|
|
Min(
|
|
|
|
CompareGroup.Width * 2 - Var1InBtn.Width + VarList.BorderSpacing.Right,
|
|
|
|
OptionsGroup.Width)
|
|
|
|
);
|
|
|
|
ParamsPanel.Constraints.MinHeight := Notebook.Top + Notebook.Height +
|
|
|
|
OptionsGroup.BorderSpacing.Top + OptionsGroup.Height + Bevel1.Height +
|
|
|
|
CloseBtn.Height + CloseBtn.BorderSpacing.Top;
|
|
|
|
|
|
|
|
Constraints.MinWidth := ParamsPanel.Constraints.MinWidth + 300;
|
|
|
|
Constraints.MinHeight := ParamsPanel.Constraints.MinHeight + ParamsPanel.BorderSpacing.Top * 2;
|
|
|
|
if Width < Constraints.MinWidth then Width := 1;
|
|
|
|
if Height < Constraints.MinHeight then Height := 1;
|
|
|
|
|
2020-09-30 10:19:19 +00:00
|
|
|
// Notebook.AutoSize := false;
|
2020-09-29 13:49:25 +00:00
|
|
|
Position := poDesigned;
|
|
|
|
FAutoSized := true;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
procedure TCompareDistFrm.FormCreate(Sender: TObject);
|
|
|
|
begin
|
|
|
|
Assert(OS3MainFrm <> nil);
|
|
|
|
if GraphFrm = nil then Application.CreateForm(TGraphFrm, GraphFrm);
|
|
|
|
|
|
|
|
InitForm(self);
|
|
|
|
|
|
|
|
FReportFrame := TReportFrame.Create(self);
|
|
|
|
FReportFrame.Parent := ReportPage;
|
|
|
|
FReportFrame.Align := alClient;
|
|
|
|
|
2020-09-30 10:19:19 +00:00
|
|
|
FCumFreqChartFrame := TChartFrame.Create(self);
|
|
|
|
FCumFreqChartFrame.Parent := CumFreqChartPage;
|
|
|
|
FCumFreqChartFrame.Align := alClient;
|
|
|
|
FCumFreqChartFrame.Chart.BottomAxis.Intervals.MaxLength := 80;
|
|
|
|
FCumFreqChartFrame.Chart.BottomAxis.Intervals.MinLength := 30;
|
|
|
|
FCumFreqChartFrame.SetYTitle('Cumulative frequency');
|
|
|
|
FCumFreqChartFrame.SetTitle('Plot of Cumulative Distributions');
|
|
|
|
|
|
|
|
FFreqChartFrame := TChartFrame.Create(self);
|
|
|
|
FFreqChartFrame.Parent := FreqChartPage;
|
|
|
|
FFreqChartFrame.Align := alClient;
|
|
|
|
FFreqChartFrame.Chart.BottomAxis.Intervals.MaxLength := 80;
|
|
|
|
FFreqChartFrame.Chart.BottomAxis.Intervals.MinLength := 30;
|
|
|
|
FFreqChartFrame.SetYTitle('Frequency');
|
|
|
|
FFreqChartFrame.SetTitle('Plot of Distributions');
|
2020-09-29 13:49:25 +00:00
|
|
|
|
|
|
|
Reset;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
2020-09-30 10:19:19 +00:00
|
|
|
procedure TCompareDistFrm.Plot(AChartFrame: TChartFrame; Y1Values, Y2Values: DblDyneVec;
|
|
|
|
AName1, AName2: String);
|
|
|
|
var
|
|
|
|
ser1, ser2: TChartSeries;
|
|
|
|
plotType: TPlotType;
|
|
|
|
begin
|
|
|
|
AChartFrame.Clear;
|
|
|
|
|
|
|
|
if BarPlotBtn.Down then
|
|
|
|
plotType := ptBars
|
|
|
|
else
|
|
|
|
plotType := ptLines;
|
|
|
|
|
|
|
|
ser1 := AChartFrame.PlotXY(plotType, nil, Y1Values, nil, nil, AName1, DATA_COLORS[0]);
|
|
|
|
ser2 := AChartFrame.PlotXY(plotType, nil, Y2Values, nil, nil, AName2, DATA_Colors[1]);
|
|
|
|
|
|
|
|
if (ser1 is TBarSeries) then
|
|
|
|
begin
|
|
|
|
with ser1 as TBarSeries do
|
|
|
|
begin
|
|
|
|
BarWidthPercent := 40;
|
|
|
|
BarOffsetPercent := -20;
|
|
|
|
end;
|
|
|
|
with ser2 as TBarSeries do
|
|
|
|
begin
|
|
|
|
BarWidthPercent := 40;
|
|
|
|
BarOffsetPercent := +20;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
2020-09-29 13:49:25 +00:00
|
|
|
procedure TCompareDistFrm.Reset;
|
2020-03-30 18:01:44 +00:00
|
|
|
var
|
|
|
|
i: integer;
|
|
|
|
begin
|
|
|
|
VarList.Clear;
|
2020-09-30 10:19:19 +00:00
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
VarOneEdit.Text := '';
|
|
|
|
VarTwoEdit.Text := '';
|
2020-09-30 10:19:19 +00:00
|
|
|
DF1Edit.Text := '';
|
|
|
|
DF2Edit.Text := '';
|
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
for i := 1 to NoVariables do
|
|
|
|
VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]);
|
2020-09-30 10:19:19 +00:00
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
CompareGroup.ItemIndex := 0;
|
2020-09-29 13:49:25 +00:00
|
|
|
CompareGroupClick(nil);
|
2020-09-30 10:19:19 +00:00
|
|
|
NormalDistChk.Checked := true;
|
|
|
|
DistChange(nil);
|
2020-09-29 13:49:25 +00:00
|
|
|
|
|
|
|
FReportFrame.Clear;
|
2020-09-30 10:19:19 +00:00
|
|
|
FCumFreqChartFrame.Clear;
|
|
|
|
FFreqChartFrame.Clear;
|
|
|
|
FreqChartPage.TabVisible := false;
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
|
2020-09-29 13:49:25 +00:00
|
|
|
|
|
|
|
procedure TCompareDistFrm.ResetBtnClick(Sender: TObject);
|
|
|
|
begin
|
|
|
|
Reset;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
procedure TCompareDistFrm.UpdateBtnStates;
|
|
|
|
begin
|
|
|
|
Var1InBtn.Enabled := (VarList.ItemIndex > -1) and (VarOneEdit.Text = '');
|
|
|
|
Var2InBtn.Enabled := (VarList.ItemIndex > -1) and (VarTwoEdit.Text = '');
|
|
|
|
Var1OutBtn.Enabled := VarOneEdit.Text <> '';
|
|
|
|
Var2OutBtn.Enabled := VarTwoEdit.Text <> '';
|
|
|
|
|
|
|
|
FReportFrame.UpdateBtnStates;
|
2020-09-30 10:19:19 +00:00
|
|
|
FCumFreqChartFrame.UpdateBtnStates;
|
|
|
|
FFreqChartFrame.UpdateBtnStates;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
procedure TCompareDistFrm.UpdateDF1;
|
|
|
|
|
|
|
|
procedure DFCandidates(AVarName: String; out AMean: Double; out ANumCases: Integer);
|
|
|
|
var
|
|
|
|
col, i: Integer;
|
|
|
|
begin
|
|
|
|
for col := 1 to NoVariables do
|
|
|
|
if AVarName = OS3MainFrm.DataGrid.Cells[col, 0] then
|
|
|
|
begin
|
|
|
|
AMean := 0;
|
|
|
|
ANumCases := 0;
|
|
|
|
for i := 1 to NoCases do
|
|
|
|
if ValidValue(i, col) then
|
|
|
|
begin
|
|
|
|
AMean := AMean + StrToFloat(OS3MainFrm.DataGrid.Cells[col, i]);
|
|
|
|
inc(ANumCases);
|
|
|
|
end;
|
|
|
|
if ANumCases > 1 then
|
|
|
|
AMean := AMean / ANumCases
|
|
|
|
else
|
|
|
|
AMean := NaN;
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
AMean := NaN;
|
|
|
|
ANumCases := -1;
|
|
|
|
end;
|
|
|
|
|
|
|
|
var
|
|
|
|
m: Double;
|
|
|
|
n: Integer;
|
|
|
|
begin
|
|
|
|
if (CompareTo = ctTheoreticalDistrib) then
|
|
|
|
begin
|
|
|
|
DFCandidates(VarOneEdit.Text, m, n);
|
|
|
|
case CompareDist of
|
|
|
|
cd_t :
|
|
|
|
if n > 0 then
|
|
|
|
DF1Edit.Text := IntToStr(n-1);
|
|
|
|
cd_Poisson:
|
|
|
|
if not IsNaN(m) then
|
|
|
|
DF1Edit.Text := FormatFloat('0', m);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
function TCompareDistFrm.Validate(ANumCases: Integer;
|
|
|
|
out AMsg: String; out AControl: TWinControl): Boolean;
|
|
|
|
var
|
|
|
|
n: Integer = 0;
|
|
|
|
begin
|
|
|
|
Result := false;
|
|
|
|
|
|
|
|
if CompareDist <> cd_Normal then
|
|
|
|
begin
|
|
|
|
if DF1Edit.Text = '' then
|
|
|
|
begin
|
|
|
|
AMsg := 'This control cannot be empty.';
|
|
|
|
AControl := DF1Edit;
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
if not TryStrToInt(DF1Edit.Text, n) or (n < 0) then
|
|
|
|
begin
|
|
|
|
AMsg := 'Positive integer value required.';
|
|
|
|
AControl := DF1Edit;
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
if (n >= ANumCases) and (CompareDist <> cd_Poisson) then
|
|
|
|
begin
|
|
|
|
AMsg := 'Degrees of freedom cannot be greater than the number of cases.';
|
|
|
|
AControl := DF1Edit;
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
if CompareDist = cd_F then
|
|
|
|
begin
|
|
|
|
if DF2Edit.Text = '' then
|
|
|
|
begin
|
|
|
|
AMsg := 'This control cannot be empty.';
|
|
|
|
AControl := DF2Edit;
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
if not TryStrToInt(DF2Edit.Text, n) or (n < 0) then
|
|
|
|
begin
|
|
|
|
AMsg := 'Positive integer value required.';
|
|
|
|
AControl := DF2Edit;
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
if n >= ANumCases then
|
|
|
|
begin
|
|
|
|
AMsg := 'Degrees of freedom cannot be greater than the number of cases.';
|
|
|
|
AControl := DF2Edit;
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
Result := true;
|
2020-09-29 13:49:25 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
procedure TCompareDistFrm.Var1InBtnClick(Sender: TObject);
|
|
|
|
var
|
|
|
|
i: integer;
|
|
|
|
begin
|
|
|
|
i := 0;
|
|
|
|
while (VarOneEdit.Text = '') and (i < VarList.Items.Count) do
|
|
|
|
begin
|
|
|
|
if VarList.Selected[i] then
|
|
|
|
begin
|
|
|
|
VarOneEdit.Text := VarList.Items[i];
|
|
|
|
VarList.Items.Delete(i);
|
|
|
|
i := 0;
|
|
|
|
end else
|
|
|
|
inc(i);
|
|
|
|
end;
|
|
|
|
UpdateBtnStates;
|
2020-09-30 10:19:19 +00:00
|
|
|
UpdateDF1;
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
|
2020-09-29 13:49:25 +00:00
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
procedure TCompareDistFrm.Var1OutBtnClick(Sender: TObject);
|
|
|
|
begin
|
|
|
|
if VarOneEdit.Text <> '' then
|
|
|
|
begin
|
|
|
|
VarList.Items.Add(VarOneEdit.Text);
|
|
|
|
VarOneEdit.Text := '';
|
|
|
|
end;
|
|
|
|
UpdateBtnStates;
|
|
|
|
end;
|
|
|
|
|
2020-09-29 13:49:25 +00:00
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
procedure TCompareDistFrm.Var2InBtnClick(Sender: TObject);
|
|
|
|
var
|
|
|
|
i: integer;
|
|
|
|
begin
|
|
|
|
i := 0;
|
|
|
|
while (VarTwoEdit.Text = '') and (i < VarList.Items.Count) do
|
|
|
|
begin
|
|
|
|
if VarList.Selected[i] then
|
|
|
|
begin
|
|
|
|
VarTwoEdit.Text := VarList.Items[i];
|
|
|
|
VarList.Items.Delete(i);
|
|
|
|
i := 0;
|
|
|
|
end else
|
|
|
|
inc(i);
|
|
|
|
end;
|
|
|
|
UpdateBtnStates;
|
|
|
|
end;
|
|
|
|
|
2020-09-29 13:49:25 +00:00
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
procedure TCompareDistFrm.Var2OutBtnClick(Sender: TObject);
|
|
|
|
begin
|
|
|
|
if VarTwoEdit.Text <> '' then
|
|
|
|
begin
|
|
|
|
VarList.Items.Add(VarTwoEdit.Text);
|
|
|
|
VarTwoEdit.Text := '';
|
|
|
|
end;
|
|
|
|
UpdateBtnStates;
|
|
|
|
end;
|
|
|
|
|
2020-09-29 13:49:25 +00:00
|
|
|
|
|
|
|
procedure TCompareDistFrm.VarListDblClick(Sender: TObject);
|
|
|
|
var
|
|
|
|
index: Integer;
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
2020-09-29 13:49:25 +00:00
|
|
|
index := VarList.ItemIndex;
|
|
|
|
if (index > -1) then
|
|
|
|
begin
|
|
|
|
if VarOneEdit.Text = '' then
|
|
|
|
begin
|
|
|
|
VarOneEdit.Text := VarList.Items[index];
|
|
|
|
VarList.Items.Delete(index);
|
|
|
|
end;
|
|
|
|
if CompareGroup.ItemIndex = 1 then // Compare to another variable
|
|
|
|
begin
|
|
|
|
VarTwoEdit.Text := VarList.Items[index];
|
|
|
|
VarList.Items.Delete(index);
|
|
|
|
end;
|
|
|
|
UpdateBtnStates;
|
|
|
|
end;
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
|
2020-09-29 13:49:25 +00:00
|
|
|
|
|
|
|
procedure TCompareDistFrm.VarListSelectionChange(Sender: TObject; User: boolean);
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
2020-09-29 13:49:25 +00:00
|
|
|
UpdateBtnStates;
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
end.
|
|
|
|
|