从数据点c#计算指数增长方程

时间:2013-01-25 14:06:07

标签: c# visual-studio-2010 math exponential

我正在尝试使用C#app分析一些数据,并需要计算趋势线。我知道有多种类型的趋势线,但现在我试图计算指数增长;我将用它来预测未来的价值观。我一直在努力的等式是

x(t) = x(0) * ((1+r)^t)

这是我为编写和复制图表而编写的代码:

public void ExponentialBestFit(List<DateTime> xvalues, List<double> yvalues)

        {
            //Find the first value of y (The start value) and the first value of x (The start date)
            xzero = Convert.ToDouble(xvalues[0].ToOADate());
            yzero = yvalues[0];
            if (yzero == 0)
                yzero += 0.1;

            //For every value of x (exluding the 1st value) find the r value
            //
            //                       |   y   |          Where t = the time sinse the start time (time period)
            //Equation for r = t root|-------| - 1      Where y = the current y value
            //                       |  y[0] |          Where y[0] = the first y value  #IMPROVMENT - Average 1st y value in range
            //
            double r = 0;

            //c is a count of how many r values are added; it is not equal to the count of all the values
            int c = 0;
            for (int i = 1; i < xvalues.Count; i++)
            {
                r += Math.Pow(yvalues[i]/yzero, 1/(Convert.ToDouble(xvalues[i].ToOADate()) - xzero)) - 1;
                c++;
            }

            r = r / c;           
        }

我传入的数据是一段时间,但时间增加的增量不一样。当我在Excel中创建图表时,他们使用不同的公式

x(t) = x(0)*(e^kt)

我想我不知道从哪里生成k值。我传入的两个列表是日期和值,每个列表中的每一行对应于另一个列表中的同一行。问题是 - 是否有更好的方法来创建方程和变量,并且我得到的变量是我的数据最准确的变量?

3 个答案:

答案 0 :(得分:3)

这是所提供的javascript的c#版本。

    IEnumerable<double> Growth(IList<double> knownY, IList<double> knownX, IList<double> newX, bool useConst)
    {
        // Credits: Ilmari Karonen

        // Default values for optional parameters:
        if (knownY == null) return null;
        if (knownX == null)
        {
            knownX = new List<double>();
            for (var i  = 0; i<=knownY.Count; i++)
                knownX.Add(i++);
        }
        if (newX == null)
        {
            newX = new List<double>();
            for (var i = 0; i <= knownY.Count; i++)
                newX.Add(i++);
        }

        int n = knownY.Count;
        double avg_x = 0.0;
        double avg_y = 0.0;
        double avg_xy = 0.0;
        double avg_xx = 0.0;
        double beta = 0.0;
        double alpha = 0.0;
        for (var i = 0; i < n; i++)
        {
            var x = knownX[i];
            var y = Math.Log(knownY[i]);
            avg_x += x;
            avg_y += y;
            avg_xy += x * y;
            avg_xx += x * x;
        }
        avg_x /= n;
        avg_y /= n;
        avg_xy /= n;
        avg_xx /= n;

        // Compute linear regression coefficients:
        if (useConst)
        {
            beta = (avg_xy - avg_x * avg_y) / (avg_xx - avg_x * avg_x);
            alpha = avg_y - beta * avg_x;
        }
        else
        {
            beta = avg_xy / avg_xx;
            alpha = 0.0;
        }

        // Compute and return result array:
        return newX.Select(t => Math.Exp(alpha + beta*t)).ToList();

    }

答案 1 :(得分:1)

以下JavaScript代码应该有所帮助。我用它来实现Excel的GROWTH函数。它是用JavaScript编写的,但将它移植到C#应该非常简单。请注意,其中大部分是由其他人撰写的(代码中的信用)。

function GROWTH(known_y, known_x, new_x, use_const) {
  // Credits: Ilmari Karonen

  // Default values for optional parameters:
  if (typeof(known_x) == 'undefined') {
    known_x = [];
    for (var i = 1; i <= known_y.length; i++) known_x.push(i);
  }
  if (typeof(new_x) == 'undefined') {
    new_x = [];
    for (var i = 1; i <= known_y.length; i++) new_x.push(i);
  }
  if (typeof(use_const) == 'undefined') use_const = true;

  // Calculate sums over the data:
  var n = known_y.length;
  var avg_x = 0;
  var avg_y = 0;
  var avg_xy = 0;
  var avg_xx = 0; 
  for (var i = 0; i < n; i++) {
    var x = known_x[i];
    var y = Math.log(known_y[i]);
    avg_x += x;
    avg_y += y;
    avg_xy += x*y;
    avg_xx += x*x;
  }
  avg_x /= n;
  avg_y /= n;
  avg_xy /= n;
  avg_xx /= n;

  // Compute linear regression coefficients:
  if (use_const) {
    var beta = (avg_xy - avg_x*avg_y) / (avg_xx - avg_x*avg_x);
    var alpha = avg_y - beta*avg_x;
  } else {
    var beta = avg_xy / avg_xx;
    var alpha = 0;
  }

  // Compute and return result array:
  var new_y = [];
  for (var i = 0; i < new_x.length; i++) {
    new_y.push(Math.exp(alpha + beta * new_x[i]));
  }
  return new_y;
}

答案 2 :(得分:0)

x(t)=x(0)*e^{kt}开始,我们可以使用对数来获取ln x(t)=ln x(0) + kt。这意味着要查找ln x(0)k,您可以找到适合数据{(t,ln x(t))}的最小二乘法。这会告诉您ln x(t) = b + atk=ax(0)=e^b