|
|
@@ -0,0 +1,283 @@
|
|
|
+package com.lc.ibps.components.verification.model2;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.alibaba.fastjson.serializer.SerializerFeature;
|
|
|
+import com.baomidou.mybatisplus.extension.api.R;
|
|
|
+import com.lc.ibps.components.verification.model.InspectionConfigVO;
|
|
|
+import com.lc.ibps.components.verification.regression.PolynomialRegression;
|
|
|
+import com.lc.ibps.components.verification.report.ChartDTO;
|
|
|
+import com.lc.ibps.components.verification.report.TableDTO;
|
|
|
+import org.apache.commons.lang3.ArrayUtils;
|
|
|
+import org.apache.commons.math3.stat.StatUtils;
|
|
|
+import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
|
|
|
+
|
|
|
+import java.util.*;
|
|
|
+
|
|
|
+public class LinearRangeADLPctBnd extends PVModel {
|
|
|
+
|
|
|
+ private final double[] means;
|
|
|
+ private double mean;
|
|
|
+ private final double[] standardDeviations;
|
|
|
+
|
|
|
+ private double[] targetValues;
|
|
|
+ private boolean isTarget = true;
|
|
|
+
|
|
|
+ private double adl;
|
|
|
+ private double cv;
|
|
|
+ private double pctBnd;
|
|
|
+
|
|
|
+ private final PolynomialRegression pr1 = new PolynomialRegression(1);
|
|
|
+ private final PolynomialRegression pr2 = new PolynomialRegression(2);
|
|
|
+ private final PolynomialRegression pr3 = new PolynomialRegression(3);
|
|
|
+ private PolynomialRegression prBest;
|
|
|
+
|
|
|
+ public LinearRangeADLPctBnd(double[][] data, InspectionConfigVO configVO) {
|
|
|
+ super(data, configVO);
|
|
|
+
|
|
|
+ this.means = new double[this.specimensNum];
|
|
|
+ this.standardDeviations = new double[this.specimensNum];
|
|
|
+ this.targetValues = new double[this.specimensNum];
|
|
|
+ calcTarget(configVO.getTargetValue());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void calculate() {
|
|
|
+ final int n = specimensNum * repeatNum;
|
|
|
+ for (int i = 0; i < specimensNum; i++) {
|
|
|
+ DescriptiveStatistics stat = new DescriptiveStatistics(data[i]);
|
|
|
+ means[i] = stat.getMean();
|
|
|
+ standardDeviations[i] = stat.getStandardDeviation();
|
|
|
+
|
|
|
+ }
|
|
|
+ mean = StatUtils.mean(means);
|
|
|
+
|
|
|
+ pr1.addData(targetValues, means, repeatNum);
|
|
|
+ pr2.addData(targetValues, means, repeatNum);
|
|
|
+ pr3.addData(targetValues, means, repeatNum);
|
|
|
+
|
|
|
+ if (pr2.isNonlinear() && pr3.isNonlinear()) {
|
|
|
+ if (pr2.getStdError() > pr3.getStdError()) prBest = pr3;
|
|
|
+ else prBest = pr2;
|
|
|
+ } else if (pr2.isNonlinear()) {
|
|
|
+ prBest = pr2;
|
|
|
+ } else if (pr3.isNonlinear()) {
|
|
|
+ prBest = pr3;
|
|
|
+ } else{
|
|
|
+ prBest = pr1;
|
|
|
+ }
|
|
|
+ //calc sdl
|
|
|
+ if (prBest.getPower()>1) {
|
|
|
+ double valSum = 0.0;
|
|
|
+ for (int i = 0; i < specimensNum; i++) {
|
|
|
+ valSum += Math.pow(prBest.calcFunc(targetValues[i])-pr1.calcFunc(targetValues[i]),2);
|
|
|
+ }
|
|
|
+ adl = 100* Math.sqrt(valSum/n)/mean;
|
|
|
+ }
|
|
|
+ cv = 100d*prBest.getStdError()/mean;
|
|
|
+ pctBnd = 0.05 * Math.sqrt(n/ prBest.getPower() ==3?6.5:6.3);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void calcTarget(double[] targets) {
|
|
|
+ if (ArrayUtils.isEmpty(targets)) {
|
|
|
+ for (int i = 0; i < specimensNum; i++) {
|
|
|
+ targetValues[i] = i + 1;
|
|
|
+ }
|
|
|
+ isTarget = false;
|
|
|
+ } else if (targets.length == 2) {
|
|
|
+ targetValues[0] = targets[0];
|
|
|
+ targetValues[specimensNum - 1] = targets[1];
|
|
|
+ int range = specimensNum - 1;
|
|
|
+ for (int i = 1; i < range; i++) {
|
|
|
+ targetValues[i] = format(targets[0] * (range - i) / range + targets[1] * i / range, 2);
|
|
|
+ }
|
|
|
+ } else if (targets.length == specimensNum) {
|
|
|
+ targetValues = targets;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public TableDTO buildDataTableDTO() {
|
|
|
+ List<String> header = new ArrayList<String>();
|
|
|
+
|
|
|
+ header.add("标本号");
|
|
|
+ if (isTarget) header.add("目标值");
|
|
|
+ for (int i = 1; i <= repeatNum; i++) {
|
|
|
+ header.add(String.format("重复#%d", i));
|
|
|
+ }
|
|
|
+ TableDTO table = new TableDTO();
|
|
|
+ table.buildHeader(header.toArray(new String[header.size()]));
|
|
|
+
|
|
|
+ String[][] r = new String[specimensNum][];
|
|
|
+ for (int i = 0; i < data.length; i++) {
|
|
|
+ List<String> rl = new ArrayList();
|
|
|
+ rl.add(String.valueOf(i + 1));
|
|
|
+ if (isTarget) rl.add(String.valueOf(targetValues[i]));
|
|
|
+
|
|
|
+ for (int j = 0; j < data[i].length; j++) {
|
|
|
+ rl.add(format(data[i][j]));
|
|
|
+ }
|
|
|
+ r[i] = rl.toArray(new String[rl.size()]);
|
|
|
+ }
|
|
|
+ table.buildData(r);
|
|
|
+ return table;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String generateResult() {
|
|
|
+ return renderReportTemplate(this, "/report/linearRangeEP6A.ftl");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String[] tableNames() {
|
|
|
+ return new String[]{"表1: 重复性差异检测结果", "表2: 多项式回归分析结果", "表3: 线性偏离计算结果"};
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String[] chartNames() {
|
|
|
+ return new String[]{"图1: 线性实验", "图2: 线性评价差值点图"};
|
|
|
+ }
|
|
|
+
|
|
|
+// @Override
|
|
|
+// ChartDTO buildChart2DTO(int sheetIndex) {
|
|
|
+// ChartDTO chartDTO = new ChartDTO("linesForRange");
|
|
|
+// double[][] data = new double[targetValues.length][2];
|
|
|
+// for (int i = 0; i < data.length; i++) {
|
|
|
+// data[i] = new double[]{i + 1, diffs[1][i]};
|
|
|
+// }
|
|
|
+//// chartDTO.setData(data);
|
|
|
+// final HashMap<String, Object> config = new HashMap<>();
|
|
|
+// config.put("yAxisUp", 0.1);
|
|
|
+// config.put("yAxisLow", -0.1);
|
|
|
+// config.put("data", JSONObject.toJSONString(data, SerializerFeature.DisableCircularReferenceDetect));
|
|
|
+//
|
|
|
+// chartDTO.setOption(renderChartTemplate(config, 1, "/scatter/linesForRange.ftl"));
|
|
|
+// return chartDTO;
|
|
|
+// }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ ChartDTO buildChart1DTO(int sheetIndex) {
|
|
|
+ ChartDTO chartDTO = new ChartDTO("polynomialRegression");
|
|
|
+ double[][] data = new double[targetValues.length][2];
|
|
|
+ for (int i = 0; i < data.length; i++) {
|
|
|
+ data[i] = new double[]{targetValues[i], means[i]};
|
|
|
+ }
|
|
|
+// chartDTO.setData(data);
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ map.put("data", JSONObject.toJSONString(data, SerializerFeature.DisableCircularReferenceDetect));
|
|
|
+
|
|
|
+ chartDTO.setOption(renderChartTemplate(map, 0, "/scatter/polynomialRegression.ftl"));
|
|
|
+ return chartDTO;
|
|
|
+ }
|
|
|
+ @Override
|
|
|
+ TableDTO buildTable2DTO(int sheetIndex) {
|
|
|
+
|
|
|
+ TableDTO table = new TableDTO();
|
|
|
+ String[] header = {"阶别", "系数", "系数值", "系数标准误", "t 检验", "自由度", "回归标准误"};
|
|
|
+ table.buildHeader(header);
|
|
|
+ table.getHeader()[0].put("merge", "true");
|
|
|
+ table.getHeader()[5].put("merge", "true");
|
|
|
+ table.getHeader()[6].put("merge", "true");
|
|
|
+ String[][] r = new String[9][7];
|
|
|
+ int i = 0;
|
|
|
+ for (int j = 0; j < pr1.getParameters().length; j++) {
|
|
|
+ r[i][0] = "一阶";
|
|
|
+ r[i][1] = String.format("b%d", j);
|
|
|
+ r[i][2] = format(pr1.getParameters()[j]);
|
|
|
+ r[i][3] = format(pr1.getStdErrors()[j]);
|
|
|
+ r[i][4] = format(pr1.gettValues()[j]);
|
|
|
+ r[i][5] = pr1.getDfDependent().toString();
|
|
|
+ r[i][6] = format((pr1.getStdError()));
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+ for (int j = 0; j < pr2.getParameters().length; j++) {
|
|
|
+ r[i][0] = "二阶";
|
|
|
+ r[i][1] = String.format("b%d", j);
|
|
|
+ r[i][2] = format(pr2.getParameters()[j]);
|
|
|
+ r[i][3] = format(pr2.getStdErrors()[j]);
|
|
|
+ r[i][4] = format(pr2.gettValues()[j]);
|
|
|
+ r[i][5] = pr2.getDfDependent().toString();
|
|
|
+ r[i][6] = format((pr2.getStdError()));
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+ for (int j = 0; j < pr3.getParameters().length; j++) {
|
|
|
+ r[i][0] = "三阶";
|
|
|
+ r[i][1] = String.format("b%d", j);
|
|
|
+ r[i][2] = format(pr3.getParameters()[j]);
|
|
|
+ r[i][3] = format(pr3.getStdErrors()[j]);
|
|
|
+ r[i][4] = format(pr3.gettValues()[j]);
|
|
|
+ r[i][5] = pr3.getDfDependent().toString();
|
|
|
+ r[i][6] = format((pr3.getStdError()));
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+ table.buildData(r);
|
|
|
+ return table;
|
|
|
+ }
|
|
|
+ @Override
|
|
|
+ TableDTO buildTable3DTO(int sheetIndex) {
|
|
|
+
|
|
|
+ TableDTO table = new TableDTO();
|
|
|
+ String[] header = {"不精密度百分比", "L×R=10", "L×R=12", "L×R=14", "L×R=16", "L×R=18","L×R=20"};
|
|
|
+ table.buildHeader(header);
|
|
|
+
|
|
|
+
|
|
|
+ String[][] r3 = new String[][]{
|
|
|
+ {"1","5.5","5.5","5.4","5.4","5.4","5.4"},
|
|
|
+ {"2","6.1","6.0","5.9","5.9","5.8","5.8"},
|
|
|
+ {"3","6.7","6.5","6.4","6.3","6.2","6.2"},
|
|
|
+ {"4","7.2","7.0","6.9","6.8","6.7","6.6"},
|
|
|
+ {"5","7.8","7.6","7.4","7.2","7.1","7.0"},
|
|
|
+ {"6","8.4","8.1","7.9","7.7","7.5","7.4"},
|
|
|
+ {"7","9.0(P)","8.7(P)","8.4","8.2","8.0","7.8"},
|
|
|
+ {"8","P","P","8.9(P)","8.6(P)","8.4","8.2"},
|
|
|
+ {"9","P","P","P","P","8.9(P)","8.7(P)"},
|
|
|
+ {">9","P","P","P","P","P","P"}
|
|
|
+ };
|
|
|
+
|
|
|
+ String[][] r1 = new String[][]{
|
|
|
+ {"1","5.5","5.5","5.4","5.4","5.4","5.4"},
|
|
|
+ {"2","6.1","6.0","5.9","5.8","5.8","5.7"},
|
|
|
+ {"3","6.6","6.4","6.3","6.3","6.2","6.1"},
|
|
|
+ {"4","7.1","6.9","6.8","6.7","6.6","6.5"},
|
|
|
+ {"5","6.6","7.4","7.2","7.1","7.0","6.9"},
|
|
|
+ {"6","8.2","7.9","7.7","7.5","7.4","7.2"},
|
|
|
+ {"7","8.7(P)","8.4(P)","8.1","7.9","7.8","7.6"},
|
|
|
+ {"8","P","P","8.6(P)","8.3(P)","8.1","8.0"},
|
|
|
+ {"9","P","P","P","P","8.5(P)","8.3(P)"},
|
|
|
+ {">9","P","P","P","P","P","P"}
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
+ table.buildData(prBest == pr3?r3:r1);
|
|
|
+ final String note = new StringJoiner("<br />")
|
|
|
+ .add("L: 样本数")
|
|
|
+ .add("R: 重复测量的次数")
|
|
|
+ .add("P: 标注P的表格表示最优拟合方程的精密度太差,无法进行线性判断").toString();
|
|
|
+ table.setNote(note);
|
|
|
+ return table;
|
|
|
+ }
|
|
|
+
|
|
|
+ public double getMean() {
|
|
|
+ return mean;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setMean(double mean) {
|
|
|
+ this.mean = mean;
|
|
|
+ }
|
|
|
+
|
|
|
+ public double getAdl() {
|
|
|
+ return adl;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setAdl(double adl) {
|
|
|
+ this.adl = adl;
|
|
|
+ }
|
|
|
+
|
|
|
+ public double getCv() {
|
|
|
+ return cv;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setCv(double cv) {
|
|
|
+ this.cv = cv;
|
|
|
+ }
|
|
|
+}
|