br_maths/
processing_analysis.rs

1use json::{JsonValue, object};
2
3/// 加工分析
4#[derive(Debug, Clone)]
5pub struct Pa {
6    /// 整体数据
7    pub data_whole: Vec<f64>,
8    /// 基础数据
9    data: Vec<f64>,
10    // /// 分组数据
11    // data_groups: Vec<Vec<f64>>,
12    /// 总体数量
13    pub total: f64,
14    pub center_value: f64,
15    /// 规格上限
16    pub usl: f64,
17    /// 规格下限
18    pub lsl: f64,
19    /// 标准差 整体
20    pub std_dev_zt: f64,
21    /// 标准差 组内
22    pub std_dev_zn: f64,
23    /// 样本标准差 组内 列表
24    pub std_dev_zn_data: Vec<f64>,
25    /// 组内 均值
26    pub average_zn: f64,
27    /// 整体 均值
28    pub average_zt: f64,
29    /// 过程性能指数
30    pub pp: f64,
31    pub ppl: f64,
32    pub ppu: f64,
33    pub ppk: f64,
34    /// 精密度 CPK
35    pub cpk: f64,
36    /// 精确度 cp
37    pub cp: f64,
38    /// 精确度 cpu 上限要求
39    pub cpu: f64,
40    /// 精确度 cpl 下限要求
41    pub cpl: f64,
42    /// ppm
43    pub ppm: f64,
44    /// 缺陷数量
45    pub defects: f64,
46    /// 中心偏移
47    pub offset_center: f64,
48    /// 精确度 Ca
49    pub ca: f64,
50    /// 规格中心值
51    pub scv: f64,
52    /// 最大值
53    pub max_value: f64,
54    /// 最小值
55    pub min_value: f64,
56    /// 样本极差值
57    pub avg_r: Vec<f64>,
58
59    /// 分组数
60    pub group_count: usize,
61    /// 分组后的平均值
62    pub average_zn_data: Vec<f64>,
63    /// 组内极差数据
64    pub range_zn_data: Vec<f64>,
65    /// 组内极差值
66    pub range_zn: f64,
67}
68
69impl Pa {
70    /// 初始化
71    /// * types true 计量型 false 计数型
72    /// * group_count 分组数量
73    pub fn new(data: Vec<f64>, usl: f64, lsl: f64, mut group_count: usize, types: bool) -> Pa {
74        let data_whole = data.clone();
75        if group_count == 0 {
76            group_count = data.len().to_string().parse::<f64>().unwrap().sqrt() as usize;
77        }
78        if !types {
79            group_count = 0;
80        }
81        let total = data_whole.len() as f64;
82        let max_value = data_whole.iter().cloned().fold(f64::NEG_INFINITY, f64::max);
83        let min_value = data_whole.iter().cloned().fold(f64::INFINITY, f64::min);
84
85        let center_value = (max_value + min_value) / 2.0;
86
87        let filtered_records: Vec<f64> = data_whole.clone().into_iter()
88            .filter(|&x| x > usl || x < lsl)
89            .collect::<Vec<f64>>();
90        let defects = filtered_records.len() as f64;
91
92        // 整体均值
93        let mut average_zt = data_whole.iter().sum::<f64>() / data_whole.clone().len() as f64;
94        average_zt = format!("{:.4}", average_zt).parse::<f64>().unwrap();
95
96        // 整体标准差
97        let std_dev_zt = standard_deviation(data_whole.clone(), average_zt);
98
99
100        // let mut data_groups = vec![];
101        let mut range_zn_data = vec![];
102        let mut average_zn_data = vec![];
103        let mut std_dev_zn_data = vec![];
104        let mut average_zn = 0.0;
105        let mut range_zn = 0.0;
106        let mut std_dev_zn = 0.0;
107        let mut variance_list = vec![];
108        if group_count > 0 {
109            let data_groups = data_whole.chunks(group_count)
110                .map(|chunk| {
111                    let group = chunk.to_vec();
112                    // 组内极差数组
113                    let max_value = group.iter().cloned().fold(f64::NEG_INFINITY, f64::max);
114                    let min_value = group.iter().cloned().fold(f64::INFINITY, f64::min);
115                    range_zn_data.push(max_value - min_value);
116                    // 组内均值数据
117                    let average = group.iter().sum::<f64>() / group.len() as f64;
118                    average_zn_data.push(average);
119                    // 组内标准差数据
120                    let subgroup_variance = group.iter().map(|&x| (x - average).powi(2)).sum::<f64>() / (group.len() - 1) as f64;
121                    std_dev_zn_data.push(subgroup_variance.sqrt());
122                    // 组内标准差结果
123                    variance_list.push(subgroup_variance);
124
125                    group
126                }).collect::<Vec<Vec<f64>>>();
127
128            range_zn = range_zn_data.iter().sum::<f64>() / range_zn_data.len() as f64;
129            range_zn = format!("{:.4}", range_zn).parse::<f64>().unwrap();
130
131
132            average_zn = average_zn_data.iter().sum::<f64>() / average_zn_data.len() as f64;
133            average_zn = format!("{:.4}", average_zn).parse::<f64>().unwrap();
134
135
136            // 计算 Sp 的自由度
137            let total_dof = data_groups.iter().map(|n| (n.len() - 1) as f64).sum::<f64>();
138            let c4_value = c4(total_dof as usize);
139
140            let within_group_variance = variance_list.iter().sum::<f64>() / variance_list.len() as f64;
141            std_dev_zn = within_group_variance.sqrt() * c4_value;
142
143            // std_dev_zn = within_group_variance.sqrt();
144            std_dev_zn = format!("{:.5}", std_dev_zn).parse::<f64>().unwrap();
145        }
146
147        Self {
148            data_whole,
149            data: data.clone(),
150            average_zn,
151            range_zn,
152            total,
153            usl,
154            lsl,
155            std_dev_zt,
156            std_dev_zn,
157            pp: 0.0,
158            ppl: 0.0,
159            ppu: 0.0,
160            ppk: 0.0,
161            cpk: 0.0,
162            cp: 0.0,
163            cpu: 0.0,
164            cpl: 0.0,
165            ppm: 0.0,
166            defects,
167            offset_center: 0.0,
168            ca: 0.0,
169            scv: 0.0,
170            max_value,
171            min_value,
172            avg_r: vec![],
173            group_count,
174            average_zt,
175
176            center_value,
177            // data_groups,
178            std_dev_zn_data,
179            average_zn_data,
180            range_zn_data,
181        }
182    }
183    /// 精确度 Ca
184    pub fn ca(&mut self) {
185        if self.ca != 0.0 {
186            return;
187        }
188        self.scv = (self.usl + self.lsl) / 2.0;
189        self.offset_center = (self.scv - self.average_zn).abs();
190        self.ca = self.offset_center / ((self.usl - self.lsl) / 2.0);
191        self.ca = format!("{:.3}", self.ca).parse::<f64>().unwrap();
192    }
193    /// 精密度 cpk
194    /// true 第一种方法考虑了规范上限和下限与平均值之间的差异,分别计算了规范上限和下限的 CPK 值,并选择了较小的值作为最终的 CPK 值。这种方法更适用于当规范上限和下限的差异较大时,或者当你更关注上限和下限之间的不对称性时
195    /// false 第二种方法直接计算了规范上限和下限之间的距离,并以此作为 CPK 的分子。这种方法更适用于当你关注的是整个过程的总体能力时,而不考虑上限和下限之间的差异。
196    pub fn cpk(&mut self) {
197        if self.cpk != 0.0 {
198            return;
199        }
200        self.cp();
201        self.ca();
202        let cpk = f64::min(self.cpu, self.cpl);
203        self.cpk = format!("{:.3}", cpk).parse::<f64>().unwrap();
204    }
205    /// cpk 的结果
206    pub fn cpk_desc(&mut self) -> (&'static str, &'static str) {
207        self.cpk();
208        match self.cpk {
209            2.0.. => {
210                ("A++", "过程非常稳定,质量控制良好,可考虑降低成本。")
211            }
212            1.67..=2.0 => {
213                ("A+", "质量控制良好,过程基本稳定,但仍有改进的潜力。")
214            }
215            1.33..=1.67 => {
216                ("A", "过程基本稳定,但存在改进的空间,质量控制较为良好。")
217            }
218            1.00..=1.33 => {
219                ("B", "过程接近边界,质量控制需要改进,但可能仍能满足一些标准。")
220            }
221            0.67..=1.00 => {
222                ("C", "过程不稳定,质量控制问题严重,需要立即调整和改进。")
223            }
224            _ => ("D", "不可接受,其能力太差,应考虑重新整改设计制程。")
225        }
226    }
227
228    /// PPM
229    /// (Parts Per Million,百万分之一)是一种用于表示某个物质或事件在总体中的比例或浓度的单位。在质量管理中,PPM 通常用于表示产品的缺陷率或质量水平。
230    pub fn ppm(&mut self) {
231        if self.ppm != 0.0 {
232            return;
233        }
234        self.ppm = (self.defects / self.total) * 1_000_000.0;
235        self.ppm = format!("{:.0}", self.ppm).parse::<f64>().unwrap();
236    }
237    pub fn cp(&mut self) {
238        if self.cp != 0.0 {
239            return;
240        }
241        self.cp = (self.usl - self.lsl) / (6.0 * self.std_dev_zn);
242
243        if self.average_zn >= self.usl {
244            self.cpu = 0.0
245        } else {
246            self.cpu = (self.usl - self.average_zn) / (3.0 * self.std_dev_zn)
247        }
248        if self.average_zn <= self.lsl {
249            self.cpl = 0.0
250        } else {
251            self.cpl = (self.average_zn - self.lsl) / (3.0 * self.std_dev_zn)
252        }
253        self.cp = format!("{:.3}", self.cp).parse::<f64>().unwrap();
254        self.cpu = format!("{:.3}", self.cpu).parse::<f64>().unwrap();
255        self.cpl = format!("{:.3}", self.cpl).parse::<f64>().unwrap();
256    }
257    #[allow(clippy::type_complexity)]
258    pub fn cp_desc(&mut self) -> ((f64, &str, &str), (f64, &str, &str), (f64, &str, &str)) {
259        self.cp();
260        let cp = match self.cp {
261            2.0.. => {
262                (self.cp, "A++", "过程非常稳定,质量控制良好,可考虑降低成本。")
263            }
264            1.67..=2.0 => {
265                (self.cp, "A+", "质量控制良好,过程基本稳定,但仍有改进的潜力。")
266            }
267            1.33..=1.67 => {
268                (self.cp, "A", "过程基本稳定,但存在改进的空间,质量控制较为良好。")
269            }
270            1.00..=1.33 => {
271                (self.cp, "B", "过程接近边界,质量控制需要改进,但可能仍能满足一些标准。")
272            }
273            0.67..=1.00 => {
274                (self.cp, "C", "过程不稳定,质量控制问题严重,需要立即调整和改进。")
275            }
276            _ => (self.cp, "D", "不可接受,其能力太差,应考虑重新整改设计制程。")
277        };
278
279        let cpu = match self.cpu {
280            2.0.. => {
281                (self.cpu, "A++", "过程非常稳定,质量控制良好,可考虑降低成本。")
282            }
283            1.67..=2.0 => {
284                (self.cpu, "A+", "质量控制良好,过程基本稳定,但仍有改进的潜力。")
285            }
286            1.33..=1.67 => {
287                (self.cpu, "A", "过程基本稳定,但存在改进的空间,质量控制较为良好。")
288            }
289            1.00..=1.33 => {
290                (self.cpu, "B", "过程接近边界,质量控制需要改进,但可能仍能满足一些标准。")
291            }
292            0.67..=1.00 => {
293                (self.cpu, "C", "过程不稳定,质量控制问题严重,需要立即调整和改进。")
294            }
295            _ => (self.cpu, "D", "不可接受,其能力太差,应考虑重新整改设计制程。")
296        };
297
298        let cpl = match self.cpl {
299            2.0.. => {
300                (self.cpl, "A++", "过程非常稳定,质量控制良好,可考虑降低成本。")
301            }
302            1.67..=2.0 => {
303                (self.cpl, "A+", "质量控制良好,过程基本稳定,但仍有改进的潜力。")
304            }
305            1.33..=1.67 => {
306                (self.cpl, "A", "过程基本稳定,但存在改进的空间,质量控制较为良好。")
307            }
308            1.00..=1.33 => {
309                (self.cpl, "B", "过程接近边界,质量控制需要改进,但可能仍能满足一些标准。")
310            }
311            0.67..=1.00 => {
312                (self.cpl, "C", "过程不稳定,质量控制问题严重,需要立即调整和改进。")
313            }
314            _ => (self.cpl, "D", "不可接受,其能力太差,应考虑重新整改设计制程。")
315        };
316        (cpu, cp, cpl)
317    }
318
319    /// 正态分布图
320    pub fn normal_distribution_plot(&mut self) -> Vec<Vec<f64>> {
321        let list = vec![
322            vec![self.scv - self.std_dev_zt * 3.0, self.scv - self.std_dev_zt * 2.0],
323            vec![self.scv - self.std_dev_zt * 2.0, self.scv - self.std_dev_zt * 1.0],
324            vec![self.scv - self.std_dev_zt * 1.0, self.scv],
325            vec![self.scv, self.scv + self.std_dev_zt * 1.0],
326            vec![self.scv + self.std_dev_zt * 1.0, self.scv + self.std_dev_zt * 2.0],
327            vec![self.scv + self.std_dev_zt * 2.0, self.scv + self.std_dev_zt * 3.0]
328        ];
329        // 计算每个区间内的数据点数量
330        let mut counts = vec![0.0; list.len()];
331        for &value in self.data.iter() {
332            for (index, item) in list.iter().enumerate() {
333                if value >= item[0] && value < item[1] {
334                    counts[index] += 1.0;
335                    break;
336                }
337            }
338        }
339
340        list
341    }
342
343    /// 计算R(范围)
344    pub fn xbar_r(&mut self) -> JsonValue {
345        let x_ucl = self.average_zn + a2(self.group_count) * self.range_zn;
346        let x_ucl = format!("{:.3}", x_ucl).parse::<f64>().unwrap();
347
348        let x_lcl = self.average_zn - a2(self.group_count) * self.range_zn;
349        let x_lcl = format!("{:.3}", x_lcl).parse::<f64>().unwrap();
350
351        let r_ucl = format!("{:.3}", d4(self.group_count) * self.range_zn).parse::<f64>().unwrap();
352        let r_lcl = 0.00;
353
354        object! {
355            group_count:self.group_count,
356            usl:self.usl,
357            lsl:self.lsl,
358            x_double_bar:self.average_zn,
359            x_ucl:x_ucl,
360            x_lcl:x_lcl,
361            average_zn_data:self.average_zn_data.clone(),
362            r_double_bar:self.range_zn,
363            r_ucl:r_ucl,
364            r_lcl:r_lcl,
365            range_data: self.range_zn_data.clone()
366        }
367    }
368    /// 计算R(范围)
369    pub fn xbar_s(&mut self) -> JsonValue {
370        let mut std_dev_zn = self.std_dev_zn_data.iter().sum::<f64>() / self.std_dev_zn_data.len() as f64;
371        std_dev_zn = format!("{:.3}", std_dev_zn).parse::<f64>().unwrap();
372        if std_dev_zn.is_nan() {
373            std_dev_zn = 0.0;
374        }
375
376        let x_ucl = self.average_zn + a3(self.group_count) * std_dev_zn;
377        let x_lcl = self.average_zn - a3(self.group_count) * std_dev_zn;
378
379        let x_ucl = format!("{:.3}", x_ucl).parse::<f64>().unwrap();
380        let x_lcl = format!("{:.3}", x_lcl).parse::<f64>().unwrap();
381
382        let s_ucl = b4(self.group_count) * std_dev_zn;
383        let s_ucl = format!("{:.3}", s_ucl).parse::<f64>().unwrap();
384
385        let s_lcl = b3(self.group_count) * std_dev_zn;
386
387        object! {
388            group_count:self.group_count,
389            usl:self.usl,
390            lsl:self.lsl,
391            x_double_bar:self.average_zn,
392            x_ucl:x_ucl,
393            x_lcl:x_lcl,
394            average_zn_data:self.average_zn_data.clone(),
395            s_double_bar:std_dev_zn,
396            s_ucl:s_ucl,
397            s_lcl:s_lcl,
398            std_dev_zn_data: self.std_dev_zn_data.clone()
399        }
400    }
401    /// 计算R(范围)
402    pub fn xbar(&mut self) -> (f64, f64, f64) {
403        let x_ucl = self.average_zn + a2(self.group_count) * self.range_zn;
404        let x_ucl = format!("{:.3}", x_ucl).parse::<f64>().unwrap();
405
406        let x_lcl = self.average_zn - a2(self.group_count) * self.range_zn;
407        let x_lcl = format!("{:.3}", x_lcl).parse::<f64>().unwrap();
408
409        (self.average_zn, x_ucl, x_lcl)
410    }
411    /// I-MR 控制图
412    /// I-MR 控制图是一种统计质量控制方法,用于监控过程中连续变量的稳定性和一致性。I 代表 Individual,表示个体值,MR 代表 Moving Range,表示移动范围。
413    pub fn i_mr(&mut self) -> JsonValue {
414        // let s_mr = self.range_zn / d2(self.range_zn_data.len() - 1);
415
416        object! {
417
418        }
419    }
420    /// U 控制图
421    /// 不合格品数量的平均值
422    pub fn u(&mut self) -> (f64, Vec<f64>) {
423        (self.average_zt, self.data.clone())
424    }
425    /// P 控制图
426    /// 不合格品比例的平均值
427    pub fn p(&mut self) -> (f64, Vec<f64>) {
428        let len = self.data.len() as f64;
429        let p_list = self.data.clone().iter().map(|&x| {
430            x / len
431        }).collect::<Vec<f64>>();
432        let p = p_list.iter().sum::<f64>() / p_list.len() as f64;
433        (p, p_list)
434    }
435    /// NP 控制图
436    /// 不合格品比例的平均值
437    pub fn np(&mut self) -> (f64, f64, Vec<f64>) {
438        let u6 = self.average_zt + 4.0 * self.std_dev_zt;
439        (self.average_zt, u6, self.data.clone())
440    }
441
442    fn get_pp(&mut self) {
443        if self.pp != 0.0 {
444            return;
445        }
446        self.pp = (self.usl - self.lsl) / (6.0 * self.std_dev_zt);
447        self.pp = format!("{:.3}", self.pp).parse::<f64>().unwrap()
448    }
449    fn get_ppl(&mut self) {
450        if self.ppl != 0.0 {
451            return;
452        }
453        self.ppl = (self.average_zt - self.lsl) / (3.0 * self.std_dev_zt);
454        self.ppl = format!("{:.3}", self.ppl).parse::<f64>().unwrap()
455    }
456    fn get_ppu(&mut self) {
457        if self.ppu != 0.0 {
458            return;
459        }
460        self.ppu = (self.usl - self.average_zt) / (3.0 * self.std_dev_zt);
461        self.ppu = format!("{:.3}", self.ppu).parse::<f64>().unwrap()
462    }
463    fn get_ppk(&mut self) {
464        if self.ppk != 0.0 {
465            return;
466        }
467        self.get_ppl();
468        self.get_ppu();
469        self.ppk = f64::min(self.ppu, self.ppl);
470        self.ppk = format!("{:.3}", self.ppk).parse::<f64>().unwrap()
471    }
472    /// 直方图
473    pub fn histogram(&mut self) -> JsonValue {
474        self.get_pp();
475        self.get_ppl();
476        self.get_ppu();
477        self.get_ppk();
478        self.cp();
479        self.cpk();
480        self.ppm();
481
482        let _bin_width = (self.max_value - self.min_value) / 6.0;
483
484        let mut histogram = object! {};
485        for &value in self.data_whole.iter() {
486            if histogram[value.to_string()].is_empty() {
487                histogram[value.to_string()] = 1.0.into();
488            }
489            histogram[value.to_string()] = (histogram[value.to_string()].as_f64().unwrap() + 1.0).into();
490        }
491
492        object! {
493            usl:self.usl,
494            lsl:self.lsl,
495            histogram:histogram,
496            std_dev_zn_data:self.std_dev_zn_data.clone()
497        }
498    }
499
500    /// 正态分布
501    pub fn normal_distribution(&mut self) -> JsonValue {
502        let mut normal_distribution = object! {};
503        for item in self.data_whole.clone().iter_mut() {
504            if normal_distribution[item.clone().to_string().as_str()].is_empty() {
505                normal_distribution[item.clone().to_string().as_str()] = 1.into();
506            } else {
507                normal_distribution[item.clone().to_string().as_str()] = JsonValue::from(normal_distribution[item.clone().to_string().as_str()].clone().to_string().parse::<i32>().unwrap() + 1);
508            }
509        }
510
511        object! {
512            usl:self.usl,
513            lsl:self.lsl,
514            min:self.min_value,
515            max:self.max_value,
516            std_dev_zt:self.std_dev_zt,
517            average_zt:self.average_zt,
518            normal_distribution:normal_distribution,
519        }
520    }
521}
522
523// 计算样本的标准差
524fn standard_deviation(data: Vec<f64>, mean: f64) -> f64 {
525    let variance = data.iter().map(|x| (x - mean).powi(2)).sum::<f64>() / (data.len() as f64 - 1.0);
526    format!("{:.5}", variance.sqrt()).parse::<f64>().unwrap()
527}
528
529/// 计量型 X-R图 A2
530fn a2(len: usize) -> f64 {
531    match len {
532        2 => 1.880,
533        3 => 1.023,
534        4 => 0.729,
535        5 => 0.577,
536        6 => 0.483,
537        7 => 0.149,
538        8 => 0.373,
539        9 => 0.337,
540        10 => 0.308,
541        11 => 0.285,
542        12 => 0.266,
543        13 => 0.249,
544        14 => 0.235,
545        15 => 0.223,
546        16 => 0.212,
547        17 => 0.203,
548        18 => 0.194,
549        19 => 0.187,
550        20 => 0.180,
551        21 => 0.173,
552        22 => 0.167,
553        23 => 0.162,
554        24 => 0.157,
555        25 => 0.153,
556        _ => 0.0
557    }
558}
559
560/// 计量型 X-S图 A3
561fn a3(len: usize) -> f64 {
562    match len {
563        2 => 2.659,
564        3 => 1.954,
565        4 => 1.628,
566        5 => 1.427,
567        6 => 1.287,
568        7 => 1.182,
569        8 => 1.099,
570        9 => 1.032,
571        10 => 0.975,
572        11 => 0.927,
573        12 => 0.886,
574        13 => 0.850,
575        14 => 0.817,
576        15 => 0.789,
577        16 => 0.763,
578        17 => 0.739,
579        18 => 0.718,
580        19 => 0.698,
581        20 => 0.680,
582        _ => 0.0
583    }
584}
585
586/// 计量型 X-R图 B3 计算控制限用的系数 UCLs
587fn b3(len: usize) -> f64 {
588    match len {
589        2 => 0.0,
590        3 => 0.0,
591        4 => 0.0,
592        5 => 0.0,
593        6 => 0.03,
594        7 => 0.118,
595        8 => 0.185,
596        9 => 0.239,
597        10 => 0.284,
598        11 => 0.321,
599        12 => 0.354,
600        13 => 0.382,
601        14 => 0.406,
602        15 => 0.428,
603        16 => 0.448,
604        17 => 0.446,
605        18 => 0.482,
606        19 => 0.497,
607        20 => 0.510,
608        _ => 0.0
609    }
610}
611
612/// 计量型 X-R图 B4 计算控制限用的系数 UCLs
613fn b4(len: usize) -> f64 {
614    match len {
615        2 => 3.267,
616        3 => 2.568,
617        4 => 2.266,
618        5 => 2.089,
619        6 => 1.970,
620        7 => 1.882,
621        8 => 1.815,
622        9 => 1.761,
623        10 => 1.716,
624        11 => 1.679,
625        12 => 1.646,
626        13 => 1.618,
627        14 => 1.594,
628        15 => 1.572,
629        16 => 1.552,
630        17 => 1.534,
631        18 => 1.518,
632        19 => 1.503,
633        20 => 1.490,
634        _ => 0.0
635    }
636}
637
638/// C4
639fn c4(len: usize) -> f64 {
640    match len {
641        2 => 0.79785,
642        3 => 0.87153,
643        4 => 0.905763,
644        5 => 0.925222,
645        6 => 0.937892,
646        7 => 0.946837,
647        8 => 0.953503,
648        9 => 0.958669,
649        // 9=>0.972788,
650        10 => 0.962793,
651        // 10 => 0.972659,
652        11 => 0.966163,
653        12 => 0.968968,
654        13 => 0.971341,
655        14 => 0.973375,
656        15 => 0.975137,
657        16 => 0.976679,
658        17 => 0.978039,
659        18 => 0.979249,
660        19 => 0.980331,
661        20 => 0.981305,
662        21 => 0.982187,
663        22 => 0.982988,
664        23 => 0.98372,
665        24 => 0.984391,
666        25 => 0.985009,
667        26 => 0.985579,
668        27 => 0.986107,
669        28 => 0.986597,
670        29 => 0.987054,
671        30 => 0.98748,
672        31 => 0.987878,
673        32 => 0.988252,
674        33 => 0.988603,
675        34 => 0.988934,
676        35 => 0.989246,
677        36 => 0.98954,
678        37 => 0.989819,
679        38 => 0.990083,
680        39 => 0.990333,
681        40 => 0.990571,
682        41 => 0.990797,
683        42 => 0.991013,
684        43 => 0.991218,
685        44 => 0.991415,
686        45 => 0.991602,
687        46 => 0.991782,
688        47 => 0.991953,
689        48 => 0.992118,
690        49 => 0.992276,
691        50 => 0.992427,
692        51 => 0.992573,
693        52 => 0.992713,
694        53 => 0.992848,
695        54 => 0.992978,
696        55 => 0.993103,
697        56 => 0.993224,
698        57 => 0.99334,
699        58 => 0.993452,
700        59 => 0.993561,
701        60 => 0.993666,
702        61 => 0.993767,
703        62 => 0.993866,
704        63 => 0.993961,
705        64 => 0.994053,
706        65 => 0.994142,
707        66 => 0.994229,
708        67 => 0.994313,
709        68 => 0.994395,
710        69 => 0.994474,
711        70 => 0.994551,
712        71 => 0.994626,
713        72 => 0.994699,
714        73 => 0.994769,
715        74 => 0.994838,
716        75 => 0.994905,
717        76 => 0.99497,
718        77 => 0.995034,
719        78 => 0.995096,
720        79 => 0.995156,
721        80 => 0.995215,
722        81 => 0.995272,
723        82 => 0.995328,
724        83 => 0.995383,
725        84 => 0.995436,
726        85 => 0.995489,
727        86 => 0.995539,
728        87 => 0.995589,
729        88 => 0.995638,
730        89 => 0.995685,
731        90 => 0.995732,
732        91 => 0.995777,
733        92 => 0.995822,
734        93 => 0.995865,
735        94 => 0.995908,
736        95 => 0.995949,
737        96 => 0.99599,
738        97 => 0.996030,
739        98 => 0.996069,
740        99 => 0.996108,
741        100 => 0.996145,
742        101 => 0.996182,
743        102 => 0.996218,
744        103 => 0.996253,
745        104 => 0.996288,
746        105 => 0.996322,
747        106 => 0.996356,
748        107 => 0.996389,
749        108 => 0.996421,
750        109 => 0.996452,
751        110 => 0.996483,
752        111 => 0.996514,
753        112 => 0.996544,
754        113 => 0.996573,
755        114 => 0.996602,
756        115 => 0.996631,
757        116 => 0.996658,
758        117 => 0.996686,
759        118 => 0.996713,
760        _ => 0.0,
761    }
762}
763
764// /// D2
765// fn d2(len: usize) -> f64 {
766//     match len {
767//         2 => 1.128,
768//         3 => 1.693,
769//         4 => 2.059,
770//         5 => 2.326,
771//         6 => 2.534,
772//         7 => 2.704,
773//         8 => 2.847,
774//         9 => 2.97,
775//         10 => 3.078,
776//         11 => 3.173,
777//         12 => 3.258,
778//         13 => 3.336,
779//         14 => 3.407,
780//         15 => 3.472,
781//         16 => 3.532,
782//         17 => 3.588,
783//         18 => 3.64,
784//         19 => 3.689,
785//         20 => 3.735,
786//         21 => 3.778,
787//         22 => 3.819,
788//         23 => 3.858,
789//         24 => 3.895,
790//         25 => 3.931,
791//         _ => 0.0,
792//     }
793// }
794
795// /// 计量型 X-R图 D3 计算控制限用的系数 LCLr
796// fn d3(len: usize) -> f64 {
797//     match len {
798//         2 => 0.8525,
799//         3 => 0.8884,
800//         4 => 0.8798,
801//         5 => 0.8641,
802//         6 => 0.848,
803//         7 => 0.8332,
804//         8 => 0.8198,
805//         9 => 0.8078,
806//         10 => 0.7971,
807//         11 => 0.7873,
808//         12 => 0.7785,
809//         13 => 0.7704,
810//         14 => 0.763,
811//         15 => 0.7562,
812//         16 => 0.7499,
813//         17 => 0.7441,
814//         18 => 0.7386,
815//         19 => 0.7335,
816//         20 => 0.7287,
817//         21 => 0.7242,
818//         22 => 0.7199,
819//         23 => 0.7159,
820//         24 => 0.7121,
821//         25 => 0.7084,
822//         _ => 0.0,
823//     }
824// }
825
826/// 计量型 X-R图 D4 计算控制限用的系数 UCLr
827fn d4(len: usize) -> f64 {
828    match len {
829        2 => 3.267,
830        3 => 2.574,
831        4 => 2.282,
832        5 => 2.114,
833        6 => 2.004,
834        7 => 1.924,
835        8 => 1.864,
836        9 => 1.816,
837        10 => 1.777,
838        11 => 1.744,
839        12 => 1.717,
840        13 => 1.693,
841        14 => 1.672,
842        15 => 1.653,
843        16 => 1.637,
844        17 => 1.622,
845        18 => 1.608,
846        19 => 1.597,
847        20 => 1.585,
848        21 => 1.575,
849        22 => 1.566,
850        23 => 1.557,
851        24 => 1.548,
852        25 => 1.541,
853        _ => 0.0
854    }
855}
856
857#[test]
858fn test() {
859    let cp = (10.0 - 8.0) / (6.0 * 0.5);
860    let cp = format!("{:.3}", cp).parse::<f64>().unwrap();
861    assert_eq!(cp, 0.667)
862}
863
864#[test]
865fn ppm_test() {
866    let cp = (10.0 - 8.0) / (6.0 * 0.5);
867    let cp = format!("{:.3}", cp).parse::<f64>().unwrap();
868    assert_eq!(cp, 0.667)
869}