diff --git a/applications/lazstats/docs/HelpNDoc/LazStats.hnd b/applications/lazstats/docs/HelpNDoc/LazStats.hnd index 8c4644d16..73a83cb6b 100644 Binary files a/applications/lazstats/docs/HelpNDoc/LazStats.hnd and b/applications/lazstats/docs/HelpNDoc/LazStats.hnd differ diff --git a/applications/lazstats/docs/chm/LazStats.chm b/applications/lazstats/docs/chm/LazStats.chm index 4d3e99ff6..661ab616d 100644 Binary files a/applications/lazstats/docs/chm/LazStats.chm and b/applications/lazstats/docs/chm/LazStats.chm differ diff --git a/applications/lazstats/source/forms/analysis/nonparametric/runstestunit.lfm b/applications/lazstats/source/forms/analysis/nonparametric/runstestunit.lfm index e951068ef..81306541c 100644 --- a/applications/lazstats/source/forms/analysis/nonparametric/runstestunit.lfm +++ b/applications/lazstats/source/forms/analysis/nonparametric/runstestunit.lfm @@ -54,6 +54,7 @@ object runstestform: Trunstestform BorderSpacing.Right = 8 ItemHeight = 0 MultiSelect = True + OnSelectionChange = VarListSelectionChange TabOrder = 0 end object InBtn: TBitBtn @@ -100,6 +101,7 @@ object runstestform: Trunstestform BorderSpacing.Left = 8 BorderSpacing.Right = 8 BorderSpacing.Bottom = 12 + ReadOnly = True TabOrder = 3 Text = 'TestVarEdit' end @@ -220,6 +222,8 @@ object runstestform: Trunstestform Anchors = [akLeft, akRight, akBottom] BorderSpacing.Right = 8 BorderSpacing.Bottom = 4 + Font.Style = [fsBold] + ParentFont = False ReadOnly = True TabOrder = 4 Text = 'MeanEdit' @@ -239,9 +243,11 @@ object runstestform: Trunstestform BorderSpacing.Left = 8 BorderSpacing.Right = 8 BorderSpacing.Bottom = 4 + Font.Style = [fsBold] + ParentFont = False ReadOnly = True TabOrder = 5 - Text = 'Edit1' + Text = 'StdDevEdit' end object NUpEdit: TEdit AnchorSideLeft.Control = StdDevEdit @@ -257,9 +263,11 @@ object runstestform: Trunstestform Anchors = [akLeft, akRight, akBottom] BorderSpacing.Right = 8 BorderSpacing.Bottom = 4 + Font.Style = [fsBold] + ParentFont = False ReadOnly = True TabOrder = 6 - Text = 'Edit1' + Text = 'NUpEdit' end object NDownEdit: TEdit AnchorSideLeft.Control = StdDevEdit @@ -274,9 +282,11 @@ object runstestform: Trunstestform Anchors = [akLeft, akRight, akBottom] BorderSpacing.Right = 8 BorderSpacing.Bottom = 4 + Font.Style = [fsBold] + ParentFont = False ReadOnly = True TabOrder = 7 - Text = 'Edit1' + Text = 'NDownEdit' end object NRunsEdit: TEdit AnchorSideLeft.Control = StdDevEdit @@ -291,9 +301,11 @@ object runstestform: Trunstestform Anchors = [akLeft, akRight, akBottom] BorderSpacing.Right = 8 BorderSpacing.Bottom = 4 + Font.Style = [fsBold] + ParentFont = False ReadOnly = True TabOrder = 8 - Text = 'Edit1' + Text = 'NRunsEdit' end object StatEdit: TEdit AnchorSideLeft.Control = StdDevEdit @@ -307,9 +319,11 @@ object runstestform: Trunstestform Alignment = taRightJustify Anchors = [akLeft, akRight, akBottom] BorderSpacing.Bottom = 4 + Font.Style = [fsBold] + ParentFont = False ReadOnly = True TabOrder = 9 - Text = 'Edit1' + Text = 'StatEdit' end object ProbEdit: TEdit AnchorSideLeft.Control = StdDevEdit @@ -323,9 +337,11 @@ object runstestform: Trunstestform Alignment = taRightJustify Anchors = [akLeft, akRight, akBottom] BorderSpacing.Bottom = 8 + Font.Style = [fsBold] + ParentFont = False ReadOnly = True TabOrder = 10 - Text = 'Edit1' + Text = 'ProbEdit' end object ConclusionEdit: TEdit AnchorSideLeft.Control = Label10 @@ -340,83 +356,70 @@ object runstestform: Trunstestform Anchors = [akLeft, akRight, akBottom] BorderSpacing.Left = 8 BorderSpacing.Right = 8 + Font.Style = [fsBold] + ParentFont = False ReadOnly = True TabOrder = 11 - Text = 'Edit1' + Text = 'ConclusionEdit' end object ResetBtn: TButton - AnchorSideRight.Control = CancelBtn + AnchorSideRight.Control = ComputeBtn AnchorSideBottom.Control = Owner AnchorSideBottom.Side = asrBottom - Left = 79 + Left = 167 Height = 25 Top = 405 Width = 54 Anchors = [akRight, akBottom] AutoSize = True BorderSpacing.Left = 8 - BorderSpacing.Right = 12 + BorderSpacing.Right = 8 BorderSpacing.Bottom = 8 Caption = 'Reset' OnClick = ResetBtnClick TabOrder = 12 end - object CancelBtn: TButton - AnchorSideRight.Control = ComputeBtn - AnchorSideBottom.Control = Owner - AnchorSideBottom.Side = asrBottom - Left = 145 - Height = 25 - Top = 405 - Width = 62 - Anchors = [akRight, akBottom] - AutoSize = True - BorderSpacing.Right = 12 - BorderSpacing.Bottom = 8 - Cancel = True - Caption = 'Cancel' - ModalResult = 2 - TabOrder = 13 - end object ComputeBtn: TButton - AnchorSideRight.Control = ReturnBtn + AnchorSideRight.Control = CloseBtn AnchorSideBottom.Control = Owner AnchorSideBottom.Side = asrBottom - Left = 219 + Left = 229 Height = 25 Top = 405 Width = 76 Anchors = [akRight, akBottom] AutoSize = True - BorderSpacing.Right = 12 + BorderSpacing.Left = 8 + BorderSpacing.Right = 8 BorderSpacing.Bottom = 8 Caption = 'Compute' OnClick = ComputeBtnClick - TabOrder = 14 + TabOrder = 13 end - object ReturnBtn: TButton + object CloseBtn: TButton AnchorSideRight.Control = Owner AnchorSideRight.Side = asrBottom AnchorSideBottom.Control = Owner AnchorSideBottom.Side = asrBottom - Left = 307 + Left = 313 Height = 25 Top = 405 - Width = 61 + Width = 55 Anchors = [akRight, akBottom] AutoSize = True + BorderSpacing.Left = 8 BorderSpacing.Top = 8 BorderSpacing.Right = 8 BorderSpacing.Bottom = 8 - Caption = 'Return' - ModalResult = 1 - TabOrder = 15 + Caption = 'Close' + ModalResult = 11 + TabOrder = 14 end object Bevel1: TBevel AnchorSideLeft.Control = Owner AnchorSideRight.Control = Owner AnchorSideRight.Side = asrBottom - AnchorSideBottom.Control = ReturnBtn + AnchorSideBottom.Control = CloseBtn Left = 0 Height = 8 Top = 389 diff --git a/applications/lazstats/source/forms/analysis/nonparametric/runstestunit.pas b/applications/lazstats/source/forms/analysis/nonparametric/runstestunit.pas index b67387d0f..cb04bf611 100644 --- a/applications/lazstats/source/forms/analysis/nonparametric/runstestunit.pas +++ b/applications/lazstats/source/forms/analysis/nonparametric/runstestunit.pas @@ -1,3 +1,5 @@ +// File for testing: RunTest.laz, use VAR1 + unit RunsTestUnit; {$mode objfpc}{$H+} @@ -7,21 +9,20 @@ interface uses Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls, Buttons, ExtCtrls, - MainUnit, OutputUnit, Globals, DataProcs; + MainUnit, Globals, DataProcs; type - { Trunstestform } + { TRunstestform } Trunstestform = class(TForm) Bevel1: TBevel; Bevel2: TBevel; - CancelBtn: TButton; ComputeBtn: TButton; MeanEdit: TEdit; Memo1: TLabel; ResetBtn: TButton; - ReturnBtn: TButton; + CloseBtn: TButton; StdDevEdit: TEdit; NUpEdit: TEdit; NDownEdit: TEdit; @@ -49,9 +50,11 @@ type procedure InBtnClick(Sender: TObject); procedure OutBtnClick(Sender: TObject); procedure ResetBtnClick(Sender: TObject); + procedure VarListSelectionChange(Sender: TObject; User: boolean); private { private declarations } FAutoSized: Boolean; + procedure UpdateBtnStates; public { public declarations } end; @@ -62,168 +65,162 @@ var implementation uses - Math; + Math, Utils; { Trunstestform } procedure Trunstestform.ResetBtnClick(Sender: TObject); -VAR i : integer; +var + i: integer; begin - VarList.Clear; - for i := 1 to NoVariables do - VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]); - TestVarEdit.Text := ''; - MeanEdit.Text := ''; - StdDevEdit.Text := ''; - NUpEdit.Text := ''; - NDownEdit.Text := ''; - StatEdit.Text := ''; - ProbEdit.Text := ''; - ConclusionEdit.Text := ''; - NRunsEdit.Text := ''; - InBtn.Enabled := true; - OutBtn.Enabled := false; + VarList.Clear; + for i := 1 to NoVariables do + VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]); + TestVarEdit.Text := ''; + MeanEdit.Text := ''; + StdDevEdit.Text := ''; + NUpEdit.Text := ''; + NDownEdit.Text := ''; + StatEdit.Text := ''; + ProbEdit.Text := ''; + ConclusionEdit.Text := ''; + NRunsEdit.Text := ''; + UpdateBtnStates; end; procedure Trunstestform.ComputeBtnClick(Sender: TObject); -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; - strvalue, outstr, astring : string; - values : DblDyneVec; - +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; + strvalue: string; + values: DblDyneVec; begin - col := 0; - N := 0; - N1 := 0; - N2 := 0; - Nless := 0; - Nmore := 0; - R := 1; - Mean := 0.0; - for i := 1 to NoVariables do - begin - strvalue := Trim(OS3MainFrm.DataGrid.Cells[i,0]); - if TestVarEdit.Text = strvalue then col := i; - end; - if col = 0 then - begin - ShowMessage('No variable was selected. Returning.'); - exit; - end; - SetLength(values,NoCases); - for i := 1 to NoCases do - begin - if not ValidValue(i,col) then continue; - values[i-1] := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[col,i])); - N := N + 1; - end; - if N <= 10 then - begin - ShowMessage('Insufficient data. You must have at least 11 values.'); - values := nil; - exit; - end; - for i := 0 to N-1 do Mean := Mean + values[i]; - Mean := Mean / N; - // 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 - // check to see if it is less than the mean - else 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; // close of else i - end; // end of if values[i] not equal to the mean - end; // end of i loop - // 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 t := 1.0 - p - else t := 1.0 - (1.0 - p); // this is P value - // show results - outstr := format('%8.3f',[Mean]); - MeanEdit.Text := outstr; - outstr := format('%8.3f',[SD]); - StdDevEdit.Text := outstr; - NUpEdit.Text := IntToStr(N1); - NDownEdit.Text := IntToStr(N2); - NRunsEdit.Text := IntToStr(R); - outstr := format('%8.3f',[z]); - StatEdit.Text := outstr; -// if t < 0.0001 then astring := 'Almost Zero' -// else -// begin - outstr := format('%6.4f',[t]); - ProbEdit.Text := outstr; -// end; - // determine the conclusion - if t < 0.01 then - begin - astring := 'Very strong evidence against randomness (trend or seasonality'; - ConclusionEdit.Text := astring; - end - else if (t < 0.05) and (t >= 0.01) then - begin - astring := 'Moderate evidence against randomness'; - ConclusionEdit.Text := astring; - end - else if (t < 0.10) and (t >= 0.05) then - begin - astring := 'Suggestive evidence against normality'; - ConclusionEdit.Text := astring; - end - else if t >= 0.10 then - begin - astring := 'Little or no real evidence against randomness'; - ConclusionEdit.Text := astring; - end - else - begin - astring := 'Strong evidence against randomness (trend or seasonality exists)'; - ConclusionEdit.Text := astring; - end; - values := nil; + col := 0; + N := 0; + N1 := 0; + N2 := 0; + Nless := 0; + Nmore := 0; + R := 1; + Mean := 0.0; + for i := 1 to NoVariables do + begin + strvalue := Trim(OS3MainFrm.DataGrid.Cells[i,0]); + if TestVarEdit.Text = strvalue then col := i; + end; + if col = 0 then + begin + MessageDlg('No variable was selected.', mtError, [mbOK], 0); + exit; + end; + + SetLength(Values, NoCases); + for i := 1 to NoCases do + begin + if not ValidValue(i, col) then continue; + Values[i-1] := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[col,i])); + N := N + 1; + end; + + if N <= 10 then + begin + MessageDlg('Insufficient data. You must have at least 11 values.', mtError, [mbOK], 0); + Values := nil; + exit; + end; + + for i := 0 to N-1 do + Mean := Mean + values[i]; + Mean := Mean / N; + + // 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; // close of else i + end; // end of if values[i] not equal to the mean + end; // end of i loop + + // 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 + t := 1.0 - p + else + t := 1.0 - (1.0 - p); // this is P value + + // show results + MeanEdit.Text := Format('%.3f', [Mean]); + StdDevEdit.Text := Format('%.3f', [SD]); + NUpEdit.Text := IntToStr(N1); + NDownEdit.Text := IntToStr(N2); + NRunsEdit.Text := IntToStr(R); + StatEdit.Text := Format('%.3f', [z]); + ProbEdit.Text := Format('%.3f', [z]); + + // determine the conclusion + if t < 0.01 then + ConclusionEdit.Text := 'Very strong evidence against randomness (trend or seasonality' + else if (t < 0.05) and (t >= 0.01) then + ConclusionEdit.Text := 'Moderate evidence against randomness' + else if (t < 0.10) and (t >= 0.05) then + ConclusionEdit.Text := 'Suggestive evidence against normality' + else if t >= 0.10 then + ConclusionEdit.Text := 'Little or no real evidence against randomness' + else + ConclusionEdit.Text := 'Strong evidence against randomness (trend or seasonality exists)'; + + Values := nil; end; procedure Trunstestform.FormActivate(Sender: TObject); @@ -233,11 +230,10 @@ begin if FAutoSized then exit; - w := MaxValue([ResetBtn.Width, CancelBtn.Width, ComputeBtn.Width, ReturnBtn.Width]); + w := MaxValue([ResetBtn.Width, ComputeBtn.Width, CloseBtn.Width]); ResetBtn.Constraints.MinWidth := w; - CancelBtn.Constraints.MinWidth := w; ComputeBtn.Constraints.MinWidth := w; - ReturnBtn.Constraints.MinWidth := w; + CloseBtn.Constraints.MinWidth := w; Constraints.MinWidth := Width; Constraints.MinHeight := Height; @@ -251,23 +247,37 @@ begin end; procedure Trunstestform.InBtnClick(Sender: TObject); -VAR index : integer; +var + index: integer; begin - index := VarList.ItemIndex; - if index < 0 then exit; - TestVarEdit.Text := VarList.Items.Strings[index]; - VarList.Items.Delete(index); - InBtn.Enabled := false; - OutBtn.Enabled := true; + 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 exit; - VarList.Items.Add(TestVarEdit.Text); - TestVarEdit.Text := ''; - InBtn.Enabled := true; - OutBtn.Enabled := false; + if TestVarEdit.Text <> '' then + begin + VarList.Items.Add(TestVarEdit.Text); + TestVarEdit.Text := ''; + UpdateBtnStates; + end; +end; + +procedure TRunsTestForm.UpdateBtnStates; +begin + InBtn.Enabled := AnySelected(VarList) and (TestVarEdit.Text = ''); + OutBtn.Enabled := TestVarEdit.Text <> ''; +end; + +procedure Trunstestform.VarListSelectionChange(Sender: TObject; User: boolean); +begin + UpdateBtnStates; end; initialization