|
@@ -0,0 +1,253 @@
|
|
|
|
|
+package com.lc.ibps.components.verification.model2;
|
|
|
|
|
+
|
|
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
|
|
+import com.alibaba.fastjson.serializer.SerializerFeature;
|
|
|
|
|
+import com.lc.ibps.components.verification.regression.PolynomialRegression;
|
|
|
|
|
+import com.lc.ibps.components.verification.report.ReportDataDTO;
|
|
|
|
|
+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 EP6ALinearRangeVO extends CalcVO {
|
|
|
|
|
+
|
|
|
|
|
+ private double[][] data;
|
|
|
|
|
+
|
|
|
|
|
+ private double[] means;
|
|
|
|
|
+ private double[][] diffs;
|
|
|
|
|
+ private double[][] dli;
|
|
|
|
|
+ private double maxDli;
|
|
|
|
|
+ private double mean;
|
|
|
|
|
+ private double[] standardDeviations;
|
|
|
|
|
+
|
|
|
|
|
+ private double[] targetValues;
|
|
|
|
|
+ private boolean isTarget = true;
|
|
|
|
|
+
|
|
|
|
|
+ private int specimensNum;
|
|
|
|
|
+ private int repeatNum;
|
|
|
|
|
+ private PolynomialRegression pr1 = new PolynomialRegression();
|
|
|
|
|
+ private PolynomialRegression pr2 = new PolynomialRegression();
|
|
|
|
|
+ private PolynomialRegression pr3 = new PolynomialRegression();
|
|
|
|
|
+ private PolynomialRegression prBest;
|
|
|
|
|
+
|
|
|
|
|
+ private double claimValue;
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ private double sdr;
|
|
|
|
|
+ private double cvr;
|
|
|
|
|
+
|
|
|
|
|
+ public EP6ALinearRangeVO(double[][] data, double[] targetValues, double claimValue,int scale){
|
|
|
|
|
+ this.data = data;
|
|
|
|
|
+ this.setScale(scale);
|
|
|
|
|
+ this.specimensNum = data.length;
|
|
|
|
|
+ this.repeatNum = data[0].length;
|
|
|
|
|
+ this.means = new double[this.specimensNum];
|
|
|
|
|
+ this.diffs = new double[5][this.specimensNum];
|
|
|
|
|
+ this.dli = new double[5][this.specimensNum];
|
|
|
|
|
+ this.standardDeviations = new double[this.specimensNum];
|
|
|
|
|
+ this.targetValues = new double[this.specimensNum];
|
|
|
|
|
+ this.claimValue = claimValue;
|
|
|
|
|
+ calcTarget(targetValues);
|
|
|
|
|
+ calculate();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public void calculate() {
|
|
|
|
|
+
|
|
|
|
|
+ for (int i = 0; i < specimensNum; i++) {
|
|
|
|
|
+ DescriptiveStatistics stat = new DescriptiveStatistics(data[i]);
|
|
|
|
|
+ means[i] = format(stat.getMean(),2);
|
|
|
|
|
+ standardDeviations[i] = stat.getStandardDeviation();
|
|
|
|
|
+ if(repeatNum == 2){
|
|
|
|
|
+ diffs[1][i] = data[i][0] - data[i][1]; //diff
|
|
|
|
|
+ diffs[2][i] = Math.pow(diffs[1][i],2) /2; //diff * diff / 2
|
|
|
|
|
+ diffs[3][i] = diffs[1][i] / means[i] ; //%diff
|
|
|
|
|
+ diffs[4][i] = Math.pow(diffs[3][i],2) /2; //%diff * %diff /2
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ diffs[0] = means;
|
|
|
|
|
+ mean = StatUtils.mean(means);
|
|
|
|
|
+ sdr = Math.sqrt(StatUtils.mean(diffs[2]))*100;
|
|
|
|
|
+ cvr = Math.sqrt(StatUtils.mean(diffs[4]))*100;
|
|
|
|
|
+ //TODO: check cvr
|
|
|
|
|
+
|
|
|
|
|
+ pr1.addData(targetValues, means, repeatNum,1);
|
|
|
|
|
+ pr2.addData(targetValues, means, repeatNum,2);
|
|
|
|
|
+ pr3.addData(targetValues, means, repeatNum,3);
|
|
|
|
|
+
|
|
|
|
|
+ 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;
|
|
|
|
|
+ }
|
|
|
|
|
+ //calc dli
|
|
|
|
|
+ if(prBest != null) {
|
|
|
|
|
+ if(isTarget) dli[0] = targetValues;
|
|
|
|
|
+ else dli[0] = means;
|
|
|
|
|
+
|
|
|
|
|
+ for (int i = 0; i < specimensNum; i++) {
|
|
|
|
|
+ dli[1][i] = prBest.calcFunc(dli[0][i]);
|
|
|
|
|
+ dli[2][i] = pr1.calcFunc(dli[0][i]);
|
|
|
|
|
+ dli[3][i] = dli[1][i] - dli[2][i];
|
|
|
|
|
+ dli[4][i] = 100 * dli[3][i] / dli[0][i];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ maxDli = Arrays.stream(dli[4]).max().getAsDouble();
|
|
|
|
|
+ }
|
|
|
|
|
+//
|
|
|
|
|
+// double s1 = pr1.getStdError() / mean;
|
|
|
|
|
+// double s2 = pr2.getStdError() /mean;
|
|
|
|
|
+// double s3 = pr3.getStdError() /mean;
|
|
|
|
|
+// pr1.getParameters();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ 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;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public Map<String, TableDTO> buildReportTableDTO(){
|
|
|
|
|
+ Map<String, TableDTO> reports = new HashMap<>();
|
|
|
|
|
+ reports.put("表1: 重复性差异检测结果",buildTable1DTO());
|
|
|
|
|
+ reports.put("表2: 多项式回归分析结果",buildTable2DTO());
|
|
|
|
|
+ reports.put("表3: 线性偏离计算结果",buildTable3DTO());
|
|
|
|
|
+ return reports;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private TableDTO buildTable1DTO(){
|
|
|
|
|
+
|
|
|
|
|
+ TableDTO table = new TableDTO();
|
|
|
|
|
+ String[] header = {"标本号", "均值", "差值Diff", "Diff<sup>2</sup>/2", "%Diff", "%Diff<sup>2</sup>/2"};
|
|
|
|
|
+ table.buildHeader(header);
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ double[][] r = new double[specimensNum][6];
|
|
|
|
|
+ double[][] doubles = transposeMatrix(diffs);
|
|
|
|
|
+
|
|
|
|
|
+ for (int i = 0; i < doubles.length; i++) {
|
|
|
|
|
+ r[i] = ArrayUtils.add(doubles[i], 0, i+1);
|
|
|
|
|
+ }
|
|
|
|
|
+ table.buildData(r,getScale());
|
|
|
|
|
+ return table;
|
|
|
|
|
+ }
|
|
|
|
|
+ private TableDTO buildTable2DTO(){
|
|
|
|
|
+
|
|
|
|
|
+ TableDTO table = new TableDTO();
|
|
|
|
|
+ String[] header = {"阶别", "系数", "系数值", "SE<sub>i</sub>", "t 检验", "S<sub>y.x</sub>","自由度"};
|
|
|
|
|
+ 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] = "1";
|
|
|
|
|
+ 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.gettValue()[j]);
|
|
|
|
|
+ r[i][5] = format((pr1.getStdError()));
|
|
|
|
|
+ r[i][6] = pr1.getDfDependent().toString();
|
|
|
|
|
+ i++;
|
|
|
|
|
+ }
|
|
|
|
|
+ for (int j = 0; j < pr2.getParameters().length; j++) {
|
|
|
|
|
+ r[i][0] = "2";
|
|
|
|
|
+ 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.gettValue()[j]);
|
|
|
|
|
+ r[i][5] = format((pr2.getStdError()));
|
|
|
|
|
+ r[i][6] = pr2.getDfDependent().toString();
|
|
|
|
|
+ i++;
|
|
|
|
|
+ }
|
|
|
|
|
+ for (int j = 0; j < pr3.getParameters().length; j++) {
|
|
|
|
|
+ r[i][0] = "3";
|
|
|
|
|
+ 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.gettValue()[j]);
|
|
|
|
|
+ r[i][5] = format((pr3.getStdError()));
|
|
|
|
|
+ r[i][6] = pr3.getDfDependent().toString();
|
|
|
|
|
+ i++;
|
|
|
|
|
+ }
|
|
|
|
|
+ table.buildData(r);
|
|
|
|
|
+ return table;
|
|
|
|
|
+ }
|
|
|
|
|
+ private TableDTO buildTable3DTO(){
|
|
|
|
|
+
|
|
|
|
|
+ TableDTO table = new TableDTO();
|
|
|
|
|
+ String[] header = {"标本号", "x<sub>i</sub>", "p(x<sub>i</sub>)", "b<sub>0</sub>+b<sub>1</sub>x<sub>i</sub>", "DL<sub>i</sub>", "%DL<sub>i</sub>"};
|
|
|
|
|
+ table.buildHeader(header);
|
|
|
|
|
+
|
|
|
|
|
+ double[][] r = new double[specimensNum][6];
|
|
|
|
|
+ double[][] doubles = transposeMatrix(dli);
|
|
|
|
|
+
|
|
|
|
|
+ for (int i = 0; i < doubles.length; i++) {
|
|
|
|
|
+ r[i] = ArrayUtils.add(doubles[i], 0, i+1);
|
|
|
|
|
+ }
|
|
|
|
|
+ table.buildData(r,getScale());
|
|
|
|
|
+ return table;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static void main(String[] args){
|
|
|
|
|
+ double[][] data = {{-0.01,-0.01},{5.00,4.99},{10.18,10.05},{14.65,14.65},{19.57,19.65},{24.02,24.09}};
|
|
|
|
|
+ EP6ALinearRangeVO ep6 = new EP6ALinearRangeVO(data, new double[]{0,24.09},1,3);
|
|
|
|
|
+ TableDTO tableDTO = ep6.buildDataTableDTO();
|
|
|
|
|
+ Map<String, TableDTO> stringTableDTOMap = ep6.buildReportTableDTO();
|
|
|
|
|
+ ReportDataDTO report = new ReportDataDTO();
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ report.setDataDTO(tableDTO);
|
|
|
|
|
+ report.setReportDataDTO(stringTableDTOMap);
|
|
|
|
|
+ String s = JSONObject.toJSONString(report, SerializerFeature.DisableCircularReferenceDetect);
|
|
|
|
|
+
|
|
|
|
|
+ System.out.println(s);
|
|
|
|
|
+// ep6.getT()
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+}
|