You've already forked lazarus-ccr
LazStats: Fix bug in NormalDist. Nicer report layout in CompareDistUnit.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7724 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -527,13 +527,13 @@ inherited CompareDistFrm: TCompareDistFrm
|
|||||||
Height = 519
|
Height = 519
|
||||||
Top = 8
|
Top = 8
|
||||||
Width = 599
|
Width = 599
|
||||||
ActivePage = CumFreqChartPage
|
ActivePage = ReportPage
|
||||||
Align = alClient
|
Align = alClient
|
||||||
BorderSpacing.Left = 4
|
BorderSpacing.Left = 4
|
||||||
BorderSpacing.Top = 8
|
BorderSpacing.Top = 8
|
||||||
BorderSpacing.Right = 8
|
BorderSpacing.Right = 8
|
||||||
BorderSpacing.Bottom = 8
|
BorderSpacing.Bottom = 8
|
||||||
TabIndex = 1
|
TabIndex = 0
|
||||||
TabOrder = 1
|
TabOrder = 1
|
||||||
object ReportPage: TTabSheet
|
object ReportPage: TTabSheet
|
||||||
Caption = 'Report'
|
Caption = 'Report'
|
||||||
|
@ -80,25 +80,39 @@ type
|
|||||||
FAutoSized: Boolean;
|
FAutoSized: Boolean;
|
||||||
CompareTo: TCompareTo;
|
CompareTo: TCompareTo;
|
||||||
CompareDist: TCompareDist;
|
CompareDist: TCompareDist;
|
||||||
|
|
||||||
procedure CalcFreq(XValues, FreqValues, CumFreqValues: DblDyneVec;
|
procedure CalcFreq(XValues, FreqValues, CumFreqValues: DblDyneVec;
|
||||||
AMin, AIncrement: Double; ANumIntervals, AColIndex: Integer);
|
AMin, AIncrement: Double; ANumIntervals, AColIndex: Integer);
|
||||||
|
|
||||||
procedure CalcFreq(XValues, FreqValues, CumFreqValues: DblDyneVec;
|
procedure CalcFreq(XValues, FreqValues, CumFreqValues: DblDyneVec;
|
||||||
AMin, AMax: Double; ANumIntervals, ANumCases: Integer;
|
AMin, AMax: Double; ANumIntervals, ANumCases: Integer;
|
||||||
ACompareDist: TCompareDist; DF1: Integer = -1; DF2: Integer = -1);
|
ACompareDist: TCompareDist; DF1: Integer = -1; DF2: Integer = -1);
|
||||||
|
|
||||||
procedure CalcIntervals(var AMin, AMax, AIntervalsize: Double;
|
procedure CalcIntervals(var AMin, AMax, AIntervalsize: Double;
|
||||||
out ANumIntervals: Integer);
|
out ANumIntervals: Integer);
|
||||||
|
|
||||||
function CalcMinMax(out AMin, AMax: Double; AColIndex: Integer): Integer;
|
function CalcMinMax(out AMin, AMax: Double; AColIndex: Integer): Integer;
|
||||||
|
|
||||||
procedure CalcTheoreticalDist(XValues, FreqValues, CumFreqValues: DblDyneVec;
|
procedure CalcTheoreticalDist(XValues, FreqValues, CumFreqValues: DblDyneVec;
|
||||||
ANumIntervals, ANumCases: Integer; ACompareDist: TCompareDist; out AName: String);
|
ANumIntervals, ANumCases: Integer; ACompareDist: TCompareDist; out AName: String);
|
||||||
|
|
||||||
|
procedure DisplayReport(XValue1, XValue2, FreqValues1, FreqValues2,
|
||||||
|
CumFreqValues1, CumFreqValues2: DblDyneVec; AName1, AName2: String;
|
||||||
|
ANumIntervals: Integer);
|
||||||
|
|
||||||
procedure Plot(AChartFrame: TChartFrame; Y1Values, Y2Values: DblDyneVec;
|
procedure Plot(AChartFrame: TChartFrame; Y1Values, Y2Values: DblDyneVec;
|
||||||
ASeriesTitle1, ASeriesTitle2, AYTitle, ATitle: String);
|
ASeriesTitle1, ASeriesTitle2, AYTitle, ATitle: String);
|
||||||
|
|
||||||
procedure UpdateBtnStates;
|
procedure UpdateBtnStates;
|
||||||
|
|
||||||
procedure UpdateDF1;
|
procedure UpdateDF1;
|
||||||
|
|
||||||
function Validate(ANumCases: Integer;
|
function Validate(ANumCases: Integer;
|
||||||
out AMsg: String; out AControl: TWinControl): Boolean;
|
out AMsg: String; out AControl: TWinControl): Boolean;
|
||||||
|
|
||||||
public
|
public
|
||||||
procedure Reset; override;
|
procedure Reset; override;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -272,35 +286,6 @@ begin
|
|||||||
end;
|
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;
|
|
||||||
*)
|
|
||||||
|
|
||||||
procedure TCompareDistFrm.CloseBtnClick(Sender: TObject);
|
procedure TCompareDistFrm.CloseBtnClick(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
Close;
|
Close;
|
||||||
@ -326,10 +311,8 @@ var
|
|||||||
min1, max1, min2, max2: double;
|
min1, max1, min2, max2: double;
|
||||||
incrSize1: Double = 0.0;
|
incrSize1: Double = 0.0;
|
||||||
incrSize2: Double = 0.0;
|
incrSize2: Double = 0.0;
|
||||||
KS: double;
|
name1, name2, msg: string;
|
||||||
cellVal, name1, name2, msg: string;
|
|
||||||
C: TWinControl;
|
C: TWinControl;
|
||||||
lReport: TStrings;
|
|
||||||
begin
|
begin
|
||||||
// Get columns of the variables
|
// Get columns of the variables
|
||||||
col1 := 0;
|
col1 := 0;
|
||||||
@ -409,29 +392,7 @@ begin
|
|||||||
name1 := VarOneEdit.Text;
|
name1 := VarOneEdit.Text;
|
||||||
|
|
||||||
// Print distributions to report
|
// Print distributions to report
|
||||||
lReport := TStringList.Create;
|
DisplayReport(xValue1, xValue2, var1Freq, var2Freq, cumfreq1, cumFreq2, name1, name2, noInts);
|
||||||
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', [
|
|
||||||
'X1 Value', 'Frequency', 'Cum. Freq.', 'X2 Value', 'Frequency', 'Cum. Freq.'
|
|
||||||
]);
|
|
||||||
lReport.Add('---------- ---------- ---------- ---------- ---------- ----------');
|
|
||||||
for i := 1 to noints do
|
|
||||||
lReport.Add('%10.3f %10.0f %10.3f %10.3f %10.0f %10.3f', [
|
|
||||||
XValue1[i-1], Var1Freq[i-1], Cumfreq1[i-1], XValue2[i-1], Var2Freq[i-1], Cumfreq2[i-1]
|
|
||||||
]);
|
|
||||||
lReport.Add('');
|
|
||||||
KS := KolmogorovTest(noInts, Cumfreq1, noInts, Cumfreq2, 'D', lReport);
|
|
||||||
lReport.Add('Kolmogorov-Smirnov statistic: %5.3f', [KS]);
|
|
||||||
|
|
||||||
FReportFrame.DisplayReport(lReport);
|
|
||||||
finally
|
|
||||||
lReport.Free;
|
|
||||||
end;
|
|
||||||
|
|
||||||
// Plot the cumulative distributions
|
// Plot the cumulative distributions
|
||||||
Plot(FCumFreqChartFrame, cumFreq1, cumFreq2, VarOneEdit.Text, name2,
|
Plot(FCumFreqChartFrame, cumFreq1, cumFreq2, VarOneEdit.Text, name2,
|
||||||
@ -443,6 +404,75 @@ begin
|
|||||||
'Frequency', 'Plot of Distributions');
|
'Frequency', 'Plot of Distributions');
|
||||||
|
|
||||||
FreqChartPage.TabVisible := BothChk.Checked;
|
FreqChartPage.TabVisible := BothChk.Checked;
|
||||||
|
|
||||||
|
(*
|
||||||
|
// Print distributions to report
|
||||||
|
name1 := CenterString(name1, 12);
|
||||||
|
name2 := CenterString(name2, 12);
|
||||||
|
lReport := TStringList.Create;
|
||||||
|
try
|
||||||
|
lReport.Add('DISTRIBUTION COMPARISON by Bill Miller');
|
||||||
|
lReport.Add('');
|
||||||
|
lReport.Add('%12s %12s %12s %12s %12s %12s', [
|
||||||
|
name1, name1, name1, name2, name2, name2
|
||||||
|
]);
|
||||||
|
lReport.Add('%12s %12s %12s %12s %12s %12s', [
|
||||||
|
CenterString('X1 Value', 12), CenterString('Frequency', 12), CenterString('Cum. Freq.', 12),
|
||||||
|
CenterString('X2 Value', 12), CenterString('Frequency', 12), CenterString('Cum. Freq.', 12)
|
||||||
|
]);
|
||||||
|
lReport.Add('------------ ------------ ------------ ------------ ------------ ------------');
|
||||||
|
for i := 1 to noints do
|
||||||
|
lReport.Add('%12.3f %12.0f %12.3f %12.3f %12.0f %12.3f', [
|
||||||
|
XValue1[i-1], Var1Freq[i-1], Cumfreq1[i-1], XValue2[i-1], Var2Freq[i-1], Cumfreq2[i-1]
|
||||||
|
]);
|
||||||
|
lReport.Add('');
|
||||||
|
KS := KolmogorovTest(noInts, Cumfreq1, noInts, Cumfreq2, '', lReport);
|
||||||
|
lReport.Add('Kolmogorov-Smirnov statistic: %5.3f', [KS]);
|
||||||
|
|
||||||
|
FReportFrame.DisplayReport(lReport);
|
||||||
|
finally
|
||||||
|
lReport.Free;
|
||||||
|
end;
|
||||||
|
*)
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TCompareDistFrm.DisplayReport(XValue1, XValue2, FreqValues1, FreqValues2,
|
||||||
|
CumFreqValues1, CumFreqValues2: DblDyneVec; AName1, AName2: String;
|
||||||
|
ANumIntervals: Integer);
|
||||||
|
var
|
||||||
|
lReport: TStrings;
|
||||||
|
i: Integer;
|
||||||
|
KS: Double;
|
||||||
|
begin
|
||||||
|
AName1 := CenterString(AName1, 12);
|
||||||
|
AName2 := CenterString(AName2, 12);
|
||||||
|
|
||||||
|
lReport := TStringList.Create;
|
||||||
|
try
|
||||||
|
lReport.Add('DISTRIBUTION COMPARISON by Bill Miller');
|
||||||
|
lReport.Add('');
|
||||||
|
lReport.Add('%12s %12s %12s %12s %12s %12s', [
|
||||||
|
AName1, AName1, AName1, AName2, AName2, AName2
|
||||||
|
]);
|
||||||
|
lReport.Add('%12s %12s %12s %12s %12s %12s', [
|
||||||
|
CenterString('X1 Value', 12), CenterString('Frequency', 12), CenterString('Cum. Freq.', 12),
|
||||||
|
CenterString('X2 Value', 12), CenterString('Frequency', 12), CenterString('Cum. Freq.', 12)
|
||||||
|
]);
|
||||||
|
lReport.Add('------------ ------------ ------------ ------------ ------------ ------------');
|
||||||
|
for i := 0 to ANumIntervals-1 do
|
||||||
|
lReport.Add('%12.3f %12.0f %12.3f %12.3f %12.0f %12.3f', [
|
||||||
|
XValue1[i], FreqValues1[i], CumFreqValues1[i],
|
||||||
|
XValue2[i], FreqValues2[i], CumFreqValues2[i]
|
||||||
|
]);
|
||||||
|
lReport.Add('');
|
||||||
|
KS := KolmogorovTest(ANumIntervals, CumFreqValues1, ANumIntervals, CumFreqValues2, '', lReport);
|
||||||
|
lReport.Add('Kolmogorov-Smirnov statistic: %5.3f', [KS]);
|
||||||
|
|
||||||
|
FReportFrame.DisplayReport(lReport);
|
||||||
|
finally
|
||||||
|
lReport.Free;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -553,6 +583,7 @@ begin
|
|||||||
AChartFrame.Clear;
|
AChartFrame.Clear;
|
||||||
|
|
||||||
AChartFrame.SetTitle(ATitle);
|
AChartFrame.SetTitle(ATitle);
|
||||||
|
AChartFrame.SetXTitle('Interval Index');
|
||||||
AChartFrame.SetYTitle(AYTitle);
|
AChartFrame.SetYTitle(AYTitle);
|
||||||
|
|
||||||
if BarPlotBtn.Down then
|
if BarPlotBtn.Down then
|
||||||
|
@ -139,7 +139,7 @@ begin
|
|||||||
if x < 0 then
|
if x < 0 then
|
||||||
Result := (1.0 - erf(-x / SQRT2)) * 0.5
|
Result := (1.0 - erf(-x / SQRT2)) * 0.5
|
||||||
else
|
else
|
||||||
Result := 0;
|
Result := 0.5;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function NormalDistDensity(x, AMean, AStdDev: Double): Double;
|
function NormalDistDensity(x, AMean, AStdDev: Double): Double;
|
||||||
|
@ -28,15 +28,16 @@ procedure Exchange(var a, b: String); overload;
|
|||||||
procedure SortOnX(X: DblDyneVec; Y: DblDyneVec = nil; Z: DblDyneVec = nil);
|
procedure SortOnX(X: DblDyneVec; Y: DblDyneVec = nil; Z: DblDyneVec = nil);
|
||||||
procedure SortOnX(X: DblDyneVec; Y: DblDyneMat);
|
procedure SortOnX(X: DblDyneVec; Y: DblDyneMat);
|
||||||
|
|
||||||
procedure QuickSortOnX(X: DblDyneVec; Y: DblDyneVec = nil; Z: DblDyneVec = nil);
|
procedure QuickSortOnX(X: DblDyneVec; Y: DblDyneVec = nil; Z: DblDyneVec = nil); // not 100% tested...
|
||||||
|
|
||||||
|
function CenterString(S: String; Width: Integer): String;
|
||||||
function IndexOfString(L: StrDyneVec; s: String): Integer;
|
function IndexOfString(L: StrDyneVec; s: String): Integer;
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Math, ToolWin;
|
StrUtils, Math, ToolWin;
|
||||||
|
|
||||||
// https://stackoverflow.com/questions/4093595/create-ttoolbutton-runtime
|
// https://stackoverflow.com/questions/4093595/create-ttoolbutton-runtime
|
||||||
procedure AddButtonToToolbar(AToolButton: TToolButton; AToolBar: TToolBar);
|
procedure AddButtonToToolbar(AToolButton: TToolButton; AToolBar: TToolBar);
|
||||||
@ -225,6 +226,28 @@ begin
|
|||||||
DoQuickSort(0, High(X));
|
DoQuickSort(0, High(X));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function CenterString(S: String; Width: Integer): String;
|
||||||
|
var
|
||||||
|
n1, n2: Integer;
|
||||||
|
begin
|
||||||
|
n1 := Width - Length(S);
|
||||||
|
if n1 <= 0 then
|
||||||
|
begin
|
||||||
|
Result := S;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
n1 := n1 div 2;
|
||||||
|
if Length(S) + 2*n1 < Width then
|
||||||
|
n2 := n1+1
|
||||||
|
else
|
||||||
|
n2 := n1;
|
||||||
|
|
||||||
|
Result := DupeString(' ', n1) + S + DupeString(' ', n2);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function IndexOfString(L: StrDyneVec; s: String): Integer;
|
function IndexOfString(L: StrDyneVec; s: String): Integer;
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
|
Reference in New Issue
Block a user