You've already forked lazarus-ccr
LazStats: Improved calculation of V-Mask in CUSUMUnit; slide V-Mask over data set.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7660 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -3,6 +3,7 @@ inherited CUSUMChartForm: TCUSUMChartForm
|
||||
HelpKeyword = 'html/CUMSUMChart.htm'
|
||||
Caption = 'Cumulative Sum Control Chart'
|
||||
OnActivate = FormActivate
|
||||
ShowHint = True
|
||||
inherited SpecsPanel: TPanel
|
||||
Width = 432
|
||||
ClientWidth = 432
|
||||
@ -55,20 +56,21 @@ inherited CUSUMChartForm: TCUSUMChartForm
|
||||
end
|
||||
object GroupBox1: TGroupBox[8]
|
||||
AnchorSideLeft.Control = MeasEdit
|
||||
AnchorSideTop.Control = MeasEdit
|
||||
AnchorSideTop.Control = GroupBox2
|
||||
AnchorSideTop.Side = asrBottom
|
||||
AnchorSideRight.Control = MeasEdit
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 228
|
||||
Height = 107
|
||||
Top = 120
|
||||
Height = 153
|
||||
Top = 202
|
||||
Width = 204
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
BorderSpacing.Top = 24
|
||||
Caption = 'CUMSUM V-Mask Specifications'
|
||||
ClientHeight = 87
|
||||
AutoSize = True
|
||||
BorderSpacing.Top = 16
|
||||
Caption = 'V-Mask Specifications'
|
||||
ClientHeight = 133
|
||||
ClientWidth = 200
|
||||
TabOrder = 3
|
||||
TabOrder = 4
|
||||
object Label4: TLabel
|
||||
AnchorSideLeft.Control = GroupBox1
|
||||
AnchorSideTop.Control = DeltaEdit
|
||||
@ -112,6 +114,7 @@ inherited CUSUMChartForm: TCUSUMChartForm
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 114
|
||||
Height = 23
|
||||
Hint = 'Detection level for a shift in the process mean, '#13#10'expressed in data units (default), or'#13#10'as a multiple of the standard deviation of the '#13#10'data points (when "Normalized CUSUM" is checked).'
|
||||
Top = 2
|
||||
Width = 78
|
||||
Alignment = taRightJustify
|
||||
@ -131,6 +134,7 @@ inherited CUSUMChartForm: TCUSUMChartForm
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 114
|
||||
Height = 23
|
||||
Hint = 'Probability of concluding that a shift in the process has occurred, when in fact it did not. '
|
||||
Top = 29
|
||||
Width = 78
|
||||
Alignment = taRightJustify
|
||||
@ -150,6 +154,7 @@ inherited CUSUMChartForm: TCUSUMChartForm
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 114
|
||||
Height = 23
|
||||
Hint = 'Probability of not detecting that a shift in the process mean has, in fact, occurred'
|
||||
Top = 56
|
||||
Width = 78
|
||||
Alignment = taRightJustify
|
||||
@ -161,25 +166,52 @@ inherited CUSUMChartForm: TCUSUMChartForm
|
||||
TabOrder = 2
|
||||
Text = 'BetaEdit'
|
||||
end
|
||||
object VMaskScrollbar: TScrollBar
|
||||
AnchorSideLeft.Control = Label1
|
||||
AnchorSideTop.Control = Label1
|
||||
AnchorSideTop.Side = asrBottom
|
||||
AnchorSideRight.Control = BetaEdit
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 12
|
||||
Height = 17
|
||||
Top = 104
|
||||
Width = 180
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
BorderSpacing.Top = 2
|
||||
BorderSpacing.Bottom = 12
|
||||
PageSize = 0
|
||||
TabOrder = 3
|
||||
end
|
||||
object Label1: TLabel
|
||||
AnchorSideLeft.Control = Label4
|
||||
AnchorSideTop.Control = BetaEdit
|
||||
AnchorSideTop.Side = asrBottom
|
||||
Left = 12
|
||||
Height = 15
|
||||
Top = 87
|
||||
Width = 100
|
||||
Caption = 'Position of V-Mask'
|
||||
ParentColor = False
|
||||
end
|
||||
end
|
||||
object GroupBox2: TGroupBox[9]
|
||||
AnchorSideLeft.Control = GroupBox1
|
||||
AnchorSideTop.Control = GroupBox1
|
||||
AnchorSideTop.Control = MeasEdit
|
||||
AnchorSideTop.Side = asrBottom
|
||||
AnchorSideRight.Control = MeasEdit
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 228
|
||||
Height = 51
|
||||
Top = 243
|
||||
Height = 74
|
||||
Top = 112
|
||||
Width = 204
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
AutoSize = True
|
||||
BorderSpacing.Top = 16
|
||||
BorderSpacing.Bottom = 8
|
||||
Caption = 'Option:'
|
||||
ClientHeight = 31
|
||||
ClientHeight = 54
|
||||
ClientWidth = 200
|
||||
TabOrder = 4
|
||||
TabOrder = 3
|
||||
object TargetChk: TCheckBox
|
||||
AnchorSideLeft.Control = GroupBox2
|
||||
AnchorSideTop.Control = TargetEdit
|
||||
@ -207,11 +239,24 @@ inherited CUSUMChartForm: TCUSUMChartForm
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
BorderSpacing.Left = 8
|
||||
BorderSpacing.Right = 8
|
||||
BorderSpacing.Bottom = 8
|
||||
BorderSpacing.Bottom = 4
|
||||
Constraints.MinWidth = 64
|
||||
TabOrder = 1
|
||||
Text = 'TargetEdit'
|
||||
end
|
||||
object ShowMeanDevChk: TCheckBox
|
||||
AnchorSideLeft.Control = TargetChk
|
||||
AnchorSideTop.Control = TargetEdit
|
||||
AnchorSideTop.Side = asrBottom
|
||||
Left = 12
|
||||
Height = 19
|
||||
Top = 27
|
||||
Width = 169
|
||||
BorderSpacing.Top = 4
|
||||
BorderSpacing.Bottom = 8
|
||||
Caption = 'Show mean group deviation'
|
||||
TabOrder = 2
|
||||
end
|
||||
end
|
||||
end
|
||||
inherited SpecsSplitter: TSplitter
|
||||
|
@ -15,6 +15,9 @@ type
|
||||
TCUSUMChartForm = class(TBasicSPCForm)
|
||||
AlphaEdit: TEdit;
|
||||
BetaEdit: TEdit;
|
||||
Label1: TLabel;
|
||||
VMaskScrollbar: TScrollBar;
|
||||
ShowMeanDevChk: TCheckBox;
|
||||
DeltaEdit: TEdit;
|
||||
GroupBox1: TGroupBox;
|
||||
GroupBox2: TGroupBox;
|
||||
@ -26,6 +29,7 @@ type
|
||||
procedure FormActivate(Sender: TObject);
|
||||
private
|
||||
SEMean: Double;
|
||||
k, h: Double;
|
||||
protected
|
||||
procedure Compute; override;
|
||||
procedure PlotMeans(ATitle, AXTitle, AYTitle, ADataTitle, AGrandMeanTitle: String;
|
||||
@ -52,7 +56,8 @@ uses
|
||||
procedure TCUSUMChartForm.Compute;
|
||||
var
|
||||
i, j, grpIndex, numGrps, grpSize, oldGrpSize, numValues: Integer;
|
||||
X, Xsq, Xmin, Xmax, target, grandMean, grandSum, grandSD, UCL, LCL: Double;
|
||||
X, Xsq, Xmin, Xmax, target, diff, grandMean, grandSum, grandSD: Double;
|
||||
deltaSD, alpha, beta: double;
|
||||
sizeError: Boolean;
|
||||
grp: String;
|
||||
groups: StrDyneVec = nil;
|
||||
@ -140,8 +145,9 @@ begin
|
||||
grandSum := grandSum + (means[0] - target);
|
||||
for j := 1 to numGrps-1 do
|
||||
begin
|
||||
cusums[j] := cusums[j-1] + (means[j] - target);
|
||||
grandSum := grandSum + (means[j] - target);
|
||||
diff := means[j] - target;
|
||||
cusums[j] := cusums[j-1] + diff;
|
||||
grandSum := grandSum + diff;
|
||||
end;
|
||||
|
||||
SEMean := SEMean - sqr(grandMean)/numValues;
|
||||
@ -150,9 +156,18 @@ begin
|
||||
SEMean := SEMean/sqrt(numValues);
|
||||
grandMean := grandMean/numValues; // mean of all observations
|
||||
grandSum := grandSum/numGrps; // mean of the group means
|
||||
UCL := grandMean + 3.0*SEMean;
|
||||
LCL := grandMean - 3.0*SEMean;
|
||||
if (LCL < 0.0) then LCL := 0.0;
|
||||
|
||||
if DeltaEdit.Text <> '' then
|
||||
begin
|
||||
deltaSD := StrToFloat(DeltaEdit.Text) / SEMean;
|
||||
// This is in multiples of std deviations
|
||||
|
||||
// see : https://www.itl.nist.gov/div898/handbook/pmc/section3/pmc323.htm
|
||||
alpha := StrToFloat(AlphaEdit.Text);
|
||||
beta := StrToFloat(BetaEdit.Text);
|
||||
k := deltaSD * SEMean / 2.0;
|
||||
h := SEMean / deltaSD * ln((1 - beta) / alpha);
|
||||
end;
|
||||
|
||||
// Print results
|
||||
lReport := TStringList.Create;
|
||||
@ -160,19 +175,35 @@ begin
|
||||
lReport.Clear;
|
||||
lReport.Add('CUSUM Chart Results');
|
||||
lReport.Add('');
|
||||
lReport.Add(' Group Size Mean Std.Dev. Cum.Dev. of' );
|
||||
lReport.Add(' Mean from Target');
|
||||
lReport.Add('------- ---- -------- -------- ----------------');
|
||||
for i := 0 to numGrps - 1 do
|
||||
lReport.Add('%7d %4d %8.2f %8.2f %10.2f', [i+1, count[i], means[i], stddev[i], cusums[i]]);
|
||||
lReport.Add('');
|
||||
lReport.Add('Mean of group deviations: %8.3f', [grandSum]);
|
||||
lReport.Add('Mean of all observations: %8.3f', [grandMean]);
|
||||
lReport.Add('Std. Dev. of Observations: %8.3f', [grandSD]);
|
||||
lReport.Add('Standard Error of Mean: %8.3f', [SEMean]);
|
||||
lReport.Add('Target Specification: %8.3f', [target]);
|
||||
lReport.Add('Lower Control Limit: %8.3f', [LCL]);
|
||||
lReport.Add('Upper Control Limit: %8.3f', [UCL]);
|
||||
|
||||
lReport.Add('');
|
||||
lReport.Add('Differences in data units');
|
||||
lReport.Add('');
|
||||
|
||||
lReport.Add('Group Size Mean Std.Dev. Mean-Dev Cum.Dev. of' );
|
||||
lReport.Add(' Mean from Target');
|
||||
lReport.Add('----- ---- -------- -------- -------- ----------------');
|
||||
for i := 0 to numGrps - 1 do
|
||||
begin
|
||||
lReport.Add('%5s %4d %8.3f %8.3f %8.3f %10.3f', [
|
||||
groups[i], count[i], means[i], stddev[i], means[i]-target, cusums[i]
|
||||
]);
|
||||
end;
|
||||
|
||||
if DeltaEdit.Text <> '' then
|
||||
begin
|
||||
lReport.Add('');
|
||||
lReport.Add('V-Mask parameters:');
|
||||
lReport.Add(' Alpha (Type I error) %8.3f', [alpha]);
|
||||
lReport.Add(' Beta (Type II error) %8.3f', [beta]);
|
||||
lReport.Add(' k: %8.3f (%.2f sigma)', [k, k/SEMean]);
|
||||
lReport.Add(' h: %8.3f (%.2f sigma)', [h, h/SEMean]);
|
||||
end;
|
||||
|
||||
ReportMemo.Lines.Assign(lReport);
|
||||
finally
|
||||
@ -180,6 +211,9 @@ begin
|
||||
end;
|
||||
|
||||
// Show graph
|
||||
VMaskScrollbar.Max := numGrps;
|
||||
if not ShowMeanDevChk.Checked then
|
||||
grandSum := NaN;
|
||||
PlotMeans(
|
||||
Format('Cumulative Sum Chart for "%s"', [GetFileName]), // chart title
|
||||
GroupEdit.Text, // x title
|
||||
@ -218,61 +252,58 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{ Overridden to draw the V-Mark }
|
||||
procedure TCUSUMChartForm.PlotMeans(ATitle, AXTitle, AYTitle, ADataTitle, AGrandMeanTitle: String;
|
||||
const Groups: StrDyneVec; const Means: DblDyneVec;
|
||||
UCL, LCL, GrandMean, TargetSpec, LowerSpec, UpperSpec: double);
|
||||
var
|
||||
alpha, beta, delta, deltaSD, gamma, d, h, k: Double;
|
||||
ser: TLineSeries;
|
||||
ext: TDoubleRect;
|
||||
x0, y0, x1, y1, x2, y2, x3, y3: Double;
|
||||
xVM, yVM, x1, y1, x2, y2, x3, y3, x4, y4: Double;
|
||||
begin
|
||||
inherited;
|
||||
if DeltaEdit.Text = '' then
|
||||
exit;
|
||||
|
||||
alpha := StrToFloat(AlphaEdit.Text);
|
||||
beta := StrToFloat(BetaEdit.Text);
|
||||
delta := StrToFloat(DeltaEdit.Text); // This is in data units
|
||||
deltaSD := delta / SEMean; // This is in multiples of std deviations
|
||||
|
||||
// see : https://www.itl.nist.gov/div898/handbook/pmc/section3/pmc323.htm
|
||||
d := 2.0 / sqr(deltaSD) * ln((1.0 - beta)/alpha);
|
||||
k := deltaSD * SEMean / 2.0;
|
||||
h := d * k;
|
||||
|
||||
ser := TLineSeries.Create(FChartFrame.Chart);
|
||||
FChartFrame.Chart.AddSeries(ser);
|
||||
ser.SeriesColor := clBlue;
|
||||
ser.Title := 'V-Mask';
|
||||
|
||||
ext := FChartFrame.Chart.GetFullExtent;
|
||||
x1 := Length(Means); // 1-based!
|
||||
y1 := Means[High(Means)] + h;
|
||||
x0 := 1;
|
||||
y0 := y1 - k*(x0 - x1);
|
||||
// Position of V mask point
|
||||
xVM := VMaskScrollbar.Position;
|
||||
yVM := Means[VMaskScrollbar.Position-1];
|
||||
|
||||
x2 := x1;
|
||||
y2 := Means[High(Means)] - h;
|
||||
x3 := x0;
|
||||
y3 := y2 + k*(x3 - x2);
|
||||
// Upper part of V mask
|
||||
x2 := xVM;
|
||||
y2 := yVM + h;
|
||||
x1 := 1; // x values begin with 1
|
||||
y1 := y2 - k*(x1 - x2);
|
||||
|
||||
// Lower part of V mask
|
||||
x3 := xVM;
|
||||
y3 := yVM - h;
|
||||
x4 := 1;
|
||||
y4 := y3 + k*(x4 - x3);
|
||||
|
||||
ser.AddXY(x0, y0);
|
||||
ser.AddXY(x1, y1);
|
||||
ser.AddXY(x2, y2);
|
||||
ser.AddXY(x2, NaN); // Do not draw the vertical line
|
||||
ser.AddXY(x3, y3);
|
||||
ser.AddXY(x4, y4);
|
||||
end;
|
||||
|
||||
|
||||
procedure TCUSUMChartForm.Reset;
|
||||
begin
|
||||
inherited;
|
||||
DeltaEdit.Clear;
|
||||
AlphaEdit.Text := FormatFloat('0.00', DEFAULT_ALPHA_LEVEL);
|
||||
BetaEdit.Text := FormatFloat('0.00', DEFAULT_BETA_LEVEL);
|
||||
ShowMeanDevChk.Checked := false;
|
||||
TargetEdit.Clear;
|
||||
DeltaEdit.Clear;
|
||||
AlphaEdit.Text := FormatFloat('0.00000', 0.0027); //DEFAULT_ALPHA_LEVEL);
|
||||
BetaEdit.Text := FormatFloat('0.00000', 0.01); //DEFAULT_BETA_LEVEL);
|
||||
VMaskScrollbar.Min := 2;
|
||||
VMaskScrollbar.Max := 1000;
|
||||
VMaskScrollbar.Position := VMaskScrollbar.Max;
|
||||
end;
|
||||
|
||||
|
||||
|
@ -2123,7 +2123,7 @@ procedure TOS3MainFrm.mnuAnalysisSPC_CChartClick(Sender: TObject);
|
||||
begin
|
||||
if CChartForm = nil then
|
||||
Application.CreateForm(TCChartForm, CChartForm);
|
||||
CChartForm.ShowModal;
|
||||
CChartForm.Show;
|
||||
end;
|
||||
|
||||
|
||||
@ -2132,7 +2132,7 @@ procedure TOS3MainFrm.mnuAnalysisSPC_CUSUMClick(Sender: TObject);
|
||||
begin
|
||||
if CUSUMChartForm = nil then
|
||||
Application.CreateForm(TCUSUMChartForm, CUSUMChartForm);
|
||||
CUSUMChartForm.ShowModal;
|
||||
CUSUMChartForm.Show;
|
||||
end;
|
||||
|
||||
|
||||
@ -2141,7 +2141,7 @@ procedure TOS3MainFrm.mnuAnalysisSPC_PChartClick(Sender: TObject);
|
||||
begin
|
||||
if PChartForm = nil then
|
||||
Application.CreateForm(TPChartForm, PChartForm);
|
||||
PChartForm.ShowModal;
|
||||
PChartForm.Show;
|
||||
end;
|
||||
|
||||
|
||||
@ -2150,7 +2150,7 @@ procedure TOS3MainFrm.mnuAnalysisSPC_RangeClick(Sender: TObject);
|
||||
begin
|
||||
if RChartForm = nil then
|
||||
Application.CreateForm(TRChartForm, RChartForm);
|
||||
RChartForm.ShowModal;
|
||||
RChartForm.Show;
|
||||
end;
|
||||
|
||||
|
||||
@ -2159,7 +2159,7 @@ procedure TOS3MainFrm.mnuAnalysisSPC_SChartClick(Sender: TObject);
|
||||
begin
|
||||
if SChartForm = nil then
|
||||
Application.CreateForm(TSChartForm, SChartForm);
|
||||
SChartForm.ShowModal;
|
||||
SChartForm.Show;
|
||||
end;
|
||||
|
||||
|
||||
@ -2168,7 +2168,7 @@ procedure TOS3MainFrm.mnuAnalysisSPC_UChartClick(Sender: TObject);
|
||||
begin
|
||||
if UChartForm = nil then
|
||||
Application.CreateForm(TUChartForm, UChartForm);
|
||||
UChartForm.ShowModal;
|
||||
UChartForm.Show;
|
||||
end;
|
||||
|
||||
|
||||
@ -2177,7 +2177,7 @@ procedure TOS3MainFrm.mnuAnalysisSPC_XBarClick(Sender: TObject);
|
||||
begin
|
||||
if XBarChartForm = nil then
|
||||
Application.CreateForm(TXBarChartForm, XBarChartForm);
|
||||
XBarChartForm.ShowModal;
|
||||
XBarChartForm.Show;
|
||||
end;
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user