LazStats: Fix crash in ABRAnovaUnit when there are not enough C variables.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7799 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2020-10-24 22:55:18 +00:00
parent 57aa148c56
commit 44c7f6af69

View File

@ -74,7 +74,6 @@ type
ABSums, ACSums, BCSums, AMatrix, PooledMat : DblDyneMat; ABSums, ACSums, BCSums, AMatrix, PooledMat : DblDyneMat;
ABCSums: DblDyneCube; ABCSums: DblDyneCube;
ABCNcnt: IntDyneCube; ABCNcnt: IntDyneCube;
RowLabels, ColLabels : StrDyneVec;
selected : integer; selected : integer;
FMeansReportFrame: TReportFrame; FMeansReportFrame: TReportFrame;
@ -273,8 +272,6 @@ procedure TABRAnovaForm.CleanUp;
begin begin
ABCNcnt := nil; ABCNcnt := nil;
ABCSums := nil; ABCSums := nil;
ColLabels := nil;
RowLabels := nil;
Ccnt := nil; Ccnt := nil;
Bcnt := nil; Bcnt := nil;
Acnt := nil; Acnt := nil;
@ -437,8 +434,6 @@ begin
SetLength(Acnt, NoAGrps); SetLength(Acnt, NoAGrps);
SetLength(Bcnt, NoBGrps); SetLength(Bcnt, NoBGrps);
SetLength(Ccnt, MaxRows); SetLength(Ccnt, MaxRows);
SetLength(RowLabels, NoSelected);
SetLength(ColLabels, NoSelected);
SetLength(ABCSums, NoAGrps, NoBGrps, NoSelected); SetLength(ABCSums, NoAGrps, NoBGrps, NoSelected);
SetLength(ABCNcnt, NoAGrps, NoBGrps, NoSelected); SetLength(ABCNcnt, NoAGrps, NoBGrps, NoSelected);
@ -731,79 +726,86 @@ end;
procedure TABRAnovaForm.MeansReport(AReport: TStrings); procedure TABRAnovaForm.MeansReport(AReport: TStrings);
var var
ColHeader, LabelStr: string; ColLabels: StrDyneVec = nil;
RowLabels: StrDyneVec = nil;
ColHeader: string;
Title: string; Title: string;
i, j, k, row: integer; i, j, k, row: integer;
begin begin
AReport.Clear; AReport.Clear;
row := 1;
//OutputFrm.Clear;
Title := 'ABR Means Table'; Title := 'ABR Means Table';
ColHeader := 'Repeated Measures'; ColHeader := 'Repeated Measures';
for i := 1 to NoAGrps do SetLength(RowLabels, MaxRows);
SetLength(ColLabels, NoSelected);
row := 0;
for i := 0 to NoAGrps-1 do
begin begin
for j := 1 to NoBGrps do for j := 0 to NoBGrps-1 do
begin begin
LabelStr := format('A%d B%d',[i,j]); RowLabels[row] := Format('A%d B%d',[i+1, j+1]);
RowLabels[row-1] := LabelStr; for k := 0 to NoSelected-1 do
for k := 1 to NoSelected do
begin begin
AMatrix[row-1,k-1] := ABCSums[i-1,j-1,k-1] / NinGrp; AMatrix[row, k] := ABCSums[i, j, k] / NinGrp;
ColLabels[k-1] := OS3MainFrm.DataGrid.Cells[ColNoSelected[k-1],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, NInGrp, AReport);
AReport.Add('');
AReport.Add(DIVIDER_SMALL_AUTO);
AReport.Add('');
Title := 'AB Means Table'; Title := 'AB Means Table';
ColHeader := 'B Levels'; ColHeader := 'B Levels';
for i := 1 to NoAGrps do SetLength(RowLabels, NoAGrps);
SetLength(ColLabels, NoBGrps);
for i := 0 to NoAGrps-1 do
begin begin
LabelStr := format('A%d',[i]); RowLabels[i] := Format('A%d',[i+1]);
RowLabels[i-1] := LabelStr; for j := 0 to NoBGrps-1 do
for j := 1 to NoBGrps do AMatrix[i, j] := ABSums[i, j] / (NInGrp * NoSelected);
AMatrix[i-1,j-1] := ABSums[i-1,j-1] / (NinGrp * NoSelected);
end; end;
for j := 1 to NoBGrps do for j := 0 to NoBGrps-1 do
begin ColLabels[j] := Format('B %d',[j+1]);
LabelStr := format('B %d',[j]); MatPrint(AMatrix, NoAgrps, NoBgrps, Title, RowLabels, ColLabels, NinGrp*NoSelected, AReport);
ColLabels[j-1] := LabelStr;
end; AReport.Add('');
MatPrint(AMatrix,NoAgrps,NoBgrps,Title,RowLabels,ColLabels,NinGrp*NoSelected, AReport); AReport.Add(DIVIDER_SMALL_AUTO);
AReport.Add('');
Title := 'AC Means Table'; Title := 'AC Means Table';
ColHeader := 'C Levels'; ColHeader := 'C Levels';
for i := 1 to NoAGrps do SetLength(RowLabels, NoAGrps);
SetLength(ColLabels, NoSelected);
for i := 0 to NoAGrps-1 do
begin begin
LabelStr := format('A%d',[i-1]); RowLabels[i] := Format('A%d',[i+1]);
RowLabels[i-1] := LabelStr; for j := 0 to NoSelected-1 do
for j := 1 to NoSelected do AMatrix[i, j] := ACSums[i, j] / (NInGrp * NoBGrps);
AMatrix[i-1,j-1] := ACSums[i-1,j-1] / (NinGrp * NoBGrps);
end; end;
for j := 1 to NoSelected do for j := 0 to NoSelected-1 do
begin ColLabels[j] := Format('C%d',[j+1]);
LabelStr := format('C%d',[j-1]); MatPrint(AMatrix, NoAGrps, NoSelected, Title, RowLabels, ColLabels, NInGrp*NoBGrps, AReport);
ColLabels[j-1] := LabelStr;
end; AReport.Add(DIVIDER_SMALL_AUTO);
MatPrint(AMatrix,NoAGrps,NoSelected,Title,RowLabels,ColLabels,NinGrp*NoBGrps, AReport); AReport.Add('');
Title := 'BC Means Table'; Title := 'BC Means Table';
ColHeader := 'C Levels'; ColHeader := 'C Levels';
for i := 1 to NoBGrps do SetLength(RowLabels, NoBGrps);
SetLength(ColLabels, NoSelected);
for i := 0 to NoBGrps-1 do
begin begin
LabelStr := format('B%d',[i]); RowLabels[i] := Format('B%d',[i+1]);
RowLabels[i-1] := LabelStr; for j := 0 to NoSelected-1 do
for j := 1 to NoSelected do AMatrix[i, j] := BCSums[i, j] / (NInGrp * NoAGrps);
AMatrix[i-1,j-1] := BCSums[i-1,j-1] / (NinGrp * NoAGrps);
end; end;
for j := 1 to NoSelected do for j := 0 to NoSelected-1 do
begin ColLabels[j] := Format('C%d', [j+1]);
LabelStr := format('C%d',[j]); MatPrint(AMatrix, NoBGrps, NoSelected, Title, RowLabels, ColLabels, NInGrp*NoAGrps, AReport);
ColLabels[j-1] := LabelStr;
end;
MatPrint(AMatrix,NoBGrps,NoSelected,Title,RowLabels,ColLabels,NinGrp*NoAGrps, AReport);
FMeansReportFrame.DisplayReport(AReport); FMeansReportFrame.DisplayReport(AReport);
AReport.Clear; AReport.Clear;
@ -816,9 +818,11 @@ var
XVector: DblDyneVec = nil; XVector: DblDyneVec = nil;
XSums: DblDyneVec = nil; XSums: DblDyneVec = nil;
DetMat: DblDyneMat = nil; DetMat: DblDyneMat = nil;
M1, M2, Sum1, C1, C2, f1, f2, chi, ProbChi, X, avgvar,avgcov : double; ColLabels: StrDyneVec = nil;
ColHeader, LabelStr : string; RowLabels: StrDyneVec = nil;
Title : string; M1, M2, Sum1, C1, C2, f1, f2, chi, ProbChi, X, avgvar, avgcov: double;
ColHeader, LabelStr: string;
Title: string;
i, j, k, l, row, SubjA, SubjB, N, p, quad : integer; i, j, k, l, row, SubjA, SubjB, N, p, quad : integer;
errorcode : boolean = false; // to silence the compiler errorcode : boolean = false; // to silence the compiler
Det: Double = 0.0; Det: Double = 0.0;
@ -829,12 +833,13 @@ begin
SetLength(XSums, NoSelected); SetLength(XSums, NoSelected);
SetLength(DetMat, NoSelected+1, NoSelected+1); SetLength(DetMat, NoSelected+1, NoSelected+1);
SetLength(PooledMat, NoSelected+1, NoSelected+1); SetLength(PooledMat, NoSelected+1, NoSelected+1);
SetLength(ColLabels, NoSelected);
SetLength(RowLabels, NoSelected);
for i := 0 to NoSelected-1 do for i := 0 to NoSelected-1 do
begin begin
LabelStr := Format('C%d', [i+1]); RowLabels[i] := Format('C%d', [i+1]);
RowLabels[i] := LabelStr; ColLabels[i] := RowLabels[i];
ColLabels[i] := LabelStr;
for j := 0 to NoSelected-1 do PooledMat[i, j] := 0.0; for j := 0 to NoSelected-1 do PooledMat[i, j] := 0.0;
end; end;
@ -847,7 +852,7 @@ begin
begin begin
for j := 1 to NoBGrps do for j := 1 to 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;
ColHeader := 'C Levels'; ColHeader := 'C Levels';
@ -893,7 +898,7 @@ begin
end; end;
end; end;
MatPrint(AMatrix,NoSelected,NoSelected,Title,RowLabels,ColLabels,NoCases, AReport); MatPrint(AMatrix, NoSelected, NoSelected, Title, RowLabels, ColLabels, NoCases, AReport);
for k := 0 to NoSelected-1 do for k := 0 to NoSelected-1 do
for L := 0 to NoSelected-1 do for L := 0 to NoSelected-1 do
@ -930,10 +935,10 @@ begin
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;
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:');
AReport.Add(''); AReport.Add('');
AReport.Add('Chi-Squared %0.3f with %d degrees of freedom.', [chi,round(f1)]); AReport.Add('Chi-Squared %0.3f with %d degrees of freedom.', [chi, round(f1)]);
AReport.Add('Probability of > Chi-Squared: %0.3f', [ProbChi]); AReport.Add('Probability of > Chi-Squared: %0.3f', [ProbChi]);
AReport.Add(''); AReport.Add('');
AReport.Add(''); AReport.Add('');
@ -964,7 +969,7 @@ begin
DetMat[j-1,i-1] := avgcov; DetMat[j-1,i-1] := avgcov;
end; end;
end; end;
Determ(DetMat,NoSelected,NoSelected,Det,errorcode); Determ(DetMat, NoSelected, NoSelected, Det, errorcode);
if (Det > EPS) then if (Det > EPS) then
begin begin
N := NoAGrps * NoBGrps * NinGrp; N := NoAGrps * NoBGrps * NinGrp;
@ -1058,7 +1063,7 @@ const
); );
var var
serSource: TListChartSource; serSource: TListChartSource;
i, j: Integer; i: Integer;
begin begin
case AInteraction of case AInteraction of
AB: serSource := ListChartSource_AB; AB: serSource := ListChartSource_AB;
@ -1164,9 +1169,12 @@ begin
exit; exit;
end; end;
if CList.Items.Count = 0 then if CList.Items.Count <= 1 then
begin begin
AMsg := 'No Repeated Measures variable(s) specified.'; if CList.Items.Count = 0 then
AMsg := 'No Repeated Measures variable(s) specified.'
else
AMsg := 'There must be at least one Repeated Measures variable.';
AControl := CList; AControl := CList;
exit; exit;
end; end;