public class GrayModel
{
private double a0, a1, a2;
private int size;
private double error;
public GrayModel()
{
}
public void build(double[] x0)
{
size = x0.Length;
double[] x1 = new double[size];
x1[0] = x0[0];
for (int i = 1; i < size; i++)
{
x1[i] = x0[i] + x1[i - 1];
}
double[,] b = new double[size - 1, 2];
double[,] bt = new double[2, size - 1];
double[,] y = new double[size - 1, 1];
for (int i = 0; i < b.GetLength(0); i++)
{
b[i, 0] = -(x1[i] + x1[i + 1]) / 2;
b[i, 1] = 1;
bt[0, i] = b[i, 0];
bt[1, i] = 1;
y[i, 0] = x0[i + 1];
}
double[,] t = new double[2, 2];
multiply(bt, b, t);
t = inverse(t);
double[,] t1 = new double[2, size - 1];
multiply(t, bt, t1);
double[,] t2 = new double[2, 1];
multiply(t1, y, t2);
a0 = t2[0, 0];
double u = t2[1, 0];
a2 = u / a0;
a1 = x0[0] - a2;
a0 = -a0;
error = 0;
for (int i = 0; i < x0.Length; i++)
{
double d = (x0[i] - getX0(i));
error += d * d;
}
error /= x0.Length;
}
/// <summary>
/// 误差
/// </summary>
/// <returns></returns>
public double getError()
{
return error;
}
double getX1(int k)
{
return a1 * Math.Exp(a0 * k) + a2;
}
double getX0(int k)
{
// return a0 * a1 * Math.exp(a0 * k);
if (k == 0)
return a1 * Math.Exp(a0 * k) + a2;
else
return a1 * (Math.Exp(a0 * k) - Math.Exp(a0 * (k - 1)));
}
/// <summary>
/// 预测后续的值
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public double nextValue(int index)
{
if (index < 0)
throw new Exception("超出索引范围");
return getX0(size + index);
}
/// <summary>
/// 预测下一个值
/// </summary>
/// <returns></returns>
public double nextValue()
{
return nextValue(0);
}
static double[,] inverse(double[,] t)
{
double[,] a = new double[2, 2];
double det = t[0, 0] * t[1, 1] - t[0, 1] * t[1, 0];
a[0, 0] = t[1, 1] / det;
a[0, 1] = -t[1, 0] / det;
a[1, 0] = -t[0, 1] / det;
a[1, 1] = t[0, 0] / det;
return a;
}
static void multiply(double[,] left, double[,] right, double[,] dest)
{
int n1 = left.GetLength(0);
int m1 = left.GetLength(1);
int m2 = right.GetLength(1);
for (int k = 0; k < n1; k++)
{
for (int s = 0; s < m2; s++)
{
dest[k, s] = 0;
for (int i = 0; i < m1; i++)
{
dest[k, s] += left[k, i] * right[i, s];
}
}
}
}
}
static void Main(string[] args) { double[] a=new double[5]{2.874,3.278,3.337,3.390,3.679}; GrayModel gm = new GrayModel(); gm.build(a); Console.WriteLine(gm.nextValue()); Console.Read(); }