1use json::{JsonValue, object};
2pub struct Spc {
3 pub data: Vec<f64>,
5 pub data_len: usize,
7 pub group_len: usize,
9 pub upper: f64,
11 pub lower: f64,
13 pub value: f64,
15
16 pub max: f64,
18 pub min: f64,
20 pub avg: f64,
22 pub total: f64,
24 pub group_avg: Vec<f64>,
26 pub group_range: Vec<f64>,
28 pub group_range_max: f64,
30 pub group_range_min: f64,
32
33 pub group_r_avgs: Vec<f64>,
35 pub group_x_avgs: Vec<f64>,
37 pub group_r_avg: f64,
39 pub group_x_avg: f64,
41
42 pub group_r_avg_sum: f64,
43 pub group_x_avg_sum: f64,
44
45 pub group_sums: Vec<f64>,
47
48 pub group_data: Vec<Vec<f64>>,
50 pub decimal: usize,
52 pub cpu: f64,
54 pub cpl: f64,
56 pub a2: f64,
58 pub d2: f64,
60 pub d3: f64,
62 pub d4: f64,
64
65 pub cp: f64,
67 pub cpk: f64,
69 pub cr: f64,
71 pub stdev: f64,
73 pub stdevp: f64,
75 pub var: f64,
77 pub varp: f64,
79 pub pp: f64,
81 pub pr: f64,
83 pub ppk: f64,
85
86 pub sigma: f64,
88 pub sigma_list: Vec<f64>,
90
91 pub uclr: f64,
93 pub clr: f64,
95 pub lclr: f64,
97
98 pub uclx: f64,
100 pub clx: f64,
102 pub lclx: f64,
104}
105
106impl Spc {
107 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 max: 0.0,
125 min: 0.0,
126 avg: 0.0,
127 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 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 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 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
303fn 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
334fn 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
365fn 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
391fn 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}