背景
由于项目中需要根据磁盘的历史使用情况预测未来一段时间的使用情况,决定采用最小二乘法做多项式拟合,这里简单描述下:
假设给定的数据点和其对应的函数值为 (x1, y1), (x2, y2), ... (xm, ym),需要做的就是得到一个多项式函数
f(x) = a0 * x + a1 * pow(x, 2) + .. + an * pow(x, n),使其对所有给定x所计算出的f(x)与实际对应的y值的差的平方和最小,
也就是计算多项式的各项系数 a0, a1, ... an.
根据最小二乘法的原理,该问题可转换为求以下线性方程组的解:Ga = B,
所以从编程的角度来说需要做两件事情,1,确定线性方程组的各个系数,2,解线性方程组
确定系数比较简单,对给定的 (x1, y1), (x2, y2), ... (xm, ym) 做相应的计算即可,相关代码:
private void compute() {
...
}
解线性方程组稍微复杂,这里用到了高斯消元法,基本思想是通过递归做矩阵转换,逐渐减少求解的多项式系数的个数,相关代码:
private double[] calcLinearEquation(double[][] a, double[] b) {
...
}
Java代码
package com.my.study.algorithm.leastSquareMethod;
/**
* Least square method class.
*/
public class LeastSquareMethod {
private double[] x;
private double[] y;
private double[] weight;
private int n;
private double[] coefficient;
/**
* Constructor method.
*
* @param x
* Array of x
* @param y
* Array of y
* @param n
* The order of polynomial
*/
public LeastSquareMethod(double[] x, double[] y, int n) {
if (x == null || y == null || x.length < 2 || x.length != y.length
|| n < 2) {
throw new IllegalArgumentException(
"IllegalArgument