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>
|
||||
<Filename Value="forms\simulations\corsimunit.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<ComponentName Value="CorSimFrm"/>
|
||||
<ComponentName Value="CorSimForm"/>
|
||||
<HasResources Value="True"/>
|
||||
<ResourceBaseClass Value="Form"/>
|
||||
<UnitName Value="CorSimUnit"/>
|
||||
|
@ -1373,9 +1373,9 @@ end;
|
||||
// Menu "Simulations" > "Bivariate Scatter Plot"
|
||||
procedure TOS3MainFrm.mnuSimBivarScatterPlotClick(Sender: TObject);
|
||||
begin
|
||||
if CorSimFrm = nil then
|
||||
Application.CreateForm(TCorSimFrm, CorSimFrm);
|
||||
CorSimFrm.ShowModal;
|
||||
if CorSimForm = nil then
|
||||
Application.CreateForm(TCorSimForm, CorSimForm);
|
||||
CorSimForm.Show;
|
||||
end;
|
||||
|
||||
// Menu "Simulations" > "Chisquare Probability"
|
||||
|
@ -1,4 +1,4 @@
|
||||
object CorSimFrm: TCorSimFrm
|
||||
inherited CorSimForm: TCorSimForm
|
||||
Left = 542
|
||||
Height = 447
|
||||
Top = 126
|
||||
@ -8,223 +8,263 @@ object CorSimFrm: TCorSimFrm
|
||||
Caption = 'Correlation Simulation'
|
||||
ClientHeight = 447
|
||||
ClientWidth = 857
|
||||
OnShow = FormShow
|
||||
Position = poMainFormCenter
|
||||
LCLVersion = '2.1.0.0'
|
||||
object Image1: TImage
|
||||
Left = 8
|
||||
Height = 389
|
||||
Top = 8
|
||||
Width = 841
|
||||
Align = alClient
|
||||
BorderSpacing.Left = 8
|
||||
BorderSpacing.Top = 8
|
||||
BorderSpacing.Right = 8
|
||||
end
|
||||
object Panel1: TPanel
|
||||
AnchorSideTop.Side = asrCenter
|
||||
Left = 8
|
||||
Height = 26
|
||||
Top = 413
|
||||
Width = 841
|
||||
Align = alBottom
|
||||
AutoSize = True
|
||||
BorderSpacing.Around = 8
|
||||
BevelOuter = bvNone
|
||||
ClientHeight = 26
|
||||
ClientWidth = 841
|
||||
TabOrder = 0
|
||||
object Label1: TLabel
|
||||
AnchorSideLeft.Control = Panel1
|
||||
AnchorSideTop.Control = MeanX
|
||||
inherited ParamsPanel: TPanel
|
||||
Height = 431
|
||||
Width = 267
|
||||
ClientHeight = 431
|
||||
ClientWidth = 267
|
||||
inherited CloseBtn: TButton
|
||||
Left = 212
|
||||
Top = 406
|
||||
TabOrder = 10
|
||||
end
|
||||
inherited ComputeBtn: TButton
|
||||
Left = 128
|
||||
Top = 406
|
||||
TabOrder = 9
|
||||
end
|
||||
inherited ResetBtn: TButton
|
||||
Left = 66
|
||||
Top = 406
|
||||
TabOrder = 8
|
||||
end
|
||||
inherited HelpBtn: TButton
|
||||
Left = 7
|
||||
Top = 406
|
||||
TabOrder = 7
|
||||
Visible = False
|
||||
end
|
||||
inherited ButtonBevel: TBevel
|
||||
Top = 390
|
||||
Width = 267
|
||||
end
|
||||
object Label1: TLabel[5]
|
||||
AnchorSideLeft.Control = ParamsPanel
|
||||
AnchorSideTop.Control = MeanXEdit
|
||||
AnchorSideTop.Side = asrCenter
|
||||
Left = 0
|
||||
Height = 15
|
||||
Top = 6
|
||||
Top = 4
|
||||
Width = 43
|
||||
Caption = 'Mean X:'
|
||||
ParentColor = False
|
||||
end
|
||||
object Label2: TLabel
|
||||
AnchorSideLeft.Control = MeanX
|
||||
object MeanXEdit: TEdit[6]
|
||||
AnchorSideLeft.Control = Label1
|
||||
AnchorSideLeft.Side = asrBottom
|
||||
AnchorSideTop.Control = Label1
|
||||
Left = 108
|
||||
AnchorSideTop.Control = ParamsPanel
|
||||
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
|
||||
Top = 6
|
||||
Top = 35
|
||||
Width = 43
|
||||
BorderSpacing.Left = 16
|
||||
Caption = 'Mean Y:'
|
||||
ParentColor = False
|
||||
end
|
||||
object Label3: TLabel
|
||||
AnchorSideLeft.Control = MeanY
|
||||
object MeanYEdit: TEdit[8]
|
||||
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
|
||||
AnchorSideTop.Control = Label2
|
||||
Left = 221
|
||||
AnchorSideTop.Control = StdDevXEdit
|
||||
AnchorSideTop.Side = asrCenter
|
||||
Left = 135
|
||||
Height = 15
|
||||
Top = 6
|
||||
Top = 4
|
||||
Width = 50
|
||||
BorderSpacing.Left = 16
|
||||
BorderSpacing.Left = 24
|
||||
Caption = 'Std.Dev.X'
|
||||
ParentColor = False
|
||||
end
|
||||
object Label4: TLabel
|
||||
AnchorSideLeft.Control = SDX
|
||||
object StdDevXEdit: TEdit[10]
|
||||
AnchorSideLeft.Control = Label3
|
||||
AnchorSideLeft.Side = asrBottom
|
||||
AnchorSideTop.Control = Label3
|
||||
Left = 345
|
||||
AnchorSideTop.Control = ParamsPanel
|
||||
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
|
||||
Top = 6
|
||||
Top = 35
|
||||
Width = 50
|
||||
BorderSpacing.Left = 16
|
||||
Caption = 'Std.Dev.Y'
|
||||
ParentColor = False
|
||||
end
|
||||
object Label5: TLabel
|
||||
AnchorSideLeft.Control = SDY
|
||||
object StdDevYEdit: TEdit[12]
|
||||
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
|
||||
AnchorSideTop.Control = Label4
|
||||
Left = 450
|
||||
AnchorSideTop.Control = CorrEdit
|
||||
AnchorSideTop.Side = asrCenter
|
||||
AnchorSideRight.Control = CorrEdit
|
||||
Left = 51
|
||||
Height = 15
|
||||
Top = 6
|
||||
Width = 36
|
||||
Top = 82
|
||||
Width = 76
|
||||
Anchors = [akTop, akRight]
|
||||
BorderSpacing.Left = 8
|
||||
Caption = 'Cor.XY'
|
||||
BorderSpacing.Right = 8
|
||||
Caption = 'Correlation XY'
|
||||
ParentColor = False
|
||||
end
|
||||
object Label6: TLabel
|
||||
AnchorSideLeft.Control = Corr
|
||||
object CorrEdit: TEdit[14]
|
||||
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
|
||||
AnchorSideTop.Control = Label5
|
||||
AnchorSideTop.Control = NumObsEdit
|
||||
AnchorSideTop.Side = asrCenter
|
||||
Left = 554
|
||||
AnchorSideRight.Control = NumObsEdit
|
||||
Left = 92
|
||||
Height = 15
|
||||
Top = 6
|
||||
Top = 113
|
||||
Width = 35
|
||||
Anchors = [akTop, akRight]
|
||||
BorderSpacing.Left = 16
|
||||
BorderSpacing.Right = 8
|
||||
Caption = 'N Size:'
|
||||
ParentColor = False
|
||||
end
|
||||
object MeanX: TEdit
|
||||
AnchorSideLeft.Control = Label1
|
||||
AnchorSideLeft.Side = asrBottom
|
||||
AnchorSideTop.Control = Panel1
|
||||
AnchorSideTop.Side = asrCenter
|
||||
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
|
||||
object NumObsEdit: TEdit[16]
|
||||
AnchorSideLeft.Control = CorrEdit
|
||||
AnchorSideTop.Control = CorrEdit
|
||||
AnchorSideTop.Side = asrBottom
|
||||
AnchorSideRight.Control = CorrEdit
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 775
|
||||
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
|
||||
Left = 135
|
||||
Height = 23
|
||||
Top = 2
|
||||
Width = 40
|
||||
Top = 109
|
||||
Width = 60
|
||||
Alignment = taRightJustify
|
||||
BorderSpacing.Left = 8
|
||||
OnKeyPress = NobsKeyPress
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
BorderSpacing.Top = 8
|
||||
TabOrder = 5
|
||||
Text = 'Nobs'
|
||||
Text = 'NumObsEdit'
|
||||
end
|
||||
object PlotOptionsGroup: TGroupBox[17]
|
||||
AnchorSideLeft.Control = ParamsPanel
|
||||
AnchorSideTop.Control = NumObsEdit
|
||||
AnchorSideTop.Side = asrBottom
|
||||
Left = 0
|
||||
Height = 90
|
||||
Top = 148
|
||||
Width = 178
|
||||
AutoSize = True
|
||||
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
|
||||
object Bevel1: TBevel
|
||||
Left = 0
|
||||
Height = 8
|
||||
Top = 397
|
||||
Width = 857
|
||||
Align = alBottom
|
||||
Shape = bsBottomLine
|
||||
inherited ParamsSplitter: TSplitter
|
||||
Left = 279
|
||||
Height = 447
|
||||
end
|
||||
inherited PageControl: TPageControl
|
||||
Left = 288
|
||||
Height = 431
|
||||
Width = 561
|
||||
TabOrder = 1
|
||||
end
|
||||
end
|
||||
|
@ -5,462 +5,491 @@ unit CorSimUnit;
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
|
||||
ExtCtrls, StdCtrls, Math,
|
||||
Globals, OutputUnit;
|
||||
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
|
||||
ExtCtrls, StdCtrls, ComCtrls, Spin,
|
||||
TAGraph, TACustomSeries,
|
||||
Globals, BasicStatsReportAndChartFormUnit;
|
||||
|
||||
type
|
||||
|
||||
{ TCorSimFrm }
|
||||
TCorSimResult = record
|
||||
a, b: Double;
|
||||
xMean, xStdDev: Double;
|
||||
yMean, yStdDev: Double;
|
||||
CorrXY: Double;
|
||||
end;
|
||||
|
||||
TCorSimFrm = class(TForm)
|
||||
Bevel1: TBevel;
|
||||
Nobs: TEdit;
|
||||
Image1: TImage;
|
||||
{ TCorSimForm }
|
||||
|
||||
TCorSimForm = class(TBasicStatsReportAndChartForm)
|
||||
BinCountChk: TCheckBox;
|
||||
Label7: TLabel;
|
||||
PlotOptionsGroup: TGroupBox;
|
||||
NumObsEdit: TEdit;
|
||||
Label6: TLabel;
|
||||
CloseBtn: TButton;
|
||||
ComputeBtn: TButton;
|
||||
Corr: TEdit;
|
||||
CorrEdit: TEdit;
|
||||
Label5: TLabel;
|
||||
SDY: TEdit;
|
||||
NumBinsEdit: TSpinEdit;
|
||||
StdDevYEdit: TEdit;
|
||||
Label4: TLabel;
|
||||
SDX: TEdit;
|
||||
StdDevXEdit: TEdit;
|
||||
Label3: TLabel;
|
||||
MeanY: TEdit;
|
||||
MeanYEdit: TEdit;
|
||||
Label2: TLabel;
|
||||
MeanX: TEdit;
|
||||
MeanXEdit: TEdit;
|
||||
Label1: TLabel;
|
||||
Panel1: TPanel;
|
||||
procedure ComputeBtnClick(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);
|
||||
procedure BinCountChkChange(Sender: TObject);
|
||||
procedure NumBinsEditChange(Sender: TObject);
|
||||
private
|
||||
{ private declarations }
|
||||
xmean, ymean, xsd, ysd, corxy, corsqr, yvariance, predvar : double;
|
||||
errvariance, stderror, b, constant, newxmean, newymean : double;
|
||||
newxsd, newysd, newcorr, randomerror, newb, newconstant : double;
|
||||
x, y: DblDyneVec;
|
||||
freqx, freqy: IntDyneVec;
|
||||
N: integer;
|
||||
XHistogramChart: TChart;
|
||||
YHistogramChart: TChart;
|
||||
XHistogramSeries: TChartSeries;
|
||||
YHistogramSeries: TChartSeries;
|
||||
xValues, yValues: DblDyneVec;
|
||||
simResult: TCorSimResult;
|
||||
|
||||
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;
|
||||
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 declarations }
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
procedure Reset; override;
|
||||
end;
|
||||
|
||||
var
|
||||
CorSimFrm: TCorSimFrm;
|
||||
CorSimForm: TCorSimForm;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
{ TCorSimFrm }
|
||||
{$R *.lfm}
|
||||
|
||||
procedure TCorSimFrm.MeanXKeyPress(Sender: TObject; var Key: char);
|
||||
begin
|
||||
if Key = #13 then MeanY.SetFocus;
|
||||
end;
|
||||
uses
|
||||
Math,
|
||||
TAGeometry, TAChartUtils, TALegend, TASeries,
|
||||
MatrixUnit, ChartFrameUnit;
|
||||
|
||||
procedure TCorSimFrm.CorrKeyPress(Sender: TObject; var Key: char);
|
||||
begin
|
||||
if Key = #13 then Nobs.SetFocus;
|
||||
end;
|
||||
|
||||
procedure TCorSimFrm.ComputeBtnClick(Sender: TObject);
|
||||
var
|
||||
i: integer;
|
||||
msg: String;
|
||||
C: TWinControl;
|
||||
lReport: TStrings;
|
||||
{ TCorSimForm }
|
||||
|
||||
constructor TCorSimForm.Create(AOwner: TComponent);
|
||||
begin
|
||||
if not Validate(msg, C) then begin
|
||||
C.SetFocus;
|
||||
MessageDlg(msg, mtError, [mbOk], 0);
|
||||
exit;
|
||||
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;
|
||||
|
||||
N := StrToInt(NObs.Text);
|
||||
xmean := StrToFloat(MeanX.Text);
|
||||
ymean := StrToFloat(MeanY.Text);
|
||||
xsd := StrToFloat(SDX.Text);
|
||||
ysd := StrToFloat(SDY.Text);
|
||||
corxy := StrToFloat(Corr.Text);
|
||||
XHistogramSeries := TBarSeries.Create(FChartFrame);
|
||||
with TBarSeries(XHistogramSeries) do
|
||||
begin
|
||||
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;
|
||||
|
||||
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
|
||||
ext: TDoubleRect;
|
||||
R: Trect;
|
||||
begin
|
||||
ext := FChartFrame.Chart.CurrentExtent;
|
||||
R.TopLeft := FChartFrame.Chart.GraphToImage(DoublePoint(ext.a.x, ext.b.y));
|
||||
R.BottomRight := FChartFrame.Chart.GraphToImage(DoublePoint(ext.b.x, ext.a.y));
|
||||
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;
|
||||
|
||||
|
||||
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;
|
||||
|
||||
SetLength(freqx, N + 1);
|
||||
SetLength(freqy, N + 1);
|
||||
SetLength(x, N + 1);
|
||||
SetLength(y, N + 1);
|
||||
// Calculate the fitted line parameters
|
||||
B := CorrXY * (YStdDev / XStdDev);
|
||||
A := YMean - B * XMean;
|
||||
|
||||
// generate x and y data observations
|
||||
corsqr := corxy * corxy;
|
||||
yvariance := ysd * ysd;
|
||||
predvar := corsqr * yvariance;
|
||||
errvariance := yvariance - predvar;
|
||||
stderror := sqrt(errvariance);
|
||||
b := corxy * (ysd / xsd);
|
||||
constant := ymean - b * xmean;
|
||||
// Calculate the "scatter" parameters
|
||||
corrSqr := sqr(CorrXY);
|
||||
yVariance := YStdDev * YStdDev;
|
||||
predVariance := corrSqr * yVariance;
|
||||
errVariance := yVariance - predVariance;
|
||||
stdError := sqrt(errVariance);
|
||||
|
||||
newxmean := 0.0;
|
||||
newymean := 0.0;
|
||||
newxsd := 0.0;
|
||||
newysd := 0.0;
|
||||
newcorr := 0.0;
|
||||
for i := 1 to N do
|
||||
// Calculate x and y values
|
||||
xValues := nil;
|
||||
yValues := nil;
|
||||
SetLength(xValues, ACount);
|
||||
SetLength(yValues, ACount);
|
||||
for i := 0 to ACount-1 do
|
||||
begin
|
||||
x[i] := RandG(xmean, xsd);
|
||||
randomerror := 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;
|
||||
xValues[i] := RandG(xMean, xStdDev);
|
||||
yValues[i] := A + B * xValues[i] + RandG(0.0, stdError);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCorSimFrm.FormShow(Sender: TObject);
|
||||
begin
|
||||
Image1.Canvas.Pen.Color := clBlack;
|
||||
Image1.Canvas.Brush.Color := clWhite;
|
||||
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';
|
||||
procedure TCorSimForm.NumBinsEditChange(Sender: TObject);
|
||||
begin
|
||||
if Assigned(FChartFrame) and Assigned(xValues) and Assigned(yValues) then
|
||||
Plot;
|
||||
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);
|
||||
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;
|
||||
procedure TCorSimForm.Plot;
|
||||
var
|
||||
minx, maxx, miny, maxy, xincrement, yincrement: double;
|
||||
predy1, predy2, lowerx, upperx, frange, prop: double;
|
||||
charlabel: string;
|
||||
xpos, ypos, xpos1, ypos1, xpos2, ypos2: integer;
|
||||
i, winwidth, winheight, xoffset, yoffset, xaxislong, yaxislong: integer;
|
||||
j, xspacing, yspacing, labelwidth, minfreq, maxfreq: integer;
|
||||
flength, theight, lowery, uppery: integer;
|
||||
freqData: DblDyneVec;
|
||||
x, mn, mx: Double;
|
||||
i, n: Integer;
|
||||
xpts, ypts: DblDyneVec;
|
||||
begin
|
||||
// get min and max of x and y points
|
||||
minx := x[1];
|
||||
maxx := minx;
|
||||
miny := y[1];
|
||||
maxy := miny;
|
||||
for i := 1 to N do
|
||||
FChartFrame.Clear;
|
||||
XHistogramSeries.Clear;
|
||||
YHistogramSeries.Clear;
|
||||
|
||||
// Chart labelling
|
||||
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
|
||||
if (minx > x[i]) then minx := x[i];
|
||||
if (maxx < x[i]) then maxx := x[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);
|
||||
x := i / (n-1) * (mx - mn) + mn;
|
||||
XHistogramSeries.AddXY(x, freqData[i]);
|
||||
end;
|
||||
|
||||
// do yaxis
|
||||
for i := 0 to 11 do
|
||||
begin
|
||||
Image1.Canvas.Line(xoffset, yaxislong - i * yspacing, xoffset-10, yaxislong - i * yspacing);
|
||||
charlabel := Format('%.3f', [miny + i * yincrement]);
|
||||
labelwidth := Image1.Canvas.TextWidth(charlabel);
|
||||
xpos := xoffset - 10 - labelwidth;
|
||||
ypos := yaxislong - i * yspacing;
|
||||
Image1.Canvas.TextOut(xpos, ypos, charlabel);
|
||||
end;
|
||||
// Draw regression line
|
||||
// Regression line
|
||||
SetLength(xpts, 2);
|
||||
SetLength(yPts, 2);
|
||||
xpts[0] := mn; ypts[0] := SimResult.a + SimResult.b * xpts[0];
|
||||
xpts[1] := mx; ypts[1] := SimResult.a + SimResult.b * xpts[1];
|
||||
FChartFrame.PlotXY(ptLines, xpts, ypts, nil, nil, 'Regression line', clBlack);
|
||||
|
||||
// plot points
|
||||
Image1.Canvas.Pen.Color := clRed;
|
||||
for i := 1 to N do
|
||||
// Draw right histogram
|
||||
VecMaxMin(yValues, mx, mn);
|
||||
n := NumBinsEdit.Value;
|
||||
freqData := VecHistogram(yValues, mn, mx, n);
|
||||
for i := 0 to n-1 do
|
||||
begin
|
||||
xpos := round(xoffset + ((x[i] - minx) / (maxx - minx) * xaxislong));
|
||||
ypos := round(yaxislong - ((y[i] - miny) / (maxy - miny) * yaxislong));
|
||||
Image1.Canvas.Ellipse(xpos, ypos, xpos+5, ypos+5);
|
||||
x := i / (n-1) * (mx - mn) + mn;
|
||||
YHistogramSeries.AddXY(x, freqData[i]);
|
||||
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;
|
||||
|
||||
// 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;
|
||||
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
|
||||
for j := 1 to 51 do
|
||||
begin
|
||||
lowery := round(miny + j * yincrement);
|
||||
uppery := round(miny + ((j+1) * yincrement));
|
||||
if (y[i] >= lowery) and (y[i] < uppery) then
|
||||
freqy[j] := freqy[j] + 1;
|
||||
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;
|
||||
|
||||
procedure TCorSimForm.Reset;
|
||||
begin
|
||||
inherited;
|
||||
MeanXEdit.Text := '100';
|
||||
MeanYEdit.Text := '100';
|
||||
StdDevXEdit.Text := '15';
|
||||
StdDevYEdit.Text := '15';
|
||||
CorrEdit.Text := '0.8';
|
||||
NumObsEdit.Text := '100';
|
||||
NumBinsEdit.Value := 12;
|
||||
end;
|
||||
|
||||
|
||||
function TCorSimForm.Validate(out AMsg: String; out AControl: TWinControl): Boolean;
|
||||
var
|
||||
x: Double;
|
||||
n: Integer;
|
||||
begin
|
||||
Result := false;
|
||||
|
||||
if (MeanX.Text = '') or (MeanY.Text = '') or
|
||||
(SDX.Text = '') or (SDY.Text = '') or
|
||||
(Corr.Text = '') or (NObs.Text = '') then
|
||||
if (MeanXEdit.Text = '') or (MeanYEdit.Text = '') or
|
||||
(StdDevXEdit.Text = '') or (StdDevYEdit.Text = '') or
|
||||
(CorrEdit.Text = '') or (NumObsEdit.Text = '') then
|
||||
begin
|
||||
if MeanX.Text = '' then
|
||||
AControl := MeanX
|
||||
else if MeanY.Text = '' then
|
||||
AControl := MeanY
|
||||
else if SDX.Text = '' then
|
||||
AControl := SDX
|
||||
else if SDY.Text = '' then
|
||||
AControl := SDY
|
||||
else if Corr.Text = '' then
|
||||
AControl := Corr
|
||||
else if NObs.Text = '' then
|
||||
AControl := NObs;
|
||||
if MeanXEdit.Text = '' then
|
||||
AControl := MeanXEdit
|
||||
else if MeanYEdit.Text = '' then
|
||||
AControl := MeanYEdit
|
||||
else if StdDevXEdit.Text = '' then
|
||||
AControl := StdDevXEdit
|
||||
else if StdDevYEdit.Text = '' then
|
||||
AControl := StdDevYEdit
|
||||
else if CorrEdit.Text = '' then
|
||||
AControl := CorrEdit
|
||||
else if NumObsEdit.Text = '' then
|
||||
AControl := NumObsEdit;
|
||||
AMsg := 'Input cannot be empty.';
|
||||
exit;
|
||||
end;
|
||||
|
||||
if not TryStrToFloat(MeanX.Text, xMean) then
|
||||
if not TryStrToFloat(MeanXEdit.Text, x) then
|
||||
begin
|
||||
AControl := MeanX;
|
||||
AControl := MeanXEdit;
|
||||
AMsg := 'Mean X must be a valid number.';
|
||||
exit;
|
||||
end;
|
||||
|
||||
if not TryStrToFloat(MeanY.Text, yMean) then
|
||||
if not TryStrToFloat(MeanYEdit.Text, x) then
|
||||
begin
|
||||
AControl := MeanY;
|
||||
AControl := MeanYEdit;
|
||||
AMsg := 'Mean Y must be a valid number.';
|
||||
exit;
|
||||
end;
|
||||
|
||||
if not TryStrToFloat(SDX.Text, xSD) or (xSD <= 0) then
|
||||
if not TryStrToFloat(StdDevXEdit.Text, x) or (x <= 0) then
|
||||
begin
|
||||
AControl := SDX;
|
||||
AControl := StdDevXEdit;
|
||||
AMsg := 'Std.Dev X must be a valid positive number.';
|
||||
exit;
|
||||
end;
|
||||
|
||||
if not TryStrToFloat(SDY.Text, ySD) or (ySD <= 0) then
|
||||
if not TryStrToFloat(StdDevYEdit.Text, x) or (x <= 0) then
|
||||
begin
|
||||
AControl := SDY;
|
||||
AControl := StdDevYEdit;
|
||||
AMsg := 'Std.Dev Y must be a valid positive number.';
|
||||
exit;
|
||||
end;
|
||||
|
||||
if not TryStrToFloat(Corr.Text, corXY) then
|
||||
if not TryStrToFloat(CorrEdit.Text, x) then
|
||||
begin
|
||||
AControl := Corr;
|
||||
AControl := CorrEdit;
|
||||
AMsg := 'Correlation XY must be a valid number.';
|
||||
exit;
|
||||
end;
|
||||
|
||||
if not TryStrToInt(NObs.Text, N) or (N <= 0) then
|
||||
if not TryStrToInt(NumObsEdit.Text, n) or (n <= 0) then
|
||||
begin
|
||||
AControl := NObs;
|
||||
AControl := NumObsEdit;
|
||||
AMsg := 'Number of observations must be a valid positive integer.';
|
||||
exit;
|
||||
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;
|
||||
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.
|
||||
|
||||
|
@ -42,19 +42,24 @@ procedure VecMeanVarStdDevSS(const AData: TDblVector;
|
||||
procedure VecSumSS(const AData: TDblVector;
|
||||
out Sum, SS: Double);
|
||||
|
||||
function VecHistogram(const AData: TDblVector; AMin, AMax: Double;
|
||||
N: Integer): TDblVector;
|
||||
|
||||
function VecMedian(const AData: TDblVector): Double;
|
||||
|
||||
|
||||
// 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: 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;
|
||||
procedure MatCheck(A: TDblMatrix);
|
||||
procedure MatCheckSquare(A: TDblMatrix; out n: Integer);
|
||||
@ -319,6 +324,26 @@ begin
|
||||
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;
|
||||
var
|
||||
N, midPt: integer;
|
||||
|
Reference in New Issue
Block a user