xzknet 发表于 2013-1-27 04:41:47

最小二乘法拟合

 /**
 * 最小二乘法拟合
 * 
 *
 * @author Ken转发
 *
 */
public class Linest {
 /**
  * <p>
  * 函数功能:最小二乘法曲线拟合
  * </p>
  *
  * @param x
  *            实型一维数组,长度为 n 。存放给定 n 个数据点的 X 坐标
  * @param y
  *            实型一维数组,长度为 n 。存放给定 n 个数据点的 Y 坐标
  * @param n
  *            变量。给定数据点的个数
  * @param a
  *            实型一维数组,长度为 m 。返回 m-1 次拟合多项式的 m 个系数
  * @param m
  *            拟合多项式的项数,即拟合多项式的最高次数为 m-1. 要求 m<=n 且m<=20。若 m>n 或 m>20
  *            ,则本函数自动按 m=min{n,20} 处理.
  *            <p>
  *            Date:2007-12-25 16:21 PM
  *            </p>
  * @author qingbao-gao
  * @return
  */
 public static double[] PolyFit(double x[], double y[], int n, double a[],
   int m) {
  int i, j, k;
  double z, p, c, g, q = 0, d1, d2;
  double[] s = new double;
  double[] t = new double;
  double[] b = new double;
  double[] dt = new double;
  for (i = 0; i <= m - 1; i++) {
   a = 0.0;
  }
  if (m > n) {
   m = n;
  }
  if (m > 20) {
   m = 20;
  }
  z = 0.0;
  for (i = 0; i <= n - 1; i++) {
   z = z + x / (1.0 * n);
  }
  b = 1.0;
  d1 = 1.0 * n;
  p = 0.0;
  c = 0.0;
  for (i = 0; i <= n - 1; i++) {
   p = p + (x - z);
   c = c + y;
  }
  c = c / d1;
  p = p / d1;
  a = c * b;
  if (m > 1) {
   t = 1.0;
   t = -p;
   d2 = 0.0;
   c = 0.0;
   g = 0.0;
   for (i = 0; i <= n - 1; i++) {
    q = x - z - p;
    d2 = d2 + q * q;
    c = c + y * q;
    g = g + (x - z) * q * q;
   }
   c = c / d2;
   p = g / d2;
   q = d2 / d1;
   d1 = d2;
   a = c * t;
   a = c * t + a;
  }
  for (j = 2; j <= m - 1; j++) {
   s = t;
   s = -p * t + t;
   if (j >= 3)
    for (k = j - 2; k >= 1; k--) {
     s = -p * t + t - q * b;
    }
   s = -p * t - q * b;
   d2 = 0.0;
   c = 0.0;
   g = 0.0;
   for (i = 0; i <= n - 1; i++) {
    q = s;
    for (k = j - 1; k >= 0; k--) {
     q = q * (x - z) + s;
    }
    d2 = d2 + q * q;
    c = c + y * q;
    g = g + (x - z) * q * q;
   }
   c = c / d2;
   p = g / d2;
   q = d2 / d1;
   d1 = d2;
   a = c * s;
   t = s;
   for (k = j - 1; k >= 0; k--) {
    a = c * s + a;
    b = t;
    t = s;
   }
  }
  dt = 0.0;
  dt = 0.0;
  dt = 0.0;
  for (i = 0; i <= n - 1; i++) {
   q = a;
   for (k = m - 2; k >= 0; k--) {
    q = a + q * (x - z);
   }
   p = q - y;
   if (Math.abs(p) > dt) {
    dt = Math.abs(p);
   }
   dt = dt + p * p;
   dt = dt + Math.abs(p);
  }
  return a;
 }
 /**
  * <p>
  * 对X轴数据节点球平均值
  * </p>
  *
  * @param x
  *            存储X轴节点的数组
  *            <p>
  *            Date:2007-12-25 20:21 PM
  *            </p>
  * @author qingbao-gao
  * @return 平均值
  */
 public static double ave(double[] x) {
  double ave = 0;
  double sum = 0;
  if (x != null) {
   for (int i = 0; i < x.length; i++) {
    sum += x;
   }
   System.out.println("sum-->" + sum);
   ave = sum / x.length;
   System.out.println("ave" + ave + "x.length" + x.length);
  }
  return ave;
 }
 /**
  * <p>
  * 由X值获得Y值
  * </p>
  *
  * @param x
  *            当前X轴输入值,即为预测的月份
  * @param xx
  *            当前X轴输入值的前X数据点
  * @param a
  *            存储多项式系数的数组
  * @param m
  *            存储多项式的最高次数的数组
  *            <p>
  *            Date:2007-12-25 PM 20:07
  *            </p>
  *            <P>
  *            Author:qingbao-gao
  *            </P>
  * @return 对应X轴节点值的Y轴值
  */
 public static double getY(double x, double[] xx, double[] a, int m) {
  double y = 0;
  double ave = ave(xx);
  double l = 0;
  for (int i = 0; i < m; i++) {
   l = a;
   if (i > 0) {
    y += a * Math.pow((x - ave), i);
    System.out.println(i + "--|-->" + y + "--a--" + a);
   }
   System.out.println("a|" + a);
  }
  System.out.println("l--|" + (l));
  return (y + l);
 }
 // --------------------------------------------测试代码
 public static void main(String[] args) {
  double[] x = { 200401, 200402, 200403, 200404, 200405, 200406, 200407,
    200408, 200409, 2004010, 2004011, 2004012, 200501, 200502,
    200503, 200504 };
  double[] y = { 51, 51, 53, 53, 54, 55, 57, 60, 63, 64, 66, 66, 69, 71,
    72, 75 };
  double[] a = new double;
  double[] aa = PolyFit(x, y, 16, a, 3);
  double yy = 0;
  System.out.println("拟合-->" + getY(200505, x, aa, 3));
 }
}
页: [1]
查看完整版本: 最小二乘法拟合