From 44c7f6af69e4e6590d83cd3da45ded43ce0f8f6c Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Sat, 24 Oct 2020 22:55:18 +0000 Subject: [PATCH] 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 --- .../analysis/comparisons/abranovaunit.pas | 134 ++++++++++-------- 1 file changed, 71 insertions(+), 63 deletions(-) diff --git a/applications/lazstats/source/forms/analysis/comparisons/abranovaunit.pas b/applications/lazstats/source/forms/analysis/comparisons/abranovaunit.pas index 53511e279..2c6b2fc44 100644 --- a/applications/lazstats/source/forms/analysis/comparisons/abranovaunit.pas +++ b/applications/lazstats/source/forms/analysis/comparisons/abranovaunit.pas @@ -74,7 +74,6 @@ type ABSums, ACSums, BCSums, AMatrix, PooledMat : DblDyneMat; ABCSums: DblDyneCube; ABCNcnt: IntDyneCube; - RowLabels, ColLabels : StrDyneVec; selected : integer; FMeansReportFrame: TReportFrame; @@ -273,8 +272,6 @@ procedure TABRAnovaForm.CleanUp; begin ABCNcnt := nil; ABCSums := nil; - ColLabels := nil; - RowLabels := nil; Ccnt := nil; Bcnt := nil; Acnt := nil; @@ -437,8 +434,6 @@ begin SetLength(Acnt, NoAGrps); SetLength(Bcnt, NoBGrps); SetLength(Ccnt, MaxRows); - SetLength(RowLabels, NoSelected); - SetLength(ColLabels, NoSelected); SetLength(ABCSums, NoAGrps, NoBGrps, NoSelected); SetLength(ABCNcnt, NoAGrps, NoBGrps, NoSelected); @@ -731,79 +726,86 @@ end; procedure TABRAnovaForm.MeansReport(AReport: TStrings); var - ColHeader, LabelStr: string; + ColLabels: StrDyneVec = nil; + RowLabels: StrDyneVec = nil; + ColHeader: string; Title: string; i, j, k, row: integer; begin AReport.Clear; - row := 1; - //OutputFrm.Clear; Title := 'ABR Means Table'; 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 - for j := 1 to NoBGrps do + for j := 0 to NoBGrps-1 do begin - LabelStr := format('A%d B%d',[i,j]); - RowLabels[row-1] := LabelStr; - for k := 1 to NoSelected do + RowLabels[row] := Format('A%d B%d',[i+1, j+1]); + for k := 0 to NoSelected-1 do begin - AMatrix[row-1,k-1] := ABCSums[i-1,j-1,k-1] / NinGrp; - ColLabels[k-1] := OS3MainFrm.DataGrid.Cells[ColNoSelected[k-1],0]; + AMatrix[row, k] := ABCSums[i, j, k] / NinGrp; + ColLabels[k] := OS3MainFrm.DataGrid.Cells[ColNoSelected[k], 0]; end; inc(row); 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'; ColHeader := 'B Levels'; - for i := 1 to NoAGrps do + SetLength(RowLabels, NoAGrps); + SetLength(ColLabels, NoBGrps); + for i := 0 to NoAGrps-1 do begin - LabelStr := format('A%d',[i]); - RowLabels[i-1] := LabelStr; - for j := 1 to NoBGrps do - AMatrix[i-1,j-1] := ABSums[i-1,j-1] / (NinGrp * NoSelected); + RowLabels[i] := Format('A%d',[i+1]); + for j := 0 to NoBGrps-1 do + AMatrix[i, j] := ABSums[i, j] / (NInGrp * NoSelected); end; - for j := 1 to NoBGrps do - begin - LabelStr := format('B %d',[j]); - ColLabels[j-1] := LabelStr; - end; - MatPrint(AMatrix,NoAgrps,NoBgrps,Title,RowLabels,ColLabels,NinGrp*NoSelected, AReport); + for j := 0 to NoBGrps-1 do + ColLabels[j] := Format('B %d',[j+1]); + MatPrint(AMatrix, NoAgrps, NoBgrps, Title, RowLabels, ColLabels, NinGrp*NoSelected, AReport); + + AReport.Add(''); + AReport.Add(DIVIDER_SMALL_AUTO); + AReport.Add(''); Title := 'AC Means Table'; ColHeader := 'C Levels'; - for i := 1 to NoAGrps do + SetLength(RowLabels, NoAGrps); + SetLength(ColLabels, NoSelected); + for i := 0 to NoAGrps-1 do begin - LabelStr := format('A%d',[i-1]); - RowLabels[i-1] := LabelStr; - for j := 1 to NoSelected do - AMatrix[i-1,j-1] := ACSums[i-1,j-1] / (NinGrp * NoBGrps); + RowLabels[i] := Format('A%d',[i+1]); + for j := 0 to NoSelected-1 do + AMatrix[i, j] := ACSums[i, j] / (NInGrp * NoBGrps); end; - for j := 1 to NoSelected do - begin - LabelStr := format('C%d',[j-1]); - ColLabels[j-1] := LabelStr; - end; - MatPrint(AMatrix,NoAGrps,NoSelected,Title,RowLabels,ColLabels,NinGrp*NoBGrps, AReport); + for j := 0 to NoSelected-1 do + ColLabels[j] := Format('C%d',[j+1]); + MatPrint(AMatrix, NoAGrps, NoSelected, Title, RowLabels, ColLabels, NInGrp*NoBGrps, AReport); + + AReport.Add(DIVIDER_SMALL_AUTO); + AReport.Add(''); Title := 'BC Means Table'; ColHeader := 'C Levels'; - for i := 1 to NoBGrps do + SetLength(RowLabels, NoBGrps); + SetLength(ColLabels, NoSelected); + for i := 0 to NoBGrps-1 do begin - LabelStr := format('B%d',[i]); - RowLabels[i-1] := LabelStr; - for j := 1 to NoSelected do - AMatrix[i-1,j-1] := BCSums[i-1,j-1] / (NinGrp * NoAGrps); + RowLabels[i] := Format('B%d',[i+1]); + for j := 0 to NoSelected-1 do + AMatrix[i, j] := BCSums[i, j] / (NInGrp * NoAGrps); end; - for j := 1 to NoSelected do - begin - LabelStr := format('C%d',[j]); - ColLabels[j-1] := LabelStr; - end; - MatPrint(AMatrix,NoBGrps,NoSelected,Title,RowLabels,ColLabels,NinGrp*NoAGrps, AReport); + for j := 0 to NoSelected-1 do + ColLabels[j] := Format('C%d', [j+1]); + MatPrint(AMatrix, NoBGrps, NoSelected, Title, RowLabels, ColLabels, NInGrp*NoAGrps, AReport); FMeansReportFrame.DisplayReport(AReport); AReport.Clear; @@ -816,9 +818,11 @@ var XVector: DblDyneVec = nil; XSums: DblDyneVec = nil; DetMat: DblDyneMat = nil; - M1, M2, Sum1, C1, C2, f1, f2, chi, ProbChi, X, avgvar,avgcov : double; - ColHeader, LabelStr : string; - Title : string; + ColLabels: StrDyneVec = nil; + RowLabels: StrDyneVec = nil; + 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; errorcode : boolean = false; // to silence the compiler Det: Double = 0.0; @@ -829,12 +833,13 @@ begin SetLength(XSums, NoSelected); SetLength(DetMat, NoSelected+1, NoSelected+1); SetLength(PooledMat, NoSelected+1, NoSelected+1); + SetLength(ColLabels, NoSelected); + SetLength(RowLabels, NoSelected); for i := 0 to NoSelected-1 do begin - LabelStr := Format('C%d', [i+1]); - RowLabels[i] := LabelStr; - ColLabels[i] := LabelStr; + RowLabels[i] := Format('C%d', [i+1]); + ColLabels[i] := RowLabels[i]; for j := 0 to NoSelected-1 do PooledMat[i, j] := 0.0; end; @@ -847,7 +852,7 @@ begin begin for j := 1 to NoBGrps do 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; ColHeader := 'C Levels'; @@ -893,7 +898,7 @@ begin 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 L := 0 to NoSelected-1 do @@ -930,10 +935,10 @@ begin C1 := C1 * ( (NoAGrps * NoBGrps * (1.0 / NinGrp)) - (1.0 / (NinGrp * NoAGrps * NoBGrps))); f1 := (NoSelected * (NoSelected + 1.0) * (NoAGrps * NoBGrps - 1.0))/2.0; 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(''); - 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(''); AReport.Add(''); @@ -964,7 +969,7 @@ begin DetMat[j-1,i-1] := avgcov; end; end; - Determ(DetMat,NoSelected,NoSelected,Det,errorcode); + Determ(DetMat, NoSelected, NoSelected, Det, errorcode); if (Det > EPS) then begin N := NoAGrps * NoBGrps * NinGrp; @@ -1058,7 +1063,7 @@ const ); var serSource: TListChartSource; - i, j: Integer; + i: Integer; begin case AInteraction of AB: serSource := ListChartSource_AB; @@ -1164,9 +1169,12 @@ begin exit; end; - if CList.Items.Count = 0 then + if CList.Items.Count <= 1 then 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; exit; end;