LazStats: Refactor tTestUnit.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7845 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2020-11-05 13:38:59 +00:00
parent ff2834b9fe
commit 7ea76148e5
4 changed files with 300 additions and 218 deletions

View File

@ -1,7 +1,7 @@
inherited TtestForm: TTtestForm
Left = 947
Left = 740
Height = 546
Top = 176
Top = 175
Width = 889
HelpType = htKeyword
HelpKeyword = 'html/tTests.htm'
@ -40,7 +40,7 @@ inherited TtestForm: TTtestForm
end
object Label1: TLabel[5]
AnchorSideLeft.Control = ParamsPanel
AnchorSideTop.Control = CInterval
AnchorSideTop.Control = CIntervalEdit
AnchorSideTop.Side = asrCenter
Left = 0
Height = 15
@ -49,7 +49,7 @@ inherited TtestForm: TTtestForm
Caption = 'Percent Confidence Interval:'
ParentColor = False
end
object CInterval: TEdit[6]
object CIntervalEdit: TEdit[6]
AnchorSideLeft.Control = Label1
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = TailCombo
@ -76,12 +76,12 @@ inherited TtestForm: TTtestForm
Height = 335
Top = 154
Width = 368
PageIndex = 0
PageIndex = 1
Anchors = [akTop, akLeft, akRight, akBottom]
TabOrder = 4
object Page1: TPage
object Mean1Label: TLabel
AnchorSideLeft.Control = Mean1
AnchorSideLeft.Control = Mean1Edit
AnchorSideLeft.Side = asrCenter
AnchorSideTop.Control = Page1
Left = 83
@ -93,7 +93,7 @@ inherited TtestForm: TTtestForm
ParentColor = False
end
object Mean2Label: TLabel
AnchorSideTop.Control = Mean1
AnchorSideTop.Control = Mean1Edit
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = Mean1Label
AnchorSideRight.Side = asrBottom
@ -107,7 +107,7 @@ inherited TtestForm: TTtestForm
ParentColor = False
end
object SD1Label: TLabel
AnchorSideLeft.Control = SD1
AnchorSideLeft.Control = SD1Edit
AnchorSideLeft.Side = asrCenter
AnchorSideTop.Control = Mean1Label
Left = 157
@ -119,7 +119,7 @@ inherited TtestForm: TTtestForm
ParentColor = False
end
object SD2Label: TLabel
AnchorSideLeft.Control = SD2
AnchorSideLeft.Control = SD2Edit
AnchorSideLeft.Side = asrCenter
AnchorSideTop.Control = Mean2Label
Left = 157
@ -131,7 +131,7 @@ inherited TtestForm: TTtestForm
ParentColor = False
end
object SampSize1Label: TLabel
AnchorSideLeft.Control = N1
AnchorSideLeft.Control = N1Edit
AnchorSideLeft.Side = asrCenter
AnchorSideTop.Control = Mean1Label
Left = 231
@ -143,7 +143,7 @@ inherited TtestForm: TTtestForm
ParentColor = False
end
object SampSize2Label: TLabel
AnchorSideLeft.Control = N2
AnchorSideLeft.Control = N2Edit
AnchorSideLeft.Side = asrCenter
AnchorSideTop.Control = Mean2Label
Left = 231
@ -155,9 +155,9 @@ inherited TtestForm: TTtestForm
ParentColor = False
end
object Cor12Label: TLabel
AnchorSideLeft.Control = Cor12
AnchorSideLeft.Control = Cor12Edit
AnchorSideLeft.Side = asrCenter
AnchorSideTop.Control = SD2
AnchorSideTop.Control = SD2Edit
AnchorSideTop.Side = asrBottom
Left = 111
Height = 15
@ -168,11 +168,11 @@ inherited TtestForm: TTtestForm
Caption = 'Correlation Between Scores:'
ParentColor = False
end
object Mean1: TEdit
object Mean1Edit: TEdit
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = Mean1Label
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = SD1
AnchorSideRight.Control = SD1Edit
Left = 77
Height = 23
Top = 49
@ -183,13 +183,13 @@ inherited TtestForm: TTtestForm
BorderSpacing.Top = 2
BorderSpacing.Right = 32
TabOrder = 0
Text = 'Mean1'
Text = 'Mean1Edit'
end
object Mean2: TEdit
AnchorSideLeft.Control = Mean1
object Mean2Edit: TEdit
AnchorSideLeft.Control = Mean1Edit
AnchorSideTop.Control = Mean2Label
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = Mean1
AnchorSideRight.Control = Mean1Edit
AnchorSideRight.Side = asrBottom
Left = 77
Height = 23
@ -199,12 +199,12 @@ inherited TtestForm: TTtestForm
Anchors = [akTop, akRight]
BorderSpacing.Top = 2
TabOrder = 1
Text = 'Mean2'
Text = 'Mean2Edit'
end
object SD1: TEdit
object SD1Edit: TEdit
AnchorSideLeft.Control = Page1
AnchorSideLeft.Side = asrCenter
AnchorSideTop.Control = Mean1
AnchorSideTop.Control = Mean1Edit
Left = 159
Height = 23
Top = 49
@ -212,12 +212,12 @@ inherited TtestForm: TTtestForm
Alignment = taRightJustify
BorderSpacing.Left = 6
TabOrder = 2
Text = 'SD1'
Text = 'SD1Edit'
end
object SD2: TEdit
AnchorSideLeft.Control = SD1
AnchorSideTop.Control = Mean2
AnchorSideRight.Control = SD1
object SD2Edit: TEdit
AnchorSideLeft.Control = SD1Edit
AnchorSideTop.Control = Mean2Edit
AnchorSideRight.Control = SD1Edit
AnchorSideRight.Side = asrBottom
Left = 159
Height = 23
@ -226,12 +226,12 @@ inherited TtestForm: TTtestForm
Alignment = taRightJustify
Anchors = [akTop, akRight]
TabOrder = 3
Text = 'SD2'
Text = 'SD2Edit'
end
object N1: TEdit
AnchorSideLeft.Control = SD1
object N1Edit: TEdit
AnchorSideLeft.Control = SD1Edit
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = Mean1
AnchorSideTop.Control = Mean1Edit
Left = 241
Height = 23
Top = 49
@ -239,12 +239,12 @@ inherited TtestForm: TTtestForm
Alignment = taRightJustify
BorderSpacing.Left = 32
TabOrder = 4
Text = 'N1'
Text = 'N1Edit'
end
object N2: TEdit
AnchorSideLeft.Control = N1
AnchorSideTop.Control = Mean2
AnchorSideRight.Control = N1
object N2Edit: TEdit
AnchorSideLeft.Control = N1Edit
AnchorSideTop.Control = Mean2Edit
AnchorSideRight.Control = N1Edit
AnchorSideRight.Side = asrBottom
Left = 241
Height = 23
@ -253,10 +253,10 @@ inherited TtestForm: TTtestForm
Alignment = taRightJustify
Anchors = [akTop, akRight]
TabOrder = 5
Text = 'N2'
Text = 'N2Edit'
end
object Cor12: TEdit
AnchorSideLeft.Control = SD1
object Cor12Edit: TEdit
AnchorSideLeft.Control = SD1Edit
AnchorSideLeft.Side = asrCenter
AnchorSideTop.Control = Cor12Label
AnchorSideTop.Side = asrBottom
@ -267,7 +267,7 @@ inherited TtestForm: TTtestForm
Alignment = taRightJustify
BorderSpacing.Top = 2
TabOrder = 6
Text = 'Cor12'
Text = 'Cor12Edit'
end
end
object Page2: TPage
@ -277,8 +277,8 @@ inherited TtestForm: TTtestForm
Left = 0
Height = 15
Top = 0
Width = 83
Caption = 'Select Variables:'
Width = 97
Caption = 'Available Variables'
ParentColor = False
end
object VarList: TListBox
@ -307,12 +307,12 @@ inherited TtestForm: TTtestForm
Left = 203
Height = 15
Top = 25
Width = 62
Width = 59
Alignment = taRightJustify
Anchors = [akLeft, akBottom]
BorderSpacing.Right = 8
BorderSpacing.Bottom = 2
Caption = '1st Variable:'
Caption = '1st Variable'
ParentColor = False
end
object Var2Label: TLabel
@ -321,11 +321,11 @@ inherited TtestForm: TTtestForm
Left = 203
Height = 15
Top = 101
Width = 67
Width = 64
Alignment = taRightJustify
Anchors = [akLeft, akBottom]
BorderSpacing.Right = 8
Caption = '2nd Variable:'
Caption = '2nd Variable'
ParentColor = False
end
object GrpLabel: TLabel
@ -335,12 +335,12 @@ inherited TtestForm: TTtestForm
Left = 203
Height = 15
Top = 177
Width = 67
Width = 77
Alignment = taRightJustify
Anchors = [akLeft, akBottom]
BorderSpacing.Right = 8
BorderSpacing.Bottom = 2
Caption = 'Group Code:'
Caption = 'Group Variable'
ParentColor = False
end
object Bevel5: TBevel
@ -651,7 +651,7 @@ inherited TtestForm: TTtestForm
end
object Bevel3: TBevel[10]
AnchorSideLeft.Control = ParamsPanel
AnchorSideTop.Control = CInterval
AnchorSideTop.Control = CIntervalEdit
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = ParamsPanel
AnchorSideRight.Side = asrBottom

View File

@ -31,8 +31,8 @@ type
Page1: TPage;
Page2: TPage;
Cor12Label: TLabel;
Cor12: TEdit;
CInterval: TEdit;
Cor12Edit: TEdit;
CIntervalEdit: TEdit;
GrpEdit: TEdit;
Label1: TLabel;
Var1In: TBitBtn;
@ -44,16 +44,16 @@ type
Var2Label: TLabel;
VarList: TListBox;
SelVarLabel: TLabel;
N2: TEdit;
N1: TEdit;
N2Edit: TEdit;
N1Edit: TEdit;
SampSize2Label: TLabel;
SampSize1Label: TLabel;
SD2: TEdit;
SD1: TEdit;
SD2Edit: TEdit;
SD1Edit: TEdit;
SD2Label: TLabel;
SD1Label: TLabel;
Mean2: TEdit;
Mean1: TEdit;
Mean2Edit: TEdit;
Mean1Edit: TEdit;
Mean2Label: TLabel;
Mean1Label: TLabel;
DataEntryGroup: TRadioGroup;
@ -76,6 +76,12 @@ type
independent: boolean;
griddata: boolean;
function Eval_DependentGridData(out AMean1, AMean2, AVariance1, AVariance2,
AStdDev1, AStdDev2, ACovar12, r12: Double; out ANumCases1, ANumCases2: Integer): Boolean;
function Eval_IndependentGridData(out AMean1, AMean2, AVariance1, AVariance2,
AStdDev1, AStdDev2: Double; out ANumCases1, ANumCases2: Integer;
out ALabel1Str, ALabel2Str: String): Boolean;
protected
procedure AdjustConstraints; override;
procedure Compute; override;
@ -97,7 +103,7 @@ implementation
uses
Math,
MathUnit, GridProcs;
Utils, MathUnit, MatrixUnit, GridProcs;
{ TTtestForm }
@ -105,7 +111,7 @@ uses
constructor TTtestForm.Create(AOwner: TComponent);
begin
inherited;
CInterval.Text := FormatFloat('0.0', DEFAULT_CONFIDENCE_LEVEL_PERCENT);
CIntervalEdit.Text := FormatFloat('0.0', DEFAULT_CONFIDENCE_LEVEL_PERCENT);
end;
@ -119,7 +125,7 @@ begin
);
ParamsPanel.Constraints.MinHeight := DataEntryGroup.Height +
TailCombo.BorderSpacing.Top + TailCombo.Height +
CInterval.BorderSpacing.Top + CInterval.Height + CInterval.BorderSpacing.Bottom +
CIntervalEdit.BorderSpacing.Top + CIntervalEdit.Height + CIntervalEdit.BorderSpacing.Bottom +
Bevel3.Height + Bevel3.BorderSpacing.Bottom +
GrpIn.Top + GroupCodeGroup.Height +
ButtonBevel.Height + CloseBtn.BorderSpacing.Top + CloseBtn.Height;
@ -128,154 +134,58 @@ end;
procedure TTtestForm.Compute;
var
M1, M2, Dif, stddev1, stddev2, r12, stderr1, stderr2: double;
mean1, mean2, Dif, stddev1, stddev2, r12, stderr1, stderr2: double;
tequal, tunequal, cov12, lowci, hici, F, Fp, df1, df2: double;
tprobability, value1, value2: double;
variance1, variance2, pooled, sedif, df, ConfInt, tconfint: double;
i, nCases1, nCases2: integer;
group, min, max: integer;
minf, maxf: Double;
ColNoSelected: IntDyneVec = nil;
label1Str, label2Str: string;
lReport: TStrings;
begin
SetLength(ColNoSelected,NoVariables);
ncases1 := 0;
ncases2 := 0;
variance1 := 0.0;
variance2 := 0.0;
M1 := 0.0;
M2 := 0.0;
Dif := 0.0;
r12 := 0.0;
stddev1 := 0.0;
stddev2 := 0.0;
ConfInt := (100.0 - StrToFloat(CInterval.Text)) / 2.0 ;
ConfInt := (100.0 - StrToFloat(CIntervalEdit.Text)) / 2.0 ;
ConfInt := (100.0 - ConfInt) / 100.0; // one tail
if independent then
Var2Edit.Text := GrpEdit.Text;
// data read from grid
if griddata then
begin
SetLength(ColNoSelected, 2);
ColNoSelected[0] := GetVariableIndex(OS3MainFrm.DataGrid, Var1Edit.Text);
ColNoSelected[1] := GetVariableIndex(OS3MainFrm.DataGrid, Var2Edit.Text);
ncases1 := 0;
ncases2 := 0;
M1 := 0.0;
M2 := 0.0;
variance1 := 0.0;
variance2 := 0.0;
r12 := 0.0;
if not independent then // correlated data
begin
for i := 1 to NoCases do
begin
if not GoodRecord(OS3MainFrm.DataGrid, i, ColNoSelected) then continue;
ncases1 := ncases1 + 1;
value1 := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[ColNoSelected[0], i]));
value2 := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[ColNoSelected[1], i]));
M1 := M1 + value1;
M2 := M2 + value2;
variance1 := variance1 + value1 * value1;
variance2 := variance2 + value2 * value2;
r12 := r12 + value1 * value2;
end;
ncases2 := ncases1;
variance1 := variance1 - (M1 * M1 / ncases1);
variance1 := variance1 / (ncases1 - 1);
stddev1 := sqrt(variance1);
variance2 := variance2 - (M2 * M2 / ncases2);
variance2 := variance2 / (ncases2 - 1);
stddev2 := sqrt(variance2);
r12 := r12 - (M1 * M2 / ncases1);
r12 := r12 / (ncases1 - 1);
cov12 := r12;
r12 := r12 / (stddev1 * stddev2);
M1 := M1 / ncases1;
M2 := M2 / ncases2;
Dif := M1 - M2;
end; //if not independent
// Read and analyze data from grid
if independent then
begin
if GroupCodeChk.Checked then
begin
min := StrToInt(Grp1CodeEdit.Text);
max := StrToInt(Grp2CodeEdit.Text);
if not Eval_IndependentGridData(
mean1, mean2, variance1, variance2, stddev1, stddev2,
nCases1, nCases2, Label1Str, Label2Str)
then
exit;
end else
begin
min := MaxInt;
max := min;
if not Eval_DependentGridData(
mean1, mean2, variance1, variance2, stddev1, stddev2,
cov12, r12, nCases1, nCases2)
then
exit;
end;
for i := 1 to NoCases do
end else
begin
if not GoodRecord(OS3MainFrm.DataGrid, i, ColNoSelected) then continue;
group := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[ColNoSelected[1], i])));
if not GroupCodeChk.Checked then
begin
if group < min then min := group;
if group > max then max := group;
end;
end;
for i := 1 to NoCases do
begin
if not GoodRecord(OS3MainFrm.DataGrid, i, ColNoSelected) then continue;
value1 := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[ColNoSelected[0], i]));
value2 := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[ColNoSelected[1], i]));
group := round(value2);
if group = min then
begin
M1 := M1 + value1;
variance1 := variance1 + (value1 * value1);
ncases1 := ncases1 + 1;
end else if group = max then
begin
M2 := M2 + value1;
variance2 := variance2 + (value1 * value1);
ncases2 := Ncases2 + 1;
end;
end; // next case
variance1 := variance1 - ((M1 * M1) / ncases1);
variance1 := variance1 / (ncases1 - 1);
stddev1 := sqrt(variance1);
variance2 := variance2 - ((M2 * M2) / ncases2);
variance2 := variance2 / (ncases2 - 1);
stddev2 := sqrt(variance2);
M1 := M1 / ncases1;
M2 := M2 / ncases2;
Dif := M1 - M2;
Label1Str := format('Group %d',[min]);
Label2Str := format('Group %d',[max]);
end; // if independent data
end; // if reading grid data
if not griddata then // data read from form
begin
M1 := StrToFloat(Mean1.Text);
M2 := StrToFloat(Mean2.Text);
stddev1 := StrToFloat(SD1.Text);
stddev2 := StrToFloat(SD2.Text);
ncases1 := round(StrToFloat(N1.Text));
ncases2 := round(StrToFloat(N2.Text));
// Read data from form
mean1 := StrToFloat(mean1Edit.Text);
mean2 := StrToFloat(mean2Edit.Text);
stddev1 := StrToFloat(SD1Edit.Text);
stddev2 := StrToFloat(SD2Edit.Text);
ncases1 := round(StrToFloat(N1Edit.Text));
ncases2 := round(StrToFloat(N2Edit.Text));
variance1 := stddev1 * stddev1;
variance2 := stddev2 * stddev2;
Label1Str := 'Group 1';
Label2Str := 'Group 2';
Dif := M1 - M2;
if not independent then
begin
r12 := StrToFloat(Cor12.Text);
r12 := StrToFloat(Cor12Edit.Text);
cov12 := r12 * stddev1 * stddev2;
end;
end;
dif := mean1 - mean2;
// Initialize output form
lReport := TStringList.Create;
@ -289,8 +199,8 @@ begin
stderr1 := sqrt(variance1 / ncases1);
Stderr2 := sqrt(variance2 / ncases2);
lReport.Add('Variable Mean Variance Std.Dev. S.E.Mean N');
lReport.Add('%-10s%8.2f %8.2f %8.2f %8.2f %d', [Label1Str, M1, variance1, stddev1, stderr1, ncases1]);
lReport.Add('%-10s%8.2f %8.2f %8.2f %8.2f %d', [Label2Str, M2, variance2, stddev2, stderr2, ncases2]);
lReport.Add('%-10s%8.2f %8.2f %8.2f %8.2f %d', [Label1Str, mean1, variance1, stddev1, stderr1, ncases1]);
lReport.Add('%-10s%8.2f %8.2f %8.2f %8.2f %d', [Label2Str, mean2, variance2, stddev2, stderr2, ncases2]);
lReport.Add('');
pooled := ((ncases1-1) * variance1) + ((ncases2-1) * variance2);
@ -349,8 +259,8 @@ begin
stderr1 := sqrt(variance1 / ncases1);
Stderr2 := sqrt(variance2 / ncases2);
lReport.Add('Variable Mean Variance Std.Dev. S.E.Mean N');
lReport.Add('%-10s%8.2f %8.2f %8.2f %8.2f %d', [Label1Str, M1, variance1, stddev1, stderr1, ncases1]);
lReport.Add('%-10s%8.2f %8.2f %8.2f %8.2f %d', [Label2Str,M2, variance2, stddev2, stderr2, ncases2]);
lReport.Add('%-10s%8.2f %8.2f %8.2f %8.2f %d', [Label1Str, mean1, variance1, stddev1, stderr1, ncases1]);
lReport.Add('%-10s%8.2f %8.2f %8.2f %8.2f %d', [Label2Str, mean2, variance2, stddev2, stderr2, ncases2]);
lReport.Add('');
sedif := variance1 + variance2 - (2.0 * cov12);
sedif := sqrt(sedif / ncases1);
@ -399,6 +309,9 @@ begin
Var2Edit.Visible := false;
end;
GroupCodeChk.Visible := independent;
GroupCodeGroup.Visible := independent;
Var2Label.Visible := Var2Edit.Visible;
Var2In.Visible := Var2Edit.Visible;
Var2Out.Visible := Var2Edit.Visible;
@ -427,11 +340,109 @@ begin
Var2In.Visible := not independent;
Var2Out.Visible := not independent;
Cor12.Visible := not independent;
Cor12Edit.Visible := not independent;
Cor12Label.Visible := not independent;
end;
function TtTestForm.Eval_DependentGridData(out AMean1, AMean2,
AVariance1, AVariance2, AStdDev1, AStdDev2, ACovar12, r12: Double;
out ANumCases1, ANumCases2: Integer): Boolean;
var
colNoSelected: IntDyneVec = nil;
values1: DblDyneVec = nil;
values2: DblDyneVec = nil;
begin
SetLength(colNoSelected, 2);
colNoSelected[0] := GetVariableIndex(OS3MainFrm.DataGrid, Var1Edit.Text);
colNoSelected[1] := GetVariableIndex(OS3MainFrm.DataGrid, Var2Edit.Text);
values1 := CollectVecValues(OS3MainFrm.DataGrid, colNoSelected[0], colNoSelected);
values2 := CollectVecValues(OS3MainFrm.DataGrid, colNoSelected[1], colNoSelected);
ANumCases1 := Length(values1);
ANumCases2 := Length(values2);
if ANumCases1 <> ANumCases2 then
begin
ErrorMsg('Both variables must have the same count of cases.');
Result := false;
exit;
end;
if ANumCases1 < 2 then
begin
ErrorMsg('There must be at least two cases.');
Result := false;
exit;
end;
VecMeanVarStdDev(values1, AMean1, AVariance1, AStdDev1);
VecMeanVarStdDev(values2, AMean2, AVariance2, AStdDev2);
ACovar12 := (values1 - AMean1) * (values2 - AMean2) / (ANumCases1-1);
r12 := ACovar12 / (AStdDev1 * AStdDev2);
Result := true;
end;
function TtTestForm.Eval_IndependentGridData(out AMean1, AMean2,
AVariance1, AVariance2, AStdDev1, AStdDev2: Double;
out ANumCases1, ANumCases2: Integer; out ALabel1Str, ALabel2Str: String): Boolean;
var
colNoSelected: IntDyneVec = nil;
values1: DblDyneVec = nil;
values2: DblDyneVec = nil;
grp1, grp2: Integer;
minf, maxf: Double;
begin
SetLength(colNoSelected, 2);
colNoSelected[0] := GetVariableIndex(OS3MainFrm.DataGrid, Var1Edit.Text);
colNoSelected[1] := GetVariableIndex(OS3MainFrm.DataGrid, GrpEdit.Text);
if GroupCodeChk.Checked then
begin
grp1 := StrToInt(Grp1CodeEdit.Text);
grp2 := StrToInt(Grp2CodeEdit.Text);
end else
begin
GetMinMax(OS3MainFrm.DataGrid, colNoSelected[1], colNoSelected, minf, maxf);
grp1 := round(minf);
grp2 := round(maxf);
end;
// Values in group with code given by grp1
values1 := CollectFilteredVecValues(OS3MainFrm.DataGrid, colNoSelected[0], colNoSelected[1], grp1, colNoSelected);
// Values in group with code given by grp2
values2 := CollectFilteredVecValues(OS3MainFrm.DataGrid, colNoSelected[0], colNoSelected[1], grp2, colNoSelected);
ANumCases1 := Length(values1);
ANumCases2 := Length(values2);
if ANumCases1 <> ANumCases2 then
begin
ErrorMsg('Both variables must have the same count of cases.');
Result := false;
exit;
end;
if ANumCases1 < 2 then begin
ErrorMsg('There must be at least 2 cases.');
Result := false;
exit;
end;
VecMeanVarStdDev(values1, AMean1, AVariance1, AStdDev1);
VecMeanVarStdDev(values2, AMean2, AVariance2, AStdDev2);
ALabel1Str := format('Group %d', [grp1]);
ALabel2Str := format('Group %d', [grp2]);
Result := true;
end;
procedure TTtestForm.GroupCodeChkChange(Sender: TObject);
begin
Grp1CodeEdit.Enabled := GroupCodeChk.Checked;
@ -482,13 +493,13 @@ begin
VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]);
Var1Edit.Clear;
Var2Edit.Clear;
Mean1.Clear;
Mean2.Clear;
SD1.Clear;
SD2.Clear;
N1.Clear;
N2.Clear;
Cor12.Clear;
Mean1Edit.Clear;
Mean2Edit.Clear;
SD1Edit.Clear;
SD2Edit.Clear;
N1Edit.Clear;
N2Edit.Clear;
Cor12Edit.Clear;
GroupCodeChk.Checked := false;
GrpEdit.Clear;
Grp1CodeEdit.Clear;
@ -524,39 +535,39 @@ begin
AMsg := '';
if Notebook.PageIndex = 0 then
begin
if (Mean1.Text = '') or not TryStrToFloat(Mean1.Text, x) then
if (Mean1Edit.Text = '') or not TryStrToFloat(Mean1Edit.Text, x) then
begin
AControl := Mean1;
AControl := Mean1Edit;
AMsg := 'Invalid input for the mean of sample 1';
exit;
end;
if (SD1.Text = '') or not TryStrToFloat(SD1.Text, x) or (x <= 0) then
if (SD1Edit.Text = '') or not TryStrToFloat(SD1Edit.Text, x) or (x <= 0) then
begin
AControl := SD1;
AControl := SD1Edit;
AMsg := 'Invald input for the standard deviation of sample 1';
exit;
end;
if (N1.Text = '') or not TryStrToInt(N1.Text, n) or (n <= 0) then
if (N1Edit.Text = '') or not TryStrToInt(N1Edit.Text, n) or (n <= 0) then
begin
AControl := N1;
AControl := N1Edit;
AMsg := 'Invald input for the size of sample 1';
exit;
end;
if (Mean2.Text = '') or not TryStrToFloat(Mean2.Text, x) then
if (Mean2Edit.Text = '') or not TryStrToFloat(Mean2Edit.Text, x) then
begin
AControl := Mean2;
AControl := Mean2Edit;
AMsg := 'Invalid input for the mean of sample 2';
exit;
end;
if (SD2.Text = '') or not TryStrToFloat(SD2.Text, x) or (x <= 0) then
if (SD2Edit.Text = '') or not TryStrToFloat(SD2Edit.Text, x) or (x <= 0) then
begin
AControl := SD2;
AControl := SD2Edit;
AMsg := 'Invald input for the standard deviation of sample 2';
exit;
end;
if (N2.Text = '') or not TryStrToInt(N2.Text, n) or (n <= 0) then
if (N2Edit.Text = '') or not TryStrToInt(N2Edit.Text, n) or (n <= 0) then
begin
AControl := N2;
AControl := N2Edit;
AMsg := 'Invald input for the size of sample 2';
exit;
end;
@ -581,19 +592,24 @@ begin
AMsg := 'Group variable not specified.';
exit;
end;
if Grp1CodeEdit.Visible and ((Grp1CodeEdit.Text = '') or not TryStrToInt(Grp1CodeEdit.Text, n))then
if GroupCodeChk.Checked then
begin
if Grp1CodeEdit.Visible and
((Grp1CodeEdit.Text = '') or not TryStrToInt(Grp1CodeEdit.Text, n)) then
begin
AControl := Grp1CodeEdit;
AMsg := 'Code for group 1 missing.';
exit;
end;
if Grp2CodeEdit.Visible and ((Grp2CodeEdit.Text = '') or not TryStrToInt(Grp2CodeEdit.Text, n))then
if Grp2CodeEdit.Visible and
((Grp2CodeEdit.Text = '') or not TryStrToInt(Grp2CodeEdit.Text, n))then
begin
AControl := Grp2CodeEdit;
AMsg := 'Code for group 2 missing.';
exit;
end;
end;
end;
Result := true;
end;

View File

@ -11,6 +11,9 @@ uses
function CollectVecValues(AGrid: TStringGrid; AColIndex: Integer;
AColCheck: IntDyneVec = nil): DblDyneVec;
function CollectFilteredVecValues(AGrid: TStringGrid; AColIndex, AFilterColIndex: Integer;
AcceptValue: Double; AColCheck: IntDyneVec = nil): DblDyneVec;
function CollectMatValues(AGrid: TStringGrid; AColIndices: IntDyneVec): DblDyneMat;
procedure GetMinMax(AGrid: TStringGrid; AColIndex: Integer;
@ -73,6 +76,43 @@ begin
end;
{ Extracts the grid values from the column with index AColIndex, but only those
for which the value in the same row, but column AFilterCalIndex matches the
AcceptValue }
function CollectFilteredVecValues(AGrid: TStringGrid; AColIndex, AFilterColIndex: Integer;
AcceptValue: Double; AColCheck: IntDyneVec = nil): DblDyneVec;
var
row, n: Integer;
val1, val2: Double;
begin
Result := nil;
SetLength(Result, AGrid.RowCount);
n := 0;
for row := 1 to AGrid.RowCount-1 do
begin
if Length(AColCheck) = 0 then
begin
if not ValidValue(AGrid, row, AColIndex) then continue;
if not ValidValue(AGrid, row, AFilterColIndex) then continue;
end else
if not GoodRecord(AGrid, row, AColCheck) then continue;
if not TryStrToFloat(trim(AGrid.Cells[AColIndex, row]), val1) then
raise ELazStats.CreateFmt('Non-numeric string "%s" in column %d, row %d',
[AGrid.Cells[AColIndex, row]]);
if not TryStrToFloat(trim(AGrid.Cells[AFilterColIndex, row]), val2) then
raise ELazStats.CreateFmt('Non-numeric string "%s" in column %d, row %d',
[AGrid.Cells[AFilterColIndex, row]]);
if val2 = AcceptValue then
begin
Result[n] := val1;
inc(n);
end;
end;
SetLength(Result, n);
end;
{ Extracts the grid values from the columns with indices given by AColIndices
and puts them into the columns of the result matrix.
This means: The result matrix contains the variables as columns and the

View File

@ -21,7 +21,9 @@ type
// Vectors
operator + (A, B: TDblVector): TDblVector;
operator + (A: TDblVector; b: double): TDblVector;
operator - (A, B: TDblVector): TDblVector;
operator - (A: TDblVector; b: double): TDblVector;
operator * (A, B: TDblVector): Double;
operator * (A: TDblVector; b: Double): TDblVector;
operator * (a: Double; B: TDblVector): TDblVector;
@ -129,6 +131,18 @@ begin
end;
operator + (A: TDblVector; b: double): TDblVector;
var
i, n: Integer;
begin
Result := nil;
n := Length(A);
Setlength(Result, n);
for i := 0 to n-1 do
Result[i] := A[i] + b;
end;
operator - (A, B: TDblVector): TDblVector;
var
i, n: Integer;
@ -141,6 +155,18 @@ begin
end;
operator - (A: TDblVector; b: double): TDblVector;
var
i, n: Integer;
begin
Result := nil;
n := Length(A);
Setlength(Result, n);
for i := 0 to n-1 do
Result[i] := A[i] - b;
end;
// Vector dot product
operator * (A, B: TDblVector): Double;
var