LazStats: Minor refactoring of the Compute routine in XvsMultYUnit.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7743 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2020-10-04 22:00:46 +00:00
parent bf34c484c1
commit 4e03e81c94
2 changed files with 108 additions and 121 deletions

View File

@ -9,8 +9,7 @@ interface
uses uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
StdCtrls, Buttons, ExtCtrls, Printers, ComCtrls, StdCtrls, Buttons, ExtCtrls, Printers, ComCtrls,
MainUnit, Globals, ContextHelpUnit, DataProcs, MatrixLib, BasicStatsReportAndChartFormUnit, Globals, BasicStatsReportAndChartFormUnit, ReportFrameUnit, ChartFrameUnit;
ReportFrameUnit, ChartFrameUnit;
type type
@ -33,21 +32,24 @@ type
YOutBtn: TBitBtn; YOutBtn: TBitBtn;
VarList: TListBox; VarList: TListBox;
procedure VarListDblClick(Sender: TObject); procedure VarListDblClick(Sender: TObject);
procedure VarListSelectionChange(Sender: TObject; User: boolean); procedure VarListSelectionChange(Sender: TObject; {%H-}User: boolean);
procedure XInBtnClick(Sender: TObject); procedure XInBtnClick(Sender: TObject);
procedure XOutBtnClick(Sender: TObject); procedure XOutBtnClick(Sender: TObject);
procedure YInBtnClick(Sender: TObject); procedure YInBtnClick(Sender: TObject);
procedure YOutBtnClick(Sender: TObject); procedure YOutBtnClick(Sender: TObject);
private private
{ private declarations }
selected: IntDyneVec;
procedure PlotXY(XValues: DblDyneVec; YValues: DblDyneMat); procedure PlotXY(XValues: DblDyneVec; YValues: DblDyneMat);
procedure WriteToReport(const ASelected: IntDyneVec;
const ARowLabels, AColLabels: StrDyneVec);
protected protected
procedure AdjustConstraints; override; procedure AdjustConstraints; override;
procedure Compute; override; procedure Compute; override;
procedure UpdateBtnStates; override; procedure UpdateBtnStates; override;
public public
{ public declarations } constructor Create(AOwner: TComponent); override;
procedure Reset; override; procedure Reset; override;
end; end;
@ -61,27 +63,26 @@ implementation
uses uses
TAChartUtils, TAChartUtils,
Math, Utils; MainUnit, MatrixLib, MathUnit, GridProcs, Utils;
{ TXvsMultYForm } { TXvsMultYForm }
constructor TXvsMultYForm.Create(AOwner: TComponent);
begin
inherited;
PageControl.ActivePage := ChartPage;
end;
procedure TXvsMultYForm.Compute; procedure TXvsMultYForm.Compute;
var var
i, j, N, NoY, XCol, NoSelected: integer; i, j, N, nY, xCol, NoSelected: integer;
MinX, MaxX, MinY, MaxY: double; xValues: DblDyneVec = nil;
Title: string; yValues: DblDyneMat = nil;
RMatrix: DblDyneMat = nil;
XValues: DblDyneVec = nil;
YValues: DblDyneMat = nil;
Means: DblDyneVec = nil;
Variances: DblDyneVec = nil;
StdDevs: DblDyneVec = nil;
RowLabels: StrDyneVec = nil; RowLabels: StrDyneVec = nil;
ColLabels: StrDyneVec = nil; ColLabels: StrDyneVec = nil;
errorcode: boolean = false; selected: IntDyneVec = nil;
Ncases: integer = 0;
lReport: TStrings;
begin begin
if XEdit.Text = '' then if XEdit.Text = '' then
begin begin
@ -95,116 +96,51 @@ begin
exit; exit;
end; end;
MaxX := -Infinity; xCol := OS3MainFrm.DataGrid.Rows[0].IndexOf(Trim(XEdit.Text));
MinX := Infinity; if xCol = -1 then
MaxY := -Infinity; begin
MinY := Infinity; ErrorMsg('X variable not found.');
NoY := YBox.Items.Count; exit;
end;
nY := YBox.Items.Count;
SetLength(selected, nY + 1); // one more for the x column, needed by Correlations()
for j := 0 to nY - 1 do
selected[j] := OS3MainFrm.DataGrid.Rows[0].IndexOf(YBox.Items[j]);
selected[nY] := xCol;
NoSelected := nY + 1;
SetLength(selected, NoY + 1);
SetLength(RowLabels, NoVariables); SetLength(RowLabels, NoVariables);
SetLength(ColLabels, NoVariables); SetLength(ColLabels, NoVariables);
XCol := 0;
for i := 1 to NoVariables do
if Trim(XEdit.Text) = Trim(OS3MainFrm.DataGrid.Cells[i,0]) then
begin
XCol := i;
break;
end;
for j := 0 to NoY-1 do
begin
selected[j] := 0;
for i := 1 to NoVariables do
if Trim(YBox.Items[j]) = Trim(OS3MainFrm.DataGrid.Cells[i,0]) then
begin
selected[j] := i;
Break;
end;
end;
selected[NoY] := XCol;
NoSelected := NoY + 1;
for i := 0 to NoSelected-1 do for i := 0 to NoSelected-1 do
begin begin
RowLabels[i] := Trim(OS3MainFrm.DataGrid.Cells[selected[i],0]); RowLabels[i] := Trim(OS3MainFrm.DataGrid.Cells[selected[i],0]);
ColLabels[i] := RowLabels[i]; ColLabels[i] := RowLabels[i];
end; end;
Caption := RowLabels[0] + ' ' + RowLabels[1]; // Extract x and y values
xValues := CollectValues(OS3MainFrm.DataGrid, xCol, selected);
SetLength(yValues, nY);
for i := 0 to nY-1 do
yValues[i] := CollectValues(OS3MainFrm.DataGrid, selected[i], selected);
lReport := TStringList.Create; // Make sure that all y columns have the same length
try N := Length(yValues[0]);
SetLength(YValues, NoY, NoCases); for i := 1 to nY-1 do
SetLength(XValues, NoCases); if N <> Length(yValues[i]) then
SetLength(Means, NoSelected);
SetLength(Variances, NoSelected);
SetLength(StdDevs, NoSelected);
SetLength(RMatrix, NoSelected+1, NoSelected+1);
SetLength(selected, NoVariables+1);
for i := 0 to NoSelected - 1 do
begin begin
Means[i] := 0.0; ErrorMsg('Different count of cases.');
StdDevs[i] := 0.0; exit;
for j := 0 to NoSelected-1 do RMatrix[i,j] := 0.0;
end; end;
N := 0; // Print out correclations, means, etc to report frame
// index rule: array index: i, grid-related index: i+1 WriteToReport(selected, RowLabels, ColLabels);
for i := 0 to NoCases-1 do
begin
if not GoodRecord(i+1, NoSelected, selected) then continue;
inc(N);
XValues[i] := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[XCol, i+1]));
MaxX := Max(MaxX, XValues[i]);
MinX := Min(MinX, XValues[i]);
for j := 0 to NoY - 1 do
begin
// Unlike other usages of 2-D arrays in LazStats the 1st index is the
// curve index while the 2nd index is the point index here.
YValues[j, i] := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[selected[j], i+1]));
MaxY := Max(MaxY, YValues[j, i]);
MinY := Min(MinY, YValues[j, i]);
end;
end;
// get descriptive data
lReport.Add('X VERSUS MULTIPLE Y VALUES PLOT');
lReport.Add('');
Correlations(NoSelected,selected,RMatrix,Means,Variances,StdDevs,errorcode,Ncases);
//N := Ncases;
Title := 'CORRELATIONS';
MatPrint(RMatrix, NoSelected, NoSelected, Title, RowLabels, ColLabels, N, lReport);
Title := 'Means';
DynVectorPrint(Means, NoSelected, Title, RowLabels, N, lReport);
Title := 'Variances';
DynVectorPrint(Variances, NoSelected, Title, RowLabels, N, lReport);
Title := 'Standard Deviations';
DynVectorPrint(StdDevs, NoSelected, Title, RowLabels, N, lReport);
FReportFrame.DisplayReport(lReport);
// Sort on X // Sort on X
SortOnX(XValues, YValues); SortOnX(XValues, YValues);
// Plot x vs multiple y // Plot x vs multiple y
PlotXY(XValues, YValues); PlotXY(XValues, YValues);
finally
lReport.Free;
RMatrix := nil;
StdDevs := nil;
Variances := nil;
Means := nil;
XValues := nil;
YValues := nil;
selected := nil;
ColLabels := nil;
RowLabels := nil;
end;
end; end;
@ -226,14 +162,13 @@ end;
// first one, the point index is the second one. // first one, the point index is the second one.
procedure TXvsMultYForm.PlotXY(XValues: DblDyneVec; YValues: DblDyneMat); procedure TXvsMultYForm.PlotXY(XValues: DblDyneVec; YValues: DblDyneMat);
var var
N, Ny, Nc: Integer; Ny, Nc: Integer;
j: Integer; j: Integer;
pt: TPlotType; pt: TPlotType;
begin begin
// Preparations // Preparations
if LinesBox.Checked then pt := ptLinesAndSymbols else pt := ptSymbols; if LinesBox.Checked then pt := ptLinesAndSymbols else pt := ptSymbols;
N := Length(XValues);
Ny := Length(YValues); Ny := Length(YValues);
Nc := Length(DATA_COLORS); Nc := Length(DATA_COLORS);
@ -303,6 +238,59 @@ begin
end; end;
procedure TXvsMultYForm.WriteToReport(const ASelected: IntDyneVec;
const ARowLabels, AColLabels: StrDyneVec);
var
lReport: TStrings;
i: Integer;
means: DblDyneVec = nil;
variances: DblDyneVec = nil;
stdDevs: DblDyneVec = nil;
RMatrix: DblDyneMat = nil;
nSelected: Integer = 0;
nCases: Integer = 0;
error: Boolean = false;
begin
lReport := TStringList.Create;
try
// get descriptive data
lReport.Add('X VERSUS MULTIPLE Y VALUES PLOT');
lReport.Add('');
nSelected := Length(ASelected);
SetLength(means, nSelected);
SetLength(variances, nSelected);
SetLength(stdDevs, nSelected);
SetLength(RMatrix, nSelected+1, nSelected+1);
Correlations(nSelected, ASelected, RMatrix, means, variances, stdDevs, error, nCases);
if error then
begin
lReport.Add('ERROR: zero variance detected.');
exit;
end;
//DynVectorPrint(means, nSelected, 'MEANS', ARowLabels, nSelected, lReport);
//DynVectorPrint(variances, nSelected, 'VARIANCES', ARowLabels, nCases, lReport);
//DynVectorPrint(stdDevs, nSelected, 'STANDARD DEVIATIONS', ARowLabels, nCases, lReport);
lReport.Add( ' Variable Mean Variance Std.Dev. ');
lReport.Add( '--------------- --------------- --------------- ---------------');
for i := 0 to nSelected-1 do
lReport.Add('%-15s %15.3f %15.3f %15.3f', [ARowLabels[i], means[i], variances[i], stdDevs[i]]);
lReport.Add('');
lReport.Add('');
MatPrint(RMatrix, nSelected, nSelected, 'CORRELATIONS', ARowLabels, AColLabels, nCases, lReport);
FReportFrame.DisplayReport(lReport);
finally
lReport.Free;
end;
end;
procedure TXvsMultYForm.VarListSelectionChange(Sender: TObject; User: boolean); procedure TXvsMultYForm.VarListSelectionChange(Sender: TObject; User: boolean);
begin begin
UpdateBtnStates; UpdateBtnStates;

View File

@ -114,8 +114,7 @@ VAR
ColNoSelected: IntDyneVec; ColNoSelected: IntDyneVec;
dblvalue: double; dblvalue: double;
DataGrid: DblDyneMat; DataGrid: DblDyneMat;
RowLabels: StrDyneVec = nil; RowLabels, ColLabels: StrDyneVec;
ColLabels: StrDyneVec = nil;
errorcode: boolean; errorcode: boolean;
lReport: TStrings; lReport: TStrings;
begin begin