Skip to content

Commit

Permalink
Add C⁺ and C⁻ support in cusum_rules [#6]
Browse files Browse the repository at this point in the history
  • Loading branch information
jchester committed Aug 11, 2024
1 parent 46e1ce9 commit 1ff224d
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 8 deletions.
71 changes: 70 additions & 1 deletion spec/montgomery_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -190,10 +190,27 @@ class MontgomerySpec < SpcSpec
describe "Cusum with fixed target" do
subject do
DB.from(
Sequel.lit('spc_reports.cusum_rules(?)', 10) # target mean = 10
Sequel.lit('spc_reports.cusum_rules(?, ?)',
0.5, # allowance
10 # target mean
)
).where(instrument_id:).order_by(:sample_id)
end


describe "Calculating net deviation" do
it_has_correct_values(column: :deviation, values: [
# @formatter:off
-0.55, -2.01, -0.71, 1.66, 2.16,
0.18, -1.96, 1.46, -0.8, 0.34,
-0.97, 1.47, 0.51, -0.6, 0.08,
-0.63, 0.62, 0.31, -1.48, 0.84,
0.9, -0.67, 2.29, 1.5, 0.6,
1.08, 0.38, 1.62, 1.31, 0.52
# @formatter:on
])
end

describe "Calculating Cₙ" do
it_has_correct_values(column: :c_n, values: [
# @formatter:off
Expand All @@ -206,6 +223,58 @@ class MontgomerySpec < SpcSpec
# @formatter:on
])
end

describe "Calculating positive deviation" do
it_has_correct_values(column: :deviation_plus, values: [
# @formatter:off
-1.05, -2.51, -1.21, 1.16, 1.66,
-0.32, -2.46, 0.96, -1.3, -0.16,
-1.47, 0.97, 0.01, -1.1, -0.42,
-1.13, 0.12, -0.19, -1.98, 0.34,
0.4, -1.17, 1.79, 1.0, 0.1,
0.58, -0.12, 1.12, 0.81, 0.02
# @formatter:on
])
end

describe "Calculating C⁺" do
it_has_correct_values(column: :c_plus, values: [
# @formatter:off
0, 0, 0, 1.16, 2.82,
2.50, 0.04, 1.00, 0, 0,
0, 0.97, 0.98, 0, 0,
0, 0.12, 0, 0, 0.34,
0.74, 0, 1.79, 2.79, 2.89,
3.47, 3.35, 4.47, 5.28, 5.30
# @formatter:on
])
end

describe "Calculating negative deviation" do
it_has_correct_values(column: :deviation_minus, values: [
# @formatter:off
-0.05, -1.51, -0.21, 2.16, 2.66,
0.68, -1.46, 1.96, -0.3, 0.84,
-0.47, 1.97, 1.01, -0.1, 0.58,
-0.13, 1.12, 0.81, -0.98, 1.34,
1.4, -0.17, 2.79, 2.0, 1.1,
1.58, 0.88, 2.12, 1.81, 1.02
# @formatter:on
])
end

describe "Calculating C⁻" do
it_has_correct_values(column: :c_minus, values: [
# @formatter:off
-0.05, -1.56, -1.77, 0, 0,
0, -1.46, 0, -0.3, 0,
-0.47, 0, 0, -0.1, 0,
-0.13, 0, 0, -0.98, 0,
0, -0.17, 0, 0, 0,
0, 0, 0, 0, 0
# @formatter:on
])
end
end
end
end
37 changes: 37 additions & 0 deletions sql/02-spc-intermediates-schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -508,3 +508,40 @@ $$;

-- Cumulative Sum, aka Cusum

create function spc_intermediates.cusum_c_plus_step(
last_c_plus decimal
, measurement decimal
, allowance decimal
, target_mean decimal
) returns decimal immutable language sql as
$$
select greatest(coalesce(last_c_plus, 0) + (measurement - target_mean - allowance), 0);
$$;

create aggregate spc_intermediates.cusum_c_plus(
measurement decimal
, allowance decimal
, target_mean decimal
) (
sfunc = spc_intermediates.cusum_c_plus_step,
stype = decimal
);

create function spc_intermediates.cusum_c_minus_step(
last_c_minus decimal
, measurement decimal
, allowance decimal
, target_mean decimal
) returns decimal immutable language sql as
$$
select least(coalesce(last_c_minus, 0) + (measurement - target_mean + allowance), 0);
$$;

create aggregate spc_intermediates.cusum_c_minus(
measurement decimal
, allowance decimal
, target_mean decimal
) (
sfunc = spc_intermediates.cusum_c_minus_step,
stype = decimal
);
26 changes: 19 additions & 7 deletions sql/03-spc-reports-schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -395,30 +395,42 @@ $$;
-- Cumulative Sum aka Cusum

create function spc_reports.cusum_rules(
p_target_mean decimal default null
p_allowance decimal
, p_target_mean decimal default null
)
returns table (
measurement_id bigint,
sample_id bigint,
window_id bigint,
instrument_id bigint,
measured_value decimal,
error decimal,
C_n decimal
deviation decimal,
deviation_plus decimal,
deviation_minus decimal,
C_n decimal,
C_plus decimal,
C_minus decimal
)
immutable language sql as
$$
select m.id as measurement_id
, m.sample_id
, w.id as window_id
, w.id as window_id
, s.instrument_id
, m.measured_value
, m.measured_value - coalesce(p_target_mean, mean_measured_value) as error
, m.measured_value - coalesce(p_target_mean, mean_measured_value) as deviation
, m.measured_value - coalesce(p_target_mean, mean_measured_value) - p_allowance as deviation_plus
, m.measured_value - coalesce(p_target_mean, mean_measured_value) + p_allowance as deviation_plus
, sum(m.measured_value - coalesce(p_target_mean, mean_measured_value))
over (partition by w.id order by m.id) as C_n
over (partition by w.id order by m.id) as C_n
, spc_intermediates.cusum_c_plus(m.measured_value, p_allowance, coalesce(p_target_mean, mean_measured_value))
over window_sample as C_plus
, spc_intermediates.cusum_c_minus(m.measured_value, p_allowance, coalesce(p_target_mean, mean_measured_value))
over window_sample as C_minus
from spc_data.measurements m
join spc_data.samples s on s.id = m.sample_id
join spc_data.instruments i on i.id = s.instrument_id
join spc_data.windows w on i.id = w.instrument_id
join spc_intermediates.individual_measurement_statistics_ewma imse on w.id = imse.window_id;
join spc_intermediates.individual_measurement_statistics_ewma imse on w.id = imse.window_id
window window_sample as (partition by w.id order by m.sample_id);
$$;

0 comments on commit 1ff224d

Please sign in to comment.