1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use std::fmt::Display;
use crate::stats::stddev;

/// 制程能力指标
pub struct Cpk {
    /// 制程能力
    pub cpk: f64,
    /// 制程准确度
    pub ca: f64,
    /// 制程精密度
    pub cp: f64,

    /// 规格上限
    pub usl: f64,
    /// 规格下限
    pub lsl: f64,

}

impl Cpk {
    /// 初始化
    pub fn new<T: Display + std::fmt::Debug>(usl: f64, lsl: f64, array: Vec<T>) -> Self {
        let mut total = 0.0;
        let list: Vec<f64> = array.iter().map(|x|
            {
                let y = x.to_string().parse::<f64>().unwrap();
                total += y;
                y
            }
        ).collect();

        // 标准差
        let stddev = stddev(array);
        // 样本数量
        let n = list.len();
        // 平均值
        let x = total / n as f64;
        // 规格公差
        let t = usl - lsl;

        // 规格中心
        let u = (usl + lsl) / 2.0;
        let mut cp = t / (6.0 * stddev);
        let cpu = (usl - x).abs() / (3.0 * stddev);
        let cpl = (x - lsl).abs() / (3.0 * stddev);
        let ca = (x - u) / (t / 2.0);
        let mut cpk = if cpu > cpl { cpl } else { cpu };
        if cpk.is_infinite() {
            cpk = 0.0;
        }
        if cp.is_infinite() {
            cp = 0.0;
        }
        Self {
            cpk,
            ca: ca * 100.0,
            cp,
            usl,
            lsl,
        }
    }
    pub fn cpk_rating_criteria(&self) -> (&'static str, &'static str) {
        if self.cpk >= 2.0 {
            return ("A++", "特优,可考虑降低成本。");
        } else if 1.67 <= self.cpk && self.cpk < 2.0 {
            return ("A+", "优,应当保持之。");
        } else if 1.33 <= self.cpk && self.cpk < 1.67 {
            ("A", "良,能力好,状态稳定,但应尽力提升到A+级。")
        } else if 1.00 <= self.cpk && self.cpk < 1.33 {
            ("B", "一般,制程因素稍有变异即有生产不良的危险,应利用各种资源及方法将其提升为A级。")
        } else if 0.67 <= self.cpk && self.cpk < 1.00 {
            ("C", "差,制程不良较多。须提升其能力。")
        } else {
            ("D", "不可接受,其能力太差,应考虑重新整改设计制程。")
        }
    }
    pub fn ca_rating_criteria(&self) -> (&'static str, &'static str) {
        if self.ca <= 12.5 {
            ("A", "作业员遵守作业标准操作并达到要求,需继续保持。")
        } else if 12.5 <= self.ca && self.ca <= 25.0 {
            ("B", "有必要将其改进为A级。")
        } else if 25.0 <= self.ca && self.ca <= 50.0 {
            ("C", "作业员可能看错规格或不按作业标准操作。须检讨规格及作业标准。")
        } else {
            ("D", "应采取紧急措施全面检讨所有可能影响之因素,必要时得停止生产。")
        }
    }
    pub fn cp_rating_criteria(&self) -> (&'static str, &'static str) {
        if self.cp >= 1.67 {
            ("A+", "无缺点,可考虑降低成本。")
        } else if 1.33 <= self.cp && self.cp <= 1.67 {
            ("A", "状态良好维持现状。")
        } else if 1.00 <= self.cp && self.cp <= 1.33 {
            ("B", "可以改进为A级。")
        } else if 0.67 <= self.cp && self.cp <= 1.00 {
            ("C", "制程不良较多。须提升能力。")
        } else {
            ("D", "制程能力好差,应考虑重新整改设计制程。")
        }
    }
}