今天来记录一下通过数据拟合函数的代码,这里用到了commons-math3工具包进行拟合。
参考内容:https://blog.csdn.net/wufeiwua/article/details/109004452
首先导入依赖
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.6.1</version>
</dependency>
因为博主大学数据全都还给了老师,在同事的帮助下才实现如下代码:
import com.adc.devp.function.bean.Point;
import org.apache.commons.math3.analysis.ParametricUnivariateFunction;
import org.apache.commons.math3.fitting.SimpleCurveFitter;
import org.apache.commons.math3.fitting.WeightedObservedPoints;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
/**
* 极化曲线拟合函数
*
* @author: 刘朋
* <br/>date:
*/
class PolarizationFunction implements ParametricUnivariateFunction {
private double[] parameters;
/**
* 定义公式
* V = v0 - b * Math.log10(i) - r * i
*
* @param i
* @param parameters
* @return
*/
@Override
public double value(double i, double... parameters) {
double v0 = parameters[0];
double b = parameters[1];
double r = parameters[2];
// 自定义函数
return v0 - b * Math.log10(i) - r * i;
}
@Override
public double[] gradient(double i, double... parameters) {
double[] gradients = new double[3];
// 对 v0 求导
gradients[0] = 1;
// 对 b 求导
gradients[1] = -Math.log10(i);
// 对 r 求导
gradients[2] = -i;
return gradients;
}
/**
* 拟合代码逻辑
*
* @param points 待拟合的数据
* @return
*/
public PolarizationFunction fitting(List<Point> points) {
ParametricUnivariateFunction function = new PolarizationFunction();/*多项式函数*/
/*猜测值 依次为 v0 b r 。必须和 gradient 方法返回数组对应*/
double[] guess = {250, 0.1, 0.1};
// 初始化拟合
SimpleCurveFitter curveFitter = SimpleCurveFitter.create(function, guess);
// 添加数据点。带权重的点,我的理解这个点权重越大,拟合出来的曲线会更靠近这个点
WeightedObservedPoints observedPoints = new WeightedObservedPoints();
for (Point point : points) {
observedPoints.add(point.getX(), point.getY());
}
/*
* best 为拟合结果 对应 v0 b r
* 可能会出现无法拟合的情况
* 需要合理设置初始值
* */
double[] best = curveFitter.fit(observedPoints.toList());
System.out.println(Arrays.toString(best));
parameters = best;
return this;
}
/**
* @param x
* @return
*/
public double caleY(double x) {
if (Objects.isNull(parameters)) {
throw new RuntimeException("参数为空,请先进行拟合操作");
}
return this.value(x, parameters);
}
}
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
@Data
@EqualsAndHashCode
public class Point implements Serializable {
private static final long serialVersionUID = 3256087124347421878L;
private double x;
private double y;
public Point() {
}
public Point(double x, double y) {
this.x = x;
this.y = y;
}
}
在此感谢我的同事晋津对我的帮助!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/34351.html