133 lines
3.9 KiB
Java
133 lines
3.9 KiB
Java
package com.gunshi.project.hsz.model;
|
||
|
||
import lombok.Data;
|
||
|
||
import java.math.BigDecimal;
|
||
import java.math.RoundingMode;
|
||
import java.util.List;
|
||
|
||
/**
|
||
* 线性回归方程实体类
|
||
*/
|
||
@Data
|
||
public class RegressionEquation {
|
||
/**
|
||
* 方程阶数
|
||
*/
|
||
private int order;
|
||
|
||
/**
|
||
* 方程系数(从常数项到最高次项)
|
||
* 例如:对于二次方程 y = ax² + bx + c,coefficients = [c, b, a]
|
||
*/
|
||
private List<BigDecimal> coefficients;
|
||
|
||
/**
|
||
* 相关系数 R²
|
||
*/
|
||
private BigDecimal rSquared;
|
||
|
||
/**
|
||
* 数据点数
|
||
*/
|
||
private int dataCount;
|
||
|
||
/**
|
||
* 方程字符串表示
|
||
*/
|
||
private String equationString;
|
||
|
||
public RegressionEquation(int order, List<BigDecimal> coefficients, BigDecimal rSquared, int dataCount) {
|
||
this.order = order;
|
||
this.coefficients = coefficients;
|
||
this.rSquared = rSquared;
|
||
this.dataCount = dataCount;
|
||
this.equationString = generateEquationString();
|
||
}
|
||
|
||
/**
|
||
* 生成方程字符串(使用数学符号)
|
||
*/
|
||
private String generateEquationString() {
|
||
StringBuilder sb = new StringBuilder("y = ");
|
||
|
||
for (int i = coefficients.size() - 1; i >= 0; i--) {
|
||
BigDecimal coeff = coefficients.get(i);
|
||
if (coeff.compareTo(BigDecimal.ZERO) == 0) {
|
||
continue;
|
||
}
|
||
|
||
// 符号处理
|
||
if (sb.length() > 4 && coeff.compareTo(BigDecimal.ZERO) > 0) {
|
||
sb.append(" + ");
|
||
} else if (sb.length() > 4 && coeff.compareTo(BigDecimal.ZERO) < 0) {
|
||
sb.append(" - ");
|
||
coeff = coeff.abs();
|
||
}
|
||
|
||
// 系数和变量 - 保留至少20位小数
|
||
if (i == 0) {
|
||
// 常数项 - 保留至少20位小数
|
||
sb.append(coeff.setScale(20, RoundingMode.HALF_UP).toPlainString());
|
||
} else {
|
||
// 非常数项 - 保留至少20位小数
|
||
if (coeff.compareTo(BigDecimal.ONE) != 0 && coeff.compareTo(BigDecimal.ONE.negate()) != 0) {
|
||
sb.append(coeff.setScale(20, RoundingMode.HALF_UP).toPlainString());
|
||
}
|
||
sb.append("x");
|
||
if (i > 1) {
|
||
// 使用Unicode上标数字
|
||
sb.append(getSuperscript(i));
|
||
}
|
||
}
|
||
}
|
||
|
||
return sb.toString();
|
||
}
|
||
|
||
/**
|
||
* 获取数字的Unicode上标表示
|
||
*/
|
||
private String getSuperscript(int number) {
|
||
String numStr = String.valueOf(number);
|
||
StringBuilder superscript = new StringBuilder();
|
||
for (char c : numStr.toCharArray()) {
|
||
switch (c) {
|
||
case '0': superscript.append('⁰'); break;
|
||
case '1': superscript.append('¹'); break;
|
||
case '2': superscript.append('²'); break;
|
||
case '3': superscript.append('³'); break;
|
||
case '4': superscript.append('⁴'); break;
|
||
case '5': superscript.append('⁵'); break;
|
||
case '6': superscript.append('⁶'); break;
|
||
case '7': superscript.append('⁷'); break;
|
||
case '8': superscript.append('⁸'); break;
|
||
case '9': superscript.append('⁹'); break;
|
||
default: superscript.append(c);
|
||
}
|
||
}
|
||
return superscript.toString();
|
||
}
|
||
|
||
/**
|
||
* 根据x值预测y值
|
||
*/
|
||
public BigDecimal predict(BigDecimal x) {
|
||
BigDecimal result = BigDecimal.ZERO;
|
||
BigDecimal xPower = BigDecimal.ONE;
|
||
|
||
for (int i = 0; i < coefficients.size(); i++) {
|
||
result = result.add(coefficients.get(i).multiply(xPower));
|
||
xPower = xPower.multiply(x);
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
|
||
@Override
|
||
public String toString() {
|
||
return String.format("%s", equationString);
|
||
}
|
||
}
|