Files
lazarus-ccr/applications/lazstats/source/forms/analysis/nonparametric/runstestunit.pas

272 lines
6.1 KiB
ObjectPascal

// File for testing: RunTest.laz, use VAR1
unit RunsTestUnit;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
StdCtrls, Buttons, ExtCtrls,
MainUnit, Globals, BasicStatsReportFormUnit;
type
{ TRunsTestForm }
TRunsTestForm = class(TBasicStatsReportForm)
Bevel1: TBevel;
Bevel2: TBevel;
InBtn: TBitBtn;
OutBtn: TBitBtn;
TestVarEdit: TEdit;
Label1: TLabel;
Label2: TLabel;
VarList: TListBox;
procedure InBtnClick(Sender: TObject);
procedure OutBtnClick(Sender: TObject);
procedure VarListDblClick(Sender: TObject);
procedure VarListSelectionChange(Sender: TObject; {%H-}User: boolean);
private
protected
procedure AdjustConstraints; override;
procedure Compute; override;
procedure UpdateBtnStates; override;
public
{ public declarations }
procedure Reset; override;
end;
var
RunsTestForm: TRunsTestForm;
implementation
{$R *.lfm}
uses
Math,
Utils, GridProcs, MatrixUnit;
{ TRunsTestForm }
procedure TRunsTestForm.AdjustConstraints;
begin
inherited;
ParamsPanel.Constraints.MinWidth := 4*CloseBtn.Width + 3*CloseBtn.BorderSpacing.Left;
ParamsPanel.Constraints.MinHeight := OutBtn.Top + OutBtn.Height +
ButtonBevel.Height + CloseBtn.BorderSpacing.Top + CloseBtn.Height;
end;
procedure TRunsTestForm.Compute;
var
a, i, col, N, N1, N2, NLess, Nmore, R: integer;
mean, expMean, SD1, SD2, SD3, SD4, SD, z1, z2, z, t, p1, p: double;
values: DblDyneVec = nil;
lReport: TStrings;
begin
N := 0;
N1 := 0;
N2 := 0;
Nless := 0;
Nmore := 0;
R := 1;
Mean := 0.0;
col := GetVariableIndex(OS3MainFrm.DataGrid, TestVarEdit.Text);
if col = -1 then
begin
ErrorMsg('No variable was selected.');
exit;
end;
values := CollectVecValues(OS3MainFrm.DataGrid, col);
N := Length(Values);
if N <= 10 then
begin
ErrorMsg('Insufficient data. You must have at least 11 values.');
Values := nil;
exit;
end;
mean := VecMean(values);
// run through each value and compare with the mean
for i := 0 to N-1 do
begin // check and discard the ties with the mean
if Mean <> Values[i] then
begin // check if it is greater than the mean
if Values[i] > mean then
begin
N1 := N1 + 1;
a := i;
while a > 0 do
begin
a := a - 1;
if values[a] <> mean then break;
end;
if values[a] < mean then
begin
R := R + 1;
nLess := nLess + 1;
end;
end
else // check to see if it is less than the mean
if Values[i] < Mean then
begin
N2 := N2 + 1;
a := i;
while a > 0 do
begin
a := a - 1;
if values[a] <> mean then break;
end;
if values[a] > mean then
begin
R := R + 1;
nMore := nMore + 1;
end;
end;
end;
end;
// Compute the expected mean and variance of R
expMean := 1.0 + ((2 * N1 * N2) / (N1 + N2)); // mean mu
SD1 := 2 * N1 * N2 * (2 * N1 * N2 - N1 - N2);
SD2 := power((N1 + N2), 2);
SD3 := N1 + N2 - 1;
SD4 := SD1 / (SD2 * SD3); // standard deviation "sigma"
SD := sqrt(SD4);
// calculating P Value
z1 := (R - expMean) / SD;
z2 := abs(z1);
z := z2;
if z > 0 then
t := z
else
t := -z;
p1 := power(
(1 + t * (0.049867347 + t * (0.0211410061 + t * (0.0032776283 +
t * (0.0000380036 + t * (0.0000488906 + t * (0.000005383))))))),
-16
);
p := 1.0 - p1 / 2.0;
if z > 0.0 then
p := 1.0 - p
else
p := 1.0 - (1.0 - p);
// show results
lReport := TStringList.Create;
try
lReport.Add('RUNS TEST FOR RANDOMNESS');
lReport.Add('');
lReport.Add('Variable: %22s', [TestVarEdit.Text]);
lReport.Add('');
lReport.Add('Mean: %12.3f', [mean]);
lReport.Add('Standard deviation: %12.3f', [SD]);
lReport.Add('N values > mean: %12d', [N1]);
lReport.Add('N values < mean: %12d', [N2]);
lReport.Add('Number of runs: %12d', [R]);
lReport.Add('Test statistic: %12.3f', [z]);
lReport.Add('Probability: %12.3f', [p]);
lReport.Add('');
lReport.Add('Conclusion:');
// determine the conclusion
if p < 0.01 then
lReport.Add('Very strong evidence against randomness (trend or seasonality')
else if (p < 0.05) and (p >= 0.01) then
lReport.Add('Moderate evidence against randomness')
else if (p < 0.10) and (p >= 0.05) then
lReport.Add('Suggestive evidence against normality')
else if p >= 0.10 then
lReport.Add('Little or no real evidence against randomness')
else
lReport.Add('Strong evidence against randomness (trend or seasonality exists)');;
FReportFrame.DisplayReport(lReport);
finally
lReport.Free;
end;
end;
procedure TRunsTestForm.InBtnClick(Sender: TObject);
var
index: integer;
begin
index := VarList.ItemIndex;
if (index > -1) and (TestVarEdit.Text = '') then
begin
TestVarEdit.Text := VarList.Items[index];
VarList.Items.Delete(index);
UpdateBtnStates;
end;
end;
procedure TRunsTestForm.OutBtnClick(Sender: TObject);
begin
if TestVarEdit.Text <> '' then
begin
VarList.Items.Add(TestVarEdit.Text);
TestVarEdit.Text := '';
UpdateBtnStates;
end;
end;
procedure TRunsTestForm.Reset;
var
i: integer;
begin
inherited;
TestVarEdit.Clear;
VarList.Clear;
for i := 1 to NoVariables do
VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]);
UpdateBtnStates;
end;
procedure TRunsTestForm.UpdateBtnStates;
begin
inherited;
InBtn.Enabled := AnySelected(VarList) and (TestVarEdit.Text = '');
OutBtn.Enabled := TestVarEdit.Text <> '';
end;
procedure TRunsTestForm.VarListDblClick(Sender: TObject);
var
index: Integer;
begin
index := VarList.ItemIndex;
if (index > -1) then begin
if (TestVarEdit.Text <> '') then
VarList.Items.Add(TestVarEdit.Text);
TestVarEdit.Text := VarList.Items[index];
VarList.Items.Delete(index);
UpdateBtnStates;
end;
end;
procedure TRunsTestForm.VarListSelectionChange(Sender: TObject; User: boolean);
begin
UpdateBtnStates;
end;
end.