本帖最后由 hr7913468520 于 2023-8-23 17:48 编辑
使用的类库
org.apache.commons.math3
maven
[XML] 纯文本查看 复制代码 <dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.6.1</version>
</dependency>
推荐工具
如果只是做学术研究用,不想写代码,这里推荐一个免费的工具 下载 地址:https://welsim.com/download/
用法很简单(1-4点一遍,导入数据格式不清楚的,先随便添加两行,然后导出,在编辑导出的数据,推荐导出excel,好编辑):
java 源码
好了,回归java,话不多说直接上源码:
[Java] 纯文本查看 复制代码 import com.auv.sonarjsf.bo.PointXY;
import org.apache.commons.math3.fitting.PolynomialCurveFitter;
import org.apache.commons.math3.fitting.WeightedObservedPoints;
import java.util.List;
public class Polynomial {
public static double[] getY(double[] Y_data)
{
WeightedObservedPoints obs = new WeightedObservedPoints();
for (int i = 0; i < Y_data.length; i++) {
obs.add(i, Y_data[i]);
}
PolynomialCurveFitter fitter = PolynomialCurveFitter.create(3);
double[] coeff = fitter.fit(obs.toList());
double[] res = new double[Y_data.length];
for (int i = 0; i < Y_data.length; i++) {
res[i] = fun(i, coeff);
}
return res;
}
public static double getY(double[] Y_data, double x)
{
WeightedObservedPoints obs = new WeightedObservedPoints();
for (int i = 0; i < Y_data.length; i++) {
obs.add(i, Y_data[i]);
}
PolynomialCurveFitter fitter = PolynomialCurveFitter.create(3);
double[] coeff = fitter.fit(obs.toList());
return fun(x, coeff);
}
public static double fun3(double[] coeff, double x)
{
return coeff[0] + coeff[1] * x + coeff[2] * x * x + coeff[3] * x * x * x;
}
public static double fun(double x, double... parameters)
{
double res = 0.0;
for (int i = 0; i < parameters.length; i++) {
res = res + parameters[i] * Math.pow(x, i);
}
return res;
}
}
代码中 PolynomialCurveFitter.create(3); 的3 就是3次多项式,如下图
那么其实关键是 如果求出abcd这个数字的值。
[Java] 纯文本查看 复制代码 double[] coeff = fitter.fit(obs.toList());
代码中 coeff 返回的变量中 就分别是 abcd四个值。
所以 y=coeff[0] + coeff[1] * x + coeff[2] * x * x + coeff[3] * x * x * x;
到这里就很好理解了。
调用示例:
[Java] 纯文本查看 复制代码 double[] heading = Polynomial.getY(list_heading.stream().mapToDouble(o->o).toArray());
double[] heading 就是 做完多项式回归后的值,里面的值是相对比较平滑的,可以直接拿来就用。 |