LazStats: First refactoring of WLSUnit.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7773 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2020-10-12 16:17:29 +00:00
parent fb92b9fb1d
commit 8f0071b064
2 changed files with 183 additions and 400 deletions

View File

@ -205,11 +205,7 @@ begin
ser := FChartFrame.PlotXY(ptLines, XPoints, conf, nil, nil, 'Lower confidence band', clRed); ser := FChartFrame.PlotXY(ptLines, XPoints, conf, nil, nil, 'Lower confidence band', clRed);
rightLabels.Add(ser.yValue[ser.Count-1], ser.YValue[ser.Count-1], 'LCL'); rightLabels.Add(ser.yValue[ser.Count-1], ser.YValue[ser.Count-1], 'LCL');
end; end;
{
FChartFrame.Chart.Prepare;
FChartFrame.GetXRange(xmin, xmax, false);
FChartFrame.GetYRange(ymin, ymax, false);
}
// Draw means // Draw means
if MeansChk.Checked then if MeansChk.Checked then
with ARegressionResults do with ARegressionResults do

View File

@ -7,14 +7,14 @@ interface
uses uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
StdCtrls, Buttons, ExtCtrls, ComCtrls, StdCtrls, Buttons, ExtCtrls, ComCtrls,
Globals, MainUnit, DictionaryUnit, Matrixlib, Globals, MainUnit, DictionaryUnit, Matrixlib, DataProcs,
DataProcs, BlankFrmUnit, ReportFrameUnit, ChartFrameUnit, BasicStatsParamsFormUnit; //BasicStatsReportAndChartFormUnit; MathUnit, ReportFrameUnit, ChartFrameUnit, BasicStatsParamsFormUnit;
type type
{ TWLSFrm } { TWLSFrm }
TWLSFrm = class(TBasicStatsParamsForm) //TBasicStatsReportAndChartForm) TWLSFrm = class(TBasicStatsParamsForm)
DepInBtn: TBitBtn; DepInBtn: TBitBtn;
DepOutBtn: TBitBtn; DepOutBtn: TBitBtn;
IndInBtn: TBitBtn; IndInBtn: TBitBtn;
@ -50,7 +50,7 @@ type
procedure IndOutBtnClick(Sender: TObject); procedure IndOutBtnClick(Sender: TObject);
procedure IndVarListDblClick(Sender: TObject); procedure IndVarListDblClick(Sender: TObject);
procedure VarListDblClick(Sender: TObject); procedure VarListDblClick(Sender: TObject);
procedure VarListSelectionChange(Sender: TObject; User: boolean); procedure VarListSelectionChange(Sender: TObject; {%H-}User: boolean);
procedure WghtInBtnClick(Sender: TObject); procedure WghtInBtnClick(Sender: TObject);
procedure WghtOutBtnClick(Sender: TObject); procedure WghtOutBtnClick(Sender: TObject);
@ -64,18 +64,20 @@ type
function GetPageCaption(AVarName: String): String; function GetPageCaption(AVarName: String): String;
procedure PlotSquaredResiduals(AIndepCols: IntDyneVec;
ANumIndepCols, ADepCol: Integer; AConfLevel: Double);
procedure PlotXY(AChartFrame: TChartFrame; const XPoints, YPoints: DblDyneVec;
const ARegressionResults: TBivariateRegressionResults; const XLabel, YLabel: String);
procedure PredictIt(ColNoSelected: IntDyneVec; NoVars: integer; procedure PredictIt(ColNoSelected: IntDyneVec; NoVars: integer;
Means, StdDevs, BetaWeights: DblDyneVec; Means, StdDevs, BetaWeights: DblDyneVec;
StdErrEst: double; NoIndepVars: integer); StdErrEst: double; NoIndepVars: integer);
procedure PlotXY(AChartFrame: TChartFrame; const XPoints, YPoints, UpConf, LowConf: DblDyneVec; procedure WriteDescriptiveReport(AMemo: TMemo;
ConfBand, XMean, YMean, R, Slope, Intercept: Double; XLabel, YLabel: String); const ARegressionResults: TBivariateRegressionResults;
const XLabel, YLabel: String);
procedure PlotXY(Xpoints, Ypoints, UpConf, LowConf: DblDyneVec;
ConfBand, Xmean, Ymean, R, Slope, Intercept: double;
Xmax, Xmin, Ymax, Ymin: double;
N: integer; XLabel, YLabel: string);
protected protected
procedure AdjustConstraints; override; procedure AdjustConstraints; override;
procedure Compute; override; procedure Compute; override;
@ -97,15 +99,14 @@ implementation
{$R *.lfm} {$R *.lfm}
uses uses
TAChartUtils, TALegend, TAChartUtils, TAChartAxisUtils, TALegend, TASources, TACustomSeries,
Utils, GridProcs, MathUnit; Utils, GridProcs;
{ TWLSFrm } { TWLSFrm }
constructor TWLSFrm.Create(AOwner: TComponent); constructor TWLSFrm.Create(AOwner: TComponent);
begin begin
inherited; inherited;
if BlankFrm = nil then Application.CreateForm(TBlankFrm, BlankFrm);
if DictionaryFrm = nil then Application.CreateForm(TDictionaryFrm, DictionaryFrm); if DictionaryFrm = nil then Application.CreateForm(TDictionaryFrm, DictionaryFrm);
OLSReportFrame := TReportFrame.Create(self); OLSReportFrame := TReportFrame.Create(self);
@ -150,7 +151,7 @@ end;
procedure TWLSFrm.Compute; procedure TWLSFrm.Compute;
var var
i, ii, j, Noindep, DepCol, WghtCol, olddepcol, NCases, pos, col: integer; i, j, Noindep, DepCol, WghtCol, olddepcol, NCases, pos, col: integer;
IndepCols: IntDyneVec = nil; IndepCols: IntDyneVec = nil;
RowLabels: StrDyneVec = nil; RowLabels: StrDyneVec = nil;
X, Y: double; X, Y: double;
@ -163,24 +164,14 @@ var
BtTests: DblDyneVec = nil; BtTests: DblDyneVec = nil;
tProbs: DblDyneVec = nil; tProbs: DblDyneVec = nil;
PrintDesc: boolean = true; PrintDesc: boolean = true;
Xpoints: DblDyneVec = nil;
Ypoints: DblDyneVec = nil;
upConf: DblDyneVec = nil;
lowConf: DblDyneVec = nil;
Xmax, Xmin, Ymax, Ymin, Xmean, Ymean, Xvariance, Yvariance, R: double;
temp, SEPred, Slope, Intercept, DF, SSx, t, ConfBand, sedata: double;
Xstddev, Ystddev, predicted: double;
ColNoSelected: IntDyneVec = nil; ColNoSelected: IntDyneVec = nil;
XLabel, YLabel: string; predicted: Double;
N, Xcol, Ycol, NoSelected: integer;
lReport: TStrings; lReport: TStrings;
StdErrEst: Double = 0.0; StdErrEst: Double = 0.0;
R2: Double = 0.0; R2: Double = 0.0;
errorcode: Boolean = false; errorcode: Boolean = false;
C: TWinControl; C: TWinControl;
msg: String; msg: String;
chartFrame: TChartFrame;
memo: TMemo;
begin begin
if not Validate(msg, C) then if not Validate(msg, C) then
begin begin
@ -201,10 +192,6 @@ begin
SetLength(tprobs, NoVariables + 2); SetLength(tprobs, NoVariables + 2);
SetLength(RowLabels, NoVariables + 2); SetLength(RowLabels, NoVariables + 2);
SetLength(IndepCols, NoVariables + 2); SetLength(IndepCols, NoVariables + 2);
// SetLength(Xpoints, NoCases + 1);
// SetLength(Ypoints, NoCases + 1);
// SetLength(UpConf, NoCases + 1);
// SetLength(lowConf, NoCases + 1);
SetLength(ColNoSelected, 2); SetLength(ColNoSelected, 2);
lReport := TStringList.Create; lReport := TStringList.Create;
@ -298,11 +285,6 @@ begin
OLSReportFrame.DisplayReport(lReport); OLSReportFrame.DisplayReport(lReport);
lReport.Clear; lReport.Clear;
{
lReport.Add('');
lReport.Add(DIVIDER);
lReport.Add('');
}
end; end;
if RegResChk.Checked and OLSChk.Checked then if RegResChk.Checked and OLSChk.Checked then
@ -318,13 +300,6 @@ begin
ResidualsRegReportFrame.DisplayReport(lReport); ResidualsRegReportFrame.DisplayReport(lReport);
lReport.Clear; lReport.Clear;
{
lReport.Add(DIVIDER);
lReport.Add('');
}
// FReportFrame.DisplayReport(lReport);
// lReport.Clear;
end; end;
if WeightChk.Checked and RegResChk.Checked then if WeightChk.Checked and RegResChk.Checked then
@ -366,135 +341,9 @@ begin
end; // next i end; // next i
end; // if regresChk end; // if regresChk
// Now, plot squared residuals against each independent variable // Display squared residuals for each independent variable
if RegResChk.Checked then if RegResChk.Checked then
begin PlotSquaredResiduals(IndepCols, NoIndep, DepCol, 0.95);
xCol := DepCol;
for ii := 0 to NoIndep - 1 do
begin
SetLength(xPoints, NoCases);
SetLength(yPoints, NoCases);
yCol := IndepCols[ii];
N := 0;
ColNoSelected[0] := xCol;
ColNoSelected[1] := yCol;
NoSelected := 2;
XLabel := OS3MainFrm.DataGrid.Cells[Xcol,0];
YLabel := OS3MainFrm.DataGrid.Cells[Ycol,0];
Xmax := -1.0e308;
Xmin := 1.0e308;
Ymax := -1.0e308;
Ymin := 1.0e308;
Xmean := 0.0;
Ymean := 0.0;
Xvariance := 0.0;
Yvariance := 0.0;
R := 0.0;
for i := 1 to NoCases do
begin
if (not DataProcs.GoodRecord(i,NoSelected,ColNoSelected)) then continue;
X := StrToFloat(OS3MainFrm.DataGrid.Cells[Xcol,i]);
Y := StrToFloat(OS3MainFrm.DataGrid.Cells[Ycol,i]);
Xpoints[N] := X;
Ypoints[N] := Y;
if (X > Xmax) then Xmax := X;
if (X < Xmin) then Xmin := X;
if (Y > Ymax) then Ymax := Y;
if (Y < Ymin) then Ymin := Y;
Xmean := Xmean + X;
Ymean := Ymean + Y;
Xvariance := Xvariance + X * X;
Yvariance := Yvariance + Y * Y;
R := R + X * Y;
N := N + 1;
end;
SetLength(xPoints, N);
SetLength(yPoints, N);
// sort on X
SortOnX(xPoints, yPoints);
// calculate statistics
Xvariance := Xvariance - Xmean * Xmean / N;
SSx := Xvariance;
Xvariance := Xvariance / (N - 1);
Xstddev := sqrt(Xvariance);
Yvariance := Yvariance - Ymean * Ymean / N;
Yvariance := Yvariance / (N - 1);
Ystddev := sqrt(Yvariance);
R := R - Xmean * Ymean / N;
R := R / (N - 1);
R := R / (Xstddev * Ystddev);
SEPred := sqrt(1.0 - R * R) * Ystddev;
SEPred := SEPred * sqrt((N - 1) / (N - 2));
Xmean := Xmean / N;
Ymean := Ymean / N;
Slope := R * Ystddev / Xstddev;
Intercept := Ymean - Slope * Xmean;
// Now, print the descriptive statistics if requested
lReport.Clear;
lReport.Add('Data file: %s', [OS3MainFrm.FileNameEdit.Text]);
lReport.Add('');
lReport.Add('Variables:');
lReport.Add(' X: %s', [OS3MainFrm.DataGrid.Cells[xCol, 0]]);
lReport.Add(' Y: %s', [OS3MainFrm.DataGrid.Cells[yCol, 0]]);
lReport.Add('');
lReport.Add('Variable Mean Variance Std.Dev.');
lReport.Add('---------- -------- -------- --------');
lReport.Add('%-10s %8.2f %8.2f %8.2f', [OS3MainFrm.DataGrid.Cells[xCol, 0], XMean, XVariance, XStdDev]);
lReport.Add('%-10s %8.2f %8.2f %8.2f', [OS3MainFrm.DataGrid.Cells[ycol, 0], YMean, YVariance, YStdDev]);
lReport.Add('');
lReport.Add('Correlation: %8.4f', [R]);
lReport.Add('Slope: %8.2f', [Slope]);
lReport.Add('Intercept: %8.2f', [Intercept]);
lReport.Add('Standard Error of Estimate: %8.2f', [SEPred]);
lReport.Add('Number of good cases: %8d', [N]);
// Get upper and lower confidence points for each X value
SetLength(UpConf, N);
SetLength(LowConf, N);
ConfBand := 0.95;
DF := N - 2;
t := inverset(ConfBand,DF);
for i := 0 to N-1 do
begin
X := Xpoints[i];
predicted := Slope * X + Intercept;
sedata := SEPred * sqrt(1.0 + (1.0 / N) + ((X - Xmean) * (X - Xmean) / SSx));
UpConf[i] := predicted + (t * sedata);
lowConf[i] := predicted - (t * sedata);
if (UpConf[i] > Ymax) then Ymax := UpConf[i];
if (lowConf[i] < Ymin) then Ymin := lowConf[i];
end;
// Plot the values, line and confidence band
CreateOrGetChartFrame(yCol, yLabel, memo, chartFrame);
chartFrame.Clear;
PlotXY(chartFrame, XPoints, YPoints, upConf, lowConf, confBand, xMean, yMean, R, slope, intercept, xLabel, yLabel);
memo.Lines.Assign(lReport);
lReport.Clear;
{
if NormPltChk.Checked then
PlotNormalDist(chartFrame, normDistValue);
PlotFreq(chartFrame, col, cellVal, xLabels, freq);
}
if PlotChk.Checked then
begin
PlotXY(Xpoints, Ypoints, UpConf, lowConf, ConfBand, Xmean, Ymean, R,
Slope, Intercept, Xmax, Xmin, Ymax, Ymin, N, XLabel, YLabel);
BlankFrm.ShowModal;
end;
end;
// FReportFrame.DisplayReport(lReport);
end;
if not UserWghtsChk.Checked then if not UserWghtsChk.Checked then
begin begin
@ -516,7 +365,7 @@ begin
// get means of variables and subtract from the values // get means of variables and subtract from the values
if OriginChk.Checked then if OriginChk.Checked then
begin begin
for j := 0 to Noindep do for j := 0 to NoIndep do
begin begin
Means[j] := 0.0; Means[j] := 0.0;
NCases := 0; NCases := 0;
@ -647,6 +496,22 @@ begin
AChartFrame.Chart.Legend.TextFormat := tfHTML; AChartFrame.Chart.Legend.TextFormat := tfHTML;
AChartFrame.Chart.BottomAxis.Intervals.MaxLength := 80; AChartFrame.Chart.BottomAxis.Intervals.MaxLength := 80;
AChartFrame.Chart.BottomAxis.Intervals.MinLength := 30; AChartFrame.Chart.BottomAxis.Intervals.MinLength := 30;
with AChartFrame.Chart.AxisList.Add do
begin
Alignment := calRight;
Marks.Source := TListChartSource.Create(self);
Marks.Style := smsLabel;
Grid.Visible := false;
TickColor := clNone;
end;
with AChartFrame.Chart.AxisList.Add do
begin
Alignment := calTop;
Marks.Source := TListChartSource.Create(self);
Marks.Style := smsLabel;
Grid.Visible := false;
TickColor := clNone;
end;
// ... and add memo // ... and add memo
AMemo := TMemo.Create(tabSheet); AMemo := TMemo.Create(tabSheet);
@ -749,6 +614,116 @@ begin
end; end;
end; end;
procedure TWLSFrm.PlotSquaredResiduals(AIndepCols: IntDyneVec;
ANumIndepCols, ADepCol: Integer; AConfLevel: Double);
var
xCol, yCol: Integer;
xLabel, yLabel: String;
i: Integer;
colNoSelected: IntDyneVec = nil;
xPoints: DblDyneVec = nil;
yPoints: DblDyneVec = nil;
regressionRes: TBivariateRegressionResults;
memo: TMemo;
chartFrame: TChartFrame;
begin
SetLength(colNoSelected, 2);
xCol := ADepCol;
for i := 0 to ANumIndepCols-1 do
begin
// Get values
yCol := AIndepCols[i];
colNoSelected[0] := xCol;
colNoSelected[1] := yCol;
xLabel := OS3MainFrm.DataGrid.Cells[xCol, 0];
yLabel := OS3MainFrm.DataGrid.Cells[yCol, 0];
xPoints := CollectValues(OS3MainFrm.DataGrid, xCol, colNoSelected);
yPoints := CollectValues(OS3MainFrm.DataGrid, yCol, colNoSelected);
SortOnX(xPoints, yPoints);
// Regression
Calc_BivariateRegression(xPoints, yPoints, AConfLevel, regressionRes);
// Create tab with chart and report controls
CreateOrGetChartFrame(yCol, yLabel, memo, chartFrame);
// Plot
PlotXY(chartFrame, xPoints, yPoints, regressionRes, xLabel, yLabel);
// Print the descriptive statistics
WriteDescriptiveReport(memo, regressionRes, xLabel, yLabel);
end;
end;
procedure TWLSFrm.PlotXY(AChartFrame: TChartFrame; const XPoints, YPoints: DblDyneVec;
const ARegressionResults: TBivariateRegressionResults; const XLabel, YLabel: String);
var
xpts: DblDyneVec = nil;
ypts: DblDyneVec = nil;
conf: DblDyneVec = nil;
ext: TDoubleRect;
i: Integer;
rightLabels, topLabels: TListChartSource;
ser: TChartSeries;
begin
rightLabels := AChartFrame.Chart.AxisList[2].Marks.Source as TListChartSource;
rightLabels.Clear;
topLabels := AChartFrame.Chart.AxisList[3].Marks.Source as TListChartSource;
topLabels.Clear;
AChartFrame.Clear;
with ARegressionResults do
AChartFrame.SetFooter(Format('R(X,Y) = %.3f, Slope = %.3f, Intercept = %.3f', [
R, Slope, Intercept
]));
// Data points
AChartFrame.SetXTitle(XLabel);
AChartFrame.SetYTitle(YLabel);
AChartFrame.PlotXY(ptSymbols, XPoints, YPoints, nil, nil, 'Data', DATA_COLORS[0]);
// Regression line
SetLength(xpts, 2);
SetLengtH(ypts, 2);
ext := AChartFrame.Chart.GetFullExtent;
xpts[0] := ext.a.x;
xpts[1] := ext.b.x;
with ARegressionResults do
begin
ypts[0] := Intercept + Slope * xpts[0];
ypts[1] := Intercept + Slope * xpts[1];
end;
AChartFrame.PlotXY(ptLines, xpts, ypts, nil, nil, 'Predicted', clBlack);
rightLabels.Add(ypts[1], ypts[1], 'Predicted');
// Upper ...
SetLength(conf, ARegressionResults.Count);
for i := 0 to High(conf) do
conf[i] := ARegressionResults.ConfidenceLimits(XPoints[i], true);
ser := AChartFrame.PlotXY(ptLines, XPoints, conf, nil, nil, 'Upper confidence band', clRed);
rightLabels.Add(ser.yValue[ser.Count-1], ser.yValue[ser.Count-1], 'UCL');
// ... and lower confidence limit curves
for i := 0 to High(conf) do
conf[i] := ARegressionResults.ConfidenceLimits(XPoints[i], false);
ser := AChartFrame.PlotXY(ptLines, XPoints, conf, nil, nil, 'Lower confidence band', clRed);
rightLabels.Add(ser.yValue[ser.Count-1], ser.yValue[ser.Count-1], 'LCL');
// Mean lines
with ARegressionResults do
begin
AChartFrame.VertLine(XMean, clGreen, psDashDot, 'Mean ' + XLabel);
topLabels.Add(XMean, XMean, 'Mean ' + XLabel);
AChartFrame.HorLine(YMean, clGreen, psDash, 'Mean ' + YLabel);
rightLabels.Add(YMean, YMean, 'Mean ' + YLabel);
end;
end;
{ Routine obtains predicted raw and standardized scores and their { Routine obtains predicted raw and standardized scores and their
residuals. It is assumed that the dependent variable is last in the residuals. It is assumed that the dependent variable is last in the
list of variable column pointers stored in the ColNoSelected vector. list of variable column pointers stored in the ColNoSelected vector.
@ -837,230 +812,6 @@ begin
end; end;
procedure TWLSFrm.PlotXY(AChartFrame: TChartFrame;
const XPoints, YPoints, UpConf, LowConf: DblDyneVec;
ConfBand, XMean, YMean, R, Slope, Intercept: Double; XLabel, YLabel: String);
var
xpts: DblDyneVec = nil;
ypts: DblDyneVec = nil;
ext: TDoubleRect;
begin
AChartFrame.SetFooter(Format('R(X,Y) = %.3f, Slope = %.3f, Intercept = %.3f', [
R, Slope, Intercept
]));
// Data points
AChartFrame.SetXTitle(XLabel);
AChartFrame.SetYTitle(YLabel);
AChartFrame.PlotXY(ptSymbols, XPoints, YPoints, nil, nil, 'Data', DATA_COLORS[0]);
// Regression line
SetLength(xpts, 2);
SetLengtH(ypts, 2);
ext := AChartFrame.Chart.GetFullExtent;
xpts[0] := ext.a.x;
xpts[0] := ext.b.x;
ypts[0] := Intercept + Slope * xpts[0];
ypts[1] := Intercept + Slope * xpts[1];
AChartFrame.PlotXY(ptLines, xpts, ypts, nil, nil, 'Predicted', clBlack);
// Upper and lower confidence limit curves
AChartFrame.PlotXY(ptLines, XPoints, UpConf, nil, nil, 'UCL', clRed);
AChartFrame.PlotXY(ptLines, XPoints, LowConf, nil, nil, 'LCL', clRed);
// Mean lines
AChartFrame.VertLine(XMean, clGreen, psDashDot, 'Mean ' + XLabel);
// topLabels.Add(XMean, XMean, 'Mean ' + XLabel);
AChartFrame.HorLine(YMean, clGreen, psDash, 'Mean ' + YLabel);
// rightLabels.Add(YMean, YMean, 'Mean ' + YLabel);
end;
procedure TWLSFrm.PlotXY(Xpoints, Ypoints, UpConf, LowConf : DblDyneVec;
ConfBand, Xmean, Ymean, R, Slope, Intercept : double;
Xmax, Xmin, Ymax, Ymin : double;
N : integer; XLabel, YLabel : string);
VAR
i, xpos, ypos, hleft, hright, vtop, vbottom, imagewide : integer;
vhi, hwide, offset, strhi, imagehi : integer;
valincr, Yvalue, Xvalue, value : double;
Title, outline : string;
begin
BlankFrm.Image1.Canvas.Clear;
Title := 'X versus Y PLOT Using File: ' + OS3MainFrm.FileNameEdit.Text;
BlankFrm.Caption := Title;
imagewide := BlankFrm.Image1.Width;
imagehi := BlankFrm.Image1.Height;
BlankFrm.Image1.Canvas.Pen.Color := clBlack;
BlankFrm.Image1.Canvas.Brush.Color := clWhite;
BlankFrm.Image1.Canvas.Rectangle(0,0,imagewide,imagehi);
BlankFrm.Image1.Canvas.FloodFill(0,0,clWhite,fsBorder);
vtop := 20;
vbottom := round(imagehi) - 80;
vhi := vbottom - vtop;
hleft := 100;
hright := imagewide - 80;
hwide := hright - hleft;
BlankFrm.Image1.Canvas.Pen.Color := clBlack;
BlankFrm.Image1.Canvas.Brush.Color := clWhite;
// Draw chart border
BlankFrm.Image1.Canvas.Rectangle(0,0,imagewide,imagehi);
// draw Means
ypos := round(vhi * ( (Ymax - Ymean) / (Ymax - Ymin)));
ypos := ypos + vtop;
xpos := hleft;
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
xpos := hright;
BlankFrm.Image1.Canvas.Pen.Color := clGreen;
BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
Title := 'MEAN ';
Title := Title + YLabel;
strhi := BlankFrm.Image1.Canvas.TextHeight(Title);
ypos := ypos - strhi div 2;
BlankFrm.Image1.Canvas.Brush.Color := clWhite;
BlankFrm.Image1.Canvas.TextOut(xpos,ypos,Title);
xpos := round(hwide * ( (Xmean - Xmin) / (Xmax - Xmin)));
xpos := xpos + hleft;
ypos := vtop;
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
ypos := vbottom;
BlankFrm.Image1.Canvas.Pen.Color := clGreen;
BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
Title := 'MEAN ';
Title := Title + XLabel;
strhi := BlankFrm.Image1.Canvas.TextWidth(Title);
xpos := xpos - strhi div 2;
ypos := vtop - BlankFrm.Image1.Canvas.TextHeight(Title);
BlankFrm.Image1.Canvas.Brush.Color := clWhite;
BlankFrm.Image1.Canvas.TextOut(xpos,ypos,Title);
// draw slope line
BlankFrm.Image1.Canvas.Pen.Color := clBlack;
Yvalue := (Xpoints[1] * Slope) + Intercept; // predicted score
ypos := round(vhi * ( (Ymax - Yvalue) / (Ymax - Ymin)));
ypos := ypos + vtop;
xpos := round(hwide * ( (Xpoints[1]- Xmin) / (Xmax - Xmin)));
xpos := xpos + hleft;
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
Yvalue := (Xpoints[N] * Slope) + Intercept; // predicted score
ypos := round(vhi * ( (Ymax - Yvalue) / (Ymax - Ymin)));
ypos := ypos + vtop;
xpos := round(hwide * ( (Xpoints[N] - Xmin) / (Xmax - Xmin)));
xpos := xpos + hleft;
BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
// draw horizontal axis
BlankFrm.Image1.Canvas.Pen.Color := clBlack;
BlankFrm.Image1.Canvas.MoveTo(hleft,vbottom);
BlankFrm.Image1.Canvas.LineTo(hright,vbottom);
valincr := (Xmax - Xmin) / 10.0;
for i := 1 to 11 do
begin
ypos := vbottom;
Xvalue := Xmin + valincr * (i - 1);
xpos := round(hwide * ((Xvalue - Xmin) / (Xmax - Xmin)));
xpos := xpos + hleft;
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
ypos := ypos + 10;
BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
outline := format('%6.2f',[Xvalue]);
Title := outline;
offset := BlankFrm.Image1.Canvas.TextWidth(Title) div 2;
xpos := xpos - offset;
BlankFrm.Image1.Canvas.Pen.Color := clBlack;
BlankFrm.Image1.Canvas.TextOut(xpos,ypos,Title);
end;
xpos := hleft + (hwide div 2) - (BlankFrm.Image1.Canvas.TextWidth(XLabel) div 2);
ypos := vbottom + 20;
BlankFrm.Image1.Canvas.TextOut(xpos,ypos,XLabel);
outline := format('R(X,Y) := %5.3f, Slope := %6.2f, Intercept := %6.2f',
[R,Slope,Intercept]);
Title := outline;
xpos := hleft + (hwide div 2) - (BlankFrm.Image1.Canvas.TextWidth(Title) div 2);
ypos := ypos + 15;
BlankFrm.Image1.Canvas.TextOut(xpos,ypos,Title);
// Draw vertical axis
Title := YLabel;
// xpos := hleft - 10 - BlankFrm.Image1.Canvas.TextWidth(Title) / 2;
xpos := 10;
ypos := vtop - 8 - BlankFrm.Image1.Canvas.TextHeight(Title);
BlankFrm.Image1.Canvas.TextOut(xpos,ypos,YLabel);
xpos := hleft;
ypos := vtop;
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
ypos := vbottom;
BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
valincr := (Ymax - Ymin) / 10.0;
for i := 1 to 11 do
begin
value := Ymax - ((i-1) * valincr);
outline := format('%8.2f',[value]);
Title := outline;
strhi := BlankFrm.Image1.Canvas.TextHeight(Title);
xpos := 10;
Yvalue := Ymax - (valincr * (i-1));
ypos := round(vhi * ( (Ymax - Yvalue) / (Ymax - Ymin)));
ypos := ypos + vtop - strhi div 2;
BlankFrm.Image1.Canvas.TextOut(xpos,ypos,Title);
xpos := hleft;
ypos := ypos + strhi div 2;
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
xpos := hleft - 10;
BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
end;
// draw points for x and y pairs
for i := 0 to N-1 do
begin
ypos := round(vhi * ( (Ymax - Ypoints[i]) / (Ymax - Ymin)));
ypos := ypos + vtop;
xpos := round(hwide * ( (Xpoints[i] - Xmin) / (Xmax - Xmin)));
xpos := xpos + hleft;
BlankFrm.Image1.Canvas.Brush.Color := clNavy;
BlankFrm.Image1.Canvas.Brush.Style := bsSolid;
BlankFrm.Image1.Canvas.Pen.Color := clNavy;
BlankFrm.Image1.Canvas.Ellipse(xpos,ypos,xpos+5,ypos+5);
end;
// draw confidence bands if requested
if not (ConfBand = 0.0) then
begin
BlankFrm.Image1.Canvas.Pen.Color := clRed;
ypos := round(vhi * ((Ymax - UpConf[0]) / (Ymax - Ymin)));
ypos := ypos + vtop;
xpos := round(hwide * ( (Xpoints[0] - Xmin) / (Xmax - Xmin)));
xpos := xpos + hleft;
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
for i := 1 to N-1 do
begin
ypos := round(vhi * ((Ymax - UpConf[i]) / (Ymax - Ymin)));
ypos := ypos + vtop;
xpos := round(hwide * ( (Xpoints[i] - Xmin) / (Xmax - Xmin)));
xpos := xpos + hleft;
BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
end;
ypos := round(vhi * ((Ymax - LowConf[0]) / (Ymax - Ymin)));
ypos := ypos + vtop;
xpos := round(hwide * ( (Xpoints[0] - Xmin) / (Xmax - Xmin)));
xpos := xpos + hleft;
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
for i := 1 to N-1 do
begin
ypos := round(vhi * ((Ymax - LowConf[i]) / (Ymax - Ymin)));
ypos := ypos + vtop;
xpos := round(hwide * ( (Xpoints[i] - Xmin) / (Xmax - Xmin)));
xpos := xpos + hleft;
BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
end;
end;
end;
procedure TWLSFrm.Reset; procedure TWLSFrm.Reset;
var var
i: integer; i: integer;
@ -1191,5 +942,41 @@ begin
UpdateBtnStates; UpdateBtnStates;
end; end;
procedure TWLSFrm.WriteDescriptiveReport(AMemo: TMemo;
const ARegressionResults: TBivariateRegressionResults;
const XLabel, YLabel: String);
var
lReport: TStrings;
begin
lReport := TStringList.Create;
try
lReport.Add('Data file: %s', [OS3MainFrm.FileNameEdit.Text]);
lReport.Add('');
lReport.Add('Variables:');
lReport.Add(' X: %s', [xLabel]);
lReport.Add(' Y: %s', [yLabel]);
lReport.Add('');
lReport.Add('Variable Mean Variance Std.Dev.');
lReport.Add('---------- -------- -------- --------');
with ARegressionResults do
begin
lReport.Add('%-10s %8.2f %8.2f %8.2f', [xLabel, XMean, XVariance, XStdDev]);
lReport.Add('%-10s %8.2f %8.2f %8.2f', [yLabel, YMean, YVariance, YStdDev]);
lReport.Add('');
lReport.Add('Regression:');
lReport.Add(' Correlation: %8.3f', [R]);
lReport.Add(' Slope: %8.3f', [Slope]);
lReport.Add(' Intercept: %8.3f', [Intercept]);
lReport.Add(' Standard Error of Estimate: %8.3f', [StdErrorPredicted]);
lReport.Add(' Number of good cases: %8d', [Count]);
end;
AMemo.Lines.Assign(lReport);
finally
lReport.Free;
end;
end;
end. end.