You've already forked lazarus-ccr
LazStats: Inherit form in CorSimUnit from TBasicStatsReportAndChartForm. Use TAChart.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7784 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -809,7 +809,7 @@
|
|||||||
<Unit88>
|
<Unit88>
|
||||||
<Filename Value="forms\simulations\corsimunit.pas"/>
|
<Filename Value="forms\simulations\corsimunit.pas"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
<ComponentName Value="CorSimFrm"/>
|
<ComponentName Value="CorSimForm"/>
|
||||||
<HasResources Value="True"/>
|
<HasResources Value="True"/>
|
||||||
<ResourceBaseClass Value="Form"/>
|
<ResourceBaseClass Value="Form"/>
|
||||||
<UnitName Value="CorSimUnit"/>
|
<UnitName Value="CorSimUnit"/>
|
||||||
|
@ -1373,9 +1373,9 @@ end;
|
|||||||
// Menu "Simulations" > "Bivariate Scatter Plot"
|
// Menu "Simulations" > "Bivariate Scatter Plot"
|
||||||
procedure TOS3MainFrm.mnuSimBivarScatterPlotClick(Sender: TObject);
|
procedure TOS3MainFrm.mnuSimBivarScatterPlotClick(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
if CorSimFrm = nil then
|
if CorSimForm = nil then
|
||||||
Application.CreateForm(TCorSimFrm, CorSimFrm);
|
Application.CreateForm(TCorSimForm, CorSimForm);
|
||||||
CorSimFrm.ShowModal;
|
CorSimForm.Show;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Menu "Simulations" > "Chisquare Probability"
|
// Menu "Simulations" > "Chisquare Probability"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
object CorSimFrm: TCorSimFrm
|
inherited CorSimForm: TCorSimForm
|
||||||
Left = 542
|
Left = 542
|
||||||
Height = 447
|
Height = 447
|
||||||
Top = 126
|
Top = 126
|
||||||
@ -8,223 +8,263 @@ object CorSimFrm: TCorSimFrm
|
|||||||
Caption = 'Correlation Simulation'
|
Caption = 'Correlation Simulation'
|
||||||
ClientHeight = 447
|
ClientHeight = 447
|
||||||
ClientWidth = 857
|
ClientWidth = 857
|
||||||
OnShow = FormShow
|
inherited ParamsPanel: TPanel
|
||||||
Position = poMainFormCenter
|
Height = 431
|
||||||
LCLVersion = '2.1.0.0'
|
Width = 267
|
||||||
object Image1: TImage
|
ClientHeight = 431
|
||||||
Left = 8
|
ClientWidth = 267
|
||||||
Height = 389
|
inherited CloseBtn: TButton
|
||||||
Top = 8
|
Left = 212
|
||||||
Width = 841
|
Top = 406
|
||||||
Align = alClient
|
TabOrder = 10
|
||||||
BorderSpacing.Left = 8
|
|
||||||
BorderSpacing.Top = 8
|
|
||||||
BorderSpacing.Right = 8
|
|
||||||
end
|
end
|
||||||
object Panel1: TPanel
|
inherited ComputeBtn: TButton
|
||||||
AnchorSideTop.Side = asrCenter
|
Left = 128
|
||||||
Left = 8
|
Top = 406
|
||||||
Height = 26
|
TabOrder = 9
|
||||||
Top = 413
|
end
|
||||||
Width = 841
|
inherited ResetBtn: TButton
|
||||||
Align = alBottom
|
Left = 66
|
||||||
AutoSize = True
|
Top = 406
|
||||||
BorderSpacing.Around = 8
|
TabOrder = 8
|
||||||
BevelOuter = bvNone
|
end
|
||||||
ClientHeight = 26
|
inherited HelpBtn: TButton
|
||||||
ClientWidth = 841
|
Left = 7
|
||||||
TabOrder = 0
|
Top = 406
|
||||||
object Label1: TLabel
|
TabOrder = 7
|
||||||
AnchorSideLeft.Control = Panel1
|
Visible = False
|
||||||
AnchorSideTop.Control = MeanX
|
end
|
||||||
|
inherited ButtonBevel: TBevel
|
||||||
|
Top = 390
|
||||||
|
Width = 267
|
||||||
|
end
|
||||||
|
object Label1: TLabel[5]
|
||||||
|
AnchorSideLeft.Control = ParamsPanel
|
||||||
|
AnchorSideTop.Control = MeanXEdit
|
||||||
AnchorSideTop.Side = asrCenter
|
AnchorSideTop.Side = asrCenter
|
||||||
Left = 0
|
Left = 0
|
||||||
Height = 15
|
Height = 15
|
||||||
Top = 6
|
Top = 4
|
||||||
Width = 43
|
Width = 43
|
||||||
Caption = 'Mean X:'
|
Caption = 'Mean X:'
|
||||||
ParentColor = False
|
ParentColor = False
|
||||||
end
|
end
|
||||||
object Label2: TLabel
|
object MeanXEdit: TEdit[6]
|
||||||
AnchorSideLeft.Control = MeanX
|
AnchorSideLeft.Control = Label1
|
||||||
AnchorSideLeft.Side = asrBottom
|
AnchorSideLeft.Side = asrBottom
|
||||||
AnchorSideTop.Control = Label1
|
AnchorSideTop.Control = ParamsPanel
|
||||||
Left = 108
|
Left = 51
|
||||||
|
Height = 23
|
||||||
|
Top = 0
|
||||||
|
Width = 60
|
||||||
|
Alignment = taRightJustify
|
||||||
|
BorderSpacing.Left = 8
|
||||||
|
TabOrder = 0
|
||||||
|
Text = 'MeanXEdit'
|
||||||
|
end
|
||||||
|
object Label2: TLabel[7]
|
||||||
|
AnchorSideLeft.Control = ParamsPanel
|
||||||
|
AnchorSideTop.Control = MeanYEdit
|
||||||
|
AnchorSideTop.Side = asrCenter
|
||||||
|
Left = 0
|
||||||
Height = 15
|
Height = 15
|
||||||
Top = 6
|
Top = 35
|
||||||
Width = 43
|
Width = 43
|
||||||
BorderSpacing.Left = 16
|
|
||||||
Caption = 'Mean Y:'
|
Caption = 'Mean Y:'
|
||||||
ParentColor = False
|
ParentColor = False
|
||||||
end
|
end
|
||||||
object Label3: TLabel
|
object MeanYEdit: TEdit[8]
|
||||||
AnchorSideLeft.Control = MeanY
|
AnchorSideLeft.Control = MeanXEdit
|
||||||
|
AnchorSideTop.Control = MeanXEdit
|
||||||
|
AnchorSideTop.Side = asrBottom
|
||||||
|
AnchorSideRight.Control = MeanXEdit
|
||||||
|
AnchorSideRight.Side = asrBottom
|
||||||
|
Left = 51
|
||||||
|
Height = 23
|
||||||
|
Top = 31
|
||||||
|
Width = 60
|
||||||
|
Alignment = taRightJustify
|
||||||
|
Anchors = [akTop, akLeft, akRight]
|
||||||
|
BorderSpacing.Top = 8
|
||||||
|
TabOrder = 2
|
||||||
|
Text = 'MeanYEdit'
|
||||||
|
end
|
||||||
|
object Label3: TLabel[9]
|
||||||
|
AnchorSideLeft.Control = MeanXEdit
|
||||||
AnchorSideLeft.Side = asrBottom
|
AnchorSideLeft.Side = asrBottom
|
||||||
AnchorSideTop.Control = Label2
|
AnchorSideTop.Control = StdDevXEdit
|
||||||
Left = 221
|
AnchorSideTop.Side = asrCenter
|
||||||
|
Left = 135
|
||||||
Height = 15
|
Height = 15
|
||||||
Top = 6
|
Top = 4
|
||||||
Width = 50
|
Width = 50
|
||||||
BorderSpacing.Left = 16
|
BorderSpacing.Left = 24
|
||||||
Caption = 'Std.Dev.X'
|
Caption = 'Std.Dev.X'
|
||||||
ParentColor = False
|
ParentColor = False
|
||||||
end
|
end
|
||||||
object Label4: TLabel
|
object StdDevXEdit: TEdit[10]
|
||||||
AnchorSideLeft.Control = SDX
|
AnchorSideLeft.Control = Label3
|
||||||
AnchorSideLeft.Side = asrBottom
|
AnchorSideLeft.Side = asrBottom
|
||||||
AnchorSideTop.Control = Label3
|
AnchorSideTop.Control = ParamsPanel
|
||||||
Left = 345
|
Left = 193
|
||||||
|
Height = 23
|
||||||
|
Top = 0
|
||||||
|
Width = 60
|
||||||
|
Alignment = taRightJustify
|
||||||
|
BorderSpacing.Left = 8
|
||||||
|
TabOrder = 1
|
||||||
|
Text = 'StdDevXEdit'
|
||||||
|
end
|
||||||
|
object Label4: TLabel[11]
|
||||||
|
AnchorSideLeft.Control = Label3
|
||||||
|
AnchorSideTop.Control = StdDevYEdit
|
||||||
|
AnchorSideTop.Side = asrCenter
|
||||||
|
Left = 135
|
||||||
Height = 15
|
Height = 15
|
||||||
Top = 6
|
Top = 35
|
||||||
Width = 50
|
Width = 50
|
||||||
BorderSpacing.Left = 16
|
|
||||||
Caption = 'Std.Dev.Y'
|
Caption = 'Std.Dev.Y'
|
||||||
ParentColor = False
|
ParentColor = False
|
||||||
end
|
end
|
||||||
object Label5: TLabel
|
object StdDevYEdit: TEdit[12]
|
||||||
AnchorSideLeft.Control = SDY
|
AnchorSideLeft.Control = StdDevXEdit
|
||||||
|
AnchorSideTop.Control = MeanYEdit
|
||||||
|
AnchorSideRight.Control = StdDevXEdit
|
||||||
|
AnchorSideRight.Side = asrBottom
|
||||||
|
Left = 193
|
||||||
|
Height = 23
|
||||||
|
Top = 31
|
||||||
|
Width = 60
|
||||||
|
Alignment = taRightJustify
|
||||||
|
Anchors = [akTop, akLeft, akRight]
|
||||||
|
TabOrder = 3
|
||||||
|
Text = 'StdDevYEdit'
|
||||||
|
end
|
||||||
|
object Label5: TLabel[13]
|
||||||
AnchorSideLeft.Side = asrBottom
|
AnchorSideLeft.Side = asrBottom
|
||||||
AnchorSideTop.Control = Label4
|
AnchorSideTop.Control = CorrEdit
|
||||||
Left = 450
|
AnchorSideTop.Side = asrCenter
|
||||||
|
AnchorSideRight.Control = CorrEdit
|
||||||
|
Left = 51
|
||||||
Height = 15
|
Height = 15
|
||||||
Top = 6
|
Top = 82
|
||||||
Width = 36
|
Width = 76
|
||||||
|
Anchors = [akTop, akRight]
|
||||||
BorderSpacing.Left = 8
|
BorderSpacing.Left = 8
|
||||||
Caption = 'Cor.XY'
|
BorderSpacing.Right = 8
|
||||||
|
Caption = 'Correlation XY'
|
||||||
ParentColor = False
|
ParentColor = False
|
||||||
end
|
end
|
||||||
object Label6: TLabel
|
object CorrEdit: TEdit[14]
|
||||||
AnchorSideLeft.Control = Corr
|
AnchorSideLeft.Control = Label3
|
||||||
|
AnchorSideTop.Control = MeanYEdit
|
||||||
|
AnchorSideTop.Side = asrBottom
|
||||||
|
Left = 135
|
||||||
|
Height = 23
|
||||||
|
Top = 78
|
||||||
|
Width = 60
|
||||||
|
Alignment = taRightJustify
|
||||||
|
BorderSpacing.Top = 24
|
||||||
|
TabOrder = 4
|
||||||
|
Text = 'CorrEdit'
|
||||||
|
end
|
||||||
|
object Label6: TLabel[15]
|
||||||
AnchorSideLeft.Side = asrBottom
|
AnchorSideLeft.Side = asrBottom
|
||||||
AnchorSideTop.Control = Label5
|
AnchorSideTop.Control = NumObsEdit
|
||||||
AnchorSideTop.Side = asrCenter
|
AnchorSideTop.Side = asrCenter
|
||||||
Left = 554
|
AnchorSideRight.Control = NumObsEdit
|
||||||
|
Left = 92
|
||||||
Height = 15
|
Height = 15
|
||||||
Top = 6
|
Top = 113
|
||||||
Width = 35
|
Width = 35
|
||||||
|
Anchors = [akTop, akRight]
|
||||||
BorderSpacing.Left = 16
|
BorderSpacing.Left = 16
|
||||||
|
BorderSpacing.Right = 8
|
||||||
Caption = 'N Size:'
|
Caption = 'N Size:'
|
||||||
ParentColor = False
|
ParentColor = False
|
||||||
end
|
end
|
||||||
object MeanX: TEdit
|
object NumObsEdit: TEdit[16]
|
||||||
AnchorSideLeft.Control = Label1
|
AnchorSideLeft.Control = CorrEdit
|
||||||
AnchorSideLeft.Side = asrBottom
|
AnchorSideTop.Control = CorrEdit
|
||||||
AnchorSideTop.Control = Panel1
|
AnchorSideTop.Side = asrBottom
|
||||||
AnchorSideTop.Side = asrCenter
|
AnchorSideRight.Control = CorrEdit
|
||||||
Left = 49
|
|
||||||
Height = 23
|
|
||||||
Top = 2
|
|
||||||
Width = 43
|
|
||||||
Alignment = taRightJustify
|
|
||||||
BorderSpacing.Left = 6
|
|
||||||
OnKeyPress = MeanXKeyPress
|
|
||||||
TabOrder = 0
|
|
||||||
Text = 'MeanX'
|
|
||||||
end
|
|
||||||
object MeanY: TEdit
|
|
||||||
AnchorSideLeft.Control = Label2
|
|
||||||
AnchorSideLeft.Side = asrBottom
|
|
||||||
AnchorSideTop.Control = MeanX
|
|
||||||
Left = 159
|
|
||||||
Height = 23
|
|
||||||
Top = 2
|
|
||||||
Width = 46
|
|
||||||
Alignment = taRightJustify
|
|
||||||
BorderSpacing.Left = 8
|
|
||||||
OnKeyPress = MeanYKeyPress
|
|
||||||
TabOrder = 1
|
|
||||||
Text = 'MeanY'
|
|
||||||
end
|
|
||||||
object SDX: TEdit
|
|
||||||
AnchorSideLeft.Control = Label3
|
|
||||||
AnchorSideLeft.Side = asrBottom
|
|
||||||
AnchorSideTop.Control = MeanY
|
|
||||||
Left = 279
|
|
||||||
Height = 23
|
|
||||||
Top = 2
|
|
||||||
Width = 50
|
|
||||||
Alignment = taRightJustify
|
|
||||||
BorderSpacing.Left = 8
|
|
||||||
OnKeyPress = SDXKeyPress
|
|
||||||
TabOrder = 2
|
|
||||||
Text = 'SDX'
|
|
||||||
end
|
|
||||||
object SDY: TEdit
|
|
||||||
AnchorSideLeft.Control = Label4
|
|
||||||
AnchorSideLeft.Side = asrBottom
|
|
||||||
AnchorSideTop.Control = SDX
|
|
||||||
Left = 403
|
|
||||||
Height = 23
|
|
||||||
Top = 2
|
|
||||||
Width = 39
|
|
||||||
Alignment = taRightJustify
|
|
||||||
BorderSpacing.Left = 8
|
|
||||||
OnKeyPress = SDYKeyPress
|
|
||||||
TabOrder = 3
|
|
||||||
Text = 'SDY'
|
|
||||||
end
|
|
||||||
object Corr: TEdit
|
|
||||||
AnchorSideLeft.Control = Label5
|
|
||||||
AnchorSideLeft.Side = asrBottom
|
|
||||||
AnchorSideTop.Control = SDY
|
|
||||||
Left = 494
|
|
||||||
Height = 23
|
|
||||||
Top = 2
|
|
||||||
Width = 44
|
|
||||||
Alignment = taRightJustify
|
|
||||||
BorderSpacing.Left = 8
|
|
||||||
OnKeyPress = CorrKeyPress
|
|
||||||
TabOrder = 4
|
|
||||||
Text = 'Corr'
|
|
||||||
end
|
|
||||||
object ComputeBtn: TButton
|
|
||||||
AnchorSideTop.Control = CloseBtn
|
|
||||||
AnchorSideRight.Control = CloseBtn
|
|
||||||
Left = 702
|
|
||||||
Height = 26
|
|
||||||
Top = 0
|
|
||||||
Width = 65
|
|
||||||
Anchors = [akTop, akRight]
|
|
||||||
BorderSpacing.Right = 8
|
|
||||||
Caption = 'Compute'
|
|
||||||
OnClick = ComputeBtnClick
|
|
||||||
TabOrder = 6
|
|
||||||
end
|
|
||||||
object CloseBtn: TButton
|
|
||||||
AnchorSideTop.Control = Panel1
|
|
||||||
AnchorSideTop.Side = asrCenter
|
|
||||||
AnchorSideRight.Control = Panel1
|
|
||||||
AnchorSideRight.Side = asrBottom
|
AnchorSideRight.Side = asrBottom
|
||||||
Left = 775
|
Left = 135
|
||||||
Height = 26
|
|
||||||
Top = 0
|
|
||||||
Width = 66
|
|
||||||
Anchors = [akTop, akRight]
|
|
||||||
Caption = 'Close'
|
|
||||||
ModalResult = 11
|
|
||||||
TabOrder = 7
|
|
||||||
end
|
|
||||||
object Nobs: TEdit
|
|
||||||
AnchorSideLeft.Control = Label6
|
|
||||||
AnchorSideLeft.Side = asrBottom
|
|
||||||
AnchorSideTop.Control = Corr
|
|
||||||
Left = 597
|
|
||||||
Height = 23
|
Height = 23
|
||||||
Top = 2
|
Top = 109
|
||||||
Width = 40
|
Width = 60
|
||||||
Alignment = taRightJustify
|
Alignment = taRightJustify
|
||||||
BorderSpacing.Left = 8
|
Anchors = [akTop, akLeft, akRight]
|
||||||
OnKeyPress = NobsKeyPress
|
BorderSpacing.Top = 8
|
||||||
TabOrder = 5
|
TabOrder = 5
|
||||||
Text = 'Nobs'
|
Text = 'NumObsEdit'
|
||||||
end
|
end
|
||||||
end
|
object PlotOptionsGroup: TGroupBox[17]
|
||||||
object Bevel1: TBevel
|
AnchorSideLeft.Control = ParamsPanel
|
||||||
|
AnchorSideTop.Control = NumObsEdit
|
||||||
|
AnchorSideTop.Side = asrBottom
|
||||||
Left = 0
|
Left = 0
|
||||||
Height = 8
|
Height = 90
|
||||||
Top = 397
|
Top = 148
|
||||||
Width = 857
|
Width = 178
|
||||||
Align = alBottom
|
AutoSize = True
|
||||||
Shape = bsBottomLine
|
BorderSpacing.Top = 16
|
||||||
|
Caption = 'Plot options'
|
||||||
|
ClientHeight = 70
|
||||||
|
ClientWidth = 174
|
||||||
|
TabOrder = 6
|
||||||
|
object NumBinsEdit: TSpinEdit
|
||||||
|
AnchorSideLeft.Control = Label7
|
||||||
|
AnchorSideLeft.Side = asrBottom
|
||||||
|
AnchorSideTop.Control = PlotOptionsGroup
|
||||||
|
Left = 107
|
||||||
|
Height = 23
|
||||||
|
Top = 8
|
||||||
|
Width = 55
|
||||||
|
BorderSpacing.Left = 8
|
||||||
|
BorderSpacing.Top = 8
|
||||||
|
BorderSpacing.Right = 12
|
||||||
|
MinValue = 2
|
||||||
|
OnChange = NumBinsEditChange
|
||||||
|
TabOrder = 0
|
||||||
|
Value = 2
|
||||||
|
end
|
||||||
|
object Label7: TLabel
|
||||||
|
AnchorSideLeft.Control = PlotOptionsGroup
|
||||||
|
AnchorSideTop.Control = NumBinsEdit
|
||||||
|
AnchorSideTop.Side = asrCenter
|
||||||
|
Left = 16
|
||||||
|
Height = 15
|
||||||
|
Top = 12
|
||||||
|
Width = 83
|
||||||
|
BorderSpacing.Left = 16
|
||||||
|
Caption = 'Number of bins'
|
||||||
|
ParentColor = False
|
||||||
|
end
|
||||||
|
object BinCountChk: TCheckBox
|
||||||
|
AnchorSideLeft.Control = Label7
|
||||||
|
AnchorSideTop.Control = NumBinsEdit
|
||||||
|
AnchorSideTop.Side = asrBottom
|
||||||
|
Left = 16
|
||||||
|
Height = 19
|
||||||
|
Top = 39
|
||||||
|
Width = 113
|
||||||
|
BorderSpacing.Top = 8
|
||||||
|
BorderSpacing.Bottom = 12
|
||||||
|
Caption = 'Show frequencies'
|
||||||
|
OnChange = BinCountChkChange
|
||||||
|
TabOrder = 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
inherited ParamsSplitter: TSplitter
|
||||||
|
Left = 279
|
||||||
|
Height = 447
|
||||||
|
end
|
||||||
|
inherited PageControl: TPageControl
|
||||||
|
Left = 288
|
||||||
|
Height = 431
|
||||||
|
Width = 561
|
||||||
|
TabOrder = 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -5,462 +5,491 @@ unit CorSimUnit;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
|
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
|
||||||
ExtCtrls, StdCtrls, Math,
|
ExtCtrls, StdCtrls, ComCtrls, Spin,
|
||||||
Globals, OutputUnit;
|
TAGraph, TACustomSeries,
|
||||||
|
Globals, BasicStatsReportAndChartFormUnit;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
{ TCorSimFrm }
|
TCorSimResult = record
|
||||||
|
a, b: Double;
|
||||||
|
xMean, xStdDev: Double;
|
||||||
|
yMean, yStdDev: Double;
|
||||||
|
CorrXY: Double;
|
||||||
|
end;
|
||||||
|
|
||||||
TCorSimFrm = class(TForm)
|
{ TCorSimForm }
|
||||||
Bevel1: TBevel;
|
|
||||||
Nobs: TEdit;
|
TCorSimForm = class(TBasicStatsReportAndChartForm)
|
||||||
Image1: TImage;
|
BinCountChk: TCheckBox;
|
||||||
|
Label7: TLabel;
|
||||||
|
PlotOptionsGroup: TGroupBox;
|
||||||
|
NumObsEdit: TEdit;
|
||||||
Label6: TLabel;
|
Label6: TLabel;
|
||||||
CloseBtn: TButton;
|
CorrEdit: TEdit;
|
||||||
ComputeBtn: TButton;
|
|
||||||
Corr: TEdit;
|
|
||||||
Label5: TLabel;
|
Label5: TLabel;
|
||||||
SDY: TEdit;
|
NumBinsEdit: TSpinEdit;
|
||||||
|
StdDevYEdit: TEdit;
|
||||||
Label4: TLabel;
|
Label4: TLabel;
|
||||||
SDX: TEdit;
|
StdDevXEdit: TEdit;
|
||||||
Label3: TLabel;
|
Label3: TLabel;
|
||||||
MeanY: TEdit;
|
MeanYEdit: TEdit;
|
||||||
Label2: TLabel;
|
Label2: TLabel;
|
||||||
MeanX: TEdit;
|
MeanXEdit: TEdit;
|
||||||
Label1: TLabel;
|
Label1: TLabel;
|
||||||
Panel1: TPanel;
|
procedure BinCountChkChange(Sender: TObject);
|
||||||
procedure ComputeBtnClick(Sender: TObject);
|
procedure NumBinsEditChange(Sender: TObject);
|
||||||
procedure CorrKeyPress(Sender: TObject; var Key: char);
|
|
||||||
procedure FormShow(Sender: TObject);
|
|
||||||
procedure MeanXKeyPress(Sender: TObject; var Key: char);
|
|
||||||
procedure MeanYKeyPress(Sender: TObject; var Key: char);
|
|
||||||
procedure NobsKeyPress(Sender: TObject; var Key: char);
|
|
||||||
procedure SDXKeyPress(Sender: TObject; var Key: char);
|
|
||||||
procedure SDYKeyPress(Sender: TObject; var Key: char);
|
|
||||||
private
|
private
|
||||||
{ private declarations }
|
XHistogramChart: TChart;
|
||||||
xmean, ymean, xsd, ysd, corxy, corsqr, yvariance, predvar : double;
|
YHistogramChart: TChart;
|
||||||
errvariance, stderror, b, constant, newxmean, newymean : double;
|
XHistogramSeries: TChartSeries;
|
||||||
newxsd, newysd, newcorr, randomerror, newb, newconstant : double;
|
YHistogramSeries: TChartSeries;
|
||||||
x, y: DblDyneVec;
|
xValues, yValues: DblDyneVec;
|
||||||
freqx, freqy: IntDyneVec;
|
simResult: TCorSimResult;
|
||||||
N: integer;
|
|
||||||
|
procedure ChartAfterPaint(Sender: TChart);
|
||||||
|
procedure ChartFrameResize(Sender: TObject);
|
||||||
|
|
||||||
|
procedure GenerateData(ACount: Integer;
|
||||||
|
const XMean, YMean, XStdDev, YStdDev, CorrXY: Double; out A, B: Double);
|
||||||
|
|
||||||
procedure Plot;
|
procedure Plot;
|
||||||
function Validate(out AMsg: String; out AControl: TWinControl): Boolean;
|
|
||||||
|
procedure WriteReport(A, B, XMean, YMean, XStdDev, YStdDev, CorrXY: Double);
|
||||||
|
|
||||||
|
protected
|
||||||
|
procedure AdjustConstraints; override;
|
||||||
|
procedure Compute; override;
|
||||||
|
function Validate(out AMsg: String; out AControl: TWinControl): Boolean; override;
|
||||||
|
|
||||||
public
|
public
|
||||||
{ public declarations }
|
constructor Create(AOwner: TComponent); override;
|
||||||
|
procedure Reset; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
CorSimFrm: TCorSimFrm;
|
CorSimForm: TCorSimForm;
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
{ TCorSimFrm }
|
{$R *.lfm}
|
||||||
|
|
||||||
procedure TCorSimFrm.MeanXKeyPress(Sender: TObject; var Key: char);
|
uses
|
||||||
|
Math,
|
||||||
|
TAGeometry, TAChartUtils, TALegend, TASeries,
|
||||||
|
MatrixUnit, ChartFrameUnit;
|
||||||
|
|
||||||
|
|
||||||
|
{ TCorSimForm }
|
||||||
|
|
||||||
|
constructor TCorSimForm.Create(AOwner: TComponent);
|
||||||
begin
|
begin
|
||||||
if Key = #13 then MeanY.SetFocus;
|
inherited;
|
||||||
|
|
||||||
|
FChartFrame.OnResize := @ChartFrameResize;
|
||||||
|
FChartFrame.Chart.OnAfterPaint := @ChartAfterPaint;
|
||||||
|
FChartFrame.Chart.Foot.Alignment := taLeftJustify;
|
||||||
|
|
||||||
|
XHistogramChart := TChart.Create(FChartFrame);
|
||||||
|
with XHistogramChart do
|
||||||
|
begin
|
||||||
|
Parent := FChartFrame;
|
||||||
|
AnchorSideTop.Control := FChartFrame.ChartToolBar;
|
||||||
|
AnchorSideTop.Side := asrBottom;
|
||||||
|
AnchorSideLeft.Control := FChartFrame.Chart;
|
||||||
|
AnchorSideRight.Control := FChartFrame.Chart;
|
||||||
|
AnchorSideRight.Side := asrBottom;
|
||||||
|
Anchors := [akLeft, akTop, akRight];
|
||||||
|
Height := 200;
|
||||||
|
Color := FChartFrame.Chart.Color;
|
||||||
|
BackColor := FChartFrame.Chart.Color;
|
||||||
|
Margins.Bottom := 0;
|
||||||
|
Frame.Visible := false;
|
||||||
|
LeftAxis.Visible := false;
|
||||||
|
BottomAxis.Grid.Visible := false;
|
||||||
|
BottomAxis.Marks.Visible := false;
|
||||||
|
BottomAxis.AxisPen.Visible := true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCorSimFrm.CorrKeyPress(Sender: TObject; var Key: char);
|
XHistogramSeries := TBarSeries.Create(FChartFrame);
|
||||||
|
with TBarSeries(XHistogramSeries) do
|
||||||
begin
|
begin
|
||||||
if Key = #13 then Nobs.SetFocus;
|
BarBrush.Color := DATA_COLORS[1];
|
||||||
|
MarkPositions := lmpPositive;
|
||||||
|
end;
|
||||||
|
XHistogramChart.AddSeries(XHistogramSeries);
|
||||||
|
|
||||||
|
YHistogramChart := TChart.Create(FChartFrame);
|
||||||
|
with YHistogramChart do
|
||||||
|
begin
|
||||||
|
Parent := FChartFrame;
|
||||||
|
AnchorSideTop.Control := FChartFrame.Chart;
|
||||||
|
AnchorSideRight.Control := FChartFrame;
|
||||||
|
AnchorSideRight.Side := asrBottom;
|
||||||
|
AnchorSideBottom.Control := FChartFrame.Chart;
|
||||||
|
AnchorSideBottom.Side := asrBottom;
|
||||||
|
Anchors := [akTop, akRight, akBottom];
|
||||||
|
Width := 200;
|
||||||
|
Color := FChartFrame.Chart.Color;
|
||||||
|
BackColor := FChartFrame.Chart.Color;
|
||||||
|
Margins.Left := 0;
|
||||||
|
Frame.Visible := false;
|
||||||
|
BottomAxis.Visible := false;
|
||||||
|
LeftAxis.Grid.Visible := false;
|
||||||
|
LeftAxis.Marks.Visible := false;
|
||||||
|
LeftAxis.AxisPen.Visible := true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCorSimFrm.ComputeBtnClick(Sender: TObject);
|
YHistogramSeries := TBarSeries.Create(FChartFrame);
|
||||||
|
with TBarSeries(YHistogramSeries) do
|
||||||
|
begin
|
||||||
|
AxisIndexX := 0;
|
||||||
|
AxisIndexY := 1;
|
||||||
|
BarBrush.Color := DATA_COLORS[2];
|
||||||
|
MarkPositions := lmpPositive;
|
||||||
|
end;
|
||||||
|
YHistogramChart.AddSeries(YHistogramSeries);
|
||||||
|
|
||||||
|
with FChartFrame.Chart do
|
||||||
|
begin
|
||||||
|
Align := alNone;
|
||||||
|
AnchorSideLeft.Control := FChartFrame;
|
||||||
|
AnchorSideBottom.Control := FChartFrame;
|
||||||
|
AnchorSideBottom.Side := asrBottom;
|
||||||
|
AnchorSideTop.Control := XHistogramChart;
|
||||||
|
AnchorSideTop.Side := asrBottom;
|
||||||
|
AnchorSideRight.Control := YHistogramChart;
|
||||||
|
Anchors := [akLeft, akTop, akRight, akBottom];
|
||||||
|
end;
|
||||||
|
|
||||||
|
PageControl.ActivePageIndex := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TCorSimForm.AdjustConstraints;
|
||||||
|
begin
|
||||||
|
inherited;
|
||||||
|
|
||||||
|
ParamsPanel.Constraints.MinWidth := Max(
|
||||||
|
3*CloseBtn.Width + 2*CloseBtn.BorderSpacing.Left,
|
||||||
|
StdDevXEdit.Left + StdDevXEdit.Width
|
||||||
|
);
|
||||||
|
ParamsPanel.Constraints.MinHeight :=
|
||||||
|
PlotOptionsGroup.Top + PlotOptionsGroup.Height +
|
||||||
|
ButtonBevel.Height + CloseBtn.BorderSpacing.Top + CloseBtn.Height;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TCorSimForm.BinCountChkChange(Sender: TObject);
|
||||||
|
begin
|
||||||
|
if BinCountChk.Checked then
|
||||||
|
begin
|
||||||
|
XHistogramSeries.Marks.Style := smsValue;
|
||||||
|
YHistogramSeries.Marks.Style := smsValue;
|
||||||
|
end else
|
||||||
|
begin
|
||||||
|
XHistogramSeries.Marks.Style := smsNone;
|
||||||
|
YHistogramSeries.Marks.Style := smsNone;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TCorSimForm.ChartAfterPaint(Sender: TChart);
|
||||||
var
|
var
|
||||||
i: integer;
|
ext: TDoubleRect;
|
||||||
msg: String;
|
R: Trect;
|
||||||
C: TWinControl;
|
|
||||||
lReport: TStrings;
|
|
||||||
begin
|
begin
|
||||||
if not Validate(msg, C) then begin
|
ext := FChartFrame.Chart.CurrentExtent;
|
||||||
C.SetFocus;
|
R.TopLeft := FChartFrame.Chart.GraphToImage(DoublePoint(ext.a.x, ext.b.y));
|
||||||
MessageDlg(msg, mtError, [mbOk], 0);
|
R.BottomRight := FChartFrame.Chart.GraphToImage(DoublePoint(ext.b.x, ext.a.y));
|
||||||
exit;
|
XHistogramChart.BorderSpacing.Left := R.Left;
|
||||||
|
XHistogramChart.BorderSpacing.Right := FChartFrame.Chart.Width - R.Right;
|
||||||
|
YHistogramChart.BorderSpacing.Top := R.Top;
|
||||||
|
YHistogramChart.BorderSpacing.Bottom := FChartFrame.Chart.Height - R.Bottom;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
N := StrToInt(NObs.Text);
|
|
||||||
xmean := StrToFloat(MeanX.Text);
|
|
||||||
ymean := StrToFloat(MeanY.Text);
|
|
||||||
xsd := StrToFloat(SDX.Text);
|
|
||||||
ysd := StrToFloat(SDY.Text);
|
|
||||||
corxy := StrToFloat(Corr.Text);
|
|
||||||
|
|
||||||
|
procedure TCorSimForm.ChartFrameResize(Sender: TObject);
|
||||||
|
begin
|
||||||
|
XHistogramChart.Height := Min(FChartFrame.Width div 5, FChartFrame.Height div 5);
|
||||||
|
YHistogramChart.Width := XHistogramChart.Height;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TCorSimForm.Compute;
|
||||||
|
var
|
||||||
|
N: Integer;
|
||||||
|
a, b: Double;
|
||||||
|
xMean, yMean, xStdDev, yStdDev, corrXY: Double;
|
||||||
|
begin
|
||||||
|
N := StrToInt(NumObsEdit.Text);
|
||||||
|
xMean := StrToFloat(MeanXEdit.Text);
|
||||||
|
yMean := StrToFloat(MeanYEdit.Text);
|
||||||
|
xStdDev := StrToFloat(StdDevXEdit.Text);
|
||||||
|
yStdDev := StrToFloat(StdDevYEdit.Text);
|
||||||
|
corrXY := StrToFloat(CorrEdit.Text);
|
||||||
|
|
||||||
|
GenerateData(N, xMean, yMean, xStdDev, yStdDev, corrXY, a, b);
|
||||||
|
|
||||||
|
with SimResult do
|
||||||
|
begin
|
||||||
|
VecMeanStdDev(xValues, XMean, XStdDev);
|
||||||
|
VecMeanStdDev(yValues, YMean, YStdDev);
|
||||||
|
SimResult.CorrXY := (xValues * yValues - XMean * YMean * N) / ((N-1) * XStdDev * YStdDev);
|
||||||
|
B := CorrXY * (YStdDev / XStdDev);
|
||||||
|
A := YMean - B * XMean;
|
||||||
|
end;
|
||||||
|
|
||||||
|
WriteReport(a, b, xMean, yMean, xStdDev, yStdDev, corrXY);
|
||||||
|
Plot;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TCorSimForm.GenerateData(ACount: Integer;
|
||||||
|
const XMean, YMean, XStdDev, YStdDev, CorrXY: Double; out A, B: Double);
|
||||||
|
var
|
||||||
|
corrSqr, yVariance, predVariance, errVariance, stdError: Double;
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
Randomize;
|
Randomize;
|
||||||
|
|
||||||
SetLength(freqx, N + 1);
|
// Calculate the fitted line parameters
|
||||||
SetLength(freqy, N + 1);
|
B := CorrXY * (YStdDev / XStdDev);
|
||||||
SetLength(x, N + 1);
|
A := YMean - B * XMean;
|
||||||
SetLength(y, N + 1);
|
|
||||||
|
|
||||||
// generate x and y data observations
|
// Calculate the "scatter" parameters
|
||||||
corsqr := corxy * corxy;
|
corrSqr := sqr(CorrXY);
|
||||||
yvariance := ysd * ysd;
|
yVariance := YStdDev * YStdDev;
|
||||||
predvar := corsqr * yvariance;
|
predVariance := corrSqr * yVariance;
|
||||||
errvariance := yvariance - predvar;
|
errVariance := yVariance - predVariance;
|
||||||
stderror := sqrt(errvariance);
|
stdError := sqrt(errVariance);
|
||||||
b := corxy * (ysd / xsd);
|
|
||||||
constant := ymean - b * xmean;
|
|
||||||
|
|
||||||
newxmean := 0.0;
|
// Calculate x and y values
|
||||||
newymean := 0.0;
|
xValues := nil;
|
||||||
newxsd := 0.0;
|
yValues := nil;
|
||||||
newysd := 0.0;
|
SetLength(xValues, ACount);
|
||||||
newcorr := 0.0;
|
SetLength(yValues, ACount);
|
||||||
for i := 1 to N do
|
for i := 0 to ACount-1 do
|
||||||
begin
|
begin
|
||||||
x[i] := RandG(xmean, xsd);
|
xValues[i] := RandG(xMean, xStdDev);
|
||||||
randomerror := RandG(0.0, stderror);
|
yValues[i] := A + B * xValues[i] + RandG(0.0, stdError);
|
||||||
y[i] := b * x[i] + constant + randomerror;
|
|
||||||
newxmean := newxmean + x[i];
|
|
||||||
newymean := newymean + y[i];
|
|
||||||
newxsd := newxsd + sqr(x[i]);
|
|
||||||
newysd := newysd + sqr(y[i]);
|
|
||||||
newcorr := newcorr + x[i] * y[i];
|
|
||||||
end;
|
|
||||||
|
|
||||||
newxsd := newxsd - sqr(newxmean) / N;
|
|
||||||
newxsd := newxsd / (N - 1);
|
|
||||||
newxsd := sqrt(newxsd);
|
|
||||||
|
|
||||||
newysd := newysd - sqr(newymean) / N;
|
|
||||||
newysd := newysd / (N - 1);
|
|
||||||
newysd := sqrt(newysd);
|
|
||||||
|
|
||||||
newcorr := newcorr - newxmean * newymean / N;
|
|
||||||
newcorr := newcorr / (N - 1);
|
|
||||||
newcorr := newcorr / (newxsd * newysd);
|
|
||||||
|
|
||||||
newxmean := newxmean / N;
|
|
||||||
newymean := newymean / N;
|
|
||||||
newb := newcorr * (newysd / newxsd);
|
|
||||||
newconstant := newymean - newb * newxmean;
|
|
||||||
|
|
||||||
lReport := TStringList.Create;
|
|
||||||
try
|
|
||||||
lReport.Add('POPULATION PARAMETERS FOR THE SIMULATION');
|
|
||||||
lReport.Add('');
|
|
||||||
lReport.Add('Mean X: %8.3f', [xmean]);
|
|
||||||
lReport.Add('Std. Dev. X: %8.3f', [xsd]);
|
|
||||||
lReport.Add('');
|
|
||||||
lReport.Add('Mean Y: %8.3f', [ymean]);
|
|
||||||
lReport.Add('Std. Dev. Y: %8.3f', [ysd]);
|
|
||||||
lReport.Add('');
|
|
||||||
lReport.Add('Product-Moment Correlation: %8.3f', [corxy]);
|
|
||||||
lReport.Add('Regression line slope: %8.3f', [b]);
|
|
||||||
lReport.Add(' constant: %8.3f', [constant]);
|
|
||||||
lReport.Add('');
|
|
||||||
lReport.Add(DIVIDER);
|
|
||||||
lReport.Add('');
|
|
||||||
lReport.Add('SAMPLE STATISTICS FOR %d OBSERVATIONS FROM THE POPULATION', [N]);
|
|
||||||
lReport.Add('');
|
|
||||||
lReport.Add('Mean X: %8.3f', [newxmean]);
|
|
||||||
lReport.Add('Std. Dev. X: %8.3f', [newxsd]);
|
|
||||||
lReport.Add('');
|
|
||||||
lReport.Add('Mean Y: %8.3f', [newymean]);
|
|
||||||
lReport.Add('Std. Dev. Y: %8.3f', [newysd]);
|
|
||||||
lReport.Add('');
|
|
||||||
lReport.Add('Product-Moment Correlation: %8.3f', [newcorr]);
|
|
||||||
lReport.Add('Regression line slope: %8.3f', [newb]);
|
|
||||||
lReport.Add(' constant: %8.3f', [newconstant]);
|
|
||||||
lReport.Add('');
|
|
||||||
lReport.Add(DIVIDER);
|
|
||||||
lReport.Add('');
|
|
||||||
lReport.Add('Pair No. X Y ');
|
|
||||||
lReport.Add('-------- --------- ---------');
|
|
||||||
for i := 1 to N do
|
|
||||||
lReport.Add(' %4d %8.3f %8.3f', [i, x[i], y[i]]);
|
|
||||||
|
|
||||||
DisplayReport(lReport);
|
|
||||||
|
|
||||||
Plot();
|
|
||||||
|
|
||||||
finally
|
|
||||||
lReport.Free;
|
|
||||||
freqx := nil;
|
|
||||||
freqy := nil;
|
|
||||||
x := nil;
|
|
||||||
y := nil;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCorSimFrm.FormShow(Sender: TObject);
|
|
||||||
|
procedure TCorSimForm.NumBinsEditChange(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
Image1.Canvas.Pen.Color := clBlack;
|
if Assigned(FChartFrame) and Assigned(xValues) and Assigned(yValues) then
|
||||||
Image1.Canvas.Brush.Color := clWhite;
|
Plot;
|
||||||
Image1.Canvas.Rectangle(0, 0, Image1.Width, Image1.Height);
|
|
||||||
|
|
||||||
MeanX.Text := '100';
|
|
||||||
MeanY.Text := '100';
|
|
||||||
SDX.Text := '15';
|
|
||||||
SDY.Text := '15';
|
|
||||||
Corr.Text := '.8';
|
|
||||||
Nobs.Text := '100';
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCorSimFrm.MeanYKeyPress(Sender: TObject; var Key: char);
|
|
||||||
begin
|
|
||||||
if Key = #13 then SDX.SetFocus;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TCorSimFrm.NobsKeyPress(Sender: TObject; var Key: char);
|
procedure TCorSimForm.Plot;
|
||||||
begin
|
|
||||||
if Key = #13 then ComputeBtn.SetFocus;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TCorSimFrm.SDXKeyPress(Sender: TObject; var Key: char);
|
|
||||||
begin
|
|
||||||
if Key = #13 then SDY.SetFocus;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TCorSimFrm.SDYKeyPress(Sender: TObject; var Key: char);
|
|
||||||
begin
|
|
||||||
if Key = #13 then Corr.SetFocus;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TCorSimFrm.Plot;
|
|
||||||
var
|
var
|
||||||
minx, maxx, miny, maxy, xincrement, yincrement: double;
|
freqData: DblDyneVec;
|
||||||
predy1, predy2, lowerx, upperx, frange, prop: double;
|
x, mn, mx: Double;
|
||||||
charlabel: string;
|
i, n: Integer;
|
||||||
xpos, ypos, xpos1, ypos1, xpos2, ypos2: integer;
|
xpts, ypts: DblDyneVec;
|
||||||
i, winwidth, winheight, xoffset, yoffset, xaxislong, yaxislong: integer;
|
|
||||||
j, xspacing, yspacing, labelwidth, minfreq, maxfreq: integer;
|
|
||||||
flength, theight, lowery, uppery: integer;
|
|
||||||
begin
|
begin
|
||||||
// get min and max of x and y points
|
FChartFrame.Clear;
|
||||||
minx := x[1];
|
XHistogramSeries.Clear;
|
||||||
maxx := minx;
|
YHistogramSeries.Clear;
|
||||||
miny := y[1];
|
|
||||||
maxy := miny;
|
// Chart labelling
|
||||||
for i := 1 to N do
|
FChartFrame.SetXTitle('x distribution');
|
||||||
|
FChartFrame.SetYTitle('y distribution');
|
||||||
|
FChartFrame.SetFooter(Format(
|
||||||
|
'Correlation: %.3f' + LineEnding +
|
||||||
|
'X Mean: %.3f, StdDev: %.3f' + LineEnding +
|
||||||
|
'Y Mean: %.3f, StdDev: %.3f', [
|
||||||
|
SimResult.CorrXY, SimResult.XMean, SimResult.XStdDev, SimResult.YMean, SimResult.YStdDev
|
||||||
|
]));
|
||||||
|
FChartFrame.Chart.Legend.Alignment := laBottomCenter;
|
||||||
|
FChartFrame.Chart.Legend.ColumnCount := 2;
|
||||||
|
|
||||||
|
// Draw data points
|
||||||
|
FChartFrame.PlotXY(ptSymbols, xValues, yValues, nil, nil, 'Data', DATA_COLORS[0]);
|
||||||
|
|
||||||
|
// Draw top histogram
|
||||||
|
VecMaxMin(xValues, mx, mn);
|
||||||
|
n := NumBinsEdit.Value;
|
||||||
|
freqData := VecHistogram(xValues, mn, mx, n);
|
||||||
|
for i:= 0 to n-1 do
|
||||||
begin
|
begin
|
||||||
if (minx > x[i]) then minx := x[i];
|
x := i / (n-1) * (mx - mn) + mn;
|
||||||
if (maxx < x[i]) then maxx := x[i];
|
XHistogramSeries.AddXY(x, freqData[i]);
|
||||||
if (miny > y[i]) then miny := y[i];
|
|
||||||
if (maxy < y[i]) then maxy := y[i];
|
|
||||||
end;
|
|
||||||
xincrement := (maxx - minx) / 10;
|
|
||||||
yincrement := (maxy - miny) / 10;
|
|
||||||
|
|
||||||
winwidth := Image1.Width;
|
|
||||||
winheight := Image1.Height;
|
|
||||||
xoffset := winwidth div 5;
|
|
||||||
yoffset := winheight div 5;
|
|
||||||
xaxislong := winwidth - xoffset- winwidth div 10;
|
|
||||||
yaxislong := winheight - yoffset - winheight div 10;
|
|
||||||
xspacing := xaxislong div 10;
|
|
||||||
yspacing := yaxislong div 10;
|
|
||||||
|
|
||||||
Image1.Canvas.Pen.Color := clBlack;
|
|
||||||
Image1.Canvas.Line(xoffset, yaxislong, winwidth, yaxislong);
|
|
||||||
Image1.canvas.Line(xoffset, yaxislong, xoffset, 0);
|
|
||||||
|
|
||||||
// do xaxis
|
|
||||||
for i := 0 to 11 do
|
|
||||||
begin
|
|
||||||
Image1.Canvas.Line(xoffset + i * xspacing, yaxislong, xoffset + i * xspacing, yaxislong + 10);
|
|
||||||
charlabel := Format('%.3f', [minx + i * xincrement]);
|
|
||||||
labelwidth := Image1.Canvas.TextWidth(charlabel);
|
|
||||||
xpos := xoffset + i * xspacing - labelwidth div 2;
|
|
||||||
ypos := yaxislong + 12;
|
|
||||||
Image1.Canvas.TextOut(xpos, ypos, charlabel);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// do yaxis
|
// Draw regression line
|
||||||
for i := 0 to 11 do
|
// Regression line
|
||||||
begin
|
SetLength(xpts, 2);
|
||||||
Image1.Canvas.Line(xoffset, yaxislong - i * yspacing, xoffset-10, yaxislong - i * yspacing);
|
SetLength(yPts, 2);
|
||||||
charlabel := Format('%.3f', [miny + i * yincrement]);
|
xpts[0] := mn; ypts[0] := SimResult.a + SimResult.b * xpts[0];
|
||||||
labelwidth := Image1.Canvas.TextWidth(charlabel);
|
xpts[1] := mx; ypts[1] := SimResult.a + SimResult.b * xpts[1];
|
||||||
xpos := xoffset - 10 - labelwidth;
|
FChartFrame.PlotXY(ptLines, xpts, ypts, nil, nil, 'Regression line', clBlack);
|
||||||
ypos := yaxislong - i * yspacing;
|
|
||||||
Image1.Canvas.TextOut(xpos, ypos, charlabel);
|
|
||||||
end;
|
|
||||||
|
|
||||||
// plot points
|
// Draw right histogram
|
||||||
Image1.Canvas.Pen.Color := clRed;
|
VecMaxMin(yValues, mx, mn);
|
||||||
for i := 1 to N do
|
n := NumBinsEdit.Value;
|
||||||
|
freqData := VecHistogram(yValues, mn, mx, n);
|
||||||
|
for i := 0 to n-1 do
|
||||||
begin
|
begin
|
||||||
xpos := round(xoffset + ((x[i] - minx) / (maxx - minx) * xaxislong));
|
x := i / (n-1) * (mx - mn) + mn;
|
||||||
ypos := round(yaxislong - ((y[i] - miny) / (maxy - miny) * yaxislong));
|
YHistogramSeries.AddXY(x, freqData[i]);
|
||||||
Image1.Canvas.Ellipse(xpos, ypos, xpos+5, ypos+5);
|
|
||||||
end;
|
|
||||||
|
|
||||||
// draw regression line
|
|
||||||
Image1.Canvas.Pen.Color := clBlack;
|
|
||||||
predy1 := newb * minx + newconstant;
|
|
||||||
predy2 := newb * maxx + newconstant;
|
|
||||||
xpos1 := xoffset;
|
|
||||||
xpos2 := xoffset + xaxislong;
|
|
||||||
ypos1 := round(yaxislong - ((predy1 - miny) / (maxy - miny) * yaxislong));
|
|
||||||
ypos2 := round(yaxislong - ((predy2 - miny) / (maxy - miny) * yaxislong));
|
|
||||||
Image1.Canvas.Line(xpos1, ypos1, xpos2, ypos2);
|
|
||||||
|
|
||||||
// do x frequency distribution
|
|
||||||
xincrement := (maxx - minx) / 50.0;
|
|
||||||
xspacing := xaxislong div 50;
|
|
||||||
for j := 1 to 51 do
|
|
||||||
freqx[j] := 0;
|
|
||||||
for i := 1 to N do
|
|
||||||
begin
|
|
||||||
for j := 1 to 51 do
|
|
||||||
begin
|
|
||||||
lowerx := minx + j * xincrement;
|
|
||||||
upperx := minx + (j+1) * xincrement;
|
|
||||||
if (x[i] >= lowerx) and (x[i] < upperx) then
|
|
||||||
freqx[j] := freqx[j] + 1;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// plot the x frequencies
|
|
||||||
minfreq := N;
|
|
||||||
maxfreq := 0;
|
|
||||||
for j := 1 to 51 do
|
|
||||||
begin
|
|
||||||
if (freqx[j] > maxfreq) then
|
|
||||||
maxfreq := freqx[j];
|
|
||||||
if (freqx[j] < minfreq) then
|
|
||||||
minfreq := freqx[j];
|
|
||||||
end;
|
|
||||||
flength := winheight - (yaxislong + 25) - Panel1.Height;
|
|
||||||
for j := 1 to 51 do
|
|
||||||
begin
|
|
||||||
xpos := xoffset + j * xspacing;
|
|
||||||
ypos1 := round(yaxislong + 25 + (freqx[j] - minfreq)/ (maxfreq-minfreq) * flength);
|
|
||||||
ypos2 := yaxislong + 25;
|
|
||||||
Image1.Canvas.Line(xpos, ypos1, xpos, ypos2);
|
|
||||||
end;
|
|
||||||
Image1.Canvas.Line(xoffset, yaxislong+25, winwidth, yaxislong+25);
|
|
||||||
|
|
||||||
xpos := 20;
|
procedure TCorSimForm.Reset;
|
||||||
ypos := yaxislong+30;
|
|
||||||
Image1.Canvas.TextOut(xpos, ypos, 'X DISTRIBUTION');
|
|
||||||
|
|
||||||
theight := Image1.Canvas.TextHeight('X');
|
|
||||||
ypos := ypos + theight;
|
|
||||||
charlabel := Format('Correlation: %.3f', [newcorr]);
|
|
||||||
Image1.Canvas.TextOut(xpos, ypos, charlabel);
|
|
||||||
ypos := ypos + theight;
|
|
||||||
charlabel := Format('Mean X: %.3f; Mean Y: %.3f', [newxmean, newymean]);
|
|
||||||
Image1.Canvas.TextOut(xpos, ypos, charlabel);
|
|
||||||
charlabel := Format('SD X: %.3f; SD Y: %.3f', [newxsd, newysd]);
|
|
||||||
ypos := ypos + theight;
|
|
||||||
Image1.Canvas.TextOut(xpos,ypos,charlabel);
|
|
||||||
|
|
||||||
// do y frequency distribution
|
|
||||||
yincrement := (maxy-miny) / 50.0;
|
|
||||||
yspacing := yaxislong div 50;
|
|
||||||
for j := 1 to 51 do
|
|
||||||
freqy[j] := 0;
|
|
||||||
for i := 1 to N do
|
|
||||||
begin
|
begin
|
||||||
for j := 1 to 51 do
|
inherited;
|
||||||
begin
|
MeanXEdit.Text := '100';
|
||||||
lowery := round(miny + j * yincrement);
|
MeanYEdit.Text := '100';
|
||||||
uppery := round(miny + ((j+1) * yincrement));
|
StdDevXEdit.Text := '15';
|
||||||
if (y[i] >= lowery) and (y[i] < uppery) then
|
StdDevYEdit.Text := '15';
|
||||||
freqy[j] := freqy[j] + 1;
|
CorrEdit.Text := '0.8';
|
||||||
end;
|
NumObsEdit.Text := '100';
|
||||||
|
NumBinsEdit.Value := 12;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// plot the y frequencies
|
|
||||||
minfreq := N;
|
|
||||||
maxfreq := 0;
|
|
||||||
for j := 1 to 51 do
|
|
||||||
begin
|
|
||||||
if (freqy[j] > maxfreq) then maxfreq := freqy[j];
|
|
||||||
if (freqy[j] < minfreq) then minfreq := freqy[j];
|
|
||||||
end;
|
|
||||||
flength := winwidth - (xaxislong + 150);
|
|
||||||
for j := 1 to 51 do
|
|
||||||
begin
|
|
||||||
ypos := yaxislong - j * yspacing;
|
|
||||||
frange := maxfreq - minfreq;
|
|
||||||
prop := (freqy[j] - minfreq) / frange;
|
|
||||||
xpos1 := round(xoffset - 50 - prop * flength);
|
|
||||||
xpos2 := xoffset - 50;
|
|
||||||
Image1.Canvas.Line(xpos1, ypos, xpos2, ypos);
|
|
||||||
end;
|
|
||||||
Image1.Canvas.Line(xoffset - 50, yaxislong, xoffset - 50, 0);
|
|
||||||
Image1.Canvas.TextOut(0,0,'Y DISTRIBUTION');
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TCorSimFrm.Validate(out AMsg: String; out AControl: TWinControl): Boolean;
|
function TCorSimForm.Validate(out AMsg: String; out AControl: TWinControl): Boolean;
|
||||||
|
var
|
||||||
|
x: Double;
|
||||||
|
n: Integer;
|
||||||
begin
|
begin
|
||||||
Result := false;
|
Result := false;
|
||||||
|
|
||||||
if (MeanX.Text = '') or (MeanY.Text = '') or
|
if (MeanXEdit.Text = '') or (MeanYEdit.Text = '') or
|
||||||
(SDX.Text = '') or (SDY.Text = '') or
|
(StdDevXEdit.Text = '') or (StdDevYEdit.Text = '') or
|
||||||
(Corr.Text = '') or (NObs.Text = '') then
|
(CorrEdit.Text = '') or (NumObsEdit.Text = '') then
|
||||||
begin
|
begin
|
||||||
if MeanX.Text = '' then
|
if MeanXEdit.Text = '' then
|
||||||
AControl := MeanX
|
AControl := MeanXEdit
|
||||||
else if MeanY.Text = '' then
|
else if MeanYEdit.Text = '' then
|
||||||
AControl := MeanY
|
AControl := MeanYEdit
|
||||||
else if SDX.Text = '' then
|
else if StdDevXEdit.Text = '' then
|
||||||
AControl := SDX
|
AControl := StdDevXEdit
|
||||||
else if SDY.Text = '' then
|
else if StdDevYEdit.Text = '' then
|
||||||
AControl := SDY
|
AControl := StdDevYEdit
|
||||||
else if Corr.Text = '' then
|
else if CorrEdit.Text = '' then
|
||||||
AControl := Corr
|
AControl := CorrEdit
|
||||||
else if NObs.Text = '' then
|
else if NumObsEdit.Text = '' then
|
||||||
AControl := NObs;
|
AControl := NumObsEdit;
|
||||||
AMsg := 'Input cannot be empty.';
|
AMsg := 'Input cannot be empty.';
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if not TryStrToFloat(MeanX.Text, xMean) then
|
if not TryStrToFloat(MeanXEdit.Text, x) then
|
||||||
begin
|
begin
|
||||||
AControl := MeanX;
|
AControl := MeanXEdit;
|
||||||
AMsg := 'Mean X must be a valid number.';
|
AMsg := 'Mean X must be a valid number.';
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if not TryStrToFloat(MeanY.Text, yMean) then
|
if not TryStrToFloat(MeanYEdit.Text, x) then
|
||||||
begin
|
begin
|
||||||
AControl := MeanY;
|
AControl := MeanYEdit;
|
||||||
AMsg := 'Mean Y must be a valid number.';
|
AMsg := 'Mean Y must be a valid number.';
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if not TryStrToFloat(SDX.Text, xSD) or (xSD <= 0) then
|
if not TryStrToFloat(StdDevXEdit.Text, x) or (x <= 0) then
|
||||||
begin
|
begin
|
||||||
AControl := SDX;
|
AControl := StdDevXEdit;
|
||||||
AMsg := 'Std.Dev X must be a valid positive number.';
|
AMsg := 'Std.Dev X must be a valid positive number.';
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if not TryStrToFloat(SDY.Text, ySD) or (ySD <= 0) then
|
if not TryStrToFloat(StdDevYEdit.Text, x) or (x <= 0) then
|
||||||
begin
|
begin
|
||||||
AControl := SDY;
|
AControl := StdDevYEdit;
|
||||||
AMsg := 'Std.Dev Y must be a valid positive number.';
|
AMsg := 'Std.Dev Y must be a valid positive number.';
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if not TryStrToFloat(Corr.Text, corXY) then
|
if not TryStrToFloat(CorrEdit.Text, x) then
|
||||||
begin
|
begin
|
||||||
AControl := Corr;
|
AControl := CorrEdit;
|
||||||
AMsg := 'Correlation XY must be a valid number.';
|
AMsg := 'Correlation XY must be a valid number.';
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if not TryStrToInt(NObs.Text, N) or (N <= 0) then
|
if not TryStrToInt(NumObsEdit.Text, n) or (n <= 0) then
|
||||||
begin
|
begin
|
||||||
AControl := NObs;
|
AControl := NumObsEdit;
|
||||||
AMsg := 'Number of observations must be a valid positive integer.';
|
AMsg := 'Number of observations must be a valid positive integer.';
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
if NumBinsEdit.Text = '' then
|
||||||
|
begin
|
||||||
|
AControl := NumBinsEdit;
|
||||||
|
AMsg := 'Empty input not allowed here.';
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if not TryStrToInt(NumBinsEdit.Text, n) or (n < 2) then
|
||||||
|
begin
|
||||||
|
AControl := NumBinsEdit;
|
||||||
|
AMsg := 'There must be at least 2 bins.';
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
Result := true;
|
Result := true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
initialization
|
|
||||||
{$I corsimunit.lrs}
|
procedure TCorSimForm.WriteReport(
|
||||||
|
A, B, XMean, YMean, XStdDev, YStdDev, CorrXY: Double);
|
||||||
|
var
|
||||||
|
lReport: TStrings;
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
lReport := TStringList.Create;
|
||||||
|
try
|
||||||
|
lReport.Add('POPULATION PARAMETERS FOR THE SIMULATION');
|
||||||
|
lReport.Add('');
|
||||||
|
lReport.Add('Mean X: %8.3f', [XMean]);
|
||||||
|
lReport.Add('Std. Dev. X: %8.3f', [XStdDev]);
|
||||||
|
lReport.Add('');
|
||||||
|
lReport.Add('Mean Y: %8.3f', [YMean]);
|
||||||
|
lReport.Add('Std. Dev. Y: %8.3f', [YStdDev]);
|
||||||
|
lReport.Add('');
|
||||||
|
lReport.Add('Product-Moment Correlation: %8.3f', [CorrXY]);
|
||||||
|
lReport.Add('Regression line slope: %8.3f', [B]);
|
||||||
|
lReport.Add(' constant: %8.3f', [A]);
|
||||||
|
lReport.Add('');
|
||||||
|
lReport.Add(DIVIDER);
|
||||||
|
lReport.Add('');
|
||||||
|
lReport.Add('SAMPLE STATISTICS FOR %d OBSERVATIONS FROM THE POPULATION', [Length(xValues)]);
|
||||||
|
lReport.Add('');
|
||||||
|
lReport.Add('Mean X: %8.3f', [SimResult.XMean]);
|
||||||
|
lReport.Add('Std. Dev. X: %8.3f', [SimResult.XStdDev]);
|
||||||
|
lReport.Add('');
|
||||||
|
lReport.Add('Mean Y: %8.3f', [SimResult.YMean]);
|
||||||
|
lReport.Add('Std. Dev. Y: %8.3f', [SimResult.YStdDev]);
|
||||||
|
lReport.Add('');
|
||||||
|
lReport.Add('Product-Moment Correlation: %8.3f', [SimResult.CorrXY]);
|
||||||
|
lReport.Add('Regression line slope: %8.3f', [SimResult.B]);
|
||||||
|
lReport.Add(' constant: %8.3f', [SimResult.A]);
|
||||||
|
lReport.Add('');
|
||||||
|
lReport.Add(DIVIDER);
|
||||||
|
lReport.Add('');
|
||||||
|
lReport.Add('Pair No. X Y ');
|
||||||
|
lReport.Add('-------- --------- ---------');
|
||||||
|
for i := 0 to High(XValues) do
|
||||||
|
lReport.Add(' %4d %8.3f %8.3f', [i, xValues[i], yValues[i]]);
|
||||||
|
|
||||||
|
FReportFrame.DisplayReport(lReport);
|
||||||
|
|
||||||
|
finally
|
||||||
|
lReport.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -42,19 +42,24 @@ procedure VecMeanVarStdDevSS(const AData: TDblVector;
|
|||||||
procedure VecSumSS(const AData: TDblVector;
|
procedure VecSumSS(const AData: TDblVector;
|
||||||
out Sum, SS: Double);
|
out Sum, SS: Double);
|
||||||
|
|
||||||
|
function VecHistogram(const AData: TDblVector; AMin, AMax: Double;
|
||||||
|
N: Integer): TDblVector;
|
||||||
|
|
||||||
function VecMedian(const AData: TDblVector): Double;
|
function VecMedian(const AData: TDblVector): Double;
|
||||||
|
|
||||||
|
|
||||||
// Matrices
|
// Matrices
|
||||||
|
|
||||||
|
{ NOTE: Indices follow math convention:
|
||||||
|
- 1st index is the row index, i.e. runs vertically
|
||||||
|
- 2nd index is the col index, i.e. runs horizontally
|
||||||
|
All indices are 0-based. }
|
||||||
|
|
||||||
operator + (A, B: TDblMatrix): TDblMatrix;
|
operator + (A, B: TDblMatrix): TDblMatrix;
|
||||||
operator - (A, B: TDblMatrix): TDblMatrix;
|
operator - (A, B: TDblMatrix): TDblMatrix;
|
||||||
operator * (A, B: TDblMatrix): TDblMatrix;
|
operator * (A, B: TDblMatrix): TDblMatrix;
|
||||||
operator * (A: TDblMatrix; v: TDblVector): TDblVector;
|
operator * (A: TDblMatrix; v: TDblVector): TDblVector;
|
||||||
|
|
||||||
{ NOTE: Indices follow math convention:
|
|
||||||
- 1st index is the row index, i.e. runs vertically
|
|
||||||
- 2nd index is the col index, i.e. runs horizontally
|
|
||||||
All indices are 0-based. }
|
|
||||||
function MatAppendColVector(A: TDblMatrix; v: TDblVector): TDblMatrix;
|
function MatAppendColVector(A: TDblMatrix; v: TDblVector): TDblMatrix;
|
||||||
procedure MatCheck(A: TDblMatrix);
|
procedure MatCheck(A: TDblMatrix);
|
||||||
procedure MatCheckSquare(A: TDblMatrix; out n: Integer);
|
procedure MatCheckSquare(A: TDblMatrix; out n: Integer);
|
||||||
@ -319,6 +324,26 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function VecHistogram(const AData: TDblVector; AMin, AMax: Double;
|
||||||
|
N: Integer): TDblVector;
|
||||||
|
var
|
||||||
|
i, j: Integer;
|
||||||
|
factor: Double;
|
||||||
|
begin
|
||||||
|
SetLength(Result, N);
|
||||||
|
for j := 0 to N-1 do Result[j] := 0;
|
||||||
|
|
||||||
|
factor := N / (AMax - AMin);
|
||||||
|
for i := 0 to High(AData) do
|
||||||
|
begin
|
||||||
|
j := trunc((AData[i] - AMin) * factor);
|
||||||
|
if j <= 0 then j := 0;
|
||||||
|
if j >= N then j := N-1;
|
||||||
|
Result[j] := Result[j] + 1;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function VecMedian(const AData: TDblVector): Double;
|
function VecMedian(const AData: TDblVector): Double;
|
||||||
var
|
var
|
||||||
N, midPt: integer;
|
N, midPt: integer;
|
||||||
|
Reference in New Issue
Block a user