LazStats: Merge chart with DistribUnit.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7635 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2020-08-24 22:36:30 +00:00
parent 8dc19b33c8
commit cd7073f12e
2 changed files with 591 additions and 611 deletions

View File

@ -1,30 +1,208 @@
object DistribFrm: TDistribFrm object DistribFrm: TDistribFrm
Left = 420 Left = 420
Height = 223 Height = 432
Top = 215 Top = 215
Width = 384 Width = 687
HelpType = htKeyword HelpType = htKeyword
HelpKeyword = 'html/DistributionPlotsandCriticalValu.htm' HelpKeyword = 'html/DistributionPlotsandCriticalValu.htm'
AutoSize = True
BorderStyle = bsDialog BorderStyle = bsDialog
Caption = 'Distributions' Caption = 'Distributions'
ClientHeight = 223 ClientHeight = 432
ClientWidth = 384 ClientWidth = 687
OnActivate = FormActivate OnActivate = FormActivate
OnCreate = FormCreate
OnShow = FormShow OnShow = FormShow
Position = poMainFormCenter Position = poMainFormCenter
LCLVersion = '2.1.0.0' LCLVersion = '2.1.0.0'
object GroupBox1: TGroupBox object CloseBtn: TButton
AnchorSideTop.Control = Bevel1
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
Left = 624
Height = 25
Top = 401
Width = 55
Anchors = [akRight, akBottom]
AutoSize = True
BorderSpacing.Top = 8
BorderSpacing.Right = 8
BorderSpacing.Bottom = 6
Caption = 'Close'
ModalResult = 11
TabOrder = 2
end
object ComputeBtn: TButton
AnchorSideTop.Control = CloseBtn
AnchorSideRight.Control = CloseBtn
Left = 540
Height = 25
Top = 401
Width = 76
Anchors = [akTop, akRight]
AutoSize = True
BorderSpacing.Left = 8
BorderSpacing.Right = 8
Caption = 'Compute'
OnClick = ComputeBtnClick
TabOrder = 1
end
object ResetBtn: TButton
AnchorSideTop.Control = CloseBtn
AnchorSideRight.Control = ComputeBtn
Left = 478
Height = 25
Top = 401
Width = 54
Anchors = [akTop, akRight]
AutoSize = True
BorderSpacing.Left = 8
BorderSpacing.Right = 8
BorderSpacing.Bottom = 8
Caption = 'Reset'
OnClick = ResetBtnClick
TabOrder = 0
end
object Bevel1: TBevel
AnchorSideLeft.Control = Owner
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = CloseBtn
Left = 0
Height = 8
Top = 385
Width = 687
Anchors = [akLeft, akRight, akBottom]
Shape = bsBottomLine
end
object Panel1: TPanel
AnchorSideLeft.Control = Owner AnchorSideLeft.Control = Owner
AnchorSideTop.Control = Owner AnchorSideTop.Control = Owner
Left = 12 AnchorSideRight.Control = Panel2
Height = 109 AnchorSideBottom.Control = Bevel1
Top = 12 Left = 8
Height = 377
Top = 8
Width = 479
Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Left = 8
BorderSpacing.Top = 8
BorderSpacing.Right = 12
BevelOuter = bvNone
BorderStyle = bsSingle
ClientHeight = 373
ClientWidth = 475
Color = clWhite
ParentColor = False
TabOrder = 3
object Chart: TChart
Left = 6
Height = 361
Top = 6
Width = 463
AxisList = <
item
Grid.Color = clSilver
Grid.Visible = False
Marks.LabelBrush.Style = bsClear
Minors = <>
Title.LabelFont.Orientation = 900
Title.LabelFont.Style = [fsBold]
Title.Visible = True
Title.Caption = 'Probability Density'
Title.LabelBrush.Style = bsClear
end
item
Grid.Color = clSilver
Grid.Visible = False
Alignment = calBottom
AxisPen.Visible = True
Marks.LabelBrush.Style = bsClear
Minors = <>
Title.LabelFont.Style = [fsBold]
Title.Visible = True
Title.Caption = 'Scale'
Title.LabelBrush.Style = bsClear
Title.TextFormat = tfHTML
end>
BackColor = clWhite
Foot.Brush.Color = clBtnFace
Foot.Font.Color = clBlue
Margins.Bottom = 0
Title.Brush.Style = bsClear
Title.Font.Color = clBlue
Title.Text.Strings = (
'TAChart'
)
Title.TextFormat = tfHTML
Toolset = ChartToolset
Align = alClient
BorderSpacing.Around = 6
Color = clWhite
object FuncSeries: TFuncSeries
ExtentAutoY = True
end
object VertLineSeries: TLineSeries
Active = False
end
end
end
object SaveBtn: TButton
AnchorSideLeft.Control = Owner
AnchorSideTop.Control = CloseBtn
Left = 8
Height = 25
Top = 401
Width = 50
AutoSize = True
BorderSpacing.Left = 8
Caption = 'Save'
OnClick = SaveBtnClick
TabOrder = 4
end
object PrintBtn: TButton
AnchorSideLeft.Control = SaveBtn
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = CloseBtn
Left = 66
Height = 25
Top = 401
Width = 51
AutoSize = True
BorderSpacing.Left = 8
Caption = 'Print'
OnClick = PrintBtnClick
TabOrder = 5
end
object Panel2: TPanel
AnchorSideTop.Control = Owner
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = Bevel1
Left = 499
Height = 377
Top = 8
Width = 180
Anchors = [akTop, akRight, akBottom]
AutoSize = True
BorderSpacing.Top = 8
BorderSpacing.Right = 8
BevelOuter = bvNone
Caption = 'Panel2'
ClientHeight = 377
ClientWidth = 180
TabOrder = 6
object GroupBox1: TGroupBox
AnchorSideLeft.Control = Panel2
AnchorSideTop.Control = Panel2
AnchorSideRight.Side = asrBottom
Left = 0
Height = 136
Top = 0
Width = 180 Width = 180
AutoSize = True AutoSize = True
BorderSpacing.Left = 12
BorderSpacing.Top = 12
Caption = 'Plot Distribution:' Caption = 'Plot Distribution:'
ChildSizing.LeftRightSpacing = 16 ChildSizing.LeftRightSpacing = 16
ChildSizing.TopBottomSpacing = 8 ChildSizing.TopBottomSpacing = 8
@ -32,7 +210,7 @@ object DistribFrm: TDistribFrm
ChildSizing.EnlargeVertical = crsHomogenousSpaceResize ChildSizing.EnlargeVertical = crsHomogenousSpaceResize
ChildSizing.Layout = cclLeftToRightThenTopToBottom ChildSizing.Layout = cclLeftToRightThenTopToBottom
ChildSizing.ControlsPerLine = 1 ChildSizing.ControlsPerLine = 1
ClientHeight = 89 ClientHeight = 116
ClientWidth = 176 ClientWidth = 176
TabOrder = 0 TabOrder = 0
object NDChk: TRadioButton object NDChk: TRadioButton
@ -44,14 +222,15 @@ object DistribFrm: TDistribFrm
OnClick = NDChkClick OnClick = NDChkClick
TabOrder = 0 TabOrder = 0
end end
object ChiChk: TRadioButton object tChk: TRadioButton
Left = 16 Left = 16
Height = 19 Height = 19
Top = 35 Top = 35
Width = 144 Width = 144
Caption = 'Chi-Square Distribution' Caption = 'Student t Distribution'
OnClick = ChiChkClick OnClick = tChkClick
TabOrder = 1 TabOrder = 3
Visible = False
end end
object FChk: TRadioButton object FChk: TRadioButton
Left = 16 Left = 16
@ -62,30 +241,38 @@ object DistribFrm: TDistribFrm
OnClick = FChkClick OnClick = FChkClick
TabOrder = 2 TabOrder = 2
end end
object ChiChk: TRadioButton
Left = 16
Height = 19
Top = 89
Width = 144
Caption = 'Chi-Square Distribution'
OnClick = ChiChkClick
TabOrder = 1
end
end end
object GroupBox2: TGroupBox object GroupBox2: TGroupBox
AnchorSideLeft.Control = GroupBox1 AnchorSideLeft.Control = GroupBox1
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = GroupBox1 AnchorSideTop.Control = GroupBox1
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = GroupBox1 AnchorSideRight.Control = GroupBox1
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 204 Left = 0
Height = 140 Height = 140
Top = 12 Top = 152
Width = 170 Width = 180
AutoSize = True Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 12 BorderSpacing.Top = 16
BorderSpacing.Right = 12
BorderSpacing.Bottom = 12 BorderSpacing.Bottom = 12
Caption = 'Parameters' Caption = 'Parameters'
ClientHeight = 120 ClientHeight = 120
ClientWidth = 166 ClientWidth = 176
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 = 19 Left = 29
Height = 15 Height = 15
Top = 6 Top = 6
Width = 84 Width = 84
@ -98,7 +285,7 @@ object DistribFrm: TDistribFrm
AnchorSideTop.Control = DF1Edit AnchorSideTop.Control = DF1Edit
AnchorSideTop.Side = asrCenter AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = DF1Edit AnchorSideRight.Control = DF1Edit
Left = 12 Left = 22
Height = 15 Height = 15
Top = 33 Top = 33
Width = 91 Width = 91
@ -112,11 +299,11 @@ object DistribFrm: TDistribFrm
AnchorSideTop.Control = DF2Edit AnchorSideTop.Control = DF2Edit
AnchorSideTop.Side = asrCenter AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = DF2Edit AnchorSideRight.Control = DF2Edit
Left = 12 Left = 22
Height = 15 Height = 15
Top = 60 Top = 60
Width = 91 Width = 91
Anchors = [akTop, akLeft, akRight] Anchors = [akTop, akRight]
BorderSpacing.Left = 12 BorderSpacing.Left = 12
BorderSpacing.Right = 8 BorderSpacing.Right = 8
Caption = 'Deg. Freedom (2)' Caption = 'Deg. Freedom (2)'
@ -126,7 +313,7 @@ object DistribFrm: TDistribFrm
AnchorSideTop.Control = MeanEdit AnchorSideTop.Control = MeanEdit
AnchorSideTop.Side = asrCenter AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = MeanEdit AnchorSideRight.Control = MeanEdit
Left = 73 Left = 83
Height = 15 Height = 15
Top = 93 Top = 93
Width = 30 Width = 30
@ -140,7 +327,7 @@ object DistribFrm: TDistribFrm
AnchorSideTop.Control = GroupBox2 AnchorSideTop.Control = GroupBox2
AnchorSideRight.Control = GroupBox2 AnchorSideRight.Control = GroupBox2
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 111 Left = 121
Height = 23 Height = 23
Top = 2 Top = 2
Width = 43 Width = 43
@ -156,7 +343,7 @@ object DistribFrm: TDistribFrm
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = AlphaEdit AnchorSideRight.Control = AlphaEdit
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 111 Left = 121
Height = 23 Height = 23
Top = 29 Top = 29
Width = 43 Width = 43
@ -171,7 +358,7 @@ object DistribFrm: TDistribFrm
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = AlphaEdit AnchorSideRight.Control = AlphaEdit
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 111 Left = 121
Height = 23 Height = 23
Top = 89 Top = 89
Width = 43 Width = 43
@ -188,7 +375,7 @@ object DistribFrm: TDistribFrm
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = AlphaEdit AnchorSideRight.Control = AlphaEdit
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 111 Left = 121
Height = 23 Height = 23
Top = 56 Top = 56
Width = 43 Width = 43
@ -200,66 +387,27 @@ object DistribFrm: TDistribFrm
Text = 'DF2Edit' Text = 'DF2Edit'
end end
end end
object CloseBtn: TButton
AnchorSideTop.Control = Bevel1
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Side = asrBottom
Left = 321
Height = 25
Top = 180
Width = 55
Anchors = [akTop, akRight]
AutoSize = True
BorderSpacing.Top = 8
BorderSpacing.Right = 8
Caption = 'Close'
ModalResult = 11
TabOrder = 4
end end
object ComputeBtn: TButton object SavePictureDialog: TSavePictureDialog
AnchorSideTop.Control = CloseBtn 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 (*.*)|*.*'
AnchorSideRight.Control = CloseBtn Left = 160
Left = 237 Top = 72
Height = 25
Top = 180
Width = 76
Anchors = [akTop, akRight]
AutoSize = True
BorderSpacing.Left = 8
BorderSpacing.Right = 8
Caption = 'Compute'
OnClick = ComputeBtnClick
TabOrder = 3
end end
object ResetBtn: TButton object PrintDialog: TPrintDialog
AnchorSideTop.Control = CloseBtn Left = 160
AnchorSideRight.Control = ComputeBtn Top = 130
Left = 175 end
Height = 25 object ChartToolset: TChartToolset
Top = 180 Left = 319
Width = 54 Top = 209
Anchors = [akTop, akRight] object ZoomDragTool: TZoomDragTool
AutoSize = True Shift = [ssLeft]
BorderSpacing.Left = 8 LimitToExtent = [zdDown]
BorderSpacing.Right = 8 Brush.Style = bsClear
BorderSpacing.Bottom = 8 end
Caption = 'Reset' object PanDragTool: TPanDragTool
OnClick = ResetBtnClick Shift = [ssRight]
TabOrder = 2 LimitToExtent = [pdDown]
end end
object Bevel1: TBevel
AnchorSideLeft.Control = Owner
AnchorSideTop.Control = GroupBox2
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom
Left = 0
Height = 8
Top = 164
Width = 384
Anchors = [akTop, akLeft, akRight]
Shape = bsBottomLine
end end
end end

View File

@ -3,6 +3,8 @@
// Test input parameters: // Test input parameters:
// - F distribution: DF1 = 3, DF2 = 20 // - F distribution: DF1 = 3, DF2 = 20
// ToDo: Fix calculation of t distribution
unit DistribUnit; unit DistribUnit;
{$mode objfpc}{$H+} {$mode objfpc}{$H+}
@ -10,12 +12,9 @@ unit DistribUnit;
interface interface
uses uses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, Classes, SysUtils, FileUtil, TAGraph, TAFuncSeries, TASeries, TATools,
StdCtrls, Printers, ExtCtrls, Math, PrintersDlgs, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls,
BlankFrmUnit, FunctionsLib, Globals; Printers, ExtCtrls, ExtDlgs, Math, FunctionsLib, Globals;
type
TwoCol = array[1..2, 1..100] of double;
type type
@ -24,12 +23,25 @@ type
TDistribFrm = class(TForm) TDistribFrm = class(TForm)
AlphaEdit: TEdit; AlphaEdit: TEdit;
Bevel1: TBevel; Bevel1: TBevel;
ChartToolset: TChartToolset;
PanDragTool: TPanDragTool;
tChk: TRadioButton;
ZoomDragTool: TZoomDragTool;
PrintDialog: TPrintDialog;
SavePictureDialog: TSavePictureDialog;
VertLineSeries: TLineSeries;
FuncSeries: TFuncSeries;
Panel2: TPanel;
SaveBtn: TButton;
PrintBtn: TButton;
Chart: TChart;
ChiChk: TRadioButton; ChiChk: TRadioButton;
DF1Edit: TEdit; DF1Edit: TEdit;
DF2Edit: TEdit; DF2Edit: TEdit;
FChk: TRadioButton; FChk: TRadioButton;
MeanEdit: TEdit; MeanEdit: TEdit;
NDChk: TRadioButton; NDChk: TRadioButton;
Panel1: TPanel;
ResetBtn: TButton; ResetBtn: TButton;
ComputeBtn: TButton; ComputeBtn: TButton;
CloseBtn: TButton; CloseBtn: TButton;
@ -43,26 +55,24 @@ type
procedure ComputeBtnClick(Sender: TObject); procedure ComputeBtnClick(Sender: TObject);
procedure FChkClick(Sender: TObject); procedure FChkClick(Sender: TObject);
procedure FormActivate(Sender: TObject); procedure FormActivate(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure CalcChiSq(const AX: Double; out AY: Double);
procedure CalcF(const AX: Double; out AY: Double);
procedure CalcND(const AX: Double; out AY: Double);
procedure Calct(const AX: Double; out AY: Double);
procedure NDChkClick(Sender: TObject); procedure NDChkClick(Sender: TObject);
procedure PrintBtnClick(Sender: TObject);
procedure ResetBtnClick(Sender: TObject); procedure ResetBtnClick(Sender: TObject);
procedure SaveBtnClick(Sender: TObject);
procedure tChkClick(Sender: TObject);
private private
{ private declarations } { private declarations }
DF1: Integer;
DF2: Integer;
procedure NDPlot; procedure NDPlot;
procedure ChiPlot; procedure ChiPlot;
procedure FPlot; procedure FPlot;
procedure HScale(Xmin, Xmax: double; NSteps: integer; AColor: TColor; procedure tPlot;
FontSize: integer; X, Y, XLength: integer; CharLabel: string);
procedure VScale(Ymin, Ymax: double; NSteps: integer; AColor: TColor;
FontSize: integer; X, Y, YLength: integer; CharLabel: string);
procedure NormPts(zMin, zMax: double; NPts: integer; var RealPts: TwoCol);
procedure PltPts(RealPts: TwoCol; XMax, XMin, YMax, YMin: double;
Npts, XAxisStart, YAxisStart, XAxisRange, YAxisRange: integer; AColor: TColor);
procedure ChiPts(cMin, cMax: double; NPts, DF: integer; var RealPts: TwoCol);
procedure FPts(FMin, FMax: double; NPts, DF1, DF2: integer; var RealPts: TwoCol);
function Chi2Func(chisqr, df: double): double;
function FFunc(F: double; DF1, DF2: integer): double;
function Validate(out AMsg: String; out AControl: TWinControl): Boolean; function Validate(out AMsg: String; out AControl: TWinControl): Boolean;
public public
@ -74,18 +84,45 @@ var
implementation implementation
uses
//spe, // a numlib unit (tDist)
OSPrinters,
TAChartUtils, TADrawerSVG, TAPrint;
{ TDistribFrm } { TDistribFrm }
procedure TDistribFrm.ResetBtnClick(Sender: TObject); procedure TDistribFrm.ResetBtnClick(Sender: TObject);
begin begin
NDChk.Checked := false; NDChk.Checked := false;
ChiChk.Checked := false; tChk.Checked := false;
FChk.Checked := false; FChk.Checked := false;
ChiChk.Checked := false;
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 := ''; MeanEdit.Text := '';
GroupBox2.Enabled := false; GroupBox2.Enabled := false;
FuncSeries.OnCalculate := nil;
VertLineSeries.Active := false;
Chart.Title.Visible := false;
Chart.BottomAxis.Title.Caption := 'Scale';
end;
procedure TDistribFrm.SaveBtnClick(Sender: TObject);
var
ext: String;
begin
if SavePictureDialog.Execute then
begin
ext := Lowercase(ExtractFileExt(SavePictureDialog.FileName));
case ext of
'.bmp': Chart.SaveToFile(TBitmap, SavePictureDialog.Filename);
'.png': Chart.SaveToFile(TPortableNetworkGraphic, SavePictureDialog.FileName);
'.jpg', '.jpeg', '.jpe', '.jfif': Chart.SaveToFile(TJpegImage, SavePictureDialog.FileName);
'.svg': Chart.SaveToSVGFile(SavePictureDialog.FileName);
end;
end;
end; end;
procedure TDistribFrm.FormShow(Sender: TObject); procedure TDistribFrm.FormShow(Sender: TObject);
@ -93,6 +130,47 @@ begin
ResetBtnClick(self); ResetBtnClick(self);
end; end;
procedure TDistribFrm.CalcF(const AX: Double; out AY: Double);
var
ratio1, ratio2, ratio3, ratio4: double;
part1, part2, part3, part4, part5, part6, part7, part8, part9: double;
begin
// Returns the height of the density curve for the F statistic
ratio1 := (DF1 + DF2) / 2.0;
ratio2 := (DF1 - 2.0) / 2.0;
ratio3 := DF1 / 2.0;
ratio4 := DF2 / 2.0;
part1 := exp(lngamma(ratio1));
part2 := power(DF1, ratio3);
part3 := power(DF2, ratio4);
part4 := exp(lngamma(ratio3));
part5 := exp(lngamma(ratio4));
part6 := power(AX, ratio2);
part7 := power((AX*DF1 + DF2), ratio1);
part8 := (part1 * part2 * part3) / (part4 * part5);
if (part7 = 0.0) then
part9 := 0.0
else
part9 := part6 / part7;
AY := part8 * part9;
end;
procedure TDistribFrm.CalcND(const AX: Double; out AY: Double);
begin
AY := 1.0 / sqrt(TWO_PI) * exp(-sqr(AX)/ 2.0);
end;
procedure TDistribFrm.CalcChiSq(const AX: Double; out AY: Double);
begin
AY := 1.0 / (power(2.0, DF1*0.5) * exp(lngamma(DF1*0.5))) * power(AX, (DF1-2.0)*0.5) * (1.0 / exp(AX*0.5));
end;
procedure TDistribFrm.Calct(const AX: Double; out AY: Double);
begin
AY := Student(AX, DF1, 1.0);
//AY := tDist(AX, DF1, 1);
end;
procedure TDistribFrm.NDChkClick(Sender: TObject); procedure TDistribFrm.NDChkClick(Sender: TObject);
begin begin
if NDChk.Checked then if NDChk.Checked then
@ -111,6 +189,34 @@ begin
GroupBox2.Enabled := false; GroupBox2.Enabled := false;
end; end;
procedure TDistribFrm.PrintBtnClick(Sender: TObject);
const
MARGIN = 10;
var
R: TRect;
d: Integer;
begin
if not PrintDialog.Execute then
exit;
Printer.BeginDoc;
try
R := Rect(0, 0, Printer.PageWidth, Printer.PageHeight div 2);
d := R.Right - R.Left;
R.Left += d div MARGIN;
R.Right -= d div MARGIN;
d := R.Bottom - R.Top;
R.Top += d div MARGIN;
R.Bottom -= d div MARGIN;
Chart.Draw(TPrinterDrawer.Create(Printer, true), R);
finally
Printer.EndDoc;
end;
end;
procedure TDistribFrm.ComputeBtnClick(Sender: TObject); procedure TDistribFrm.ComputeBtnClick(Sender: TObject);
var var
msg: String; msg: String;
@ -131,6 +237,12 @@ begin
ok := true; ok := true;
end; end;
if tChk.Checked then
begin
tPlot();
ok := true;
end;
if ChiChk.Checked then if ChiChk.Checked then
begin begin
ChiPlot(); ChiPlot();
@ -182,428 +294,148 @@ begin
GroupBox2.Enabled := false; GroupBox2.Enabled := false;
end; end;
procedure TDistribFrm.tChkClick(Sender: TObject);
begin
if tChk.Checked then
begin
GroupBox2.Enabled := true;
DF1Label.Enabled := true;
DF1Edit.Enabled := true;
DF2Label.Enabled := false;
MeanLabel.Enabled := false;
AlphaLabel.Enabled := true;
AlphaEdit.Enabled := true;
DF2Edit.Enabled := false;
MeanEdit.Enabled := false;
end else
GroupBox2.Enabled := false;
end;
procedure TDistribFrm.NDPlot; procedure TDistribFrm.NDPlot;
var var
CharLabel: string; alpha: Double;
Clwidth, Clheight,X, Y, XAxisStart, XAxisEnd, YAxisStart, YAxisEnd: integer; zCrit, pCrit: Double;
i, Xrange, Yrange, t: integer;
alpha, h, z, hprop, zprop: double;
RealPts: TwoCol;
begin begin
for i := 1 to 100 do realpts[1,i] := 0.0;
for i := 1 to 100 do realpts[2,i] := 0.0;
BlankFrm.Image1.Canvas.Pen.Color := clBlack;
BlankFrm.Image1.Canvas.Brush.Color := clWhite;
BlankFrm.Image1.Canvas.Clear;
BlankFrm.Image1.Canvas.FloodFill(1,1,clWhite,fsborder);
BlankFrm.Image1.Canvas.Pen.Width := 2;
Clwidth := BlankFrm.Image1.Width;
Clheight := BlankFrm.Image1.Height;
XAxisStart := Clwidth div 8;
XAxisEnd := Clwidth - Clwidth div 8;
YAxisStart := (Clheight * 7) div 10;
YAxisEnd := Clheight div 10;
XRange := XAxisEnd - XAxisStart;
YRange := YAxisStart - YAxisEnd;
alpha := StrToFloat(AlphaEdit.Text); alpha := StrToFloat(AlphaEdit.Text);
zCrit := inversez(1.0 - alpha);
CalcND(zCrit, pCrit);
BlankFrm.Show; Chart.Title.Text.Clear;
Chart.Title.Text.Add('<b>Normal Distribution</b>');
// Create values of normal curve Chart.Title.Text.Add(Format('&alpha; = %.3g', [alpha]));
NormPts(-4.0, 4.0, 100, RealPts); Chart.Title.Text.Add(Format('Critical value = %.3f', [zCrit]));
PltPts(RealPts, 4.0, -4.0, 0.5, 0.0, 100, XAxisStart, YAxisStart, XRange, YRange, clBlack); Chart.Title.Visible := true;
Chart.BottomAxis.Title.Caption := 'z';
// Draw line for alpha z := 1.645 FuncSeries.Extent.XMin := -4;
CharLabel := 'Normal Distribution. Alpha: ' + AlphaEdit.Text; FuncSeries.Extent.XMax := +4;
BlankFrm.Caption := CharLabel; FuncSeries.Extent.UseXMin := true;
z := inversez(1.0 - alpha); FuncSeries.Extent.UseXMax := true;
zprop := (4.0 + z) / 8.0; FuncSeries.OnCalculate := @CalcND;
h := (1.0 / sqrt(2.0 * 3.1415)) * (1.0 / exp(z * z / 2.0)); FuncSeries.DomainExclusions.Clear;
hprop := (0.5 - h) / 0.5; VertLineSeries.Clear;
X := round(zprop * XRange) + XAxisStart; VertLineSeries.AddXY(zCrit, 0);
Y := YAxisEnd + round(hprop * YRange); VertLineSeries.AddXY(zCrit, pCrit);
BlankFrm.Image1.Canvas.MoveTo(X, YAxisStart); VertLineSeries.Active := true;
BlankFrm.Image1.Canvas.LineTo(X, Y-10); // alpha cutoff
// floodfill rejection section with red
BlankFrm.Image1.Canvas.Brush.Color := clRed;
BlankFrm.Image1.Canvas.Brush.Color := clWhite;
// create labeled axis
HScale(-4.0, 4.0, 11, clWhite, 10, XAxisStart, YAxisStart, XRange, 'z SCALE');
VScale(0.0, 0.5, 11, clWhite, 10, XAxisStart, YAxisStart, YRange, 'DENSITY');
// Print Heading
t := BlankFrm.Image1.Canvas.TextWidth(CharLabel);
X := (BlankFrm.Width - t) div 2;
BlankFrm.Image1.Canvas.TextOut(X, 0, charLabel);
CharLabel := 'Critical Value: ' + Format('%.3f',[z]);
t := BlankFrm.Image1.Canvas.TextWidth(charLabel);
X := (BlankFrm.Image1.Width - t) div 2;
Y := BlankFrm.Image1.Canvas.TextHeight(CharLabel);
BlankFrm.Image1.Canvas.TextOut(X, Y, CharLabel);
end; end;
procedure TDistribFrm.ChiPlot; procedure TDistribFrm.ChiPlot;
var var
charLabel: string; alpha: Double;
ClWidth, ClHeight, X, Y, XAxisStart, XAxisEnd, YAxisStart, YAxisEnd: integer; Chi2Crit, pCrit: Double;
i, Xrange, Yrange, df, t: integer;
alpha, h, z, hprop, zprop, MaxChi, MaxProb: double;
RealPts: TwoCol;
begin begin
for i := 1 to 100 do realpts[1,i] := 0.0;
for i := 1 to 100 do realpts[2,i] := 0.0;
MaxProb := 0.0;
BlankFrm.Image1.Canvas.Pen.Color := clBlack;
BlankFrm.Image1.Canvas.Brush.Color := clWhite;
BlankFrm.Image1.Canvas.Clear;
BlankFrm.Image1.Canvas.FloodFill(1, 1, clWhite, fsBorder);
BlankFrm.Image1.Canvas.Pen.Width := 2;
ClWidth := BlankFrm.Image1.Width;
ClHeight := BlankFrm.Image1.Height;
XAxisStart := ClWidth div 8;
XAxisEnd := ClWidth - ClWidth div 8;
YAxisStart := (ClHeight * 7) div 10;
YAxisEnd := ClHeight div 10;
XRange := XAxisEnd - XAxisStart;
YRange := YAxisStart - YAxisEnd;
alpha := StrToFloat(AlphaEdit.Text); alpha := StrToFloat(AlphaEdit.Text);
charLabel := 'Chi Squared Distribution. Alpha: ' + AlphaEdit.Text; DF1 := StrToInt(DF1Edit.Text);
df := StrToInt(DF1Edit.Text); Chi2Crit := InverseChi(1.0 - alpha, DF1);
if (df < 1) or (df > 100) then CalcChiSq(Chi2Crit, pCrit);
exit;
charLabel := charLabel + ' D.F.: ' + DF1Edit.Text; Chart.Title.Text.Clear;
BlankFrm.Caption := charLabel; Chart.Title.Text.Add('<b>Chi-Squared Distribution.</b>');
BlankFrm.Show; Chart.Title.Text.Add(Format('&alpha; = %.3g / Degrees of freedom = %d', [alpha, DF1]));
Chart.Title.Text.Add(Format('Critical value = %.3f', [Chi2Crit]));
// Create values of chi-squared curve Chart.Title.Visible := true;
MaxChi := 125.0; Chart.BottomAxis.Title.Caption := '&chi;<sup>2</sup>';
ChiPts(0.0, MaxChi, 100, df, realpts); FuncSeries.Extent.XMin := 0;
for i := 1 to 100 do FuncSeries.Extent.XMax := 125;
if (RealPts[2,i] > MaxProb) then FuncSeries.Extent.UseXMin := true;
MaxProb := RealPts[2,i]; FuncSeries.Extent.UseXMax := true;
PltPts(RealPts, MaxChi, 0.0, MaxProb, 0.0, 100, XAxisStart, YAxisStart, XRange, YRange, clBlack); FuncSeries.OnCalculate := @CalcChiSq;
FuncSeries.DomainExclusions.AddRange(-Infinity, 0, [ioOpenEnd]);
// Draw line for alpha VertLineSeries.Clear;
z := InverseChi(1.0-alpha, df); VertLineSeries.AddXY(Chi2Crit, 0);
zprop := z / MaxChi; VertLineSeries.AddXY(Chi2Crit, pCrit);
h := Chi2Func(z, df); VertLineSeries.Active := true;
hprop := (MaxProb - h) / MaxProb;
X := round(zprop * Xrange) + XaxisStart;
Y := YaxisEnd + round(hprop * Yrange);
BlankFrm.Image1.Canvas.MoveTo(X, YaxisStart);
BlankFrm.Image1.Canvas.LineTo(X, Y); // alpha cutoff
// floodfill main section with blue
BlankFrm.Image1.Canvas.Brush.Color := clBlue;
BlankFrm.Image1.Canvas.Brush.Color := clWhite;
// create charLabeled axis
HScale(0.0, MaxChi, 11, clWhite, 10, XAxisStart, YAxisStart, XRange, 'CHI SQUARED SCALE');
VScale(0.0, MaxProb, 11, clWhite, 10, XAxisStart, YAxisStart, YRange, 'DENSITY');
// Print Heading
t := BlankFrm.Image1.Canvas.TextWidth(CharLabel);
X := (BlankFrm.Width - t) div 2;
BlankFrm.Image1.Canvas.TextOut(X,0,CharLabel);
CharLabel := 'Critical Value: ' + Format('%6.3f',[z]);
t := BlankFrm.Image1.Canvas.TextWidth(CharLabel);
X := (BlankFrm.Image1.Width - t) div 2;
Y := BlankFrm.Image1.Canvas.TextHeight(CharLabel);
BlankFrm.Image1.Canvas.TextOut(X, Y, CharLabel);
end; end;
procedure TDistribFrm.FPlot; procedure TDistribFrm.FPlot;
var var
CharLabel: string; alpha: Double;
ClWidth, ClHeight, X, Y, XAxisStart, XAxisEnd, YAxisStart, YAxisEnd: integer; FCrit, pCrit: Double;
i, Xrange, Yrange, t, df1, df2: integer;
RealPts: TwoCol;
alpha, h, F, hprop, Fprop, MaxProb, MaxF: double;
done: boolean;
begin begin
for i := 1 to 100 do
begin
realpts[1,i] := 0.0;
realpts[2,i] := 0.0;
end;
MaxProb := 0.0;
BlankFrm.Image1.Canvas.Pen.Color := clBlack;
BlankFrm.Image1.Canvas.Brush.Color := clWhite;
BlankFrm.Image1.Canvas.Clear;
BlankFrm.Image1.Canvas.FloodFill(1,1,clWhite,fsborder);
BlankFrm.Image1.Canvas.Pen.Width := 2;
ClWidth := BlankFrm.Image1.Width;
ClHeight := BlankFrm.Image1.Height;
XAxisStart := ClWidth div 8;
XAxisEnd := ClWidth - ClWidth div 8;
YAxisStart := (ClHeight * 7) div 10;
YAxisEnd := ClHeight div 10;
XRange := XAxisEnd - XAxisStart;
YRange := YAxisStart - YAxisEnd;
alpha := StrToFloat(AlphaEdit.Text); alpha := StrToFloat(AlphaEdit.Text);
charLabel := 'F Distribution. Alpha: ' + AlphaEdit.Text; DF1 := StrToInt(DF1Edit.Text);
df1 := StrToInt(DF1Edit.Text); DF2 := StrToInt(DF2Edit.Text);
CharLabel := CharLabel + ', D.F.1: '; FCrit := FPercentPoint(1.0 - alpha, DF1, DF2);
CharLabel := CharLabel + DF1Edit.Text; CalcF(FCrit, pCrit);
df2 := StrToInt(DF2Edit.Text);
CharLabel := CharLabel + ', D.F.2: ';
CharLabel := CharLabel + DF2Edit.Text;
BlankFrm.Caption := CharLabel;
BlankFrm.Show;
// Create values of F curve Chart.Title.Text.Clear;
MaxF := 20.0; Chart.Title.Text.Add('<b>F Distribution.</b>');
done := false; Chart.Title.Text.Add(Format('&alpha; = %.3g / DF1 = %d, DF2 = %d', [alpha, DF1, DF2]));
while not done do Chart.Title.Text.Add(Format('Critical value = %.3f', [FCrit]));
begin Chart.Title.Visible := true;
h := Ffunc(MaxF, df1, df2); Chart.BottomAxis.Title.Caption := 'F';
if h < 0.001 then FuncSeries.Extent.XMin := 0;
MaxF := MaxF - 1.0 FuncSeries.Extent.XMax := 15;
else FuncSeries.Extent.UseXMin := true;
done := true; FuncSeries.Extent.UseXMax := true;
FuncSeries.OnCalculate := @CalcF;
FuncSeries.DomainExclusions.AddRange(-Infinity, 0, [ioOpenEnd]);
VertLineSeries.Clear;
VertLineSeries.AddXY(FCrit, 0);
VertLineSeries.AddXY(FCrit, pCrit);
VertLineSeries.Active := true;
end; end;
FPts(0.0, MaxF, 100, df1, df2, RealPts); procedure TDistribFrm.tPlot;
for i := 1 to 100 do
if (RealPts[2,i] > MaxProb) then
MaxProb := RealPts[2,i];
PltPts(RealPts, MaxF, 0.0, MaxProb, 0.0, 100, XAxisStart, YAxisStart, XRange, YRange, clBlack);
// Draw line for alpha
F := FPercentPoint(1.0-alpha, df1, df2);
Fprop := F / MaxF;
h := Ffunc(F, df1, df2);
hprop := (MaxProb - h) / MaxProb;
X := round(Fprop * XRange) + XAxisStart;
Y := YAxisEnd + round(hprop * YRange);
BlankFrm.Image1.Canvas.MoveTo(X, YAxisStart);
BlankFrm.Image1.Canvas.LineTo(X, Y); // alpha cutoff
// floodfill main section with blue
BlankFrm.Canvas.Brush.Color := clBlue;
// create charLabeled axis
HScale(0.0, MaxF, 11, clWhite, 10, XAxisStart, YAxisStart, XRange, 'F SCALE');
VScale(0.0, MaxProb, 11, clWhite, 10, XAxisStart, YAxisStart, YRange, 'DENSITY');
// Print Heading
t := BlankFrm.Image1.Canvas.TextWidth(CharLabel);
X := (BlankFrm.Image1.Width - t) div 2;
BlankFrm.Image1.Canvas.TextOut(X, 0, CharLabel);
charLabel := 'Critical Value: ' + Format('%.3f', [F]);
t := BlankFrm.Image1.Canvas.TextWidth(charLabel);
X := (BlankFrm.Image1.Width - t) div 2;
Y := BlankFrm.Image1.Canvas.TextHeight(CharLabel);
BlankFrm.Image1.Canvas.TextOut(X, Y, CharLabel);
end;
procedure TDistribFrm.HScale(XMin, XMax: double; Nsteps: integer;
AColor: TColor; FontSize: integer; X, Y, XLength: integer; CharLabel: string);
var var
i, TickEnd, Xpos, Ypos, TextX: integer; alpha: Double;
Xincr, Xval: double; tCrit, pCrit: Double;
begin begin
BlankFrm.Image1.Canvas.MoveTo(X,Y); alpha := StrToFloat(AlphaEdit.Text);
BlankFrm.Image1.Canvas.LineTo(X+Xlength,Y); DF1 := StrToInt(DF1Edit.Text);
BlankFrm.Image1.Canvas.Font.Size := FontSize; tCrit := Inverset(1.0 - alpha, DF1);
BlankFrm.Image1.Canvas.Brush.Color := AColor; Calct(tCrit, pCrit);
TickEnd := Y + 10;
Xincr := (Xmax - Xmin) / Nsteps;
for i := 0 to Nsteps do
begin
XPos := round(Xlength/Nsteps*i + X);
BlankFrm.Image1.Canvas.MoveTo(XPos, Y);
BlankFrm.Image1.Canvas.LineTo(XPos, TickEnd);
TextX := XPos - 8;
Xval := Xmin + i*Xincr;
BlankFrm.Image1.Canvas.TextOut(TextX, Y+15, Format('%.2f', [Xval]));
end;
// print charLabel below X axis Chart.Title.Text.Clear;
YPos := Y + 30; Chart.Title.Text.Add('<b>Student t Distribution.</b>');
XPos := round((BlankFrm.Width / 2) - (BlankFrm.Image1.Canvas.TextWidth(CharLabel) / 2)); Chart.Title.Text.Add(Format('&alpha; = %.3g / Degrees of freedom = %d', [alpha, DF1]));
BlankFrm.Image1.Canvas.TextOut(Xpos, Ypos, CharLabel); Chart.Title.Text.Add(Format('Critical value = %.3f', [tCrit]));
end; Chart.Title.Visible := true;
Chart.BottomAxis.Title.Caption := 't';
procedure TDistribFrm.VScale(YMin, YMax: double; NSteps: integer; FuncSeries.Extent.XMin := -4;
AColor: TColor; FontSize: integer; X, Y, YLength: integer; CharLabel: string); FuncSeries.Extent.XMax := 4;
var FuncSeries.Extent.UseXMin := true;
TickEnd, Ypos, Xpos, TextY: integer; FuncSeries.Extent.UseXMax := true;
Yincr, Yval: double; FuncSeries.OnCalculate := @Calct;
chpixs, i: integer; FuncSeries.DomainExclusions.Clear;
begin VertLineSeries.Clear;
BlankFrm.Image1.Canvas.MoveTo(X,Y); VertLineSeries.AddXY(tCrit, 0);
BlankFrm.Image1.Canvas.LineTo(X,Y-Ylength); VertLineSeries.AddXY(tCrit, pCrit);
BlankFrm.Image1.Canvas.Font.Size := FontSize; VertLineSeries.Active := true;
BlankFrm.Image1.Canvas.Brush.Color := AColor;
TickEnd := X - 10;
Yincr := (YMax - YMin) / Nsteps;
TextY := 0;
for i := 0 to NSteps do
begin
YPos := round(Y - Ylength / NSteps * i);
BlankFrm.Image1.Canvas.MoveTo(X, YPos);
BlankFrm.Image1.Canvas.LineTo(TickEnd, YPos);
TextY := TickEnd - 30;
Yval := Ymin + i * Yincr;
BlankFrm.Image1.Canvas.TextOut(TextY, Ypos-8, Format('%.2f', [Yval]));
end;
// print charLabel vertically
chpixs := BlankFrm.Image1.Canvas.TextHeight(CharLabel);
XPos := TextY - 15;
for i := 1 to Length(CharLabel) do
begin
YPos := round(Y - YLength / 2 - Length(charLabel) * chpixs / 2 + chpixs*i);
BlankFrm.Image1.Canvas.TextOut(XPos, YPos, CharLabel[i]);
end;
end;
procedure TDistribFrm.NormPts(zMin, zMax: double; NPts: integer;
var RealPts: TwoCol);
var
zIncr, z, h: double;
i: integer;
begin
zIncr := (zMax - zMin) / Npts;
for i := 1 to Npts do
begin
z := zMin + (zIncr * i);
h := (1.0 / sqrt(2.0 * PI)) * (1.0 / exp(z * z / 2.0));
RealPts[1, i] := z;
RealPts[2, i] := h;
end;
end;
procedure TDistribFrm.PltPts(RealPts: TwoCol; Xmax, Xmin, Ymax, Ymin: double;
NPts, XAxisStart, YAxisStart, XAxisRange, YAxisRange: integer; AColor: TColor);
var
hprop, zprop, z, h: double;
i, X, Y: integer;
intpts: array[1..100] of TPoint;
begin
for i := 1 to NPts do
begin
z := RealPts[1,i];
h := RealPts[2,i];
zprop := (z - XMin) / (XMax - XMin);
X := round(zprop * XAxisRange + XAxisStart);
hprop := (h - Ymin) / (Ymax - Ymin);
Y := round(YAxisStart - hprop * YAxisRange);
intpts[i] := Point(X, Y);
end;
BlankFrm.Image1.Canvas.Pen.Color := AColor;
BlankFrm.Image1.Canvas.Polyline(Slice(intpts, Npts - 1));
end;
procedure TDistribFrm.ChiPts(cMin, cMax: double; NPts, DF: integer;
var RealPts: TwoCol);
var
ratio1, ratio2, ratio3, cIncr, chi, h: double;
i: integer;
begin
ratio1 := DF / 2.0;
ratio2 := (DF - 2.0) / 2.0;
cIncr := (cMax - cMin) / NPts;
for i := 1 to NPts do
begin
chi := cMin + cIncr*i;
// h := inversechi(chi, df);
ratio3 := chi / 2.0;
h := (1.0 / (power(2.0, ratio1) * exp(lngamma(ratio1)))) * power(chi, ratio2) * (1.0 / exp(ratio3));
RealPts[1,i] := chi;
RealPts[2,i] := h;
end;
end;
procedure TDistribFrm.FPts(FMin, FMax: double; NPts, DF1, DF2: integer;
var RealPts: TwoCol);
var
FIncr, F, h: double;
i: integer;
begin
FIncr := (FMax - FMin) / NPts;
for i := 1 to NPts do
begin
F := FMin + FIncr * i;
h := Ffunc(F, DF1, DF2);
RealPts[1,i] := F;
RealPts[2,i] := h;
end;
end;
function TDistribFrm.Chi2Func(ChiSqr, DF: double): double;
var
ratio1, ratio2, ratio3: double;
begin
// Returns the height of the density curve for the chi-squared statistic
ratio1 := df / 2.0;
ratio2 := (df - 2.0) / 2.0;
ratio3 := chisqr / 2.0;
Result := (1.0 / (power(2.0,ratio1) * exp(lngamma(ratio1)))) * power(chisqr,ratio2) * (1.0 / exp(ratio3));
end;
function TDistribFrm.FFunc(F: double; DF1, DF2: integer): double;
var
ratio1, ratio2, ratio3, ratio4: double;
part1, part2, part3, part4, part5, part6, part7, part8, part9: double;
begin
// Returns the height of the density curve for the F statistic
ratio1 := (df1 + df2) / 2.0;
ratio2 := (df1 - 2.0) / 2.0;
ratio3 := df1 / 2.0;
ratio4 := df2 / 2.0;
part1 := exp(lngamma(ratio1));
part2 := power(df1, ratio3);
part3 := power(df2, ratio4);
part4 := exp(lngamma(ratio3));
part5 := exp(lngamma(ratio4));
part6 := power(F,ratio2);
part7 := power((F*df1 + df2), ratio1);
part8 := (part1 * part2 * part3) / (part4 * part5);
if (part7 = 0.0) then
part9 := 0.0
else
part9 := part6 / part7;
Result := part8 * part9;
{
ratio1 := (df1 + df2) / 2.0;
ratio2 := (df1 - 2.0) / 2.0;
ratio3 := df1 / 2.0;
ratio4 := df2 / 2.0;
ffunc := ((gamma(ratio1) * realraise(df1,ratio3) *
realraise(df2,ratio4)) /
(gamma(ratio3) * gamma(ratio4))) *
(realraise(f,ratio2) / realraise((f*df1+df2),ratio1));
}
end; end;
procedure TDistribFrm.FormActivate(Sender: TObject); procedure TDistribFrm.FormActivate(Sender: TObject);
var var
w: Integer; w: Integer;
begin begin
w := MaxValue([ResetBtn.Width, ComputeBtn.Width, CloseBtn.Width]); w := MaxValue([SaveBtn.Width, PrintBtn.Width, ResetBtn.Width, ComputeBtn.Width, CloseBtn.Width]);
SaveBtn.Width := w;
PrintBtn.Width := w;
ResetBtn.Constraints.MinWidth := w; ResetBtn.Constraints.MinWidth := w;
ComputeBtn.Constraints.MinWidth := w; ComputeBtn.Constraints.MinWidth := w;
CloseBtn.Constraints.MinWidth := w; CloseBtn.Constraints.MinWidth := w;
end; end;
procedure TDistribFrm.FormCreate(Sender: TObject);
begin
if BlankFrm = nil then
Application.CreateForm(TBlankFrm, BlankFrm);
end;
function TDistribFrm.Validate(out AMsg: String; out AControl: TWinControl): boolean; function TDistribFrm.Validate(out AMsg: String; out AControl: TWinControl): boolean;
var var