LazStats: More refactoring of WLSUnit.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7776 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2020-10-12 21:53:18 +00:00
parent 27d63f9c58
commit 9013e01332
4 changed files with 237 additions and 150 deletions

View File

@ -142,44 +142,38 @@ inherited WLSFrm: TWLSFrm
ParentColor = False ParentColor = False
end end
object Label2: TLabel[7] object Label2: TLabel[7]
AnchorSideLeft.Control = DepInBtn AnchorSideLeft.Control = DepVarEdit
AnchorSideLeft.Side = asrBottom
AnchorSideBottom.Control = DepVarEdit AnchorSideBottom.Control = DepVarEdit
Left = 157 Left = 161
Height = 15 Height = 15
Top = 21 Top = 21
Width = 102 Width = 102
Anchors = [akLeft, akBottom] Anchors = [akLeft, akBottom]
BorderSpacing.Left = 4
BorderSpacing.Top = 8 BorderSpacing.Top = 8
BorderSpacing.Bottom = 2 BorderSpacing.Bottom = 2
Caption = 'Dependent Variable' Caption = 'Dependent Variable'
ParentColor = False ParentColor = False
end end
object Label3: TLabel[8] object Label3: TLabel[8]
AnchorSideLeft.Control = IndInBtn AnchorSideLeft.Control = IndVarList
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = IndInBtn AnchorSideTop.Control = IndInBtn
Left = 157 Left = 161
Height = 15 Height = 15
Top = 105 Top = 105
Width = 116 Width = 116
BorderSpacing.Left = 4
Caption = 'Independent Variables' Caption = 'Independent Variables'
ParentColor = False ParentColor = False
end end
object Label4: TLabel[9] object Label4: TLabel[9]
AnchorSideLeft.Control = WeightInBtn AnchorSideLeft.Control = WeightVarEdit
AnchorSideLeft.Side = asrBottom
AnchorSideBottom.Control = WeightVarEdit AnchorSideBottom.Control = WeightVarEdit
Left = 157 Left = 161
Height = 15 Height = 15
Top = 205 Top = 205
Width = 134 Width = 77
Anchors = [akLeft, akBottom] Anchors = [akLeft, akBottom]
BorderSpacing.Left = 4
BorderSpacing.Bottom = 2 BorderSpacing.Bottom = 2
Caption = 'User''s Weights (Optional)' Caption = 'User''s Weights'
Enabled = False Enabled = False
ParentColor = False ParentColor = False
end end
@ -192,10 +186,10 @@ inherited WLSFrm: TWLSFrm
Left = 0 Left = 0
Height = 240 Height = 240
Top = 17 Top = 17
Width = 123 Width = 119
Anchors = [akTop, akLeft, akRight, akBottom] Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Top = 2 BorderSpacing.Top = 2
BorderSpacing.Right = 4 BorderSpacing.Right = 8
BorderSpacing.Bottom = 8 BorderSpacing.Bottom = 8
Constraints.MinHeight = 220 Constraints.MinHeight = 220
ItemHeight = 0 ItemHeight = 0
@ -306,12 +300,12 @@ inherited WLSFrm: TWLSFrm
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = DepOutBtn AnchorSideBottom.Control = DepOutBtn
AnchorSideBottom.Side = asrBottom AnchorSideBottom.Side = asrBottom
Left = 157 Left = 161
Height = 23 Height = 23
Top = 38 Top = 38
Width = 123 Width = 119
Anchors = [akLeft, akRight, akBottom] Anchors = [akLeft, akRight, akBottom]
BorderSpacing.Left = 4 BorderSpacing.Left = 8
BorderSpacing.Bottom = 12 BorderSpacing.Bottom = 12
ReadOnly = True ReadOnly = True
TabOrder = 3 TabOrder = 3
@ -325,12 +319,12 @@ inherited WLSFrm: TWLSFrm
AnchorSideRight.Control = ParamsPanel AnchorSideRight.Control = ParamsPanel
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = WeightInBtn AnchorSideBottom.Control = WeightInBtn
Left = 157 Left = 161
Height = 63 Height = 63
Top = 122 Top = 122
Width = 123 Width = 119
Anchors = [akTop, akLeft, akRight, akBottom] Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Left = 4 BorderSpacing.Left = 8
BorderSpacing.Top = 2 BorderSpacing.Top = 2
BorderSpacing.Bottom = 16 BorderSpacing.Bottom = 16
ItemHeight = 0 ItemHeight = 0
@ -346,12 +340,12 @@ inherited WLSFrm: TWLSFrm
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = WeightOutBtn AnchorSideBottom.Control = WeightOutBtn
AnchorSideBottom.Side = asrBottom AnchorSideBottom.Side = asrBottom
Left = 157 Left = 161
Height = 23 Height = 23
Top = 222 Top = 222
Width = 123 Width = 119
Anchors = [akLeft, akRight, akBottom] Anchors = [akLeft, akRight, akBottom]
BorderSpacing.Left = 4 BorderSpacing.Left = 8
BorderSpacing.Bottom = 12 BorderSpacing.Bottom = 12
Enabled = False Enabled = False
ReadOnly = True ReadOnly = True

View File

@ -58,6 +58,9 @@ type
ResidualsRegReportFrame: TReportFrame; ResidualsRegReportFrame: TReportFrame;
WLSReportFrame: TReportFrame; WLSReportFrame: TReportFrame;
procedure AddPredictedStuffToGrid(AIndepCols: IntDyneVec; ANumIndepCols: Integer;
BWeights: DblDyneVec);
procedure CreateOrGetChartFrame(AColIndex: Integer; AVarName: String; procedure CreateOrGetChartFrame(AColIndex: Integer; AVarName: String;
out AMemo: TMemo; out AChartFrame: TChartFrame); out AMemo: TMemo; out AChartFrame: TChartFrame);
@ -77,6 +80,13 @@ type
out AIndepCols: IntDyneVec; out AWeightCol: Integer; out AIndepCols: IntDyneVec; out AWeightCol: Integer;
out ARowLabels: StrDyneVec): Boolean; out ARowLabels: StrDyneVec): Boolean;
function Process_OLSRegression(AIndepCols: IntDyneVec; ANumIndepCols, ADepCol: Integer;
ARowLabels: StrDyneVec; ANumCases: Integer; PrintAll: Boolean): Boolean;
function Process_SquaredResidualsRegression(AIndepCols: IntDyneVec;
ANumIndepCols, ADepCol: Integer; ARowLabels: StrDyneVec;
BWeights: DblDyneVec; ANumCases: Integer; PrintAll: Boolean): Boolean;
procedure WriteDescriptiveReport(AMemo: TMemo; procedure WriteDescriptiveReport(AMemo: TMemo;
const ARegressionResults: TBivariateRegressionResults; const ARegressionResults: TBivariateRegressionResults;
const XLabel, YLabel: String); const XLabel, YLabel: String);
@ -145,6 +155,50 @@ begin
end; end;
{ Get predicted squared residuals and save recipricols to grid as weights }
procedure TWLSFrm.AddPredictedStuffToGrid(AIndepCols: IntDyneVec;
ANumIndepCols: Integer; BWeights: DblDyneVec);
var
col: Integer;
i, j: Integer;
X, predicted: Double;
begin
col := NoVariables + 1;
OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables);
DictionaryFrm.NewVar(col);
DictionaryFrm.DictGrid.Cells[1, col] := 'PredResid2';
OS3MainFrm.DataGrid.Cells[col, 0] := 'PredResid2';
col := NoVariables + 1;
OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables);
DictionaryFrm.NewVar(col);
DictionaryFrm.DictGrid.Cells[1, col] := 'WEIGHT';
OS3MainFrm.DataGrid.Cells[col, 0] := 'WEIGHT';
OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables);
for i := 1 to NoCases do
begin
if (DataProcs.ValidValue(i, col-2)) then // do we have a valid squared OLS residual?
begin
predicted := 0.0;
for j := 0 to ANumIndepCols - 1 do
begin
X := StrToFloat(OS3MainFrm.DataGrid.Cells[AIndepCols[j], i]);
predicted := predicted + BWeights[j] * X;
end;
predicted := predicted + BWeights[ANumIndepCols];
predicted := abs(predicted);
OS3MainFrm.DataGrid.Cells[col-1, i] := Format('%.3f', [predicted]);
if (predicted > 0.0) then
predicted := 1.0 / sqrt(predicted)
else
predicted := 0.0;
OS3MainFrm.DataGrid.Cells[col, i] := Format('%.3f', [predicted]);
end;
end;
end;
procedure TWLSFrm.AdjustConstraints; procedure TWLSFrm.AdjustConstraints;
begin begin
ParamsPanel.Constraints.MinHeight := DepInBtn.Top + (IndOutBtn.Top - DepInBtn.Top)*2 + DepInBtn.Top + ParamsPanel.Constraints.MinHeight := DepInBtn.Top + (IndOutBtn.Top - DepInBtn.Top)*2 + DepInBtn.Top +
@ -158,7 +212,7 @@ end;
procedure TWLSFrm.Compute; procedure TWLSFrm.Compute;
var var
i, j, Noindep, DepCol, WghtCol, olddepcol, NCases, pos, col: integer; i, j, noIndep, depCol, weightCol, oldDepCol, NCases, pos, col: integer;
IndepCols: IntDyneVec = nil; IndepCols: IntDyneVec = nil;
RowLabels: StrDyneVec = nil; RowLabels: StrDyneVec = nil;
X, Y: double; X, Y: double;
@ -170,136 +224,49 @@ var
BStdErrs: DblDyneVec = nil; BStdErrs: DblDyneVec = nil;
BtTests: DblDyneVec = nil; BtTests: DblDyneVec = nil;
tProbs: DblDyneVec = nil; tProbs: DblDyneVec = nil;
PrintDesc: boolean = true;
predicted: Double; predicted: Double;
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;
PrintDesc: boolean = true;
begin begin
PrintDesc := true;
SetLength(Means, NoVariables + 2); SetLength(Means, NoVariables + 2);
SetLength(Variances, NoVariables + 2); SetLength(Variances, NoVariables + 2);
SetLength(StdDevs, NoVariables + 2); SetLength(StdDevs, NoVariables + 2);
SetLength(BWeights, NoVariables + 2); SetLength(BWeights, NoVariables + 2); // do not remove!
SetLength(BetaWeights, NoVariables + 2); SetLength(BetaWeights, NoVariables + 2);
SetLength(BStdErrs, NoVariables + 2); SetLength(BStdErrs, NoVariables + 2);
SetLength(Bttests, NoVariables + 2); SetLength(Bttests, NoVariables + 2);
SetLength(tprobs, NoVariables + 2); SetLength(tprobs, NoVariables + 2);
// SetLength(RowLabels, NoVariables + 2);
// SetLength(IndepCols, NoVariables + 2);
// SetLength(ColNoSelected, 2);
lReport := TStringList.Create; lReport := TStringList.Create;
try try
NCases := NoCases; NCases := NoCases;
// NoIndep := IndVarList.Items.Count;
if not PrepareData(depCol, NoIndep, indepCols, wghtCol, RowLabels) then // Get column indexes and do some validation checks.
// NOTE that the Length(indepCols) is different from NoIndep.
if not PrepareData(depCol, noIndep, indepCols, weightCol, RowLabels) then
exit; exit;
{ wp: I think this is not correct: The column index is the last one in this // Save dependent column so we can re-use DepCol
call. And why is row 0 checked? oldDepCol := depCol;
// check variable types
if not ValidValue(OS3MainFrm.DataGrid, DepCol, 0) then
begin
ErrorMsg('Incorrect dependent variable type.');
exit;
end;
if (WghtCol > -1) then
begin
if not ValidValue(OS3MainFrm.DataGrid, WghtCol, 0) then
begin
ErrorMsg('Incorrect weight variable type.');
exit;
end;
end;
for j := 0 to Noindep - 1 do
begin
if not ValidValue(OS3MainFrm.DataGrid, IndepCols[j],0) then
begin
ErrorMsg('Incorrect dependent variable type.');
exit;
end;
end;
}
IndepCols[NoIndep] := depCol;
oldDepCol := DepCol; // save dependent column so we can reuse DepCol
// *** Get OLS regression *** // *** Get OLS regression ***
lReport.Clear; Process_OLSRegression(indepCols, noIndep, depCol, RowLabels, nCases, printDesc);
lReport.Add('ORDINARY LEAST SQUARES (OLS) REGRESSION RESULTS');
lReport.Add('');
MReg(Noindep, IndepCols, DepCol, RowLabels, Means, Variances, StdDevs,
BWeights, BetaWeights, BStdErrs, Bttests, tprobs, R2, stderrest,
NCases, errorcode, PrintDesc, lReport);
// Get predicted z score, residual z score, predicted raw score,
// residual raw score and squared raw residual score. Place in the DataGrid
PredictIt(IndepCols, Noindep+1, Means, StdDevs, BetaWeights, stderrest, NoIndep);
OLSReportFrame.DisplayReport(lReport);
lReport.Clear;
// *** Regress the squared residuals on the predictors *** // *** Regress the squared residuals on the predictors ***
depCol := NoVariables; depCol := NoVariables;
lReport.Clear; Process_SquaredResidualsRegression(indepCols, noIndep, depCol, RowLabels,
lReport.Add('REGRESSION OF SQUARED RESIDUALS ON INDEPENDENT VARIABLES'); BWeights, nCases, printDesc);
lReport.Add('');
MReg(Noindep, IndepCols, DepCol, RowLabels, Means, Variances, StdDevs,
BWeights, BetaWeights, BStdErrs, Bttests, tprobs, R2, stderrest,
NCases, errorcode, PrintDesc, lReport);
ResidualsRegReportFrame.DisplayReport(lReport);
lReport.Clear;
if WeightChk.Checked then if WeightChk.Checked then
begin AddPredictedStuffToGrid(indepCols, noIndep, BWeights);
// Get predicted squared residuals and save recipricols as weights
col := NoVariables + 1;
OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables);
DictionaryFrm.NewVar(col);
DictionaryFrm.DictGrid.Cells[1,col] := 'PredResid2';
OS3MainFrm.DataGrid.Cells[col,0] := 'PredResid2';
col := NoVariables + 1;
OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables);
DictionaryFrm.NewVar(col);
DictionaryFrm.DictGrid.Cells[1,col] := 'WEIGHT';
OS3MainFrm.DataGrid.Cells[col,0] := 'WEIGHT';
OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables);
for i := 1 to NoCases do
begin
if (DataProcs.ValidValue(i, col-2)) then // do we have a valid squared OLS residual?
begin
predicted := 0.0;
for j := 0 to NoIndep - 1 do
begin
pos := IndepCols[j];
X := StrToFloat(OS3MainFrm.DataGrid.Cells[pos,i]);
predicted := predicted + BWeights[j] * X;
end;
predicted := predicted + BWeights[Noindep];
predicted := abs(predicted);
OS3MainFrm.DataGrid.Cells[col-1,i] := Format('%.3f', [predicted]);
if (predicted > 0.0) then
predicted := 1.0 / sqrt(predicted)
else
predicted := 0.0;
OS3MainFrm.DataGrid.Cells[col,i] := Format('%.3f', [predicted]);
end; // if valid case
end; // next i
end; // if regresChk
// *** Display squared residuals for each independent variable *** // *** Display squared residuals for each independent variable ***
PlotSquaredResiduals(IndepCols, NoIndep, DepCol, 0.95); // NOTE: depCol points to the squared residuals column here
PlotSquaredResiduals(IndepCols, NoIndep, depCol, 0.95);
if not UserWeightsChk.Checked then if WeightChk.Checked then
begin begin
// Weight variables and do OLS regression on weighted variables // Weight variables and do OLS regression on weighted variables
DepCol := olddepcol; DepCol := olddepcol;
@ -312,7 +279,7 @@ begin
pos := IndepCols[j]; pos := IndepCols[j];
X := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[pos,i])); X := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[pos,i]));
X := X * Y; X := X * Y;
OS3MainFrm.DataGrid.Cells[pos,i] := FloatToStr(X); OS3MainFrm.DataGrid.Cells[pos,i] := FloatToStr(X); // wp: DON'T OVERWRITE GRID CELLS
end; end;
end; end;
@ -339,7 +306,7 @@ begin
begin begin
X := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[pos,i])); X := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[pos,i]));
X := X - Means[j]; X := X - Means[j];
OS3MainFrm.DataGrid.Cells[pos,i] := FloatToStr(X); OS3MainFrm.DataGrid.Cells[pos,i] := FloatToStr(X); // wp: DON'T OVERWRITE GRID DATA!
end; end;
end; // next i end; // next i
end; // next j end; // next j
@ -349,25 +316,25 @@ begin
lReport.Add('WEIGHTED LEAST SQUARES (WLS) REGRESSION RESULTS'); lReport.Add('WEIGHTED LEAST SQUARES (WLS) REGRESSION RESULTS');
lReport.Add(''); lReport.Add('');
MReg(Noindep, IndepCols, DepCol, RowLabels, Means, Variances, StdDevs, MReg(Noindep, IndepCols, DepCol, RowLabels, Means, Variances, StdDevs,
BWeights, BetaWeights, BStdErrs, Bttests, tprobs, R2, stderrest, BWeights, BetaWeights, BStdErrs, Bttests, tprobs, R2, stdErrEst,
NCases, errorcode, PrintDesc, lReport); NCases, errorcode, PrintDesc, lReport);
WLSReportFrame.DisplayReport(lReport); WLSReportFrame.DisplayReport(lReport);
lReport.Clear; lReport.Clear;
end // if useweightschk checked end; // if weightschk checked
else
// use the weights entered by the user // use the weights entered by the user
if (UserWeightsChk.Checked) then if UserWeightsChk.Checked then
begin begin
// Weight variables and do OLS regression on weighted variables // Weight variables and do OLS regression on weighted variables
DepCol := olddepcol; depCol := olddepcol;
IndepCols[Noindep] := DepCol; indepCols[Noindep] := depCol; // wp: CALCULATION SHOULD NORMALIZE USER WEIGHTS HERE !!!
for i := 1 to NoCases do for i := 1 to NoCases do
begin begin
Y := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[WghtCol,i])); // weight Y := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[weightCol,i])); // weight
for j := 0 to Noindep do for j := 0 to Noindep do
begin begin
pos := IndepCols[j]; pos := indepCols[j];
X := StrToFloat(OS3MainFrm.DataGrid.Cells[pos,i]); X := StrToFloat(OS3MainFrm.DataGrid.Cells[pos,i]);
X := X * Y; X := X * Y;
OS3MainFrm.DataGrid.Cells[pos,i] := FloatToStr(X); OS3MainFrm.DataGrid.Cells[pos,i] := FloatToStr(X);
@ -395,7 +362,7 @@ begin
begin begin
X := StrToFloat(OS3MainFrm.DataGrid.Cells[pos,i]); X := StrToFloat(OS3MainFrm.DataGrid.Cells[pos,i]);
X := X - Means[j]; X := X - Means[j];
OS3MainFrm.DataGrid.Cells[pos,i] := FloatToStr(X); OS3MainFrm.DataGrid.Cells[pos,i] := FloatToStr(X); // wp: DON'T OVERWRITE GRID DATA!
end; end;
end; // next i end; // next i
end; // next j end; // next j
@ -405,7 +372,7 @@ begin
lReport.Add('WEIGHTED LEAST SQUARES (WLS) REGRESSION RESULTS'); lReport.Add('WEIGHTED LEAST SQUARES (WLS) REGRESSION RESULTS');
lReport.Add(''); lReport.Add('');
MReg(Noindep, IndepCols, DepCol, RowLabels, Means, Variances, StdDevs, MReg(Noindep, IndepCols, DepCol, RowLabels, Means, Variances, StdDevs,
BWeights, BetaWeights, BStdErrs, Bttests, tprobs, R2, stderrest, BWeights, BetaWeights, BStdErrs, Bttests, tprobs, R2, stdErrEst,
NCases, errorcode, PrintDesc, lReport); NCases, errorcode, PrintDesc, lReport);
WLSReportFrame.DisplayReport(lReport); WLSReportFrame.DisplayReport(lReport);
@ -689,7 +656,6 @@ var
predicted, zpredicted, z1, z2, resid, residsqr: double; predicted, zpredicted, z1, z2, resid, residsqr: double;
begin begin
col := NoVariables + 1; col := NoVariables + 1;
// NoVariables := col;
OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables); OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables);
DictionaryFrm.DictGrid.ColCount := 8; DictionaryFrm.DictGrid.ColCount := 8;
DictionaryFrm.NewVar(col); DictionaryFrm.NewVar(col);
@ -697,7 +663,6 @@ begin
DictionaryFrm.DictGrid.Cells[1,col] := 'Pred.z'; DictionaryFrm.DictGrid.Cells[1,col] := 'Pred.z';
col := NoVariables + 1; col := NoVariables + 1;
// NoVariables := col;
DictionaryFrm.NewVar(col); DictionaryFrm.NewVar(col);
OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables); OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables);
OS3MainFrm.DataGrid.Cells[col,0] := 'z Resid.'; OS3MainFrm.DataGrid.Cells[col,0] := 'z Resid.';
@ -761,7 +726,7 @@ begin
begin begin
residsqr := StrToFloat(OS3MainFrm.DataGrid.Cells[col-1,i]); residsqr := StrToFloat(OS3MainFrm.DataGrid.Cells[col-1,i]);
residsqr := residsqr * residsqr; residsqr := residsqr * residsqr;
OS3MainFrm.DataGrid.Cells[col,i] := Format('%8.3f',[residsqr]); OS3MainFrm.DataGrid.Cells[col,i] := Format('%.3f',[residsqr]);
end; end;
end; end;
@ -807,10 +772,124 @@ begin
ARowLabels[i] := IndVarList.Items[i]; ARowLabels[i] := IndVarList.Items[i];
end; end;
// Append dependent column index to the independent columns vector.
AIndepCols[ANumIndepCols] := ADepCol;
// Check variable types: all of them must be numeric (float or integer)
if not IsNumericCol(ADepCol) then
begin
ErrorMsg('Incorrect data type of dependent variable.');
exit;
end;
for i := 0 to ANumIndepCols-1 do
if not IsNumericCol(AIndepCols[i]) then
begin
ErrorMsg('Incorrect data type of independent variable "%s"', [ARowLabels[i]]);
exit;
end;
if (AWeightCol > -1) and (not IsNumericCol(AWeightCol)) then
begin
ErrorMsg('Incorrect data type of weight variable.');
exit;
end;
Result := true; Result := true;
end; end;
{ Runs the ordinary least squares regression on the grid data }
function TWLSFrm.Process_OLSRegression(AIndepCols: IntDyneVec; ANumIndepCols, ADepCol: Integer;
ARowLabels: StrDyneVec; ANumCases: Integer; PrintAll: Boolean): Boolean;
var
lReport: TStrings;
means: DblDyneVec = nil;
variances: DblDyneVec = nil;
stdDevs: DblDyneVec = nil;
BWeights: DblDyneVec = nil;
BetaWeights: DblDyneVec = nil;
BStdErrs: DblDyneVec = nil;
BtTests: DblDyneVec = nil;
tProbs: DblDyneVec = nil;
R2, stdErrEst: Double;
error: Boolean;
begin
Result := false;
lReport := TStringList.Create;
try
lReport.Add('ORDINARY LEAST SQUARES (OLS) REGRESSION RESULTS');
lReport.Add('');
SetLength(means, NoVariables + 2);
SetLength(variances, NoVariables + 2);
SetLength(stdDevs, NoVariables + 2);
SetLength(BWeights, NoVariables + 2);
SetLength(BetaWeights, NoVariables + 2);
SetLength(BStdErrs, NoVariables + 2);
SetLength(Bttests, NoVariables + 2);
SetLength(tprobs, NoVariables + 2);
MReg(ANumIndepCols, AIndepCols, ADepCol, ARowLabels, Means, Variances, StdDevs,
BWeights, BetaWeights, BStdErrs, Bttests, tprobs, R2, stdErrEst,
ANumCases, error, PrintAll, lReport);
// if error then // wp: Why does MReg exit with error???
// exit;
// Get predicted z score, residual z score, predicted raw score,
// residual raw score and squared raw residual score. Place in the DataGrid
PredictIt(AIndepCols, ANumIndepCols+1, means, stdDevs, BetaWeights, stdErrEst, ANumIndepCols);
OLSReportFrame.DisplayReport(lReport);
Result := true;
finally
lReport.Free;
end;
end;
function TWLSFrm.Process_SquaredResidualsRegression(AIndepCols: IntDyneVec;
ANumIndepCols, ADepCol: Integer; ARowLabels: StrDyneVec; BWeights: DblDyneVec;
ANumCases: Integer; PrintAll: Boolean): Boolean;
var
lReport: TStrings;
means: DblDyneVec = nil;
variances: DblDyneVec = nil;
stdDevs: DblDyneVec = nil;
BetaWeights: DblDyneVec = nil;
BStdErrs: DblDyneVec = nil;
BtTests: DblDyneVec = nil;
tProbs: DblDyneVec = nil;
R2, stdErrEst: Double;
error: Boolean;
begin
lReport := TStringList.Create;
try
lReport.Add('REGRESSION OF SQUARED RESIDUALS ON INDEPENDENT VARIABLES');
lReport.Add('');
SetLength(means, NoVariables + 2);
SetLength(variances, NoVariables + 2);
SetLength(stdDevs, NoVariables + 2);
SetLength(BetaWeights, NoVariables + 2);
SetLength(BStdErrs, NoVariables + 2);
SetLength(Bttests, NoVariables + 2);
SetLength(tprobs, NoVariables + 2);
MReg(ANumIndepCols, AIndepCols, ADepCol, ARowLabels, Means, Variances, StdDevs,
BWeights, BetaWeights, BStdErrs, Bttests, tprobs, R2, stdErrEst,
ANumCases, error, PrintAll, lReport);
ResidualsRegReportFrame.DisplayReport(lReport);
finally
lReport.Free;
end;
end;
procedure TWLSFrm.Reset; procedure TWLSFrm.Reset;
var var
i: integer; i: integer;

View File

@ -25,6 +25,8 @@ function IsFiltered(AGrid: TStringGrid; ARow: integer): boolean;
function IsMissingValueCode(AGrid: TStringGrid; ARow, ACol: Integer): Boolean; function IsMissingValueCode(AGrid: TStringGrid; ARow, ACol: Integer): Boolean;
function IsNumericCol(AColIndex: Integer): Boolean;
function ValidValue(AGrid: TStringGrid; ARow, ACol: integer): boolean; function ValidValue(AGrid: TStringGrid; ARow, ACol: integer): boolean;
@ -155,6 +157,17 @@ begin
end; end;
{ Checks in the dictionary whether the variable in the specified grid column has
either data type float or integer. }
function IsNumericCol(AColIndex: Integer): Boolean;
var
typeCode: String;
begin
typeCode := Trim(DictionaryFrm.DictGrid.Cells[4, AColIndex]);
Result := (typeCode = 'F') or (typeCode = 'I');
end;
{ Checks wheter the value in cell at the given column and row is a not-filtered, { Checks wheter the value in cell at the given column and row is a not-filtered,
non-empty number. non-empty number.
NOTE: non-numeric characters in a numeric field are not taken into account! } NOTE: non-numeric characters in a numeric field are not taken into account! }

View File

@ -53,7 +53,7 @@ procedure EffectCode(GridCol, min, max : 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;
@ -347,16 +347,14 @@ begin
end; end;
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Product of matrix b times c with results returned in a // Product of matrix B times C with results returned in a: A = B C
procedure MatAxB(const A, B, C: DblDyneMat; BRows, BCols, CRows, CCols: Integer; procedure MatAxB(const A, B, C: DblDyneMat; BRows, BCols, CRows, CCols: Integer;
out ErrorCode: boolean); out ErrorCode: boolean);
var var
i, j, k: integer; i, j, k: integer;
begin begin
ErrorCode := false; ErrorCode := BCols <> CRows;
if (BCols <> CRows) then if not ErrorCode then
ErrorCode := true
else
begin begin
for i := 0 to BRows-1 do for i := 0 to BRows-1 do
begin begin
@ -633,7 +631,7 @@ end;
Variances ... Variance of each independent variable Variances ... Variance of each independent variable
StdDevs ..... Standard deviations of each independent variable StdDevs ..... Standard deviations of each independent variable
NCases ...... Count of valid cases found in the grid NCases ...... Count valid cases in the grid
ErrorCode ... if true, an error has occured during the calculations ErrorCode ... if true, an error has occured during the calculations
PrintAll .... if true, intermediate matrices and vectors are written to the report PrintAll .... if true, intermediate matrices and vectors are written to the report
AReport ..... a string list to which the report is written. AReport ..... a string list to which the report is written.
@ -641,7 +639,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;
@ -751,6 +749,9 @@ begin
// get product of the augmented X transpose times augmented X // get product of the augmented X transpose times augmented X
MatAXB(XTX, XT, X, NoIndep+1, NCases, NCases, NoIndep+1, errorcode); MatAXB(XTX, XT, X, NoIndep+1, NCases, NCases, NoIndep+1, errorcode);
if errorCode then
exit;
if PrintAll then if PrintAll then
begin begin
title := 'XTX MATRIX'; title := 'XTX MATRIX';