LazStats: Show cumulative probabilities in DistribUnit

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7639 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2020-08-28 21:58:45 +00:00
parent 74d1082ccb
commit e65cc723d5
5 changed files with 340 additions and 129 deletions

View File

@ -1429,6 +1429,11 @@
<DebugInfoType Value="dsDwarf2"/> <DebugInfoType Value="dsDwarf2"/>
</Debugging> </Debugging>
<LinkSmart Value="True"/> <LinkSmart Value="True"/>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking> </Linking>
</CompilerOptions> </CompilerOptions>
<Debugging> <Debugging>

View File

@ -2,12 +2,12 @@ object DistribFrm: TDistribFrm
Left = 420 Left = 420
Height = 432 Height = 432
Top = 215 Top = 215
Width = 687 Width = 701
HelpType = htKeyword HelpType = htKeyword
HelpKeyword = 'html/DistributionPlotsandCriticalValu.htm' HelpKeyword = 'html/DistributionPlotsandCriticalValu.htm'
Caption = 'Distributions' Caption = 'Distributions'
ClientHeight = 432 ClientHeight = 432
ClientWidth = 687 ClientWidth = 701
OnActivate = FormActivate OnActivate = FormActivate
OnShow = FormShow OnShow = FormShow
Position = poMainFormCenter Position = poMainFormCenter
@ -19,7 +19,7 @@ object DistribFrm: TDistribFrm
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = Owner AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom AnchorSideBottom.Side = asrBottom
Left = 624 Left = 638
Height = 25 Height = 25
Top = 401 Top = 401
Width = 55 Width = 55
@ -35,7 +35,7 @@ object DistribFrm: TDistribFrm
object ComputeBtn: TButton object ComputeBtn: TButton
AnchorSideTop.Control = CloseBtn AnchorSideTop.Control = CloseBtn
AnchorSideRight.Control = CloseBtn AnchorSideRight.Control = CloseBtn
Left = 540 Left = 554
Height = 25 Height = 25
Top = 401 Top = 401
Width = 76 Width = 76
@ -50,7 +50,7 @@ object DistribFrm: TDistribFrm
object ResetBtn: TButton object ResetBtn: TButton
AnchorSideTop.Control = CloseBtn AnchorSideTop.Control = CloseBtn
AnchorSideRight.Control = ComputeBtn AnchorSideRight.Control = ComputeBtn
Left = 478 Left = 492
Height = 25 Height = 25
Top = 401 Top = 401
Width = 54 Width = 54
@ -72,7 +72,7 @@ object DistribFrm: TDistribFrm
Left = 0 Left = 0
Height = 8 Height = 8
Top = 385 Top = 385
Width = 687 Width = 701
Anchors = [akLeft, akRight, akBottom] Anchors = [akLeft, akRight, akBottom]
Shape = bsBottomLine Shape = bsBottomLine
end end
@ -84,7 +84,7 @@ object DistribFrm: TDistribFrm
Left = 8 Left = 8
Height = 377 Height = 377
Top = 8 Top = 8
Width = 479 Width = 454
Anchors = [akTop, akLeft, akRight, akBottom] Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Left = 8 BorderSpacing.Left = 8
BorderSpacing.Top = 8 BorderSpacing.Top = 8
@ -92,7 +92,7 @@ object DistribFrm: TDistribFrm
BevelOuter = bvNone BevelOuter = bvNone
BorderStyle = bsSingle BorderStyle = bsSingle
ClientHeight = 373 ClientHeight = 373
ClientWidth = 475 ClientWidth = 450
Color = clWhite Color = clWhite
ParentColor = False ParentColor = False
TabOrder = 3 TabOrder = 3
@ -100,7 +100,7 @@ object DistribFrm: TDistribFrm
Left = 6 Left = 6
Height = 361 Height = 361
Top = 6 Top = 6
Width = 463 Width = 438
AxisList = < AxisList = <
item item
Grid.Color = clSilver Grid.Color = clSilver
@ -146,6 +146,12 @@ object DistribFrm: TDistribFrm
end end
object VertLineSeries: TLineSeries object VertLineSeries: TLineSeries
Active = False Active = False
LinePen.Color = clRed
LinePen.Style = psDot
end
object HorLineSeries: TLineSeries
LinePen.Color = clRed
LinePen.Style = psDot
end end
end end
end end
@ -181,42 +187,42 @@ object DistribFrm: TDistribFrm
AnchorSideRight.Control = Owner AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = Bevel1 AnchorSideBottom.Control = Bevel1
Left = 499 Left = 474
Height = 377 Height = 377
Top = 8 Top = 8
Width = 180 Width = 219
Anchors = [akTop, akRight, akBottom] Anchors = [akTop, akRight, akBottom]
AutoSize = True AutoSize = True
BorderSpacing.Top = 8 BorderSpacing.Top = 8
BorderSpacing.Right = 8 BorderSpacing.Right = 8
BevelOuter = bvNone BevelOuter = bvNone
ClientHeight = 377 ClientHeight = 377
ClientWidth = 180 ClientWidth = 219
TabOrder = 6 TabOrder = 6
object GroupBox1: TGroupBox object GroupBox1: TGroupBox
AnchorSideLeft.Control = ParameterPanel AnchorSideLeft.Control = ParameterPanel
AnchorSideTop.Control = ParameterPanel AnchorSideTop.Control = ParameterPanel
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 0 Left = 0
Height = 136 Height = 175
Top = 0 Top = 0
Width = 180 Width = 219
AutoSize = True AutoSize = True
Caption = 'Plot Distribution:' Caption = 'Plot Distribution'
ChildSizing.LeftRightSpacing = 16 ChildSizing.LeftRightSpacing = 16
ChildSizing.TopBottomSpacing = 8 ChildSizing.TopBottomSpacing = 8
ChildSizing.VerticalSpacing = 8 ChildSizing.VerticalSpacing = 8
ChildSizing.EnlargeVertical = crsHomogenousSpaceResize ChildSizing.EnlargeVertical = crsScaleChilds
ChildSizing.Layout = cclLeftToRightThenTopToBottom ChildSizing.Layout = cclLeftToRightThenTopToBottom
ChildSizing.ControlsPerLine = 1 ChildSizing.ControlsPerLine = 1
ClientHeight = 116 ClientHeight = 155
ClientWidth = 176 ClientWidth = 215
TabOrder = 0 TabOrder = 0
object NDChk: TRadioButton object NDChk: TRadioButton
Left = 16 Left = 16
Height = 19 Height = 19
Top = 8 Top = 8
Width = 144 Width = 183
Caption = 'Normal Distribution' Caption = 'Normal Distribution'
OnClick = DistributionClick OnClick = DistributionClick
TabOrder = 0 TabOrder = 0
@ -225,8 +231,8 @@ object DistribFrm: TDistribFrm
Left = 16 Left = 16
Height = 19 Height = 19
Top = 35 Top = 35
Width = 144 Width = 183
Caption = 'Student t Distribution' Caption = 'Student t Distribution (1-sided)'
OnClick = DistributionClick OnClick = DistributionClick
TabOrder = 3 TabOrder = 3
end end
@ -234,7 +240,7 @@ object DistribFrm: TDistribFrm
Left = 16 Left = 16
Height = 19 Height = 19
Top = 62 Top = 62
Width = 144 Width = 183
Caption = 'Central F Distribution' Caption = 'Central F Distribution'
OnClick = DistributionClick OnClick = DistributionClick
TabOrder = 2 TabOrder = 2
@ -243,11 +249,28 @@ object DistribFrm: TDistribFrm
Left = 16 Left = 16
Height = 19 Height = 19
Top = 89 Top = 89
Width = 144 Width = 183
Caption = 'Chi-Square Distribution' Caption = 'Chi-Square Distribution'
OnClick = DistributionClick OnClick = DistributionClick
TabOrder = 1 TabOrder = 1
end end
object Bevel2: TBevel
Left = 16
Height = 4
Top = 116
Width = 183
Constraints.MaxHeight = 4
Shape = bsBottomLine
end
object CumulativeChk: TCheckBox
Left = 16
Height = 19
Top = 128
Width = 183
Caption = 'Cumulative'
OnChange = CumulativeChkChange
TabOrder = 4
end
end end
object GroupBox2: TGroupBox object GroupBox2: TGroupBox
AnchorSideLeft.Control = GroupBox1 AnchorSideLeft.Control = GroupBox1
@ -256,21 +279,22 @@ object DistribFrm: TDistribFrm
AnchorSideRight.Control = GroupBox1 AnchorSideRight.Control = GroupBox1
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 0 Left = 0
Height = 140 Height = 107
Top = 152 Top = 191
Width = 180 Width = 219
Anchors = [akTop, akLeft, akRight] Anchors = [akTop, akLeft, akRight]
AutoSize = True
BorderSpacing.Top = 16 BorderSpacing.Top = 16
BorderSpacing.Bottom = 12 BorderSpacing.Bottom = 12
Caption = 'Parameters' Caption = 'Parameters'
ClientHeight = 120 ClientHeight = 87
ClientWidth = 176 ClientWidth = 215
TabOrder = 1 TabOrder = 1
object AlphaLabel: TLabel object AlphaLabel: TLabel
AnchorSideTop.Control = AlphaEdit AnchorSideTop.Control = AlphaEdit
AnchorSideTop.Side = asrCenter AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = AlphaEdit AnchorSideRight.Control = AlphaEdit
Left = 29 Left = 68
Height = 15 Height = 15
Top = 6 Top = 6
Width = 84 Width = 84
@ -283,7 +307,7 @@ object DistribFrm: TDistribFrm
AnchorSideTop.Control = DF1Edit AnchorSideTop.Control = DF1Edit
AnchorSideTop.Side = asrCenter AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = DF1Edit AnchorSideRight.Control = DF1Edit
Left = 22 Left = 61
Height = 15 Height = 15
Top = 33 Top = 33
Width = 91 Width = 91
@ -297,7 +321,7 @@ object DistribFrm: TDistribFrm
AnchorSideTop.Control = DF2Edit AnchorSideTop.Control = DF2Edit
AnchorSideTop.Side = asrCenter AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = DF2Edit AnchorSideRight.Control = DF2Edit
Left = 22 Left = 61
Height = 15 Height = 15
Top = 60 Top = 60
Width = 91 Width = 91
@ -307,25 +331,11 @@ object DistribFrm: TDistribFrm
Caption = 'Deg. Freedom (2)' Caption = 'Deg. Freedom (2)'
ParentColor = False ParentColor = False
end end
object MeanLabel: TLabel
AnchorSideTop.Control = MeanEdit
AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = MeanEdit
Left = 83
Height = 15
Top = 93
Width = 30
Anchors = [akTop, akRight]
BorderSpacing.Right = 8
Caption = 'Mean'
ParentColor = False
Visible = False
end
object AlphaEdit: TEdit object AlphaEdit: TEdit
AnchorSideTop.Control = GroupBox2 AnchorSideTop.Control = GroupBox2
AnchorSideRight.Control = GroupBox2 AnchorSideRight.Control = GroupBox2
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 121 Left = 160
Height = 23 Height = 23
Top = 2 Top = 2
Width = 43 Width = 43
@ -341,7 +351,7 @@ object DistribFrm: TDistribFrm
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = AlphaEdit AnchorSideRight.Control = AlphaEdit
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 121 Left = 160
Height = 23 Height = 23
Top = 29 Top = 29
Width = 43 Width = 43
@ -351,40 +361,36 @@ object DistribFrm: TDistribFrm
TabOrder = 1 TabOrder = 1
Text = 'DF1Edit' Text = 'DF1Edit'
end end
object MeanEdit: TEdit
AnchorSideTop.Control = DF2Edit
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = AlphaEdit
AnchorSideRight.Side = asrBottom
Left = 121
Height = 23
Top = 89
Width = 43
Alignment = taRightJustify
Anchors = [akTop, akRight]
BorderSpacing.Top = 4
BorderSpacing.Bottom = 8
TabOrder = 3
Text = 'MeanEdit'
Visible = False
end
object DF2Edit: TEdit object DF2Edit: TEdit
AnchorSideTop.Control = DF1Edit AnchorSideTop.Control = DF1Edit
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = AlphaEdit AnchorSideRight.Control = AlphaEdit
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 121 Left = 160
Height = 23 Height = 23
Top = 56 Top = 56
Width = 43 Width = 43
Alignment = taRightJustify Alignment = taRightJustify
Anchors = [akTop, akRight] Anchors = [akTop, akRight]
BorderSpacing.Top = 4 BorderSpacing.Top = 4
BorderSpacing.Bottom = 10 BorderSpacing.Bottom = 8
TabOrder = 2 TabOrder = 2
Text = 'DF2Edit' Text = 'DF2Edit'
end end
end end
object ShowCriticalValuesChk: TCheckBox
AnchorSideLeft.Control = ParameterPanel
AnchorSideTop.Control = GroupBox2
AnchorSideTop.Side = asrBottom
Left = 0
Height = 19
Top = 310
Width = 123
Caption = 'Show critical values'
Checked = True
State = cbChecked
TabOrder = 2
end
end end
object SavePictureDialog: TSavePictureDialog object SavePictureDialog: TSavePictureDialog
Filter = 'Graphic (*.png;*.bmp;*.jpeg;*.jpg;*.jpe;*.jfif;*.svg)|*.png;*.bmp;*.jpeg;*.jpg;*.jpe;*.jfif;*.svg|Portable Network Graphic (*.png)|*.png|Bitmaps (*.bmp)|*.bmp|Joint Picture Expert Group (*.jpeg;*.jpg;*.jpe;*.jfif)|*.jpeg;*.jpg;*.jpe;*.jfif|Scaleable Vector Graphic (*.svg)|*.svg|All Files (*.*)|*.*' Filter = 'Graphic (*.png;*.bmp;*.jpeg;*.jpg;*.jpe;*.jfif;*.svg)|*.png;*.bmp;*.jpeg;*.jpg;*.jpe;*.jfif;*.svg|Portable Network Graphic (*.png)|*.png|Bitmaps (*.bmp)|*.bmp|Joint Picture Expert Group (*.jpeg;*.jpg;*.jpe;*.jfif)|*.jpeg;*.jpg;*.jpe;*.jfif|Scaleable Vector Graphic (*.svg)|*.svg|All Files (*.*)|*.*'

View File

@ -23,7 +23,11 @@ type
TDistribFrm = class(TForm) TDistribFrm = class(TForm)
AlphaEdit: TEdit; AlphaEdit: TEdit;
Bevel1: TBevel; Bevel1: TBevel;
Bevel2: TBevel;
ShowCriticalValuesChk: TCheckBox;
HorLineSeries: TLineSeries;
ChartToolset: TChartToolset; ChartToolset: TChartToolset;
CumulativeChk: TCheckBox;
PanDragTool: TPanDragTool; PanDragTool: TPanDragTool;
tChk: TRadioButton; tChk: TRadioButton;
ZoomDragTool: TZoomDragTool; ZoomDragTool: TZoomDragTool;
@ -39,7 +43,6 @@ type
DF1Edit: TEdit; DF1Edit: TEdit;
DF2Edit: TEdit; DF2Edit: TEdit;
FChk: TRadioButton; FChk: TRadioButton;
MeanEdit: TEdit;
NDChk: TRadioButton; NDChk: TRadioButton;
ChartPanel: TPanel; ChartPanel: TPanel;
ResetBtn: TButton; ResetBtn: TButton;
@ -49,15 +52,19 @@ type
AlphaLabel: TLabel; AlphaLabel: TLabel;
DF1Label: TLabel; DF1Label: TLabel;
DF2Label: TLabel; DF2Label: TLabel;
MeanLabel: TLabel;
GroupBox1: TGroupBox; GroupBox1: TGroupBox;
procedure ComputeBtnClick(Sender: TObject); procedure ComputeBtnClick(Sender: TObject);
procedure CumulativeChkChange(Sender: TObject);
procedure FormActivate(Sender: TObject); procedure FormActivate(Sender: TObject);
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure CalcChiSq(const AX: Double; out AY: Double); procedure CalcChi2(const AX: Double; out AY: Double);
procedure CalcChi2_Cumulative(const AX: Double; out AY: Double);
procedure CalcF(const AX: Double; out AY: Double); procedure CalcF(const AX: Double; out AY: Double);
procedure CalcF_Cumulative(const AX: Double; out AY: Double);
procedure CalcND(const AX: Double; out AY: Double); procedure CalcND(const AX: Double; out AY: Double);
procedure Calct(const AX: Double; out AY: Double); procedure CalcND_Cumulative(const AX: Double; out AY: Double);
procedure CalcT(const AX: Double; out AY: Double);
procedure CalcT_Cumulative(const AX: Double; out AY: Double);
procedure DistributionClick(Sender: TObject); procedure DistributionClick(Sender: TObject);
procedure PrintBtnClick(Sender: TObject); procedure PrintBtnClick(Sender: TObject);
procedure ResetBtnClick(Sender: TObject); procedure ResetBtnClick(Sender: TObject);
@ -67,7 +74,7 @@ type
DF1: Integer; DF1: Integer;
DF2: Integer; DF2: Integer;
procedure NormalDistPlot; procedure NormalDistPlot;
procedure ChiPlot; procedure Chi2Plot;
procedure FPlot; procedure FPlot;
procedure tPlot; procedure tPlot;
@ -97,7 +104,6 @@ begin
AlphaEdit.Text := FormatFloat('0.00', DEFAULT_ALPHA_LEVEL); AlphaEdit.Text := FormatFloat('0.00', DEFAULT_ALPHA_LEVEL);
DF1Edit.Text := ''; DF1Edit.Text := '';
DF2Edit.Text := ''; DF2Edit.Text := '';
MeanEdit.Text := '';
GroupBox2.Enabled := false; GroupBox2.Enabled := false;
FuncSeries.OnCalculate := nil; FuncSeries.OnCalculate := nil;
VertLineSeries.Active := false; VertLineSeries.Active := false;
@ -105,6 +111,7 @@ begin
Chart.BottomAxis.Title.Caption := 'Scale'; Chart.BottomAxis.Title.Caption := 'Scale';
end; end;
procedure TDistribFrm.SaveBtnClick(Sender: TObject); procedure TDistribFrm.SaveBtnClick(Sender: TObject);
var var
ext: String; ext: String;
@ -121,31 +128,67 @@ begin
end; end;
end; end;
procedure TDistribFrm.FormShow(Sender: TObject); procedure TDistribFrm.FormShow(Sender: TObject);
begin begin
ResetBtnClick(self); ResetBtnClick(self);
end; end;
procedure TDistribFrm.CalcF(const AX: Double; out AY: Double); procedure TDistribFrm.CalcF(const AX: Double; out AY: Double);
begin begin
AY := FDensity(AX, DF1, DF2); AY := FDensity(AX, DF1, DF2);
end; end;
procedure TDistribFrm.CalcF_Cumulative(const AX: Double; out AY: Double);
begin
AY := 1.0 - ProbF(AX, DF1, DF2);
end;
procedure TDistribFrm.CalcND(const AX: Double; out AY: Double); procedure TDistribFrm.CalcND(const AX: Double; out AY: Double);
begin begin
AY := 1.0 / sqrt(TWO_PI) * exp(-sqr(AX)/ 2.0); AY := 1.0 / sqrt(TWO_PI) * exp(-sqr(AX)/ 2.0);
end; end;
procedure TDistribFrm.CalcChiSq(const AX: Double; out AY: Double);
procedure TDistribFrm.CalcND_Cumulative(const AX: Double; out AY: Double);
begin
// AY := ProbZ(AX); -- very slow
AY := NormalDist(AX); // borrowed from NumLib
end;
procedure TDistribFrm.CalcChi2(const AX: Double; out AY: Double);
begin begin
AY := Chi2Density(AX, DF1); AY := Chi2Density(AX, DF1);
end; end;
procedure TDistribFrm.CalcChi2_Cumulative(const AX: Double; out AY: Double);
begin
AY := ChiSquaredProb(AX, DF1);
end;
procedure TDistribFrm.Calct(const AX: Double; out AY: Double); procedure TDistribFrm.Calct(const AX: Double; out AY: Double);
begin begin
AY := tDensity(AX, DF1); AY := tDensity(AX, DF1);
end; end;
procedure TDistribFrm.CalcT_Cumulative(const AX: Double; out AY: Double);
const
ONE_SIDED = true;
begin
if AX < 0 then
AY := tDist(-AX, DF1, ONE_SIDED)
else
AY := 1.0 - tDist(AX, DF1, ONE_SIDED);
end;
procedure TDistribFrm.DistributionClick(Sender: TObject); procedure TDistribFrm.DistributionClick(Sender: TObject);
var var
rb: TRadiobutton; rb: TRadiobutton;
@ -162,28 +205,9 @@ begin
DF2Edit.Enabled := (rb = FChk) and rb.Checked; DF2Edit.Enabled := (rb = FChk) and rb.Checked;
DF2Label.Enabled := DF2Edit.Enabled; DF2Label.Enabled := DF2Edit.Enabled;
MeanEdit.Enabled := false;
MeanLabel.Enabled := false;
{
if NDChk.Checked then
begin
GroupBox2.Enabled := true;
AlphaLabel.Enabled := true;
AlphaEdit.Enabled := true;
DF1Edit.Enabled := false;
DF1Label.Enabled := false;
DF2Label.Enabled := false;
MeanLabel.Enabled := false;
DF2Edit.Enabled := false;
MeanEdit.Enabled := false;
end
else
GroupBox2.Enabled := false;
}
end; end;
procedure TDistribFrm.PrintBtnClick(Sender: TObject); procedure TDistribFrm.PrintBtnClick(Sender: TObject);
const const
MARGIN = 10; MARGIN = 10;
@ -212,6 +236,7 @@ begin
end; end;
end; end;
procedure TDistribFrm.ComputeBtnClick(Sender: TObject); procedure TDistribFrm.ComputeBtnClick(Sender: TObject);
var var
msg: String; msg: String;
@ -240,7 +265,7 @@ begin
if ChiChk.Checked then if ChiChk.Checked then
begin begin
ChiPlot(); Chi2Plot();
ok := true; ok := true;
end; end;
@ -254,13 +279,23 @@ begin
MessageDlg('Please select a distribution.', mtError, [mbOK], 0); MessageDlg('Please select a distribution.', mtError, [mbOK], 0);
end; end;
procedure TDistribFrm.CumulativeChkChange(Sender: TObject);
begin
if CumulativeChk.Checked then
Chart.LeftAxis.Title.Caption := 'Cumulative probability'
else
Chart.LeftAxis.Title.Caption := 'Probability density';
end;
procedure TDistribFrm.NormalDistPlot; procedure TDistribFrm.NormalDistPlot;
var var
alpha: Double; alpha: Double;
zMax, zCrit, pCrit: Double; zMax, zMin, zCrit, pCrit: Double;
begin begin
alpha := StrToFloat(AlphaEdit.Text); alpha := StrToFloat(AlphaEdit.Text);
zMax := InverseZ(0.9999); zMax := InverseZ(0.9999);
zMin := -zMax;
zCrit := inversez(1.0 - alpha); zCrit := inversez(1.0 - alpha);
CalcND(zCrit, pCrit); CalcND(zCrit, pCrit);
@ -270,28 +305,44 @@ begin
Chart.Title.Text.Add(Format('Critical value = %.3f', [zCrit])); Chart.Title.Text.Add(Format('Critical value = %.3f', [zCrit]));
Chart.Title.Visible := true; Chart.Title.Visible := true;
Chart.BottomAxis.Title.Caption := 'z'; Chart.BottomAxis.Title.Caption := 'z';
FuncSeries.Extent.XMin := -zMax; FuncSeries.Extent.XMin := zMin;
FuncSeries.Extent.XMax := +zMax; FuncSeries.Extent.XMax := zMax;
FuncSeries.Extent.UseXMin := true; FuncSeries.Extent.UseXMin := true;
FuncSeries.Extent.UseXMax := true; FuncSeries.Extent.UseXMax := true;
FuncSeries.OnCalculate := @CalcND; if CumulativeChk.Checked then
FuncSeries.OnCalculate := @CalcND_Cumulative
else
FuncSeries.OnCalculate := @CalcND;
FuncSeries.DomainExclusions.Clear; FuncSeries.DomainExclusions.Clear;
VertLineSeries.Clear;
VertLineSeries.AddXY(zCrit, 0); VertlineSeries.Clear;
VertLineSeries.AddXY(zCrit, pCrit); if CumulativeChk.Checked then
VertLineSeries.Active := true; begin
HorLineSeries.Clear;
HorLineSeries.AddXY(zMin, 1.0 - alpha);
HorLineSeries.AddXY(zCrit, 1.0 - alpha);
VertlineSeries.AddXY(zCrit, 1.0 - alpha);
VertLineSeries.AddXY(zCrit, 0);
end else
begin
VertLineSeries.AddXY(zCrit, 0);
VertLineSeries.AddXY(zCrit, pCrit);
end;
HorLineSeries.Active := ShowCriticalValuesChk.Checked and CumulativeChk.Checked;
VertLineSeries.Active := ShowCriticalValuesChk.Checked;
end; end;
procedure TDistribFrm.ChiPlot;
procedure TDistribFrm.Chi2Plot;
var var
alpha: Double; alpha: Double;
Chi2Max, Chi2Crit, pCrit: Double; chi2Max, chi2Crit, pCrit: Double;
begin begin
alpha := StrToFloat(AlphaEdit.Text); alpha := StrToFloat(AlphaEdit.Text);
DF1 := StrToInt(DF1Edit.Text); DF1 := StrToInt(DF1Edit.Text);
Chi2Max := InverseChi(0.9999, DF1); chi2Max := InverseChi(0.9999, DF1);
Chi2Crit := InverseChi(1.0 - alpha, DF1); chi2Crit := InverseChi(1.0 - alpha, DF1);
CalcChiSq(Chi2Crit, pCrit); CalcChi2(chi2Crit, pCrit);
Chart.Title.Text.Clear; Chart.Title.Text.Clear;
Chart.Title.Text.Add('<b>Chi-Squared Distribution</b>'); Chart.Title.Text.Add('<b>Chi-Squared Distribution</b>');
@ -300,17 +351,32 @@ begin
Chart.Title.Visible := true; Chart.Title.Visible := true;
Chart.BottomAxis.Title.Caption := '&chi;<sup>2</sup>'; Chart.BottomAxis.Title.Caption := '&chi;<sup>2</sup>';
FuncSeries.Extent.XMin := 0; FuncSeries.Extent.XMin := 0;
FuncSeries.Extent.XMax := Chi2Max; FuncSeries.Extent.XMax := chi2Max;
FuncSeries.Extent.UseXMin := true; FuncSeries.Extent.UseXMin := true;
FuncSeries.Extent.UseXMax := true; FuncSeries.Extent.UseXMax := true;
FuncSeries.OnCalculate := @CalcChiSq; if CumulativeChk.Checked then
FuncSeries.OnCalculate := @CalcChi2_Cumulative
else
FuncSeries.OnCalculate := @CalcChi2;
FuncSeries.DomainExclusions.AddRange(-Infinity, 0, [ioOpenEnd]); FuncSeries.DomainExclusions.AddRange(-Infinity, 0, [ioOpenEnd]);
VertLineSeries.Clear; VertLineSeries.Clear;
VertLineSeries.AddXY(Chi2Crit, 0); if CumulativeChk.Checked then begin
VertLineSeries.AddXY(Chi2Crit, pCrit); HorLineSeries.Clear;
VertLineSeries.Active := true; HorLineSeries.AddXY(0, 1.0 - alpha);
HorLineSeries.AddXY(chi2Crit, 1.0 - alpha);
VertlineSeries.AddXY(chi2Crit, 1.0 - alpha);
VertLineSeries.AddXY(chi2Crit, 0);
end else
begin
VertLineSeries.AddXY(chi2Crit, 0);
VertLineSeries.AddXY(chi2Crit, pCrit);
end;
HorLineSeries.Active := ShowCriticalValuesChk.Checked and CumulativeChk.Checked;
VertLineSeries.Active := ShowCriticalValuesChk.Checked;
end; end;
procedure TDistribFrm.FPlot; procedure TDistribFrm.FPlot;
var var
alpha: Double; alpha: Double;
@ -333,22 +399,39 @@ begin
FuncSeries.Extent.XMax := FMax; FuncSeries.Extent.XMax := FMax;
FuncSeries.Extent.UseXMin := true; FuncSeries.Extent.UseXMin := true;
FuncSeries.Extent.UseXMax := true; FuncSeries.Extent.UseXMax := true;
FuncSeries.OnCalculate := @CalcF; if CumulativeChk.Checked then
FuncSeries.OnCalculate := @CalcF_Cumulative
else
FuncSeries.OnCalculate := @CalcF;
FuncSeries.DomainExclusions.AddRange(-Infinity, 0, [ioOpenEnd]); FuncSeries.DomainExclusions.AddRange(-Infinity, 0, [ioOpenEnd]);
VertLineSeries.Clear; VertLineSeries.Clear;
VertLineSeries.AddXY(FCrit, 0); if CumulativeChk.Checked then
VertLineSeries.AddXY(FCrit, pCrit); begin
VertLineSeries.Active := true; HorLineSeries.Clear;
HorLineSeries.AddXY(0, 1.0 - alpha);
HorLineSeries.AddXY(FCrit, 1.0 - alpha);
VertLineSeries.AddXY(FCrit, 1.0 - alpha);
VertLineSeries.AddXY(FCrit, 0);
end else
begin
VertLineSeries.AddXY(FCrit, 0);
VertLineSeries.AddXY(FCrit, pCrit);
end;
HorLineSeries.Active := ShowCriticalValuesChk.Checked and CumulativeChk.Checked;
VertLineSeries.Active := ShowCriticalValuesChk.Checked;
end; end;
procedure TDistribFrm.tPlot; procedure TDistribFrm.tPlot;
var var
alpha: Double; alpha: Double;
tMax, tCrit, pCrit: Double; tMin, tMax, tCrit, pCrit: Double;
begin begin
alpha := StrToFloat(AlphaEdit.Text); alpha := StrToFloat(AlphaEdit.Text);
DF1 := StrToInt(DF1Edit.Text); DF1 := StrToInt(DF1Edit.Text);
tMax := Inverset(0.9999, DF1); tMax := Inverset(0.9999, DF1);
tMin := -tMax;
tCrit := Inverset(1.0 - alpha, DF1); tCrit := Inverset(1.0 - alpha, DF1);
Calct(tCrit, pCrit); Calct(tCrit, pCrit);
@ -358,18 +441,34 @@ begin
Chart.Title.Text.Add(Format('Critical value = %.3f', [tCrit])); Chart.Title.Text.Add(Format('Critical value = %.3f', [tCrit]));
Chart.Title.Visible := true; Chart.Title.Visible := true;
Chart.BottomAxis.Title.Caption := 't'; Chart.BottomAxis.Title.Caption := 't';
FuncSeries.Extent.XMin := -tmax; FuncSeries.Extent.XMin := tMin;
FuncSeries.Extent.XMax := tMax; FuncSeries.Extent.XMax := tMax;
FuncSeries.Extent.UseXMin := true; FuncSeries.Extent.UseXMin := true;
FuncSeries.Extent.UseXMax := true; FuncSeries.Extent.UseXMax := true;
FuncSeries.OnCalculate := @Calct; if CumulativeChk.Checked then
FuncSeries.OnCalculate := @CalcT_Cumulative
else
FuncSeries.OnCalculate := @CalcT;
FuncSeries.DomainExclusions.Clear; FuncSeries.DomainExclusions.Clear;
VertLineSeries.Clear; VertLineSeries.Clear;
VertLineSeries.AddXY(tCrit, 0); if CumulativeChk.Checked then
VertLineSeries.AddXY(tCrit, pCrit); begin
VertLineSeries.Active := true; HorLineSeries.Clear;
HorLineSeries.AddXY(tMin, 1.0 - alpha);
HorLineSeries.AddXY(tCrit, 1.0 - alpha);
VertLineSeries.AddXY(tCrit, 1.0 - alpha);
VertLineSeries.AddXY(tCrit, 0);
end else
begin
VertLineSeries.AddXY(tCrit, 0);
VertLineSeries.AddXY(tCrit, pCrit);
end;
HorLineSeries.Active := ShowCriticalValuesChk.Checked and CumulativeChk.Checked;
VertLineSeries.Active := ShowCriticalValuesChk.Checked;
end; end;
procedure TDistribFrm.FormActivate(Sender: TObject); procedure TDistribFrm.FormActivate(Sender: TObject);
var var
w: Integer; w: Integer;

View File

@ -980,16 +980,15 @@ begin
end; end;
//------------------------------------------------------------------- //-------------------------------------------------------------------
function probt(t,df1 : double) : double; // Returns the probability corresponding to a two-tailed t test.
function ProbT(t, df1: double): double;
var var
F, prob : double; F, prob: double;
begin begin
// Returns the probability corresponding to a two-tailed t test. F := t * t;
F := t * t; prob := ProbF(F, 1.0, df1);
prob := probf(F,1.0,df1); Result := prob;
Result := prob;
end; end;
//------------------------------------------------------------------------
function inverset(Probt, DF : double) : double; function inverset(Probt, DF : double) : double;
var var

View File

@ -9,6 +9,10 @@ interface
uses uses
Classes, SysUtils; Classes, SysUtils;
function erf(x: Double): Double;
function erfc(x: Double) : Double;
function NormalDist(x: Double): Double;
function Beta(a, b: Double): Extended; function Beta(a, b: Double): Extended;
function BetaI(a,b,x: Double): Extended; function BetaI(a,b,x: Double): Extended;
@ -26,6 +30,104 @@ implementation
uses uses
Math; Math;
// Calculates the error function
// /x
// erf(x) = 2/sqrt(pi) * | exp(-t²) dt
// /0
// borrowed from NumLib
function erf(x: Double): Double;
const
xup = 6.25;
SQRT_PI = 1.7724538509055160;
c: array[1..18] of Double = (
1.9449071068178803e0, 4.20186582324414e-2, -1.86866103976769e-2,
5.1281061839107e-3, -1.0683107461726e-3, 1.744737872522e-4,
-2.15642065714e-5, 1.7282657974e-6, -2.00479241e-8,
-1.64782105e-8, 2.0008475e-9, 2.57716e-11,
-3.06343e-11, 1.9158e-12, 3.703e-13,
-5.43e-14, -4.0e-15, 1.2e-15
);
d: array[1..17] of Double = (
1.4831105640848036e0, -3.010710733865950e-1, 6.89948306898316e-2,
-1.39162712647222e-2, 2.4207995224335e-3, -3.658639685849e-4,
4.86209844323e-5, -5.7492565580e-6, 6.113243578e-7,
-5.89910153e-8, 5.2070091e-9, -4.232976e-10,
3.18811e-11, -2.2361e-12, 1.467e-13,
-9.0e-15, 5.0e-16
);
var
t, s, s1, s2, x2: Double;
bovc, bovd, j: Integer;
sgn: Integer;
begin
bovc := SizeOf(c) div SizeOf(Double);
bovd := SizeOf(d) div SizeOf(Double);
t := abs(x);
if t <= 2 then
begin
x2 := sqr(x) - 2;
s1 := d[bovd];
s2 := 0;
j := bovd - 1;
s := x2*s1 - s2 + d[j];
while j > 1 do
begin
s2 := s1;
s1 := s;
j := j-1;
s := x2*s1 - s2 + d[j];
end;
Result := (s - s2) * x / 2;
end else
if t < xup then
begin
x2 := 2 - 20 / (t+3);
s1 := c[bovc];
s2 := 0;
j := bovc - 1;
s := x2*s1 - s2 + c[j];
while j > 1 do
begin
s2 := s1;
s1 := s;
j := j-1;
s := x2*s1 - s2 + c[j];
end;
x2 := ((s-s2) / (2*t)) * exp(-sqr(x)) / SQRT_PI;
if x < 0 then sgn := -1 else sgn := +1;
Result := (1 - x2) * sgn
end
else
if x < 0 then
Result := -1.0
else
Result := +1.0;
end;
{ calculates the complementary error function erfc(x) = 1 - erf(x) }
function erfc(x: Double) : Double;
begin
Result := 1.0 - erf(x);
end;
// Cumulative normal distribution
// x = -INF ... INF --> 0 ... 1
function NormalDist(x: Double): Double;
const
SQRT2 = sqrt(2.0);
begin
if x > 0 then
Result := (erf(x / SQRT2) + 1) * 0.5
else
if x < 0 then
Result := (1.0 - erf(-x / SQRT2)) * 0.5
else
Result := 0;
end;
function Beta(a, b: Double): Extended; function Beta(a, b: Double): Extended;
begin begin
if (a > 0) and (b > 0) then if (a > 0) and (b > 0) then