LazStats: Refactor CurSimUnit. Add its pdf to chm help. Some cleanup.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7441 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2020-05-08 21:31:22 +00:00
parent 4f87712dd6
commit c2da67888c
8 changed files with 376 additions and 286 deletions

Binary file not shown.

View File

@ -125,7 +125,6 @@ var
cumfreq : DblDyneVec; cumfreq : DblDyneVec;
prank : DblDyneVec; prank : DblDyneVec;
grpsize : IntDyneVec; grpsize : IntDyneVec;
scrgrp : DblDyneVec;
done : boolean; done : boolean;
NoSelected : integer; NoSelected : integer;
ColNoSelected : IntDyneVec; ColNoSelected : IntDyneVec;
@ -173,7 +172,7 @@ begin
NoGrps := maxgrp - mingrp + 1; NoGrps := maxgrp - mingrp + 1;
if NoGrps > 30 then if NoGrps > 30 then
begin begin
MessageDlg('Too many groups for meaningful plot.', mtError, [mbOK], 0); MessageDlg('Too many groups for a meaningful plot.', mtError, [mbOK], 0);
exit; exit;
end; end;
@ -189,7 +188,6 @@ begin
SetLength(tenpcntile,NoGrps+1); SetLength(tenpcntile,NoGrps+1);
SetLength(ninetypcntile,NoGrps+1); SetLength(ninetypcntile,NoGrps+1);
SetLength(median,NoGrps+1); SetLength(median,NoGrps+1);
SetLength(scrgrp,NoGrps+1);
// initialize // initialize
for j := 1 to NoGrps do for j := 1 to NoGrps do
@ -325,7 +323,6 @@ begin
lReport.Free; lReport.Free;
// Clean up // Clean up
scrgrp := nil;
median := nil; median := nil;
ninetypcntile := nil; ninetypcntile := nil;
tenpcntile := nil; tenpcntile := nil;

View File

@ -81,7 +81,7 @@ var
i, j, btn, nscores: integer; i, j, btn, nscores: integer;
RawScores: array[0..50] of double; RawScores: array[0..50] of double;
RawFreq: array[0..50] of double; RawFreq: array[0..50] of double;
temp, X, Y: double; X: double;
begin begin
if DistUseGroup.ItemIndex < 0 then if DistUseGroup.ItemIndex < 0 then
exit; exit;
@ -105,12 +105,8 @@ begin
for i := 1 to ncases - 1 do for i := 1 to ncases - 1 do
begin begin
for j := i+1 to ncases do for j := i+1 to ncases do
begin
X := RawScores[i-1];
Y := RawScores[j-1];
if RawScores[i-1] < RawScores[j-1] then // switch if RawScores[i-1] < RawScores[j-1] then // switch
Exchange(RawScores[i-1], RawScores[j-1]); Exchange(RawScores[i-1], RawScores[j-1]);
end;
end; end;
// get frequency of each score // get frequency of each score

View File

@ -1589,8 +1589,8 @@ end;
// Call HTML help (.chm file) // Call HTML help (.chm file)
// Is is expected that help topics are specified as HelpKeyword (HelpType = htContext). // Is is expected that help topics are specified as HelpKeyword (HelpType = htContext).
// Using numeric HelpContext values will crash the application. // Using numeric HelpContext values will crash the application.
function TOS3MainFrm.HelpHandler(Command:word; Data:PtrInt; function TOS3MainFrm.HelpHandler(Command: Word; Data: PtrInt;
var CallHelp:Boolean): Boolean; var CallHelp: Boolean): Boolean;
var var
topic: UnicodeString; topic: UnicodeString;
begin begin
@ -1599,6 +1599,9 @@ begin
// Don't call regular help // Don't call regular help
CallHelp := False; CallHelp := False;
// silence the compiler, function result not needed
Result := true;
end; end;
{$ENDIF} {$ENDIF}
{$ENDIF} {$ENDIF}

View File

@ -3,10 +3,11 @@ object CorSimFrm: TCorSimFrm
Height = 447 Height = 447
Top = 126 Top = 126
Width = 857 Width = 857
HelpType = htKeyword
HelpKeyword = 'BivariateScatterPlot.htm'
Caption = 'Correlation Simulation' Caption = 'Correlation Simulation'
ClientHeight = 447 ClientHeight = 447
ClientWidth = 857 ClientWidth = 857
OnCreate = FormCreate
OnShow = FormShow OnShow = FormShow
Position = poMainFormCenter Position = poMainFormCenter
LCLVersion = '2.1.0.0' LCLVersion = '2.1.0.0'
@ -114,6 +115,7 @@ object CorSimFrm: TCorSimFrm
Height = 23 Height = 23
Top = 2 Top = 2
Width = 43 Width = 43
Alignment = taRightJustify
BorderSpacing.Left = 6 BorderSpacing.Left = 6
OnKeyPress = MeanXKeyPress OnKeyPress = MeanXKeyPress
TabOrder = 0 TabOrder = 0
@ -127,6 +129,7 @@ object CorSimFrm: TCorSimFrm
Height = 23 Height = 23
Top = 2 Top = 2
Width = 46 Width = 46
Alignment = taRightJustify
BorderSpacing.Left = 8 BorderSpacing.Left = 8
OnKeyPress = MeanYKeyPress OnKeyPress = MeanYKeyPress
TabOrder = 1 TabOrder = 1
@ -140,6 +143,7 @@ object CorSimFrm: TCorSimFrm
Height = 23 Height = 23
Top = 2 Top = 2
Width = 50 Width = 50
Alignment = taRightJustify
BorderSpacing.Left = 8 BorderSpacing.Left = 8
OnKeyPress = SDXKeyPress OnKeyPress = SDXKeyPress
TabOrder = 2 TabOrder = 2
@ -153,6 +157,7 @@ object CorSimFrm: TCorSimFrm
Height = 23 Height = 23
Top = 2 Top = 2
Width = 39 Width = 39
Alignment = taRightJustify
BorderSpacing.Left = 8 BorderSpacing.Left = 8
OnKeyPress = SDYKeyPress OnKeyPress = SDYKeyPress
TabOrder = 3 TabOrder = 3
@ -166,14 +171,15 @@ object CorSimFrm: TCorSimFrm
Height = 23 Height = 23
Top = 2 Top = 2
Width = 44 Width = 44
Alignment = taRightJustify
BorderSpacing.Left = 8 BorderSpacing.Left = 8
OnKeyPress = CorrKeyPress OnKeyPress = CorrKeyPress
TabOrder = 4 TabOrder = 4
Text = 'Corr' Text = 'Corr'
end end
object ComputeBtn: TButton object ComputeBtn: TButton
AnchorSideTop.Control = ReturnBtn AnchorSideTop.Control = CloseBtn
AnchorSideRight.Control = ReturnBtn AnchorSideRight.Control = CloseBtn
Left = 702 Left = 702
Height = 26 Height = 26
Top = 0 Top = 0
@ -182,9 +188,9 @@ object CorSimFrm: TCorSimFrm
BorderSpacing.Right = 8 BorderSpacing.Right = 8
Caption = 'Compute' Caption = 'Compute'
OnClick = ComputeBtnClick OnClick = ComputeBtnClick
TabOrder = 5 TabOrder = 6
end end
object ReturnBtn: TButton object CloseBtn: TButton
AnchorSideTop.Control = Panel1 AnchorSideTop.Control = Panel1
AnchorSideTop.Side = asrCenter AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = Panel1 AnchorSideRight.Control = Panel1
@ -194,9 +200,9 @@ object CorSimFrm: TCorSimFrm
Top = 0 Top = 0
Width = 66 Width = 66
Anchors = [akTop, akRight] Anchors = [akTop, akRight]
Caption = 'Return' Caption = 'Close'
ModalResult = 1 ModalResult = 11
TabOrder = 6 TabOrder = 7
end end
object Nobs: TEdit object Nobs: TEdit
AnchorSideLeft.Control = Label6 AnchorSideLeft.Control = Label6
@ -206,9 +212,10 @@ object CorSimFrm: TCorSimFrm
Height = 23 Height = 23
Top = 2 Top = 2
Width = 40 Width = 40
Alignment = taRightJustify
BorderSpacing.Left = 8 BorderSpacing.Left = 8
OnKeyPress = NobsKeyPress OnKeyPress = NobsKeyPress
TabOrder = 7 TabOrder = 5
Text = 'Nobs' Text = 'Nobs'
end end
end end

View File

@ -18,7 +18,7 @@ type
Nobs: TEdit; Nobs: TEdit;
Image1: TImage; Image1: TImage;
Label6: TLabel; Label6: TLabel;
ReturnBtn: TButton; CloseBtn: TButton;
ComputeBtn: TButton; ComputeBtn: TButton;
Corr: TEdit; Corr: TEdit;
Label5: TLabel; Label5: TLabel;
@ -33,7 +33,6 @@ type
Panel1: TPanel; Panel1: TPanel;
procedure ComputeBtnClick(Sender: TObject); procedure ComputeBtnClick(Sender: TObject);
procedure CorrKeyPress(Sender: TObject; var Key: char); procedure CorrKeyPress(Sender: TObject; var Key: char);
procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure MeanXKeyPress(Sender: TObject; var Key: char); procedure MeanXKeyPress(Sender: TObject; var Key: char);
procedure MeanYKeyPress(Sender: TObject; var Key: char); procedure MeanYKeyPress(Sender: TObject; var Key: char);
@ -45,10 +44,11 @@ type
xmean, ymean, xsd, ysd, corxy, corsqr, yvariance, predvar : double; xmean, ymean, xsd, ysd, corxy, corsqr, yvariance, predvar : double;
errvariance, stderror, b, constant, newxmean, newymean : double; errvariance, stderror, b, constant, newxmean, newymean : double;
newxsd, newysd, newcorr, randomerror, newb, newconstant : double; newxsd, newysd, newcorr, randomerror, newb, newconstant : double;
x, y : DblDyneVec; x, y: DblDyneVec;
freqx, freqy : IntDyneVec; freqx, freqy: IntDyneVec;
N : integer; N: integer;
procedure plot(Sender: TObject); procedure Plot;
function Validate(out AMsg: String; out AControl: TWinControl): Boolean;
public public
{ public declarations } { public declarations }
end; end;
@ -62,314 +62,401 @@ implementation
procedure TCorSimFrm.MeanXKeyPress(Sender: TObject; var Key: char); procedure TCorSimFrm.MeanXKeyPress(Sender: TObject; var Key: char);
begin begin
if Ord(Key) = 13 then MeanY.SetFocus; if Key = #13 then MeanY.SetFocus;
end; end;
procedure TCorSimFrm.CorrKeyPress(Sender: TObject; var Key: char); procedure TCorSimFrm.CorrKeyPress(Sender: TObject; var Key: char);
begin begin
if Ord(Key) = 13 then Nobs.SetFocus; if Key = #13 then Nobs.SetFocus;
end;
procedure TCorSimFrm.FormCreate(Sender: TObject);
begin
if OutputFrm = nil then
Application.CreateForm(TOutputFrm, OutputFrm);
end; end;
procedure TCorSimFrm.ComputeBtnClick(Sender: TObject); procedure TCorSimFrm.ComputeBtnClick(Sender: TObject);
var var
outline : string; i: integer;
i : integer; msg: String;
C: TWinControl;
lReport: TStrings;
begin begin
N := StrToInt(NObs.Text); if not Validate(msg, C) then begin
xmean := StrToFloat(MeanX.Text); C.SetFocus;
ymean := StrToFloat(MeanY.Text); MessageDlg(msg, mtError, [mbOk], 0);
xsd := StrToFloat(SDX.Text); exit;
ysd := StrToFloat(SDY.Text); end;
corxy := StrToFloat(Corr.Text);
Randomize;
SetLength(freqx,N + 1); N := StrToInt(NObs.Text);
SetLength(freqy,N + 1); xmean := StrToFloat(MeanX.Text);
SetLength(x,N + 1); ymean := StrToFloat(MeanY.Text);
SetLength(y,N + 1); xsd := StrToFloat(SDX.Text);
ysd := StrToFloat(SDY.Text);
corxy := StrToFloat(Corr.Text);
// generate x and y data observations Randomize;
corsqr := corxy * corxy;
yvariance := ysd * ysd;
predvar := corsqr * yvariance;
errvariance := yvariance - predvar;
stderror := sqrt(errvariance);
b := corxy * (ysd / xsd);
constant := ymean - (b * xmean);
newxmean := 0.0; SetLength(freqx, N + 1);
newymean := 0.0; SetLength(freqy, N + 1);
newxsd := 0.0; SetLength(x, N + 1);
newysd := 0.0; SetLength(y, N + 1);
newcorr := 0.0;
// 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;
newxmean := 0.0;
newymean := 0.0;
newxsd := 0.0;
newysd := 0.0;
newcorr := 0.0;
for i := 1 to N 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 for i := 1 to N do
begin lReport.Add(' %4d %8.3f %8.3f', [i, x[i], y[i]]);
x[i] := RandG(xmean,xsd);
randomerror := RandG(0.0,stderror); DisplayReport(lReport);
y[i] := (b * x[i]) + constant + randomerror;
newxmean := newxmean + x[i]; Plot();
newymean := newymean + y[i];
newxsd := newxsd + (x[i] * x[i]); finally
newysd := newysd + (y[i] * y[i]); lReport.Free;
newcorr := newcorr + (x[i] * y[i]);
end;
newxsd := newxsd - ((newxmean * newxmean) / N);
newxsd := newxsd / (N - 1.0);
newxsd := sqrt(newxsd);
newysd := newysd - ((newymean * newymean) / N);
newysd := newysd / (N - 1.0);
newysd := sqrt(newysd);
newcorr := newcorr - ((newxmean * newymean) / N);
newcorr := newcorr / (N - 1.0);
newcorr := newcorr / (newxsd * newysd);
newxmean := newxmean / N;
newymean := newymean / N;
newb := newcorr * (newysd / newxsd);
newconstant := newymean - (newb * newxmean);
OutputFrm.RichEdit.Lines.Clear;
outline := 'POPULATION PARAMETERS FOR THE SIMULATION';
OutputFrm.RichEdit.Lines.Add(outline);
OutputFrm.RichEdit.Lines.Add('');
outline := format('Mean X := %8.3f, Std. Dev. X := %8.3f',[xmean, xsd]);
OutputFrm.RichEdit.Lines.Add(outline);
outline := format('Mean Y := %8.3f, Std. Dev. Y := %8.3f',[ymean, ysd]);
OutputFrm.RichEdit.Lines.Add(outline);
outline := format('Product-Moment Correlation := %8.3f',[corxy]);
OutputFrm.RichEdit.Lines.Add(outline);
outline := format('Regression line slope := %8.3f, constant := %8.3f',
[b, constant]);
OutputFrm.RichEdit.Lines.Add(outline);
OutputFrm.RichEdit.Lines.Add('');
OutputFrm.RichEdit.Lines.Add('');
outline := format('SAMPLE STATISTICS FOR %d OBSERVATIONS FROM THE POPULATION',[N]);
OutputFrm.RichEdit.Lines.Add(outline);
OutputFrm.RichEdit.Lines.Add('');
outline := format('Mean X := %8.3f, Std. Dev. X := %8.3f',[newxmean, newxsd]);
OutputFrm.RichEdit.Lines.Add(outline);
outline := format('Mean Y := %8.3f, Std. Dev. Y := %8.3f',[newymean, newysd]);
OutputFrm.RichEdit.Lines.Add(outline);
outline := format('Product-Moment Correlation := %8.3f',[newcorr]);
OutputFrm.RichEdit.Lines.Add(outline);
outline := format('Regression line slope := %8.3f, constant := %8.3f',
[newb, newconstant]);
OutputFrm.RichEdit.Lines.Add(outline);
OutputFrm.RichEdit.Lines.Add('');
OutputFrm.RichEdit.Lines.Add('Pair No. X Y');
for i := 1 to N do
begin
outline := format(' %3d %9.3f %9.3f',[i,x[i],y[i]]);
OutputFrm.RichEdit.Lines.Add(outline);
end;
OutputFrm.ShowModal;
plot(self);
freqx := nil; freqx := nil;
freqy := nil; freqy := nil;
x := nil; x := nil;
y := nil; y := nil;
ReturnBtn.SetFocus; end;
end; end;
procedure TCorSimFrm.FormShow(Sender: TObject); procedure TCorSimFrm.FormShow(Sender: TObject);
begin begin
Image1.Canvas.Pen.Color := clBlack; Image1.Canvas.Pen.Color := clBlack;
Image1.Canvas.Brush.Color := clWhite; Image1.Canvas.Brush.Color := clWhite;
Image1.Canvas.Rectangle(0, 0, Image1.Width, Image1.Height); Image1.Canvas.Rectangle(0, 0, Image1.Width, Image1.Height);
//Image1.Canvas.FloodFill(1,1,clWhite,fsborder);
MeanX.Text := '100'; MeanX.Text := '100';
MeanY.Text := '100'; MeanY.Text := '100';
SDX.Text := '15'; SDX.Text := '15';
SDY.Text := '15'; SDY.Text := '15';
Corr.Text := '.8'; Corr.Text := '.8';
Nobs.Text := '100'; Nobs.Text := '100';
end; end;
procedure TCorSimFrm.MeanYKeyPress(Sender: TObject; var Key: char); procedure TCorSimFrm.MeanYKeyPress(Sender: TObject; var Key: char);
begin begin
if Ord(Key) = 13 then SDX.SetFocus; if Key = #13 then SDX.SetFocus;
end; end;
procedure TCorSimFrm.NobsKeyPress(Sender: TObject; var Key: char); procedure TCorSimFrm.NobsKeyPress(Sender: TObject; var Key: char);
begin begin
if Ord(Key) = 13 then ComputeBtn.SetFocus; if Key = #13 then ComputeBtn.SetFocus;
end; end;
procedure TCorSimFrm.SDXKeyPress(Sender: TObject; var Key: char); procedure TCorSimFrm.SDXKeyPress(Sender: TObject; var Key: char);
begin begin
if Ord(Key) = 13 then SDY.SetFocus; if Key = #13 then SDY.SetFocus;
end; end;
procedure TCorSimFrm.SDYKeyPress(Sender: TObject; var Key: char); procedure TCorSimFrm.SDYKeyPress(Sender: TObject; var Key: char);
begin begin
if Ord(Key) = 13 then Corr.SetFocus; if Key = #13 then Corr.SetFocus;
end; end;
procedure TCorSimFrm.plot(Sender: TObject); procedure TCorSimFrm.Plot;
var var
minx, maxx, miny, maxy, xincrement, yincrement : double; minx, maxx, miny, maxy, xincrement, yincrement: double;
predy1, predy2, lowerx, upperx, frange, prop : double; predy1, predy2, lowerx, upperx, frange, prop: double;
charlabel : string; charlabel: string;
xpos, ypos, xpos1, ypos1, xpos2, ypos2 : integer; xpos, ypos, xpos1, ypos1, xpos2, ypos2: integer;
i, winwidth, winheight, xoffset, yoffset, xaxislong, yaxislong : integer; i, winwidth, winheight, xoffset, yoffset, xaxislong, yaxislong: integer;
j, xspacing, yspacing, labelwidth, minfreq, maxfreq : integer; j, xspacing, yspacing, labelwidth, minfreq, maxfreq: integer;
flength, theight, lowery, uppery : integer; flength, theight, lowery, uppery: integer;
begin begin
// get min and max of x and y points // get min and max of x and y points
minx := x[1]; minx := x[1];
maxx := minx; maxx := minx;
miny := y[1]; miny := y[1];
maxy := miny; maxy := miny;
for i := 1 to N do for i := 1 to N do
begin begin
if (minx > x[i]) then minx := x[i]; if (minx > x[i]) then minx := x[i];
if (maxx < x[i]) then maxx := x[i]; if (maxx < x[i]) then maxx := x[i];
if (miny > y[i]) then miny := y[i]; if (miny > y[i]) then miny := y[i];
if (maxy < y[i]) then maxy := y[i]; if (maxy < y[i]) then maxy := y[i];
end; end;
xincrement := (maxx - minx) / 10; xincrement := (maxx - minx) / 10;
yincrement := (maxy - miny) / 10; yincrement := (maxy - miny) / 10;
winwidth := Image1.Width; winwidth := Image1.Width;
winheight := Image1.Height; winheight := Image1.Height;
xoffset := winwidth div 5; xoffset := winwidth div 5;
yoffset := winheight div 5; yoffset := winheight div 5;
xaxislong := winwidth - xoffset- winwidth div 10; xaxislong := winwidth - xoffset- winwidth div 10;
yaxislong := winheight - yoffset - winheight div 10; yaxislong := winheight - yoffset - winheight div 10;
Image1.Canvas.Pen.Color := clBlack; xspacing := xaxislong div 10;
Image1.Canvas.MoveTo(xoffset,yaxislong); yspacing := yaxislong div 10;
Image1.Canvas.LineTo(winwidth,yaxislong);
Image1.Canvas.MoveTo(xoffset,yaxislong);
Image1.Canvas.LineTo(xoffset,0);
xspacing := xaxislong div 10;
yspacing := yaxislong div 10;
// do xaxis
for i := 0 to 11 do
begin
Image1.Canvas.MoveTo(xoffset + (i * xspacing),yaxislong);
Image1.Canvas.LineTo(xoffset + (i * xspacing),yaxislong + 10);
charlabel := format('%8.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;
// do yaxis
for i := 0 to 11 do
begin
Image1.Canvas.MoveTo(xoffset, yaxislong - (i * yspacing));
Image1.Canvas.LineTo(xoffset-10,yaxislong - (i * yspacing));
charlabel := format('%8.3f',[miny + (i * yincrement)]);
labelwidth := Image1.Canvas.TextWidth(charlabel);
xpos := xoffset-10-labelwidth;
ypos := yaxislong - (i * yspacing);
Image1.Canvas.TextOut(xpos,ypos,charlabel);
end;
// plot points
Image1.Canvas.Pen.Color := clRed;
for i := 1 to N 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);
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.MoveTo(xpos1,ypos1);
Image1.Canvas.LineTo(xpos2,ypos2);
// do x frequency distribution Image1.Canvas.Pen.Color := clBlack;
xincrement := (maxx-minx) / 50.0; Image1.Canvas.Line(xoffset, yaxislong, winwidth, yaxislong);
xspacing := xaxislong div 50; Image1.canvas.Line(xoffset, yaxislong, xoffset, 0);
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.MoveTo(xpos,ypos1);
Image1.Canvas.LineTo(xpos,ypos2);
end;
Image1.Canvas.MoveTo(xoffset,yaxislong+25);
Image1.Canvas.LineTo(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 := %6.3f',[newcorr]);
Image1.Canvas.TextOut(xpos,ypos,charlabel);
ypos := ypos + theight;
charlabel := format('Mean X := %8.3f, Mean Y := %8.3f',[newxmean, newymean]);
Image1.Canvas.TextOut(xpos,ypos,charlabel);
charlabel := format('SD X := %8.3f, SD Y := %8.3f',[newxsd, newysd]);
ypos := ypos + theight;
Image1.Canvas.TextOut(xpos,ypos,charlabel);
// do y frequency distribution // do xaxis
yincrement := (maxy-miny) / 50.0; for i := 0 to 11 do
yspacing := yaxislong div 50; begin
for j := 1 to 51 do freqy[j] := 0; Image1.Canvas.Line(xoffset + i * xspacing, yaxislong, xoffset + i * xspacing, yaxislong + 10);
for i := 1 to N do charlabel := Format('%.3f', [minx + i * xincrement]);
begin labelwidth := Image1.Canvas.TextWidth(charlabel);
for j := 1 to 51 do xpos := xoffset + i * xspacing - labelwidth div 2;
begin ypos := yaxislong + 12;
lowery := round(miny + (j * yincrement)); Image1.Canvas.TextOut(xpos, ypos, charlabel);
uppery := round(miny + ((j+1) * yincrement)); end;
if ((y[i] >= lowery) and (y[i] < uppery)) then freqy[j] := freqy[j] + 1;
end; // do yaxis
end; for i := 0 to 11 do
// plot the y frequencies begin
minfreq := N; Image1.Canvas.Line(xoffset, yaxislong - i * yspacing, xoffset-10, yaxislong - i * yspacing);
maxfreq := 0; 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;
// plot points
Image1.Canvas.Pen.Color := clRed;
for i := 1 to N 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);
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 for j := 1 to 51 do
begin begin
if (freqy[j] > maxfreq) then maxfreq := freqy[j]; lowerx := minx + j * xincrement;
if (freqy[j] < minfreq) then minfreq := freqy[j]; upperx := minx + (j+1) * xincrement;
if (x[i] >= lowerx) and (x[i] < upperx) then
freqx[j] := freqx[j] + 1;
end; end;
flength := winwidth - (xaxislong + 150); 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 for j := 1 to 51 do
begin begin
ypos := yaxislong - (j * yspacing); lowery := round(miny + j * yincrement);
frange := maxfreq - minfreq; uppery := round(miny + ((j+1) * yincrement));
prop := (freqy[j] - minfreq) / frange; if (y[i] >= lowery) and (y[i] < uppery) then
xpos1 := round(xoffset - 50 - (prop * flength)); freqy[j] := freqy[j] + 1;
xpos2 := xoffset - 50;
Image1.Canvas.MoveTo(xpos1,ypos);
Image1.Canvas.LineTo(xpos2,ypos);
end; end;
Image1.Canvas.MoveTo(xoffset - 50,yaxislong); end;
Image1.Canvas.LineTo(xoffset - 50,0);
Image1.Canvas.TextOut(0,0,'Y DISTRIBUTION'); // 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;
begin
Result := false;
if (MeanX.Text = '') or (MeanY.Text = '') or
(SDX.Text = '') or (SDY.Text = '') or
(Corr.Text = '') or (NObs.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;
AMsg := 'Input cannot be empty.';
exit;
end;
if not TryStrToFloat(MeanX.Text, xMean) then
begin
AControl := MeanX;
AMsg := 'Mean X must be a valid number.';
exit;
end;
if not TryStrToFloat(MeanY.Text, yMean) then
begin
AControl := MeanY;
AMsg := 'Mean Y must be a valid number.';
exit;
end;
if not TryStrToFloat(SDX.Text, xSD) or (xSD <= 0) then
begin
AControl := SDX;
AMsg := 'Std.Dev X must be a valid positive number.';
exit;
end;
if not TryStrToFloat(SDY.Text, ySD) or (ySD <= 0) then
begin
AControl := SDY;
AMsg := 'Std.Dev Y must be a valid positive number.';
exit;
end;
if not TryStrToFloat(Corr.Text, corXY) then
begin
AControl := Corr;
AMsg := 'Correlation XY must be a valid number.';
exit;
end;
if not TryStrToInt(NObs.Text, N) or (N <= 0) then
begin
AControl := NObs;
AMsg := 'Number of observations must be a valid positive integer.';
exit;
end;
Result := true;
end; end;
initialization initialization

View File

@ -78,7 +78,7 @@ procedure MReg(NoIndep : integer;
procedure MReg(NoIndep: integer; const IndepCols: IntDyneVec; DepCol: integer; procedure MReg(NoIndep: integer; const IndepCols: IntDyneVec; DepCol: integer;
const RowLabels: StrDyneVec; const RowLabels: StrDyneVec;
const Means, Variances, StdDevs, BWeights, BetaWeights, BStdErrs, Bttests, tProbs: DblDyneVec; const Means, Variances, StdDevs, BWeights, BetaWeights, BStdErrs, Bttests, tProbs: DblDyneVec;
out R2, StdErrEst: double; out NCases: integer; out ErrorCode: boolean; out R2, StdErrEst: double; NCases: integer; out ErrorCode: boolean;
PrintAll: boolean; AReport: TStrings); PrintAll: boolean; AReport: TStrings);
procedure Dynnonsymroots(var a : DblDyneMat; nv : integer; procedure Dynnonsymroots(var a : DblDyneMat; nv : integer;
@ -699,7 +699,7 @@ end;
procedure MReg(NoIndep: integer; const IndepCols: IntDyneVec; DepCol: integer; procedure MReg(NoIndep: integer; const IndepCols: IntDyneVec; DepCol: integer;
const RowLabels: StrDyneVec; const RowLabels: StrDyneVec;
const Means, Variances, StdDevs, BWeights, BetaWeights, BStdErrs, Bttests, tProbs: DblDyneVec; const Means, Variances, StdDevs, BWeights, BetaWeights, BStdErrs, Bttests, tProbs: DblDyneVec;
out R2, StdErrEst: double; out NCases: integer; out ErrorCode: boolean; out R2, StdErrEst: double; NCases: integer; out ErrorCode: boolean;
PrintAll: boolean; AReport: TStrings); PrintAll: boolean; AReport: TStrings);
var var
i, j, N: integer; i, j, N: integer;