br_maths/
spc.rs

1use json::{JsonValue, object};
2pub struct Spc {
3    /// 数据
4    pub data: Vec<f64>,
5    /// 数据长度
6    pub data_len: usize,
7    /// 样本分组数量
8    pub group_len: usize,
9    /// 规格上限
10    pub upper: f64,
11    /// 规格下限
12    pub lower: f64,
13    /// 标准值
14    pub value: f64,
15
16    /// 最大值
17    pub max: f64,
18    /// 最小值
19    pub min: f64,
20    /// 平均值
21    pub avg: f64,
22    /// 总值
23    pub total: f64,
24    /// 组均值
25    pub group_avg: Vec<f64>,
26    /// 组极差
27    pub group_range: Vec<f64>,
28    /// 组极差-最大
29    pub group_range_max: f64,
30    /// 组极差-最小
31    pub group_range_min: f64,
32
33    /// 组极差-r-均值集合
34    pub group_r_avgs: Vec<f64>,
35    /// 组极差-x-均值集合
36    pub group_x_avgs: Vec<f64>,
37    /// 组极差-r-均值
38    pub group_r_avg: f64,
39    /// 组极差-x-均值
40    pub group_x_avg: f64,
41
42    pub group_r_avg_sum: f64,
43    pub group_x_avg_sum: f64,
44
45    /// 组极差-合计-集合
46    pub group_sums: Vec<f64>,
47
48    /// 组数据
49    pub group_data: Vec<Vec<f64>>,
50    /// 小数位
51    pub decimal: usize,
52    /// 能力指数上限(CPU)
53    pub cpu: f64,
54    /// 能力指数下限(CPL)
55    pub cpl: f64,
56    /// 控制 A2 系数
57    pub a2: f64,
58    /// 控制 d2 系数
59    pub d2: f64,
60    /// 控制 D3 系数
61    pub d3: f64,
62    /// 控制 D4 系数
63    pub d4: f64,
64
65    /// 能力指数 (Cp)
66    pub cp: f64,
67    /// 过程能力指数 (Cpk)
68    pub cpk: f64,
69    /// 过程能力比值 (CR)
70    pub cr: f64,
71    /// 标准差 (n-1) 样本标准差
72    pub stdev: f64,
73    /// 标准差 (n) 总体标准差
74    pub stdevp: f64,
75    /// 变差 (n-1)
76    pub var: f64,
77    /// 变差 (n)
78    pub varp: f64,
79    /// 性能指数 (PP)
80    pub pp: f64,
81    /// 性能比率 (PR)
82    pub pr: f64,
83    /// 性能指数 (PPK)
84    pub ppk: f64,
85
86    /// 西格玛
87    pub sigma: f64,
88    /// 西格玛数组
89    pub sigma_list: Vec<f64>,
90
91    /// R 图 UCLr指标
92    pub uclr: f64,
93    /// R 图 极差值均值
94    pub clr: f64,
95    /// R 图 LCLr指标
96    pub lclr: f64,
97
98    /// X 图 UCLx 指标
99    pub uclx: f64,
100    /// X 图 CLx 均值指标
101    pub clx: f64,
102    /// X 图 UCLx 指标
103    pub lclx: f64,
104}
105
106impl Spc {
107    /// 初始化
108    ///
109    /// * usl 上限值
110    /// * lsl 下限值
111    /// * value 标准值
112    /// * array 测量数据
113    /// * group_len 样本组数量
114    /// * decimal 小数位
115    pub fn new(upper: f64, lower: f64, value: f64, array: Vec<f64>, group_len: usize, decimal: usize) -> Self {
116        Self {
117            data: array.clone(),
118            data_len: array.len(),
119            total: 0.0,
120            upper,
121            value,
122            lower,
123            // stddev,
124            max: 0.0,
125            min: 0.0,
126            avg: 0.0,
127            // cpk,
128            // ca: ca * 100.0,
129            // cp,
130            group_len,
131            group_avg: vec![],
132            group_range: vec![],
133            group_range_max: 0.0,
134            group_range_min: 0.0,
135            group_r_avgs: vec![],
136            group_data: vec![],
137            decimal,
138            cpu: 0.0,
139            cpl: 0.0,
140            a2: a2(group_len),
141            d2: d2(group_len),
142            d3: d3(group_len),
143            d4: d4(group_len),
144            cp: 0.0,
145            cpk: 0.0,
146            cr: 0.0,
147            stdev: 0.0,
148            stdevp: 0.0,
149            var: 0.0,
150            varp: 0.0,
151            pp: 0.0,
152            pr: 0.0,
153            ppk: 0.0,
154            sigma: 0.0,
155            sigma_list: vec![],
156            group_x_avgs: vec![],
157            group_r_avg: 0.0,
158            group_x_avg: 0.0,
159            group_r_avg_sum: 0.0,
160            group_x_avg_sum: 0.0,
161            group_sums: vec![],
162            uclr: 0.0,
163            clr: 0.0,
164            lclr: 0.0,
165            uclx: 0.0,
166            clx: 0.0,
167            lclx: 0.0,
168        }
169    }
170    pub fn compute(&mut self) -> &mut Self {
171        self.max = 0.0;
172        self.min = self.data[0].to_string().parse::<f64>().unwrap();
173        let mut group_list = vec![];
174
175        for x in self.data.clone() {
176            self.total += x;
177            if x > self.max {
178                self.max = x;
179            }
180            if x < self.min {
181                self.min = x;
182            }
183            group_list.push(x);
184            if group_list.len() == self.group_len {
185                self.get_group_list_info(group_list.clone());
186                self.group_data.push(group_list.clone());
187                group_list = vec![];
188            }
189        }
190        // 补数组不够的
191        if !group_list.is_empty() {
192            self.get_group_list_info(group_list.clone());
193            self.group_data.push(group_list.clone());
194        }
195
196        self.uclr = self.d4 * self.group_r_avg;
197        self.uclr = format!("{0:.1$}", self.uclr, self.decimal).parse::<f64>().unwrap();
198
199        self.clr = self.group_r_avg;
200        self.clr = format!("{0:.1$}", self.clr, self.decimal).parse::<f64>().unwrap();
201
202        self.lclr = self.d3 * self.group_r_avg;
203        self.lclr = format!("{0:.1$}", self.lclr, self.decimal).parse::<f64>().unwrap();
204
205
206        self.uclx = self.group_x_avg + self.a2 * self.group_r_avg;
207        self.uclx = format!("{0:.1$}", self.uclx, self.decimal).parse::<f64>().unwrap();
208
209        self.clx = self.group_x_avg;
210        self.clx = format!("{0:.1$}", self.clx, self.decimal).parse::<f64>().unwrap();
211
212        self.lclx = self.group_x_avg - self.a2 * self.group_r_avg;
213        self.lclx = format!("{0:.1$}", self.lclx, self.decimal).parse::<f64>().unwrap();
214
215        self.cp = (self.upper - self.lower) / (6.0 * (self.group_r_avg / self.d2));
216
217        let k = (self.value - self.group_x_avg).abs() / ((self.upper - self.lower) / 2.0);
218        self.cpk = (1.0 - k) * self.cp;
219
220        self.cp = format!("{0:.1$}", self.cp, self.decimal).parse::<f64>().unwrap();
221        self.cpk = format!("{0:.1$}", self.cpk, self.decimal).parse::<f64>().unwrap();
222
223        self.avg = self.data.clone().iter().sum::<f64>() / self.data_len as f64;
224        // 方差
225        let variance = self.data.clone().iter().map(|value| {
226            let diff = self.avg - *value;
227            diff * diff
228        }).sum::<f64>() / (self.data_len - 1) as f64;
229        // 标准差
230        self.sigma = variance.sqrt();
231
232        self
233    }
234    fn get_group_list_info(&mut self, mut group_list: Vec<f64>) {
235        group_list.sort_by(|a, b| a.partial_cmp(b).unwrap());
236
237        let max = group_list.last().unwrap();
238        let min = group_list.first().unwrap();
239
240        let max_min = format!("{0:.1$}", max - min, self.decimal).parse::<f64>().unwrap();
241
242        self.group_r_avgs.push(max_min);
243        self.group_r_avg_sum = self.group_r_avgs.iter().sum();
244        self.group_r_avg = self.group_r_avg_sum / self.group_r_avgs.len() as f64;
245
246        let mut total = 0.0;
247        for group in group_list.clone() {
248            total += group;
249        }
250        self.group_sums.push(total);
251
252        let group_x_avg = format!("{0:.1$}", total / group_list.len() as f64, self.decimal).parse::<f64>().unwrap();
253        self.group_x_avgs.push(group_x_avg);
254        self.group_x_avg_sum = self.group_x_avgs.iter().sum();
255        self.group_x_avg = self.group_x_avg_sum / self.group_x_avgs.len() as f64;
256    }
257    pub fn xbar_r(&self) -> JsonValue {
258        object! {
259            data:self.group_r_avgs.clone(),
260            UCLR:self.uclr,
261            CLR:self.clr,
262            LCLR:self.lclr
263        }
264    }
265    pub fn xbar_x(&self) -> JsonValue {
266        object! {
267            data:self.group_x_avgs.clone(),
268            UCLX:self.uclx,
269            CLX:self.clx,
270            LCLX:self.lclx
271        }
272    }
273    pub fn cpk_rating_criteria(&self) -> (&'static str, &'static str) {
274        if self.cpk >= 2.0 {
275            ("A++", "特优,可考虑降低成本。")
276        } else if 1.67 <= self.cpk && self.cpk < 2.0 {
277            return ("A+", "优,应当保持之。");
278        } else if 1.33 <= self.cpk && self.cpk < 1.67 {
279            ("A", "良,能力好,状态稳定,但应尽力提升到A+级。")
280        } else if 1.00 <= self.cpk && self.cpk < 1.33 {
281            ("B", "一般,制程因素稍有变异即有生产不良的危险,应利用各种资源及方法将其提升为A级。")
282        } else if 0.67 <= self.cpk && self.cpk < 1.00 {
283            ("C", "差,制程不良较多。须提升其能力。")
284        } else {
285            ("D", "不可接受,其能力太差,应考虑重新整改设计制程。")
286        }
287    }
288    pub fn cp_rating_criteria(&self) -> (&'static str, &'static str) {
289        if self.cp >= 1.67 {
290            ("A+", "无缺点,可考虑降低成本。")
291        } else if 1.33 <= self.cp && self.cp <= 1.67 {
292            ("A", "状态良好维持现状。")
293        } else if 1.00 <= self.cp && self.cp <= 1.33 {
294            ("B", "可以改进为A级。")
295        } else if 0.67 <= self.cp && self.cp <= 1.00 {
296            ("C", "制程不良较多。须提升能力。")
297        } else {
298            ("D", "制程能力好差,应考虑重新整改设计制程。")
299        }
300    }
301}
302
303/// 计量型 X-R图 A2
304fn a2(len: usize) -> f64 {
305    match len {
306        2 => 1.880,
307        3 => 1.023,
308        4 => 0.729,
309        5 => 0.577,
310        6 => 0.483,
311        7 => 0.149,
312        8 => 0.373,
313        9 => 0.337,
314        10 => 0.308,
315        11 => 0.285,
316        12 => 0.266,
317        13 => 0.249,
318        14 => 0.235,
319        15 => 0.223,
320        16 => 0.212,
321        17 => 0.203,
322        18 => 0.194,
323        19 => 0.187,
324        20 => 0.180,
325        21 => 0.173,
326        22 => 0.167,
327        23 => 0.162,
328        24 => 0.157,
329        25 => 0.153,
330        _ => 0.0
331    }
332}
333
334/// 计量型 X-R图 d2
335fn d2(len: usize) -> f64 {
336    match len {
337        2 => 1.128,
338        3 => 1.693,
339        4 => 2.059,
340        5 => 2.326,
341        6 => 2.534,
342        7 => 2.704,
343        8 => 2.847,
344        9 => 2.970,
345        10 => 3.078,
346        11 => 3.173,
347        12 => 3.258,
348        13 => 3.336,
349        14 => 3.407,
350        15 => 3.472,
351        16 => 3.532,
352        17 => 3.588,
353        18 => 3.640,
354        19 => 3.689,
355        20 => 3.735,
356        21 => 3.778,
357        22 => 3.819,
358        23 => 3.858,
359        24 => 3.895,
360        25 => 3.931,
361        _ => 0.0
362    }
363}
364
365/// 计量型 X-R图 D3 计算控制限用的系数 LCLr
366fn d3(len: usize) -> f64 {
367    match len {
368        7 => 0.076,
369        8 => 0.136,
370        9 => 0.184,
371        10 => 0.223,
372        11 => 0.256,
373        12 => 0.283,
374        13 => 0.307,
375        14 => 0.328,
376        15 => 0.347,
377        16 => 0.363,
378        17 => 0.738,
379        18 => 0.391,
380        19 => 0.403,
381        20 => 0.415,
382        21 => 0.425,
383        22 => 0.434,
384        23 => 0.443,
385        24 => 0.451,
386        25 => 0.459,
387        _ => 0.0
388    }
389}
390
391/// 计量型 X-R图 D4 计算控制限用的系数 UCLr
392fn d4(len: usize) -> f64 {
393    match len {
394        2 => 3.267,
395        3 => 2.574,
396        4 => 2.282,
397        5 => 2.114,
398        6 => 2.004,
399        7 => 1.924,
400        8 => 1.864,
401        9 => 1.816,
402        10 => 1.777,
403        11 => 1.744,
404        12 => 1.717,
405        13 => 1.693,
406        14 => 1.672,
407        15 => 1.653,
408        16 => 1.637,
409        17 => 1.622,
410        18 => 1.608,
411        19 => 1.597,
412        20 => 1.585,
413        21 => 1.575,
414        22 => 1.566,
415        23 => 1.557,
416        24 => 1.548,
417        25 => 1.541,
418        _ => 0.0
419    }
420}