LazStats: Refactor excessive usage of form-global variables in ABRAnovaUnit.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7801 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2020-10-25 10:21:35 +00:00
parent 990ad56ae4
commit c022ad9edf
2 changed files with 466 additions and 407 deletions

View File

@ -13,7 +13,31 @@ inherited ABRAnovaForm: TABRAnovaForm
Width = 329 Width = 329
ClientHeight = 336 ClientHeight = 336
ClientWidth = 329 ClientWidth = 329
object OptionsGroup: TGroupBox[0] inherited CloseBtn: TButton
Left = 274
Top = 311
TabOrder = 14
end
inherited ComputeBtn: TButton
Left = 190
Top = 311
TabOrder = 13
end
inherited ResetBtn: TButton
Left = 128
Top = 311
TabOrder = 12
end
inherited HelpBtn: TButton
Left = 69
Top = 311
TabOrder = 11
end
inherited ButtonBevel: TBevel
Top = 295
Width = 329
end
object OptionsGroup: TGroupBox[5]
AnchorSideLeft.Control = ParamsPanel AnchorSideLeft.Control = ParamsPanel
AnchorSideBottom.Control = ButtonBevel AnchorSideBottom.Control = ButtonBevel
Left = 0 Left = 0
@ -70,30 +94,6 @@ inherited ABRAnovaForm: TABRAnovaForm
TabOrder = 2 TabOrder = 2
end end
end end
inherited CloseBtn: TButton[1]
Left = 274
Top = 311
TabOrder = 14
end
inherited ComputeBtn: TButton[2]
Left = 190
Top = 311
TabOrder = 13
end
inherited ResetBtn: TButton[3]
Left = 128
Top = 311
TabOrder = 12
end
inherited HelpBtn: TButton[4]
Left = 69
Top = 311
TabOrder = 11
end
inherited ButtonBevel: TBevel[5]
Top = 295
Width = 329
end
object Label1: TLabel[6] object Label1: TLabel[6]
AnchorSideLeft.Control = ParamsPanel AnchorSideLeft.Control = ParamsPanel
AnchorSideTop.Control = ParamsPanel AnchorSideTop.Control = ParamsPanel
@ -331,15 +331,15 @@ inherited ABRAnovaForm: TABRAnovaForm
inherited ReportPage: TTabSheet inherited ReportPage: TTabSheet
Caption = 'ANOVA Summary' Caption = 'ANOVA Summary'
end end
object MeansPage: TTabSheet[1] inherited ChartPage: TTabSheet
Caption = 'Charts'
end
object MeansPage: TTabSheet[2]
Caption = 'Means' Caption = 'Means'
end end
object BoxTestsPage: TTabSheet[2] object BoxTestsPage: TTabSheet[3]
Caption = 'Box Tests' Caption = 'Box Tests'
end end
inherited ChartPage: TTabSheet[3]
Caption = 'Charts'
end
end end
object ListChartSource_AB: TListChartSource[3] object ListChartSource_AB: TListChartSource[3]
Left = 465 Left = 465

View File

@ -15,6 +15,38 @@ uses
type type
TABRAnovaData = record
// Counts
NoAGrps, NoBGrps, NInGrp, TotalN: Integer;
Acnt, Bcnt, Ccnt: IntDyneVec;
// Degrees of freedom
DFA, DFB, DFC, DFAB, DFAC, DFBC, DFABC, DFBetween: double;
DFerrorBetween, DFWithin, DFerrorWithin: double;
// Sums
ASums, BSums, CSums, SumPSqr: DblDyneVec;
ABSums, ACSums, BCSums: DblDyneMat;
ABCSums: DblDyneCube;
ABCNcnt: IntDyneCube;
GrandTotal: Double;
// Sums of squares
SSA, SSB, SSC, SSAB, SSAC, SSBC, SSABC: Double;
SSBetweenSubjects, SSWithinSubjects: Double;
SSerrorBetween, SSerrorWithin: Double;
SumXSqr: Double;
// Mean standard errors
MSA, MSB, MSC, MSAB, MSAC, MSBC, MSABC, MSerrorBetween, MSerrorWithin: Double;
// F values
FA, FB, FC, FAB, FAC, FBC, FABC: Double;
// Probabilities
ProbA, ProbB, ProbC, ProbAB, ProbAC, ProbBC, ProbABC: Double;
end;
{ TABRAnovaForm } { TABRAnovaForm }
TABRAnovaForm = class(TBasicStatsReportAndChartForm) TABRAnovaForm = class(TBasicStatsReportAndChartForm)
@ -54,43 +86,32 @@ type
procedure PlotChkChange(Sender: TObject); procedure PlotChkChange(Sender: TObject);
procedure ThreeDChkChange(Sender: TObject); procedure ThreeDChkChange(Sender: TObject);
procedure VarListDblClick(Sender: TObject); procedure VarListDblClick(Sender: TObject);
private private
type TInteraction = (AB, AC, BC); type TInteraction = (AB, AC, BC);
private private
ColNoSelected: IntDyneVec; ColNoSelected: IntDyneVec;
ACol, BCol, NoSelected, MinA, MaxA, MinB, MaxB, NoAGrps, NoBGrps : integer; ACol, BCol, NoSelected, MinA, MaxA, MinB, MaxB: integer;
group, MaxRows, MaxCols, TotalN, NinGrp : integer; MaxRows, MaxCols: integer;
SubjTot, GrandTotal, SumXSqr : double; selected: Integer;
DFA, DFB, DFC, DFAB, DFAC, DFBC, DFABC, DFBetween : double;
DFerrorBetween, DFWithin, DFerrorWithin : double;
SSA, SSB, SSC, SSAB, SSAC, SSBC, SSABC, SSBetweenSubjects : double;
SSerrorBetween, SSWithinSubjects, SSerrorWithin : double;
MSA, MSB, MSC, MSAB, MSAC, MSBC, MSABC, MSerrorBetween, MSerrorWithin : double;
FA, FB, FC, FAB, FAC, FBC, FABC : double;
ProbA, ProbB, ProbC, ProbAB, ProbAC, ProbBC, ProbABC : double;
Acnt, Bcnt, Ccnt : IntDyneVec;
ASums, BSums, CSums, SumPSqr : DblDyneVec;
ABSums, ACSums, BCSums: DblDyneMat;
ABCSums: DblDyneCube;
ABCNcnt: IntDyneCube;
selected : integer;
FMeansReportFrame: TReportFrame; FMeansReportFrame: TReportFrame;
FBoxTestsReportFrame: TReportFrame; FBoxTestsReportFrame: TReportFrame;
FBtnAB, FBtnAC, FBtnBC: TToolButton; FBtnAB, FBtnAC, FBtnBC: TToolButton;
FBarSeries: TBarSeries; FBarSeries: TBarSeries;
procedure InteractionChanged(Sender: TObject); procedure InteractionChanged(Sender: TObject);
procedure Set3DPlot(AEnable: Boolean);
function InitData: Boolean; function InitData(out AData: TABRAnovaData): Boolean;
procedure GetData; procedure GetData(var AData: TABRAnovaData);
procedure Calculate; procedure Calculate(var AData: TABRAnovaData);
procedure Summarize(AReport: TStrings); procedure Summarize(const AData: TABRAnovaData; AReport: TStrings);
procedure MeansReport(AReport: TStrings); procedure MeansReport(const AData: TABRAnovaData; AReport: TStrings);
procedure BoxTests(AReport: TStrings); procedure BoxTests(const AData: TABRAnovaData; AReport: TStrings);
procedure PreparePlot; procedure PreparePlot(const AData: TABRAnovaData);
procedure PlotMeans(AInteraction: TInteraction); procedure PlotMeans(AInteraction: TInteraction);
procedure CleanUp; procedure CleanUp(var AData: TABRAnovaData);
protected protected
procedure AdjustConstraints; override; procedure AdjustConstraints; override;
@ -268,8 +289,10 @@ begin
end; end;
procedure TABRAnovaForm.CleanUp; procedure TABRAnovaForm.CleanUp(var AData: TABRAnovaData);
begin begin
with AData do
begin
ABCNcnt := nil; ABCNcnt := nil;
ABCSums := nil; ABCSums := nil;
Ccnt := nil; Ccnt := nil;
@ -285,6 +308,7 @@ begin
BSums := nil; BSums := nil;
ASums := nil; ASums := nil;
ColNoSelected := nil; ColNoSelected := nil;
end;
end; end;
@ -312,27 +336,28 @@ procedure TABRAnovaForm.Compute;
var var
lReport: TStrings; lReport: TStrings;
interaction: TInteraction; interaction: TInteraction;
data: TABRAnovaData;
begin begin
lReport := TStringList.Create; lReport := TStringList.Create;
try try
if InitData then if InitData(data) then
begin begin
GetData; GetData(data);
Calculate; Calculate(data);
Summarize(lReport); Summarize(data, lReport);
MeansReport(lReport); MeansReport(data, lReport);
BoxTestsPage.TabVisible := TestChk.Checked; BoxTestsPage.TabVisible := TestChk.Checked;
if TestChk.Checked then if TestChk.Checked then
begin begin
BoxTests(lReport); BoxTests(data, lReport);
//BoxTestsPage.PageIndex := 2; //BoxTestsPage.PageIndex := 2;
end; end;
ChartPage.TabVisible := PlotChk.Checked; ChartPage.TabVisible := PlotChk.Checked;
if PlotChk.Checked then if PlotChk.Checked then
begin begin
PreparePlot; PreparePlot(data);
if FBtnAB.Down then interaction := AB else if FBtnAB.Down then interaction := AB else
if FBtnAC.Down then interaction := AC else if FBtnAC.Down then interaction := AC else
if FBtnBC.Down then interaction := BC; if FBtnBC.Down then interaction := BC;
@ -342,7 +367,7 @@ begin
end; end;
finally finally
lReport.Free; lReport.Free;
CleanUp; CleanUp(data);
end; end;
end; end;
@ -366,23 +391,17 @@ begin
UpdateBtnStates; UpdateBtnStates;
end; end;
procedure TABRAnovaForm.PlotChkChange(Sender: TObject); procedure TABRAnovaForm.PlotChkChange(Sender: TObject);
begin begin
ThreeDChk.Enabled := PlotChk.Checked; ThreeDChk.Enabled := PlotChk.Checked;
end; end;
procedure TABRAnovaForm.ThreeDChkChange(Sender: TObject);
const
DEPTH: array[boolean] of Integer = (0, 20);
begin
FBarSeries.Depth := DEPTH[ThreeDChk.Checked];
FChartFrame.Chart.LeftAxis.Grid.Visible := not ThreeDChk.Checked;
end;
function TABRAnovaForm.InitData(out AData: TABRAnovaData): Boolean;
function TABRAnovaForm.InitData: Boolean;
var var
cellstring: string; cellStr: string;
groupVal: Integer;
i, j, k: integer; i, j, k: integer;
begin begin
Result := false; Result := false;
@ -398,24 +417,27 @@ begin
end; end;
NoSelected := CList.Items.Count; NoSelected := CList.Items.Count;
MinA := 10000; MinA := MaxInt;
MaxA := -10000; MaxA := -MaxInt;
MinB := 10000; MinB := MaxInt;
MaxB := -10000; MaxB := -MaxInt;
for i := 1 to NoCases do for i := 1 to NoCases do
begin begin
if not ValidValue(OS3MainFrm.DataGrid, i, ACol) then continue; if not ValidValue(OS3MainFrm.DataGrid, i, ACol) then continue;
cellstring := Trim(OS3MainFrm.DataGrid.Cells[ACol,i]); cellStr := Trim(OS3MainFrm.DataGrid.Cells[ACol, i]);
group := round(StrToFloat(cellstring)); groupVal := round(StrToFloat(cellstr));
if (group > MaxA) then MaxA := group; if (groupVal > MaxA) then MaxA := groupVal;
if (group < MinA) then MinA := group; if (groupVal < MinA) then MinA := groupVal;
cellstring := Trim(OS3MainFrm.DataGrid.Cells[BCol,i]); cellStr := Trim(OS3MainFrm.DataGrid.Cells[BCol, i]);
if not ValidValue(OS3MainFrm.DataGrid, i, BCol) then continue; if not ValidValue(OS3MainFrm.DataGrid, i, BCol) then continue;
group := round(StrToFLoat(cellstring)); groupVal := round(StrToFLoat(cellStr));
if (group > MaxB) then MaxB := group; if (groupVal > MaxB) then MaxB := groupVal;
if (group < MinB) then MinB := group; if (groupVal < MinB) then MinB := groupVal;
end; end;
with AData do
begin
NoAGrps := MaxA - MinA + 1; NoAGrps := MaxA - MinA + 1;
NoBGrps := MaxB - MinB + 1; NoBGrps := MaxB - MinB + 1;
MaxRows := NoAGrps * NoBGrps; MaxRows := NoAGrps * NoBGrps;
@ -475,6 +497,7 @@ begin
GrandTotal := 0.0; GrandTotal := 0.0;
TotalN := 0; TotalN := 0;
SumXSqr := 0.0; SumXSqr := 0.0;
end;
Result := true; Result := true;
end; end;
@ -501,10 +524,11 @@ begin
end; end;
procedure TABRAnovaForm.GetData; procedure TABRAnovaForm.GetData(var AData: TABRAnovaData);
var var
i, j, SubjA, SubjB: integer; i, j, SubjA, SubjB: integer;
X: double; X: double;
subjTot: Double;
begin begin
for i := 0 to NoSelected - 1 do for i := 0 to NoSelected - 1 do
ColNoSelected[i] := GetVariableIndex(OS3MainFrm.DataGrid, CList.Items[i]); ColNoSelected[i] := GetVariableIndex(OS3MainFrm.DataGrid, CList.Items[i]);
@ -514,6 +538,8 @@ begin
selected := NoSelected + 2; selected := NoSelected + 2;
// read data and store sums // read data and store sums
with AData do
begin
for i := 1 to NoCases do for i := 1 to NoCases do
begin begin
if not DataProcs.GoodRecord(i,selected,ColNoSelected) then continue; if not DataProcs.GoodRecord(i,selected,ColNoSelected) then continue;
@ -538,14 +564,17 @@ begin
GrandTotal := GrandTotal + SubjTot; GrandTotal := GrandTotal + SubjTot;
NinGrp := ABCNcnt[0,0,0]; NinGrp := ABCNcnt[0,0,0];
end; end;
end;
end; end;
procedure TABRAnovaForm.Calculate; procedure TABRAnovaForm.Calculate(var AData: TABRAnovaData);
var var
SumA, SumB, SumC, SumAB, SumAC, SumBC, SumABC : double; SumA, SumB, SumC, SumAB, SumAC, SumBC, SumABC : double;
Term1, Term2, Term3, Term4, Term5, Term6, Term7, Term8, Term9, Term10 : double; Term1, Term2, Term3, Term4, Term5, Term6, Term7, Term8, Term9, Term10 : double;
i, j, k, CountA, CountB, CountC: integer; i, j, k, CountA, CountB, CountC: integer;
begin begin
with AData do
begin
Term1 := (GrandTotal * GrandTotal) / TotalN; Term1 := (GrandTotal * GrandTotal) / TotalN;
Term2 := SumXSqr; Term2 := SumXSqr;
@ -697,17 +726,21 @@ begin
ProbAC := ProbF(FAC, DFAC, DFerrorWithin); ProbAC := ProbF(FAC, DFAC, DFerrorWithin);
ProbBC := ProbF(FBC, DFBC, DFerrorWithin); ProbBC := ProbF(FBC, DFBC, DFerrorWithin);
ProbABC := ProbF(FABC, DFABC, DFerrorWithin); ProbABC := ProbF(FABC, DFABC, DFerrorWithin);
end;
end; end;
procedure TABRAnovaForm.Summarize(AReport: TStrings); procedure TABRAnovaForm.Summarize(const AData: TABRAnovaData; AReport: TStrings);
begin begin
with AData do
begin
AReport.Add(DIVIDER_SMALL_AUTO);
AReport.Add('SOURCE DF SS MS F PROB.'); AReport.Add('SOURCE DF SS MS F PROB.');
AReport.Add(''); AReport.Add(DIVIDER_SMALL_AUTO);
AReport.Add('Between Subjects %5.0f%10.3f',[DFBetween, SSBetweenSubjects]); AReport.Add('Between Subjects %5.0f%10.3f', [DFBetween, SSBetweenSubjects]);
AReport.Add(' A Effects %5.0f%10.3f%10.3f%10.3f%10.3f', [DFA, SSA, MSA, FA, ProbA]); AReport.Add(' A Effects %5.0f%10.3f%10.3f%10.3f%10.3f', [DFA, SSA, MSA, FA, ProbA]);
AReport.Add(' B Effects %5.0f%10.3f%10.3f%10.3f%10.3f', [DFB, SSB, MSB, FB, ProbB]); AReport.Add(' B Effects %5.0f%10.3f%10.3f%10.3f%10.3f', [DFB, SSB, MSB, FB, ProbB]);
AReport.Add(' AB Effects %5.0f%10.3f%10.3f%10.3f%10.3f', [DFAB, SSAB, MSAB, FAB, ProbAB]); AReport.Add(' AB Effects %5.0f%10.3f%10.3f%10.3f%10.3f', [DFAB, SSAB, MSAB, FAB, ProbAB]);
AReport.Add(' Error Between %5.0f%10.3f%10.3f', [DFerrorBetween,SSerrorBetween,MSerrorBetween]); AReport.Add(' Error Between %5.0f%10.3f%10.3f', [DFerrorBetween, SSerrorBetween, MSerrorBetween]);
AReport.Add(''); AReport.Add('');
AReport.Add('Within Subjects %5.0f%10.3f', [DFWithin, SSWithinSubjects]); AReport.Add('Within Subjects %5.0f%10.3f', [DFWithin, SSWithinSubjects]);
AReport.Add(' C Replications %5.0f%10.3f%10.3f%10.3f%10.3f', [DFC, SSC, MSC, FC, ProbC]); AReport.Add(' C Replications %5.0f%10.3f%10.3f%10.3f%10.3f', [DFC, SSC, MSC, FC, ProbC]);
@ -716,15 +749,17 @@ begin
AReport.Add(' ABC Effects %5.0f%10.3f%10.3f%10.3f%10.3f', [DFABC, SSABC, MSABC, FABC, ProbABC]); AReport.Add(' ABC Effects %5.0f%10.3f%10.3f%10.3f%10.3f', [DFABC, SSABC, MSABC, FABC, ProbABC]);
AReport.Add(' Error Within %5.0f%10.3f%10.3f', [DFerrorWithin, SSerrorWithin, MSerrorWithin]); AReport.Add(' Error Within %5.0f%10.3f%10.3f', [DFerrorWithin, SSerrorWithin, MSerrorWithin]);
AReport.Add(''); AReport.Add('');
// AReport.Add(DIVIDER_SMALL_AUTO);
AReport.Add('Total %5.0f%10.3f', [DFBetween + DFWithin, SSBetweenSubjects + SSWithinSubjects]); AReport.Add('Total %5.0f%10.3f', [DFBetween + DFWithin, SSBetweenSubjects + SSWithinSubjects]);
AReport.Add(''); AReport.Add(DIVIDER_SMALL_AUTO);
end;
FReportFrame.DisplayReport(AReport); FReportFrame.DisplayReport(AReport);
AReport.Clear; AReport.Clear;
end; end;
procedure TABRAnovaForm.MeansReport(AReport: TStrings); procedure TABRAnovaForm.MeansReport(const AData: TABRAnovaData; AReport: TStrings);
var var
ColLabels: StrDyneVec = nil; ColLabels: StrDyneVec = nil;
RowLabels: StrDyneVec = nil; RowLabels: StrDyneVec = nil;
@ -742,80 +777,80 @@ begin
SetLength(RowLabels, MaxRows); SetLength(RowLabels, MaxRows);
SetLength(ColLabels, NoSelected); SetLength(ColLabels, NoSelected);
row := 0; row := 0;
for i := 0 to NoAGrps-1 do for i := 0 to AData.NoAGrps-1 do
begin begin
for j := 0 to NoBGrps-1 do for j := 0 to AData.NoBGrps-1 do
begin begin
RowLabels[row] := Format('A%d B%d',[i+1, j+1]); RowLabels[row] := Format('A%d B%d',[i+1, j+1]);
for k := 0 to NoSelected-1 do for k := 0 to NoSelected-1 do
begin begin
AMatrix[row, k] := ABCSums[i, j, k] / NInGrp; AMatrix[row, k] := AData.ABCSums[i, j, k] / AData.NInGrp;
ColLabels[k] := OS3MainFrm.DataGrid.Cells[ColNoSelected[k], 0]; ColLabels[k] := OS3MainFrm.DataGrid.Cells[ColNoSelected[k], 0];
end; end;
inc(row); inc(row);
end; end;
end; end;
MatPrint(AMatrix, MaxRows, NoSelected, Title, RowLabels, ColLabels, NInGrp, AReport); MatPrint(AMatrix, MaxRows, NoSelected, Title, RowLabels, ColLabels, AData.NInGrp, AReport);
AReport.Add(DIVIDER_SMALL_AUTO); AReport.Add(DIVIDER_SMALL_AUTO);
AReport.Add(''); AReport.Add('');
Title := 'AB Means Table'; Title := 'AB Means Table';
ColHeader := 'B Levels'; ColHeader := 'B Levels';
SetLength(AMatrix, NoAGrps, NoBGrps); SetLength(AMatrix, AData.NoAGrps, AData.NoBGrps);
SetLength(RowLabels, NoAGrps); SetLength(RowLabels, AData.NoAGrps);
SetLength(ColLabels, NoBGrps); SetLength(ColLabels, AData.NoBGrps);
for i := 0 to NoAGrps-1 do for i := 0 to AData.NoAGrps-1 do
begin begin
RowLabels[i] := Format('A%d',[i+1]); RowLabels[i] := Format('A%d',[i+1]);
for j := 0 to NoBGrps-1 do for j := 0 to AData.NoBGrps-1 do
AMatrix[i, j] := ABSums[i, j] / (NInGrp * NoSelected); AMatrix[i, j] := AData.ABSums[i, j] / (AData.NInGrp * NoSelected);
end; end;
for j := 0 to NoBGrps-1 do for j := 0 to AData.NoBGrps-1 do
ColLabels[j] := Format('B %d',[j+1]); ColLabels[j] := Format('B %d',[j+1]);
MatPrint(AMatrix, NoAgrps, NoBgrps, Title, RowLabels, ColLabels, NinGrp*NoSelected, AReport); MatPrint(AMatrix, AData.NoAgrps, AData.NoBgrps, Title, RowLabels, ColLabels, AData.NinGrp*NoSelected, AReport);
AReport.Add(DIVIDER_SMALL_AUTO); AReport.Add(DIVIDER_SMALL_AUTO);
AReport.Add(''); AReport.Add('');
Title := 'AC Means Table'; Title := 'AC Means Table';
ColHeader := 'C Levels'; ColHeader := 'C Levels';
SetLength(AMatrix, NoAGrps, NoSelected); SetLength(AMatrix, AData.NoAGrps, NoSelected);
SetLength(RowLabels, NoAGrps); SetLength(RowLabels, AData.NoAGrps);
SetLength(ColLabels, NoSelected); SetLength(ColLabels, NoSelected);
for i := 0 to NoAGrps-1 do for i := 0 to AData.NoAGrps-1 do
begin begin
RowLabels[i] := Format('A%d',[i+1]); RowLabels[i] := Format('A%d',[i+1]);
for j := 0 to NoSelected-1 do for j := 0 to NoSelected-1 do
AMatrix[i, j] := ACSums[i, j] / (NInGrp * NoBGrps); AMatrix[i, j] := AData.ACSums[i, j] / (AData.NInGrp * AData.NoBGrps);
end; end;
for j := 0 to NoSelected-1 do for j := 0 to NoSelected-1 do
ColLabels[j] := Format('C%d',[j+1]); ColLabels[j] := Format('C%d',[j+1]);
MatPrint(AMatrix, NoAGrps, NoSelected, Title, RowLabels, ColLabels, NInGrp*NoBGrps, AReport); MatPrint(AMatrix, AData.NoAGrps, NoSelected, Title, RowLabels, ColLabels, AData.NInGrp*AData.NoBGrps, AReport);
AReport.Add(DIVIDER_SMALL_AUTO); AReport.Add(DIVIDER_SMALL_AUTO);
AReport.Add(''); AReport.Add('');
Title := 'BC Means Table'; Title := 'BC Means Table';
ColHeader := 'C Levels'; ColHeader := 'C Levels';
SetLength(AMatrix, NoBGrps, NoSelected); SetLength(AMatrix, AData.NoBGrps, NoSelected);
SetLength(RowLabels, NoBGrps); SetLength(RowLabels, AData.NoBGrps);
SetLength(ColLabels, NoSelected); SetLength(ColLabels, NoSelected);
for i := 0 to NoBGrps-1 do for i := 0 to AData.NoBGrps-1 do
begin begin
RowLabels[i] := Format('B%d',[i+1]); RowLabels[i] := Format('B%d',[i+1]);
for j := 0 to NoSelected-1 do for j := 0 to NoSelected-1 do
AMatrix[i, j] := BCSums[i, j] / (NInGrp * NoAGrps); AMatrix[i, j] := AData.BCSums[i, j] / (AData.NInGrp * AData.NoAGrps);
end; end;
for j := 0 to NoSelected-1 do for j := 0 to NoSelected-1 do
ColLabels[j] := Format('C%d', [j+1]); ColLabels[j] := Format('C%d', [j+1]);
MatPrint(AMatrix, NoBGrps, NoSelected, Title, RowLabels, ColLabels, NInGrp*NoAGrps, AReport); MatPrint(AMatrix, AData.NoBGrps, NoSelected, Title, RowLabels, ColLabels, AData.NInGrp*AData.NoAGrps, AReport);
FMeansReportFrame.DisplayReport(AReport); FMeansReportFrame.DisplayReport(AReport);
AReport.Clear; AReport.Clear;
end; end;
procedure TABRAnovaForm.BoxTests(AReport: TStrings); procedure TABRAnovaForm.BoxTests(const AData: TABRAnovaData; AReport: TStrings);
const const
EPS = 1E-35; EPS = 1E-35;
var var
@ -855,9 +890,9 @@ begin
// covariance AMatrix. Get Determinants of each AMatrix. // covariance AMatrix. Get Determinants of each AMatrix.
//OutputFrm.Clear; //OutputFrm.Clear;
Sum1 := 0.0; Sum1 := 0.0;
for i := 1 to NoAGrps do for i := 1 to AData.NoAGrps do
begin begin
for j := 1 to NoBGrps do for j := 1 to AData.NoBGrps do
begin begin
LabelStr := Format('Variance-Covariance AMatrix for A%d B%d', [i,j]); LabelStr := Format('Variance-Covariance AMatrix for A%d B%d', [i,j]);
Title := LabelStr; Title := LabelStr;
@ -899,8 +934,8 @@ begin
begin begin
for L := 0 to NoSelected-1 do for L := 0 to NoSelected-1 do
begin begin
AMatrix[k, L] := AMatrix[k, L] - (XSums[k]*XSums[L] / NInGrp); AMatrix[k, L] := AMatrix[k, L] - (XSums[k]*XSums[L] / AData.NInGrp);
AMatrix[k, L] := AMatrix[k, L] / (NInGrp - 1); AMatrix[k, L] := AMatrix[k, L] / (AData.NInGrp - 1);
PooledMat[k, L] := PooledMat[k, L] + AMatrix[k, L]; PooledMat[k, L] := PooledMat[k, L] + AMatrix[k, L];
end; end;
end; end;
@ -916,7 +951,7 @@ begin
Determ(DetMat, NoSelected, NoSelected, Det, errorcode); Determ(DetMat, NoSelected, NoSelected, Det, errorcode);
// if (Det > 0.0e35) then // wp: What's this??? // if (Det > 0.0e35) then // wp: What's this???
if Det > EPS then if Det > EPS then
Sum1 := sum1 + (NinGrp * ln(Det)) Sum1 := sum1 + (AData.NInGrp * ln(Det))
else else
MessageDlg('Determinant of a covariance AMatrix <= 0.', mtWarning, [mbOK], 0); MessageDlg('Determinant of a covariance AMatrix <= 0.', mtWarning, [mbOK], 0);
end;// next B level end;// next B level
@ -925,7 +960,7 @@ begin
// Get pooled variance-covariance // Get pooled variance-covariance
for i := 0 to NoSelected-1 do for i := 0 to NoSelected-1 do
for j := 0 to NoSelected-1 do for j := 0 to NoSelected-1 do
PooledMat[i, j] := PooledMat[i, j] / (NoAGrps * NoBGrps); PooledMat[i, j] := PooledMat[i, j] / (AData.NoAGrps * AData.NoBGrps);
Title := 'Pooled Variance-Covariance AMatrix'; Title := 'Pooled Variance-Covariance AMatrix';
MatPrint(PooledMat, NoSelected, NoSelected, Title, RowLabels, ColLabels, NoCases, AReport); MatPrint(PooledMat, NoSelected, NoSelected, Title, RowLabels, ColLabels, NoCases, AReport);
@ -941,12 +976,15 @@ begin
DetMat[i, j] := PooledMat[i, j]; DetMat[i, j] := PooledMat[i, j];
Determ(DetMat, NoSelected, NoSelected, Det, errorcode); Determ(DetMat, NoSelected, NoSelected, Det, errorcode);
if (Det > EPS) then if (Det > EPS) then
begin
with AData do
begin begin
M1 := (NinGrp*NoAGrps*NoBGrps * ln(Det)) - Sum1; M1 := (NinGrp*NoAGrps*NoBGrps * ln(Det)) - Sum1;
C1 := (2.0 * NoSelected * NoSelected + 3.0 * NoSelected - 1.0) / C1 := (2.0 * NoSelected * NoSelected + 3.0 * NoSelected - 1.0) /
(6.0 * (NoSelected+1) * (NoAGrps * NoBGrps - 1.0)); (6.0 * (NoSelected+1) * (NoAGrps * NoBGrps - 1.0));
C1 := C1 * ( (NoAGrps * NoBGrps * (1.0 / NinGrp)) - (1.0 / (NinGrp * NoAGrps * NoBGrps))); C1 := C1 * ( (NoAGrps * NoBGrps * (1.0 / NinGrp)) - (1.0 / (NinGrp * NoAGrps * NoBGrps)));
f1 := (NoSelected * (NoSelected + 1.0) * (NoAGrps * NoBGrps - 1.0))/2.0; f1 := (NoSelected * (NoSelected + 1.0) * (NoAGrps * NoBGrps - 1.0))/2.0;
end;
chi := (1.0 - C1) * M1; chi := (1.0 - C1) * M1;
ProbChi := 1.0 - ChiSquaredProb(chi, round(f1)); ProbChi := 1.0 - ChiSquaredProb(chi, round(f1));
AReport.Add('Test that sample covariances are from same population:'); AReport.Add('Test that sample covariances are from same population:');
@ -985,9 +1023,12 @@ begin
end; end;
Determ(DetMat, NoSelected, NoSelected, Det, errorcode); Determ(DetMat, NoSelected, NoSelected, Det, errorcode);
if (Det > EPS) then if (Det > EPS) then
begin
with AData do
begin begin
N := NoAGrps * NoBGrps * NinGrp; N := NoAGrps * NoBGrps * NinGrp;
p := NoAGrps * NoBGrps; p := NoAGrps * NoBGrps;
end;
quad := NoSelected * NoSelected + NoSelected - 4; quad := NoSelected * NoSelected + NoSelected - 4;
M2 := ln(M2 / Det); M2 := ln(M2 / Det);
M2 := -(N - p) * M2; M2 := -(N - p) * M2;
@ -1009,59 +1050,6 @@ begin
end; end;
procedure TABRAnovaForm.PreparePlot;
var
idx: Integer;
item: PChartDataItem;
i, j: Integer;
begin
FChartFrame.Clear;
ListChartSource_AB.Clear;
ListChartSource_AC.Clear;
ListChartSource_BC.Clear;
ChartStyles.Styles.Clear;
ListChartSource_AB.YCount := NoAGrps;
for j := 0 to NoBGrps-1 do
begin
idx := ListChartSource_AB.Add(j+1, 0);
item := ListChartSource_AB.Item[idx];
for i := 0 to NoAGrps-1 do
item^.SetY(i, ABSums[i, j] / (NInGrp * NoSelected));
end;
ListChartSource_AC.YCount := NoAGrps;
for j := 0 to NoSelected-1 do
begin
idx := ListChartSource_AC.Add(j+1, 0);
item := ListChartSource_AC.Item[idx];
for i := 0 to NoAGrps-1 do
item^.SetY(i, ACSums[i, j] / (NInGrp * NoBGrps));
end;
ListChartSource_BC.YCount := NoBGrps;
for j := 0 to NoSelected-1 do
begin
idx := ListChartSource_BC.Add(j+1, 0);
item := ListChartSource_BC.Item[idx];
for i := 0 to NoBGrps-1 do
item^.SetY(i, BCSums[i, j] / (NInGrp * NoAGrps));
end;
FBarSeries := FChartFrame.PlotXY(ptBars, nil, nil, nil, nil, '', clDefault) as TBarSeries;
with FBarSeries do
begin
Legend.Multiplicity := lmStyle;
Stacked := false;
Styles := ChartStyles;
{$IF LCL_FullVersion >= 2010000}
DepthBrightnessDelta := -30;
{$IFEND}
end;
end;
procedure TABRAnovaForm.PlotMeans(AInteraction: TInteraction); procedure TABRAnovaForm.PlotMeans(AInteraction: TInteraction);
const const
X_TITLE: array[TInteraction] of string = ( X_TITLE: array[TInteraction] of string = (
@ -1085,6 +1073,7 @@ begin
end; end;
FBarSeries.Source := serSource; FBarSeries.Source := serSource;
Set3DPlot(ThreeDChk.Checked);
ChartStyles.Styles.Clear; ChartStyles.Styles.Clear;
for i := 0 to serSource.YCount-1 do for i := 0 to serSource.YCount-1 do
@ -1105,6 +1094,58 @@ begin
end; end;
procedure TABRAnovaForm.PreparePlot(const AData: TABRAnovaData);
var
idx: Integer;
item: PChartDataItem;
i, j: Integer;
begin
FChartFrame.Clear;
ListChartSource_AB.Clear;
ListChartSource_AC.Clear;
ListChartSource_BC.Clear;
ChartStyles.Styles.Clear;
ListChartSource_AB.YCount := AData.NoAGrps;
for j := 0 to AData.NoBGrps-1 do
begin
idx := ListChartSource_AB.Add(j+1, 0);
item := ListChartSource_AB.Item[idx];
for i := 0 to AData.NoAGrps-1 do
item^.SetY(i, AData.ABSums[i, j] / (AData.NInGrp * NoSelected));
end;
ListChartSource_AC.YCount := AData.NoAGrps;
for j := 0 to NoSelected-1 do
begin
idx := ListChartSource_AC.Add(j+1, 0);
item := ListChartSource_AC.Item[idx];
for i := 0 to AData.NoAGrps-1 do
item^.SetY(i, AData.ACSums[i, j] / (AData.NInGrp * AData.NoBGrps));
end;
ListChartSource_BC.YCount := AData.NoBGrps;
for j := 0 to NoSelected-1 do
begin
idx := ListChartSource_BC.Add(j+1, 0);
item := ListChartSource_BC.Item[idx];
for i := 0 to AData.NoBGrps-1 do
item^.SetY(i, AData.BCSums[i, j] / (AData.NInGrp * AData.NoAGrps));
end;
FBarSeries := FChartFrame.PlotXY(ptBars, nil, nil, nil, nil, '', clDefault) as TBarSeries;
with FBarSeries do
begin
Legend.Multiplicity := lmStyle;
Stacked := false;
Styles := ChartStyles;
{$IF LCL_FullVersion >= 2010000}
DepthBrightnessDelta := -30;
{$IFEND}
end;
end;
procedure TABRAnovaForm.Reset; procedure TABRAnovaForm.Reset;
var var
i: integer; i: integer;
@ -1131,6 +1172,24 @@ begin
end; end;
procedure TABRAnovaForm.Set3DPlot(AEnable: Boolean);
const
DEPTH: array[boolean] of Integer = (0, 20);
begin
if (FBarSeries <> nil) then
begin
FBarSeries.Depth := DEPTH[AEnable];
FChartFrame.Chart.LeftAxis.Grid.Visible := not AEnable;
end;
end;
procedure TABRAnovaForm.ThreeDChkChange(Sender: TObject);
begin
Set3DPlot(ThreeDChk.Checked);
end;
procedure TABRAnovaForm.UpdateBtnStates; procedure TABRAnovaForm.UpdateBtnStates;
var var
lSelected: Boolean; lSelected: Boolean;