Java 使用 Apache commons-math3 线性拟合、非线性拟合实例(带效果图)
可参考地址:https://www.cnblogs.com/wufeiwua/p/15110699.html
个人目前了解的曲线方程计算过程及说明
返回结果说明
对象textR: R的值越接近1,说明曲线拟合程度越好,通常大于0.8时比较准确
对象textY:多项拟合曲线公式
/**
* 求 拟合曲线公式
*
* @param dimension 几次方差 代码支持3,4,5,6,可以根据规律自己加
* @param arrX x轴坐标
* @param arrY y轴坐标
* @return
*/
public static Map<String, String> getRY(int dimension, double[] arrX, double[] arrY) {
Map<String, String> map = new HashMap<>();
Polyfit polyfit = new Polyfit();
double[] coefficient = polyfit.MultiLine(arrX, arrY, arrY.length, dimension);
double doubleR = polyfit.CorrelationR(arrX, arrY, coefficient);
if(Double.isNaN(doubleR)){
map.put("textY", "");
map.put("textR", "");
return map;
}
BigDecimal bg = new BigDecimal(doubleR);
double f1 = bg.setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();
String textR = f1 + "";
String textY = "";
//去除-0 改为 0
for (int i = 0; i < coefficient.length; i++) {
if (Double.parseDouble(String.format("%.3f", coefficient[i])) == 0.0) {
coefficient[i] = new Double("0.000");
}
}
if (coefficient.length == 4) {
textY = String.format("%.3f", coefficient[3]) + "x3";
if (coefficient[2] >= 0) {
textY += "+" + String.format("%.3f", coefficient[2]) + "x2";
} else {
textY += String.format("%.3f", coefficient[2]) + "x2";
}
if (coefficient[1] >= 0) {
textY += "+" + String.format("%.3f", coefficient[1]) + "x";
} else {
textY += String.format("%.3f", coefficient[1]) + "x";
}
if (coefficient[0] >= 0) {
textY += "+" + String.format("%.3f", coefficient[0]);
} else {
textY += String.format("%.3f", coefficient[0]);
}
} else if (coefficient.length == 5) {
textY = String.format("%.3f", coefficient[4]) + "x4";
if (coefficient[3] >= 0) {
textY += "+" + String.format("%.3f", coefficient[3]) + "x3";
} else {
textY += String.format("%.3f", coefficient[3]) + "x3";
}
if (coefficient[2] >= 0) {
textY += "+" + String.format("%.3f", coefficient[2]) + "x2";
} else {
textY += String.format("%.3f", coefficient[2]) + "x2";
}
if (coefficient[1] >= 0) {
textY += "+" + String.format("%.3f", coefficient[1]) + "x";
} else {
textY += String.format("%.3f", coefficient[1]) + "x";
}
if (coefficient[0] >= 0) {
textY += "+" + String.format("%.3f", coefficient[0]);
} else {
textY += String.format("%.3f", coefficient[0]);
}
} else if (coefficient.length == 6) {
textY = String.format("%.3f", coefficient[5]) + "x5";
if (coefficient[4] >= 0) {
textY += "+" + String.format("%.3f", coefficient[4]) + "x4";
} else {
textY += String.format("%.3f", coefficient[4]) + "x4";
}
if (coefficient[3] >= 0) {
textY += "+" + String.format("%.3f", coefficient[3]) + "x3";
} else {
textY += String.format("%.3f", coefficient[3]) + "x3";
}
if (coefficient[2] >= 0) {
textY += "+" + String.format("%.3f", coefficient[2]) + "x2";
} else {
textY += String.format("%.3f", coefficient[2]) + "x2";
}
if (coefficient[1] >= 0) {
textY += "+" + String.format("%.3f", coefficient[1]) + "x";
} else {
textY += String.format("%.3f", coefficient[1]) + "x";
}
if (coefficient[0] >= 0) {
textY += "+" + String.format("%.3f", coefficient[0]);
} else {
textY += String.format("%.3f", coefficient[0]);
}
} else if (coefficient.length == 7) {
textY = String.format("%.3f", coefficient[6]) + "x6";
if (coefficient[5] >= 0) {
textY += "+" + String.format("%.3f", coefficient[5]) + "x5";
} else {
textY += String.format("%.3f", coefficient[5]) + "x5";
}
if (coefficient[4] >= 0) {
textY += "+" + String.format("%.3f", coefficient[4]) + "x4";
} else {
textY += String.format("%.3f", coefficient[4]) + "x4";
}
if (coefficient[3] >= 0) {
textY += "+" + String.format("%.3f", coefficient[3]) + "x3";
} else {
textY += String.format("%.3f", coefficient[3]) + "x3";
}
if (coefficient[2] >= 0) {
textY += "+" + String.format("%.3f", coefficient[2]) + "x2";
} else {
textY += String.format("%.3f", coefficient[2]) + "x2";
}
if (coefficient[1] >= 0) {
textY += "+" + String.format("%.3f", coefficient[1]) + "x";
} else {
textY += String.format("%.3f", coefficient[1]) + "x";
}
if (coefficient[0] >= 0) {
textY += "+" + String.format("%.3f", coefficient[0]);
} else {
textY += String.format("%.3f", coefficient[0]);
}
}
map.put("textY", textY);
map.put("textR", textR);
return map;
//根据曲线方程 通过x轴坐标获取y值: 通过自定义的公式规律解析的
/**
* 根据计算公式 x 获取y值
*
* @param formula 公式
* @param xValue
* @return
*/
public static double getYByX(String formula, double xValue) {
String[] one = formula.split("\\+");
List<String> list = new ArrayList<>();
List<String> listReduce = new ArrayList<>();
String[] two;
for (String str : one) {
two = str.split("-");
int i = 0;
for (String ss : two) {
if (i > 0) {
listReduce.add(ss);
} else {
list.add(ss);
}
i++;
}
}
double total = 0;
//整数集合列表
String[] dd;
String splitX = "x";
for (String data : list) {
if (StringUtils.isEmpty(data)) {
continue;
}
if (data.contains(splitX)) {
dd = data.split(splitX);
if (dd.length == 1) {
total = total + Double.parseDouble(dd[0]) * xValue;
} else {
total = total + Double.parseDouble(dd[0]) * Math.pow(xValue, Integer.parseInt(dd[1]));
}
} else {
total = total + Double.parseDouble(data);
}
}
//负数列表
for (String data : listReduce) {
if (data.contains(splitX)) {
dd = data.split(splitX);
if (dd.length == 1) {
total = total - Double.parseDouble(dd[0]) * xValue;
} else {
total = total - Double.parseDouble(dd[0]) * Math.pow(xValue, Integer.parseInt(dd[1]));
}
} else {
total = total - Double.parseDouble(data);
}
}
return total;
}