diff --git a/applications/lazstats/docs/HelpNDoc/LazStats.hnd b/applications/lazstats/docs/HelpNDoc/LazStats.hnd index 8a4d28be6..c7adb2a95 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 d60e6a62d..16397dfa9 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/simulations/errorcurvesunit.lfm b/applications/lazstats/source/forms/simulations/errorcurvesunit.lfm index 1a4abe075..5fe9f1532 100644 --- a/applications/lazstats/source/forms/simulations/errorcurvesunit.lfm +++ b/applications/lazstats/source/forms/simulations/errorcurvesunit.lfm @@ -8,6 +8,7 @@ object ErrorCurvesFrm: TErrorCurvesFrm Caption = 'Alpha and Beta Curves for z tests' ClientHeight = 306 ClientWidth = 350 + OnActivate = FormActivate OnCreate = FormCreate OnShow = FormShow Position = poMainFormCenter @@ -47,7 +48,6 @@ object ErrorCurvesFrm: TErrorCurvesFrm Height = 15 Top = 154 Width = 199 - Anchors = [akTop] BorderSpacing.Left = 24 Caption = 'Standard Deviation of the Distribution' ParentColor = False @@ -105,7 +105,7 @@ object ErrorCurvesFrm: TErrorCurvesFrm Alignment = taRightJustify BorderSpacing.Top = 8 TabOrder = 2 - Text = 'Edit1' + Text = 'AltMeanEdit' end object SDEdit: TEdit AnchorSideLeft.Control = Label3 @@ -121,7 +121,7 @@ object ErrorCurvesFrm: TErrorCurvesFrm BorderSpacing.Top = 8 BorderSpacing.Right = 24 TabOrder = 3 - Text = 'Edit1' + Text = 'SDEdit' end object TypeIEdit: TEdit AnchorSideLeft.Control = SDEdit @@ -134,7 +134,7 @@ object ErrorCurvesFrm: TErrorCurvesFrm Alignment = taRightJustify BorderSpacing.Top = 8 TabOrder = 4 - Text = 'Edit1' + Text = 'TypeIEdit' end object TypeIIEdit: TEdit AnchorSideLeft.Control = SDEdit @@ -146,9 +146,9 @@ object ErrorCurvesFrm: TErrorCurvesFrm Width = 60 Alignment = taRightJustify BorderSpacing.Top = 8 - BorderSpacing.Bottom = 8 + BorderSpacing.Bottom = 12 TabOrder = 5 - Text = 'Edit1' + Text = 'TypeIIEdit' end object NullType: TRadioGroup AnchorSideLeft.Control = Owner @@ -156,15 +156,15 @@ object ErrorCurvesFrm: TErrorCurvesFrm AnchorSideTop.Control = Owner AnchorSideRight.Control = SDEdit AnchorSideRight.Side = asrBottom - Left = 60 + Left = 48 Height = 72 Top = 8 - Width = 231 - Anchors = [akTop, akLeft, akRight] + Width = 255 AutoFill = True AutoSize = True BorderSpacing.Left = 12 BorderSpacing.Top = 8 + BorderSpacing.Right = 12 Caption = 'Null Hypothesis Characteristic:' ChildSizing.LeftRightSpacing = 12 ChildSizing.TopBottomSpacing = 6 @@ -176,11 +176,11 @@ object ErrorCurvesFrm: TErrorCurvesFrm ChildSizing.Layout = cclLeftToRightThenTopToBottom ChildSizing.ControlsPerLine = 1 ClientHeight = 52 - ClientWidth = 227 + ClientWidth = 251 ItemIndex = 1 Items.Strings = ( - 'One-tailed (Directional alterntive)' - 'Two-tailed (non-directional alterntive)' + 'One-tailed (directional alternative)' + 'Two-tailed (non-directional alternative)' ) TabOrder = 0 end @@ -192,80 +192,64 @@ object ErrorCurvesFrm: TErrorCurvesFrm AnchorSideRight.Side = asrBottom Left = 0 Height = 8 - Top = 243 + Top = 247 Width = 350 Anchors = [akTop, akLeft, akRight] Shape = bsBottomLine end - object ReturnBtn: TButton + object CloseBtn: TButton AnchorSideTop.Control = Bevel1 AnchorSideTop.Side = asrBottom AnchorSideRight.Control = Owner AnchorSideRight.Side = asrBottom AnchorSideBottom.Side = asrBottom - Left = 277 + Left = 287 Height = 25 - Top = 259 - Width = 61 + Top = 263 + Width = 55 Anchors = [akTop, akRight] AutoSize = True + BorderSpacing.Left = 8 BorderSpacing.Top = 8 - BorderSpacing.Right = 12 + BorderSpacing.Right = 8 BorderSpacing.Bottom = 8 - Caption = 'Return' - ModalResult = 1 - TabOrder = 6 - end - object CancelBtn: TButton - AnchorSideTop.Control = Bevel1 - AnchorSideTop.Side = asrBottom - AnchorSideRight.Control = ComputeBtn - AnchorSideBottom.Control = ResetBtn - Left = 115 - Height = 25 - Top = 259 - Width = 62 - Anchors = [akTop, akRight] - AutoSize = True - BorderSpacing.Top = 8 - BorderSpacing.Right = 12 - Caption = 'Cancel' - ModalResult = 2 - TabOrder = 7 + Caption = 'Close' + ModalResult = 11 + TabOrder = 8 end object ResetBtn: TButton AnchorSideTop.Control = Bevel1 AnchorSideTop.Side = asrBottom - AnchorSideRight.Control = CancelBtn + AnchorSideRight.Control = ComputeBtn AnchorSideBottom.Control = ComputeBtn - Left = 49 + Left = 141 Height = 25 - Top = 259 + Top = 263 Width = 54 Anchors = [akTop, akRight] AutoSize = True - BorderSpacing.Left = 12 + BorderSpacing.Left = 8 BorderSpacing.Top = 8 - BorderSpacing.Right = 12 + BorderSpacing.Right = 8 Caption = 'Reset' OnClick = ResetBtnClick - TabOrder = 8 + TabOrder = 6 end object ComputeBtn: TButton AnchorSideTop.Control = Bevel1 AnchorSideTop.Side = asrBottom - AnchorSideRight.Control = ReturnBtn - AnchorSideBottom.Control = ReturnBtn - Left = 189 + AnchorSideRight.Control = CloseBtn + AnchorSideBottom.Control = CloseBtn + Left = 203 Height = 25 - Top = 259 + Top = 263 Width = 76 Anchors = [akTop, akRight] AutoSize = True BorderSpacing.Top = 8 - BorderSpacing.Right = 12 + BorderSpacing.Right = 8 Caption = 'Compute' OnClick = ComputeBtnClick - TabOrder = 9 + TabOrder = 7 end end diff --git a/applications/lazstats/source/forms/simulations/errorcurvesunit.pas b/applications/lazstats/source/forms/simulations/errorcurvesunit.pas index 84966544b..e0bc7930a 100644 --- a/applications/lazstats/source/forms/simulations/errorcurvesunit.pas +++ b/applications/lazstats/source/forms/simulations/errorcurvesunit.pas @@ -1,3 +1,10 @@ +// No data file needed for testing +// +// Test input: +// - Mean for NULL Hypothesis: 100 +// - Mean for alternative Nullhyothesis: 115 +// - Standard deviation of the distribution: 15 + unit ErrorCurvesUnit; {$mode objfpc}{$H+} @@ -10,7 +17,7 @@ uses BlankFrmUnit, FunctionsLib, Globals; type - TwoCol = array[1..2,1..100] of double; + TwoCol = array[1..2, 1..100] of double; type @@ -20,9 +27,8 @@ type Bevel1: TBevel; NullType: TRadioGroup; ResetBtn: TButton; - CancelBtn: TButton; ComputeBtn: TButton; - ReturnBtn: TButton; + CloseBtn: TButton; NullMeanEdit: TEdit; AltMeanEdit: TEdit; SDEdit: TEdit; @@ -34,27 +40,20 @@ type Label4: TLabel; Label5: TLabel; procedure ComputeBtnClick(Sender: TObject); + procedure FormActivate(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormShow(Sender: TObject); procedure ResetBtnClick(Sender: TObject); private { private declarations } - procedure PltPts(realpts : TwoCol; - Xmax, Xmin, Ymax, Ymin : double; - Npts, XaxisStart, YaxisStart, XaxisRange : integer; - YaxisRange : integer; - acolor : TColor; Sender : TObject); - procedure Hscale(Xmin, Xmax : double; Nsteps : integer; - acolor : TColor; FontSize : integer; - X, Y, Xlength : integer; - charLabel : string; Sender : TObject); - procedure Vscale(Ymin, Ymax : double; Nsteps : integer; - acolor : TColor; FontSize : integer; - X, Y, Ylength : integer; - charLabel : string; Sender : TObject); - procedure NormPts(zMin, zMax : double; Npts : integer; - VAR realpts : TwoCol; - Sender : TObject); + procedure PltPts(RealPts: TwoCol; Xmax, Xmin, Ymax, Ymin: double; + Npts, XAxisStart, YAxisStart, XAxisRange, YAxisRange: integer; + AColor: TColor); + procedure Hscale(Xmin, Xmax: double; NSteps: integer; AColor: TColor; + FontSize: integer; X, Y, XLength: integer; CharLabel: string); + procedure Vscale(Ymin, Ymax: double; NSteps: integer; AColor: TColor; + FontSize: integer; X, Y, YLength: integer; CharLabel: string); + procedure NormPts(zMin, zMax: double; NPts: integer; var RealPts: TwoCol); public { public declarations } @@ -65,157 +64,222 @@ var implementation +uses + Math; + { TErrorCurvesFrm } procedure TErrorCurvesFrm.ResetBtnClick(Sender: TObject); begin - NullMeanEdit.Text := ''; - AltMeanEdit.Text := ''; - SDEdit.Text := ''; - TypeIEdit.Text := '0.05'; - TypeIIEdit.Text := '0.05'; - NullMeanEdit.SetFocus; + NullMeanEdit.Text := ''; + AltMeanEdit.Text := ''; + SDEdit.Text := ''; + TypeIEdit.Text := FormatFloat('0.00', DEFAULT_ALPHA_LEVEL); + TypeIIEdit.Text := FormatFloat('0.00', DEFAULT_ALPHA_LEVEL); end; procedure TErrorCurvesFrm.FormShow(Sender: TObject); begin - ResetBtnClick(self); + ResetBtnClick(self); end; +{ Generate a null and alternate hypothesis for a specified effect size, + Type I error rate and Type II error rate using the normal distribution z-test. + Estimate the N needed. + Uses the Plot.h header file and form FrmPlot. } procedure TErrorCurvesFrm.ComputeBtnClick(Sender: TObject); var - // generate a null and alternate hypothesis for a specified effect - // size, Type I error rate and Type II error rate using the normal - // distribution z-test. Estimate the N needed. - // Uses the Plot.h header file and form FrmPlot. - Clwidth,Clheight,X,Y,XaxisStart,XaxisEnd,YaxisStart,YaxisEnd : integer; - Xrange, Yrange, t, range, Nsize: integer; - alpha, beta, nullmean, altmean, Diff, StdDev, CriticalX, zalpha : double; - zbeta, Xprop, stderrmean, xlow, xhigh : double; - valuestr, charLabel : string; - realpts : TwoCol; + Clwidth, Clheight, X, Y, XaxisStart, XaxisEnd, YaxisStart, YaxisEnd: integer; + Xrange, Yrange, t, range, Nsize: integer; + alpha, beta, nullmean, altmean, Diff, StdDev, CriticalX, zalpha: double; + zbeta, Xprop, stderrmean, xlow, xhigh: double; + charLabel: string; + RealPts: TwoCol; begin - BlankFrm.Show; - BlankFrm.Image1.Canvas.Clear; - BlankFrm.Image1.Canvas.Pen.Color := clBlack; - BlankFrm.Image1.Canvas.Brush.Color := clWhite; - BlankFrm.Image1.Canvas.Clear; - BlankFrm.Image1.Canvas.FloodFill(1,1,clWhite,fsborder); - alpha := StrToFloat(TypeIEdit.Text); - if NullType.ItemIndex = 1 then alpha := alpha / 2.0; - beta := StrToFloat(TypeIIEdit.Text); - nullmean := StrToFloat(NullMeanEdit.Text); - altmean := StrToFloat(AltMeanEdit.Text); - StdDev := StrToFloat(SDEdit.Text); - zalpha := inversez(1.0 - alpha); - zbeta := inversez(1.0 - beta); - Diff := abs(nullmean - altmean); - Nsize := round((StdDev / Diff) * abs(zbeta + zalpha)); - Nsize := Nsize * Nsize; - CriticalX := zalpha * (StdDev / sqrt(Nsize)) + nullmean; - stderrmean := StdDev / sqrt(Nsize); - Clwidth := BlankFrm.Image1.Width; - Clheight := BlankFrm.Image1.Height; + if NullMeanEdit.Text = '' then + begin + NullMeanEdit.SetFocus; + MessageDlg('Input requred.', mtError, [mbOk], 0); + exit; + end; + if not TryStrToFloat(NullMeanEdit.Text, nullMean) then + begin + NullMeanEdit.SetFocus; + MessageDlg('Valid number required.', mtError, [mbOk], 0); + exit; + end; - // Determine X scale and print it - YaxisStart := (Clheight * 6) div 10; - YaxisEnd := Clheight div 10; - Yrange := YaxisStart - YaxisEnd; - xlow := nullmean - 4 * stderrmean; - xhigh := altmean + 4 * stderrmean; - XaxisStart := Clwidth div 8; - XaxisEnd := Clwidth - (Clwidth div 8); - Xrange := XaxisEnd - XaxisStart; - Hscale(xlow, xhigh, 9, clWhite, 8, XaxisStart, YaxisStart, Xrange,'X SCALE',BlankFrm); + if AltMeanEdit.Text = '' then + begin + AltMeanEdit.SetFocus; + MessageDlg('Input requred.', mtError, [mbOk], 0); + exit; + end; + if not TryStrToFloat(AltMeanEdit.Text, altMean) then + begin + AltMeanEdit.SetFocus; + MessageDlg('Valid number required.', mtError, [mbOk], 0); + exit; + end; - // Create values of the alternative distribution - Xprop := ( (nullmean + 4*stderrmean) - xlow) / (xhigh - xlow); - range := round(Xprop * Xrange); - NormPts(-4.0, 4.0, 100, realpts, self); - Xprop := ((altmean - 4 * stderrmean) - xlow) / (xhigh - xlow); - X := round((Xprop * Xrange) + XaxisStart); // where to start curve - PltPts(realpts, 4.0, -4.0, 0.5, 0.0, 100, X, YaxisStart, range, - Yrange, clBlack, self); + if SDEdit.Text = '' then + begin + SDEdit.SetFocus; + MessageDlg('Input requred.', mtError, [mbOk], 0); + exit; + end; + if not TryStrToFloat(SDEdit.Text, StdDev) or (StdDev <= 0) then + begin + SDEdit.SetFocus; + MessageDlg('Valid positive number required.', mtError, [mbOk], 0); + exit; + end; - //Draw vertical axis at the critical X value - Xprop := (CriticalX - xlow) / (xhigh - xlow); - X := round((Xprop * Xrange) + XaxisStart); - Y := YaxisStart; - BlankFrm.Image1.Canvas.MoveTo(X,Y); - BlankFrm.Image1.Canvas.LineTo(X,YaxisEnd); - charLabel := 'Critical X = '; - valuestr := format('%6.2f',[CriticalX]); - charLabel := charLabel + valuestr; - t := BlankFrm.Image1.Canvas.TextWidth(charLabel) div 2; - BlankFrm.Image1.Canvas.TextOut(X-t,YaxisEnd-15,charLabel); + if TypeIEdit.Text = '' then + begin + TypeIEdit.SetFocus; + MessageDlg('Input required.', mtError, [mbOK], 0); + exit; + end; + if not TryStrToFloat(TypeIEdit.Text, alpha) or (alpha < 0) or (alpha > 1) then + begin + TypeIEdit.Setfocus; + MessageDlg('Valid number required between 0 and 1.', mtError, [mbOK], 0); + exit; + end; - // floodfill Alternate distribution area with blue - Xprop := (CriticalX - xlow) / (xhigh - xlow); - X := round((Xprop * Xrange) + XaxisStart); - Y := YaxisStart - 3; - BlankFrm.Image1.Canvas.Brush.Color := clBlue; - BlankFrm.Image1.Canvas.FloodFill(X-2,Y,clBlack,fsBorder ); - BlankFrm.Image1.Canvas.Brush.Color := clWhite; + if TypeIIEdit.Text = '' then + begin + TypeIIEdit.SetFocus; + MessageDlg('Input required.', mtError, [mbOK], 0); + exit; + end; + if not TryStrToFloat(TypeIEdit.Text, beta) or (beta < 0) or (beta > 1) then + begin + TypeIIEdit.Setfocus; + MessageDlg('Valid number required between 0 and 1.', mtError, [mbOK], 0); + exit; + end; - // Create values of normal curve for null distribution - NormPts(-4.0, 4.0, 100, realpts, self); - Xprop := ( (nullmean + 4*stderrmean) - xlow) / (xhigh - xlow); - range := round(Xprop * Xrange); - BlankFrm.Image1.Canvas.Brush.Color := clWhite; - PltPts(realpts, 4.0, -4.0, 0.5, 0.0, 100, XaxisStart, YaxisStart, range, - Yrange, clBlack, self); + BlankFrm.Show; - //Draw vertical axis at null mean - Xprop := (nullmean - xlow) / (xhigh - xlow); - X := round((Xprop * Xrange) + XaxisStart); - Y := YaxisStart; - BlankFrm.Image1.Canvas.MoveTo(X,Y); - BlankFrm.Image1.Canvas.LineTo(X,YaxisEnd); - charLabel := 'Null Mean'; - t := BlankFrm.Image1.Canvas.TextWidth(charLabel) div 2; - BlankFrm.Image1.Canvas.TextOut(X-t,YaxisEnd,charLabel); + BlankFrm.Image1.Canvas.Pen.Color := clBlack; + BlankFrm.Image1.Canvas.Brush.Color := clWhite; + BlankFrm.Image1.Canvas.Clear; + BlankFrm.Image1.Canvas.FloodFill(1,1,clWhite,fsborder); - // floodfill alpha area with red - Xprop := (CriticalX - xlow) / (xhigh - xlow); - X := round((Xprop * Xrange) + XaxisStart); - Y := YaxisStart - 3; - BlankFrm.Image1.Canvas.Brush.Color := clRed; - BlankFrm.Image1.Canvas.FloodFill(X+2,Y,clBlack,fsBorder ); - BlankFrm.Image1.Canvas.Brush.Color := clWhite; + if NullType.ItemIndex = 1 then alpha := alpha / 2.0; - //Draw vertical axis at alternative mean - BlankFrm.Image1.Canvas.Pen.Color := clBlack; - Xprop := (altmean - xlow) / (xhigh - xlow); - X := round((Xprop * Xrange) + XaxisStart); - Y := YaxisStart; - BlankFrm.Image1.Canvas.MoveTo(X,Y); - BlankFrm.Image1.Canvas.LineTo(X,YaxisEnd); - charLabel := 'Alternative Mean'; - t := BlankFrm.Image1.Canvas.TextWidth(charLabel) div 2; - BlankFrm.Image1.Canvas.TextOut(X-t,YaxisEnd,charLabel); + zalpha := InverseZ(1.0 - alpha); + zbeta := InverseZ(1.0 - beta); + Diff := abs(nullmean - altmean); + Nsize := round((StdDev / Diff) * abs(zbeta + zalpha)); + Nsize := Nsize * Nsize; + CriticalX := zalpha * (StdDev / sqrt(Nsize)) + nullmean; + stderrmean := StdDev / sqrt(Nsize); - // draw the vertical density axis scale values - Vscale(0.0, 0.5, 11, clWhite, 10, XaxisStart, YaxisStart, Yrange, 'DENSITY', self); + Clwidth := BlankFrm.Image1.Width; + Clheight := BlankFrm.Image1.Height; - // Print Heading - charLabel := 'Type I and II Error Areas'; - BlankFrm.Caption := charLabel; - charLabel := 'Alpha := '; - charLabel := charLabel + TypeIEdit.Text; - charLabel := charLabel + ', Beta := '; - charLabel := charLabel + TypeIIEdit.Text; - charLabel := charLabel + ', N := '; - charLabel := charLabel + IntToStr(Nsize); - t := BlankFrm.Image1.Canvas.TextWidth(charLabel); - X := round((BlankFrm.Image1.Width / 2) - (t / 2)); - BlankFrm.Image1.Canvas.TextOut(X,0,charLabel); + // Determine X scale and print it + YaxisStart := (Clheight * 6) div 10; + YaxisEnd := Clheight div 10; + Yrange := YaxisStart - YaxisEnd; + xlow := nullmean - 4 * stderrmean; + xhigh := altmean + 4 * stderrmean; + XaxisStart := Clwidth div 8; + XaxisEnd := Clwidth - (Clwidth div 8); + Xrange := XaxisEnd - XaxisStart; + HScale(xlow, xhigh, 9, clWhite, 8, XaxisStart, YaxisStart, Xrange, 'X SCALE'); - // print z scale for the null distribution - Xprop := ( (nullmean + 4*stderrmean) - xlow) / (xhigh - xlow); - range := round(Xprop * Xrange); - Hscale(-4.0, 4.0, 11, clWhite, 8, XaxisStart, YaxisStart+50, range,'NULL Z SCALE', self); + // Create values of the alternative distribution + Xprop := ((nullmean + 4*stderrmean) - xlow) / (xhigh - xlow); + range := round(Xprop * Xrange); + NormPts(-4.0, 4.0, 100, realpts{%H-}); + Xprop := ((altmean - 4 * stderrmean) - xlow) / (xhigh - xlow); + X := round((Xprop * Xrange) + XaxisStart); // where to start curve + PltPts(realpts, 4.0, -4.0, 0.5, 0.0, 100, X, YaxisStart, range, Yrange, clBlack); - end; + //Draw vertical axis at the critical X value + Xprop := (CriticalX - xlow) / (xhigh - xlow); + X := round((Xprop * Xrange) + XaxisStart); + Y := YaxisStart; + BlankFrm.Image1.Canvas.MoveTo(X,Y); + BlankFrm.Image1.Canvas.LineTo(X,YaxisEnd); + CharLabel := 'Critical X: ' + Format('%6.2f', [CriticalX]); + t := BlankFrm.Image1.Canvas.TextWidth(CharLabel) div 2; + BlankFrm.Image1.Canvas.TextOut(X-t, YaxisEnd-15, CharLabel); + + // floodfill Alternate distribution area with blue + Xprop := (CriticalX - xlow) / (xhigh - xlow); + X := round((Xprop * Xrange) + XaxisStart); + Y := YaxisStart - 3; + BlankFrm.Image1.Canvas.Brush.Color := clBlue; + BlankFrm.Image1.Canvas.FloodFill(X-2, Y, clBlack, fsBorder); + BlankFrm.Image1.Canvas.Brush.Color := clWhite; + + // Create values of normal curve for null distribution + NormPts(-4.0, 4.0, 100, realpts); + Xprop := ( (nullmean + 4*stderrmean) - xlow) / (xhigh - xlow); + range := round(Xprop * Xrange); + BlankFrm.Image1.Canvas.Brush.Color := clWhite; + PltPts(realpts, 4.0, -4.0, 0.5, 0.0, 100, XaxisStart, YaxisStart, range, Yrange, clBlack); + + //Draw vertical axis at null mean + Xprop := (nullmean - xlow) / (xhigh - xlow); + X := round((Xprop * Xrange) + XaxisStart); + Y := YaxisStart; + BlankFrm.Image1.Canvas.MoveTo(X,Y); + BlankFrm.Image1.Canvas.LineTo(X,YaxisEnd); + CharLabel := 'Null Mean'; + t := BlankFrm.Image1.Canvas.TextWidth(charLabel) div 2; + BlankFrm.Image1.Canvas.TextOut(X-t, YaxisEnd, CharLabel); + + // floodfill alpha area with red + Xprop := (CriticalX - xlow) / (xhigh - xlow); + X := round((Xprop * Xrange) + XaxisStart); + Y := YaxisStart - 3; + BlankFrm.Image1.Canvas.Brush.Color := clRed; + BlankFrm.Image1.Canvas.FloodFill(X+2, Y, clBlack, fsBorder); + BlankFrm.Image1.Canvas.Brush.Color := clWhite; + + //Draw vertical axis at alternative mean + BlankFrm.Image1.Canvas.Pen.Color := clBlack; + Xprop := (altmean - xlow) / (xhigh - xlow); + X := round((Xprop * Xrange) + XaxisStart); + Y := YaxisStart; + BlankFrm.Image1.Canvas.MoveTo(X,Y); + BlankFrm.Image1.Canvas.LineTo(X,YaxisEnd); + charLabel := 'Alternative Mean'; + t := BlankFrm.Image1.Canvas.TextWidth(charLabel) div 2; + BlankFrm.Image1.Canvas.TextOut(X-t,YaxisEnd,charLabel); + + // draw the vertical density axis scale values + Vscale(0.0, 0.5, 11, clWhite, 10, XaxisStart, YaxisStart, Yrange, 'DENSITY'); + + // Print Heading + CharLabel := 'Type I and II Error Areas'; + BlankFrm.Caption := CharLabel; + CharLabel := 'Alpha: ' + TypeIEdit.Text + ', Beta: ' + TypeIIEdit.Text + ', N: ' + IntToStr(Nsize); + t := BlankFrm.Image1.Canvas.TextWidth(CharLabel); + X := round((BlankFrm.Image1.Width - t) / 2); + BlankFrm.Image1.Canvas.TextOut(X, 0, CharLabel); + + // print z scale for the null distribution + Xprop := ((nullmean + 4*stderrmean) - xlow) / (xhigh - xlow); + range := round(Xprop * Xrange); + Hscale(-4.0, 4.0, 11, clWhite, 8, XaxisStart, YaxisStart+50, range,'NULL Z SCALE'); +end; + +procedure TErrorCurvesFrm.FormActivate(Sender: TObject); +var + w: Integer; +begin + w := MaxValue([ResetBtn.Width, ComputeBtn.Width, CloseBtn.Width]); + ResetBtn.Constraints.MinWidth := w; + ComputeBtn.Constraints.MinWidth := w; + CloseBtn.Constraints.MinWidth := w; +end; procedure TErrorCurvesFrm.FormCreate(Sender: TObject); begin @@ -224,112 +288,105 @@ begin end; procedure TErrorCurvesFrm.PltPts(realpts: TwoCol; Xmax, Xmin, Ymax, - Ymin: double; Npts, XaxisStart, YaxisStart, XaxisRange: integer; - YaxisRange: integer; acolor: TColor; Sender: TObject); + Ymin: double; Npts, XAxisStart, YAxisStart, XAxisRange, YAxisRange: integer; + AColor: TColor); var - hprop, zprop, z, h : double; - i, X, Y : integer; - intpts : array[1..100] of TPoint; + hprop, zprop, z, h: double; + i, X, Y: integer; + intpts: array[1..100] of TPoint; begin - for i := 1 to Npts do - begin - z := realpts[1,i]; - h := realpts[2,i]; - zprop := (z - Xmin) / (Xmax - Xmin); - X := round((zprop * XaxisRange) + XaxisStart); - hprop := (h - Ymin) / (Ymax - Ymin); - Y := round(YaxisStart - (hprop * YaxisRange)); - intpts[i] := Point(X,Y); - end; - BlankFrm.Image1.Canvas.Pen.Color := acolor; - BlankFrm.Image1.Canvas.Polyline(Slice(intpts,Npts - 1)); + for i := 1 to Npts do + begin + z := RealPts[1, i]; + h := RealPts[2, i]; + zprop := (z - Xmin) / (Xmax - Xmin); + X := round((zprop * XAxisRange) + XAxisStart); + hprop := (h - Ymin) / (Ymax - Ymin); + Y := round(YAxisStart - (hprop * YAxisRange)); + intpts[i] := Point(X,Y); + end; + + BlankFrm.Image1.Canvas.Pen.Color := AColor; + BlankFrm.Image1.Canvas.Polyline(Slice(intpts, Npts - 1)); end; procedure TErrorCurvesFrm.Hscale(Xmin, Xmax: double; Nsteps: integer; - acolor: TColor; FontSize: integer; X, Y, Xlength: integer; charLabel: string; - Sender: TObject); + AColor: TColor; FontSize: integer; X, Y, XLength: integer; CharLabel: string); var - i, TickEnd, Xpos, Ypos, TextX : integer; - Xincr, Xval : double; - Svalue, Ast : string; + i, TickEnd, Xpos, Ypos, TextX: integer; + Xincr, Xval: double; begin - BlankFrm.Image1.Canvas.MoveTo(X,Y); - BlankFrm.Image1.Canvas.LineTo(X+Xlength,Y); - BlankFrm.Image1.Canvas.Font.Size := FontSize; - BlankFrm.Image1.Canvas.Brush.Color := acolor; - TickEnd := Y + 10; - Xincr := (Xmax - Xmin) / Nsteps; - for i := 0 to Nsteps + 1 do - begin - Xpos := round(((Xlength / Nsteps) * i) + X); - BlankFrm.Image1.Canvas.MoveTo(Xpos,Y); - BlankFrm.Image1.Canvas.LineTo(Xpos,TickEnd); - TextX := Xpos - 8; - Xval := Xmin + ( i * Xincr); - Svalue := format('%4.2f',[Xval]); - Ast := Svalue; - BlankFrm.Image1.Canvas.TextOut(TextX, Y+15, Ast); - end; - // print label below X axis - Ypos := Y + 30; - Xpos := round((BlankFrm.Image1.Width / 2) - (BlankFrm.Image1.Canvas.TextWidth(charLabel) / 2)); - BlankFrm.Image1.Canvas.TextOut(Xpos,Ypos,charLabel); + BlankFrm.Image1.Canvas.MoveTo(X,Y); + BlankFrm.Image1.Canvas.LineTo(X+Xlength,Y); + BlankFrm.Image1.Canvas.Font.Size := FontSize; + BlankFrm.Image1.Canvas.Brush.Color := AColor; + TickEnd := Y + 10; + Xincr := (Xmax - Xmin) / Nsteps; + for i := 0 to Nsteps + 1 do + begin + Xpos := round(Xlength/Nsteps * i + X); + BlankFrm.Image1.Canvas.MoveTo(Xpos, Y); + BlankFrm.Image1.Canvas.LineTo(Xpos, TickEnd); + TextX := Xpos - 8; + Xval := Xmin + i*Xincr; + BlankFrm.Image1.Canvas.TextOut(TextX, Y+15, Format('%.2f', [Xval])); + end; + + // print label below X axis + Ypos := Y + 30; + Xpos := round((BlankFrm.Image1.Width / 2) - (BlankFrm.Image1.Canvas.TextWidth(CharLabel) / 2)); + BlankFrm.Image1.Canvas.TextOut(Xpos, Ypos, CharLabel); end; -procedure TErrorCurvesFrm.Vscale(Ymin, Ymax: double; Nsteps: integer; - acolor: TColor; FontSize: integer; X, Y, Ylength: integer; charLabel: string; - Sender: TObject); +procedure TErrorCurvesFrm.Vscale(Ymin, Ymax: double; NSteps: integer; + AColor: TColor; FontSize: integer; X, Y, YLength: integer; CharLabel: string); var - TickEnd, Ypos, Xpos, TextY : integer; - Yincr, Yval : double; - Svalue, symbol, Ast : string; - chpixs, i : integer; + TickEnd, Ypos, Xpos, TextY: integer; + Yincr, Yval: double; + chpixs, i: integer; begin - BlankFrm.Image1.Canvas.MoveTo(X,Y); - BlankFrm.Image1.Canvas.LineTo(X,Y-Ylength); - BlankFrm.Image1.Canvas.Font.Size := FontSize; - BlankFrm.Image1.Canvas.Brush.Color := acolor; - TickEnd := X - 10; - Yincr := (Ymax - Ymin) / Nsteps; - TextY := 0; - for i := 0 to Nsteps + 1 do - begin - Ypos := round(Y - ((Ylength / Nsteps) * i)); - BlankFrm.Image1.Canvas.MoveTo(X,Ypos); - BlankFrm.Image1.Canvas.LineTo(TickEnd,Ypos); - TextY := TickEnd - 30; - Yval := Ymin + ( i * Yincr); - Svalue := format('%4.2f',[Yval]); - Ast := Svalue; - BlankFrm.Image1.Canvas.TextOut(TextY, Ypos-8, Ast); - end; - // print label vertically - Xpos := TextY - 15; - for i := 1 to Length(charLabel) do - begin - chpixs := BlankFrm.Image1.Canvas.TextHeight(charLabel); - Ypos := round(Y - (Ylength / 2) - ( (Length(charLabel) * chpixs) / 2 ) + (chpixs * i)); - symbol := charLabel[i]; -// symbol[2] := 0; - BlankFrm.Image1.Canvas.TextOut(Xpos,Ypos,symbol); - end; + BlankFrm.Image1.Canvas.MoveTo(X,Y); + BlankFrm.Image1.Canvas.LineTo(X,Y-Ylength); + BlankFrm.Image1.Canvas.Font.Size := FontSize; + BlankFrm.Image1.Canvas.Brush.Color := acolor; + TickEnd := X - 10; + Yincr := (Ymax - Ymin) / Nsteps; + TextY := 0; + + for i := 0 to Nsteps + 1 do + begin + Ypos := round(Y - Ylength/Nsteps*i); + BlankFrm.Image1.Canvas.MoveTo(X, Ypos); + BlankFrm.Image1.Canvas.LineTo(TickEnd, Ypos); + TextY := TickEnd - 30; + Yval := Ymin + i*Yincr; + BlankFrm.Image1.Canvas.TextOut(TextY, Ypos-8, Format('%.2f', [Yval])); + end; + + // print label vertically + Xpos := TextY - 15; + chpixs := BlankFrm.Image1.Canvas.TextHeight(CharLabel); + for i := 1 to Length(CharLabel) do + begin + Ypos := round(Y - Ylength/2 - Length(CharLabel)*chpixs/2 + chpixs*i); + BlankFrm.Image1.Canvas.TextOut(Xpos,Ypos, CharLabel[i]); + end; end; procedure TErrorCurvesFrm.NormPts(zMin, zMax: double; Npts: integer; - var realpts: TwoCol; Sender: TObject); + var realpts: TwoCol); var - zIncr, z, h : double; - i : integer; + zIncr, z, h: double; + i: integer; begin - zIncr := (zMax - zMin) / Npts; - for i := 1 to Npts do - begin - z := zMin + (zIncr * i); - h := (1.0 / sqrt(2.0 * 3.14159265358979)) * - ( 1.0 / exp(z * z / 2.0)); - realpts[1,i] := z; - realpts[2,i] := h; - end; + zIncr := (zMax - zMin) / Npts; + for i := 1 to Npts do + begin + z := zMin + (zIncr * i); + h := (1.0 / sqrt(2.0 * PI)) * (1.0 / exp(z * z / 2.0)); + realpts[1, i] := z; + realpts[2, i] := h; + end; end; initialization