|
@@ -0,0 +1,228 @@
|
|
|
|
+package com.gyee.generation.util.realtimesource.math;
|
|
|
|
+
|
|
|
|
+import com.gyee.generation.model.vo.PointVo;
|
|
|
|
+
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.List;
|
|
|
|
+
|
|
|
|
+public class LineUtil {
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 用最小二乘法拟合二元多次曲线
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="arrX">已知点的x坐标集合</param>
|
|
|
|
+ /// <param name="arrY">已知点的y坐标集合</param>
|
|
|
|
+ /// <param name="length">已知点的个数</param>
|
|
|
|
+ /// <param name="dimension">方程的最高次数</param>
|
|
|
|
+ /// <param name="scale">曲线的刻度</param>
|
|
|
|
+ /// <returns></returns>
|
|
|
|
+ public static List<PointVo> buildLine(double[] arrX, double[] arrY, int length, int dimension, double scale)
|
|
|
|
+ {
|
|
|
|
+
|
|
|
|
+ List<PointVo> points =new ArrayList<PointVo>();
|
|
|
|
+
|
|
|
|
+ if (arrX.length != arrY.length || arrX.length<3)
|
|
|
|
+ {
|
|
|
|
+ return points;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ double minValue=arrY[0];
|
|
|
|
+ double maxValue=arrY[arrY.length-1];
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ double min = 0;
|
|
|
|
+ double max= 0;
|
|
|
|
+
|
|
|
|
+ double[] coefficient = multiLine(arrX, arrY, length, dimension);
|
|
|
|
+
|
|
|
|
+ for (double i = arrX[0]; i <= arrX[arrX.length - 1]; i += scale)
|
|
|
|
+ {
|
|
|
|
+ PointVo point = new PointVo();
|
|
|
|
+ point.setX(i);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ for (int j = 0; j < coefficient.length; j++)
|
|
|
|
+ {
|
|
|
|
+ if(j==0)
|
|
|
|
+ {
|
|
|
|
+ point.setY(coefficient[j] * Math.pow(point.getX(), (double)j));
|
|
|
|
+ }else
|
|
|
|
+ {
|
|
|
|
+ double temp=coefficient[j] * Math.pow(point.getX(), (double)j);
|
|
|
|
+ point.setY(point.getY()+temp);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ if (point.getY() < minValue)
|
|
|
|
+ {
|
|
|
|
+ point.setY(minValue);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ if (point.getY() > maxValue)
|
|
|
|
+ {
|
|
|
|
+ point.setY(maxValue);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (point.getY() < min)
|
|
|
|
+ {
|
|
|
|
+ min = point.getY();
|
|
|
|
+ }
|
|
|
|
+ if (point.getY() > max)
|
|
|
|
+ {
|
|
|
|
+ max = point.getY();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ points.add(point);
|
|
|
|
+ }
|
|
|
|
+ builder(points, min, max);
|
|
|
|
+ return points;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static void builder(List<PointVo> points, double min, double max)
|
|
|
|
+ {
|
|
|
|
+ boolean b = false;
|
|
|
|
+ for (int i = 0; i < points.size(); i++)
|
|
|
|
+ {
|
|
|
|
+ if (b)
|
|
|
|
+ {
|
|
|
|
+ points.get(i).setY(max);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ if (max == points.get(i).getY())
|
|
|
|
+ {
|
|
|
|
+ b = true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (int i = points.size()-1; i > -1; i--)
|
|
|
|
+ {
|
|
|
|
+ if (!b)
|
|
|
|
+ {
|
|
|
|
+ points.get(i).setY(min);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ if (min == points.get(i).getY())
|
|
|
|
+ {
|
|
|
|
+ b = false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ ///<summary>
|
|
|
|
+ ///用最小二乘法拟合二元多次曲线
|
|
|
|
+ ///</summary>
|
|
|
|
+ ///<param name="arrX">已知点的x坐标集合</param>
|
|
|
|
+ ///<param name="arrY">已知点的y坐标集合</param>
|
|
|
|
+ ///<param name="length">已知点的个数</param>
|
|
|
|
+ ///<param name="dimension">方程的最高次数</param>
|
|
|
|
+ public static double[] multiLine(double[] arrX, double[] arrY, int length, int dimension)//二元多次线性方程拟合曲线
|
|
|
|
+ {
|
|
|
|
+ int n = dimension + 1; //dimension次方程需要求 dimension+1个 系数
|
|
|
|
+ double[][] guass = new double[n][n+1]; //高斯矩阵 例如:y=a0+a1*x+a2*x*x
|
|
|
|
+ for (int i = 0; i < n; i++)
|
|
|
|
+ {
|
|
|
|
+ int j;
|
|
|
|
+ for (j = 0; j < n; j++)
|
|
|
|
+ {
|
|
|
|
+ guass[i][j] = sumArr(arrX, j + i, length);
|
|
|
|
+ }
|
|
|
|
+ guass[i][j]= sumArr(arrX, i, arrY, 1, length);
|
|
|
|
+ }
|
|
|
|
+ return computGauss(guass, n);
|
|
|
|
+ }
|
|
|
|
+ public static double sumArr(double[] arr, int n, int length) //求数组的元素的n次方的和
|
|
|
|
+ {
|
|
|
|
+ double s = 0;
|
|
|
|
+ for (int i = 0; i < length; i++)
|
|
|
|
+ {
|
|
|
|
+ if (arr[i] != 0 || n != 0)
|
|
|
|
+ s = s + Math.pow(arr[i], n);
|
|
|
|
+ else
|
|
|
|
+ s = s + 1;
|
|
|
|
+ }
|
|
|
|
+ return s;
|
|
|
|
+ }
|
|
|
|
+ public static double sumArr(double[] arr1, int n1, double[] arr2, int n2, int length)
|
|
|
|
+ {
|
|
|
|
+ double s = 0;
|
|
|
|
+ for (int i = 0; i < length; i++)
|
|
|
|
+ {
|
|
|
|
+ if ((arr1[i] != 0 || n1 != 0) && (arr2[i] != 0 || n2 != 0))
|
|
|
|
+ s = s + Math.pow(arr1[i], n1) * Math.pow(arr2[i], n2);
|
|
|
|
+ else
|
|
|
|
+ s = s + 1;
|
|
|
|
+ }
|
|
|
|
+ return s;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ public static double[] computGauss(double[][] guass, int n)
|
|
|
|
+ {
|
|
|
|
+ int i, j;
|
|
|
|
+ int k, m;
|
|
|
|
+ double temp;
|
|
|
|
+ double max;
|
|
|
|
+ double s;
|
|
|
|
+ double[] x = new double[n];
|
|
|
|
+ for (i = 0; i < n; i++) x[i] = 0.0;//初始化
|
|
|
|
+
|
|
|
|
+ for (j = 0; j < n; j++)
|
|
|
|
+ {
|
|
|
|
+ max = 0;
|
|
|
|
+ k = j;
|
|
|
|
+ for (i = j; i < n; i++)
|
|
|
|
+ {
|
|
|
|
+ if (Math.abs(guass[i][j]) > max)
|
|
|
|
+ {
|
|
|
|
+ max = guass[i][j];
|
|
|
|
+ k = i;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ if (k != j)
|
|
|
|
+ {
|
|
|
|
+ for (m = j; m < n + 1; m++)
|
|
|
|
+ {
|
|
|
|
+ temp = guass[j][m];
|
|
|
|
+ guass[j][m]= guass[k][m];
|
|
|
|
+ guass[k][m] = temp;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (0 == max)
|
|
|
|
+ {
|
|
|
|
+ // "此线性方程为奇异线性方程"
|
|
|
|
+ return x;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (i = j + 1; i < n; i++)
|
|
|
|
+ {
|
|
|
|
+ s = guass[i][j];
|
|
|
|
+ for (m = j; m < n + 1; m++)
|
|
|
|
+ {
|
|
|
|
+ guass[i][m] = guass[i][m] - guass[j][m] * s / (guass[j][j]);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }//结束for (j=0;j<n;j++)
|
|
|
|
+
|
|
|
|
+ for (i = n - 1; i >= 0; i--)
|
|
|
|
+ {
|
|
|
|
+ s = 0;
|
|
|
|
+ for (j = i + 1; j < n; j++)
|
|
|
|
+ {
|
|
|
|
+ s = s + guass[i][j] * x[j];
|
|
|
|
+ }
|
|
|
|
+ x[i] = (guass[i][n]- s) / guass[i][i];
|
|
|
|
+ }
|
|
|
|
+ return x;
|
|
|
|
+ }//返回值是函数的系数
|
|
|
|
+}
|
|
|
|
+
|