diff --git a/spec/montgomery_spec.rb b/spec/montgomery_spec.rb index 332747d..39d599f 100644 --- a/spec/montgomery_spec.rb +++ b/spec/montgomery_spec.rb @@ -190,8 +190,9 @@ class MontgomerySpec < SpcSpec describe "Cusum with fixed target" do subject do DB.from( - Sequel.lit('spc_reports.cusum_rules(?, ?)', + Sequel.lit('spc_reports.cusum_rules(?, ?, ?)', 0.5, # allowance + 5, # decision interval 10 # target mean ) ).where(instrument_id:).order_by(:sample_id) diff --git a/sql/03-spc-reports-schema.sql b/sql/03-spc-reports-schema.sql index 6940d50..ea2b797 100644 --- a/sql/03-spc-reports-schema.sql +++ b/sql/03-spc-reports-schema.sql @@ -394,22 +394,28 @@ $$; -- Cumulative Sum aka Cusum +-- Asymmetric form of cusum_rules() create function spc_reports.cusum_rules( - p_allowance decimal - , p_target_mean decimal default null + p_upper_allowance decimal + , p_upper_decision_interval decimal + , p_lower_allowance decimal + , p_lower_decision_interval decimal + , p_target_mean decimal default null ) returns table ( - measurement_id bigint, - sample_id bigint, - window_id bigint, - instrument_id bigint, - measured_value decimal, - deviation decimal, - deviation_plus decimal, - deviation_minus decimal, - C_n decimal, - C_plus decimal, - C_minus decimal + measurement_id bigint, + sample_id bigint, + window_id bigint, + instrument_id bigint, + measured_value decimal, + deviation decimal, + deviation_plus decimal, + deviation_minus decimal, + C_n decimal, + C_plus decimal, + C_minus decimal, + upper_decision_interval boolean, + lower_decision_interval boolean ) immutable language sql as $$ @@ -419,18 +425,55 @@ $$ , s.instrument_id , m.measured_value , 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_minus + , m.measured_value - coalesce(p_target_mean, mean_measured_value) - p_upper_allowance as deviation_plus + , m.measured_value - coalesce(p_target_mean, mean_measured_value) + p_lower_allowance as deviation_minus , sum(m.measured_value - coalesce(p_target_mean, mean_measured_value)) 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)) + , spc_intermediates.cusum_c_plus(m.measured_value, p_upper_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)) + , spc_intermediates.cusum_c_minus(m.measured_value, p_lower_allowance, coalesce(p_target_mean, mean_measured_value)) over window_sample as C_minus + , spc_intermediates.cusum_c_plus(m.measured_value, p_upper_allowance, coalesce(p_target_mean, mean_measured_value)) + over window_sample > p_upper_decision_interval as upper_decision_interval + , spc_intermediates.cusum_c_minus(m.measured_value, p_lower_allowance, coalesce(p_target_mean, mean_measured_value)) + over window_sample < p_lower_decision_interval as lower_decision_interval 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 window window_sample as (partition by w.id order by m.sample_id); +$$; + +-- Symmetric form of cusum_rules() +create function spc_reports.cusum_rules( + p_allowance decimal + , p_decision_interval decimal + , p_target_mean decimal default null +) +returns table ( + measurement_id bigint, + sample_id bigint, + window_id bigint, + instrument_id bigint, + measured_value decimal, + deviation decimal, + deviation_plus decimal, + deviation_minus decimal, + C_n decimal, + C_plus decimal, + C_minus decimal, + upper_decision_interval boolean, + lower_decision_interval boolean +) +immutable language sql as +$$ +select * +from spc_reports.cusum_rules( + p_allowance + , p_decision_interval + , p_allowance + , p_decision_interval + , p_target_mean + ); $$; \ No newline at end of file