2013-01-25 40 views
2

我想使用C#應用程序分析一些數據並需要計算趨勢線。我知道有多種類型的趨勢線,但現在我正在計算指數增長;我將用它來預測未來的價值。我已經工作過的公式爲從數據點計算指數增長方程c#

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值是從哪裏生成的。我傳入的兩個列表是日期和值,每個列表中的每一行對應於另一列表中的同一行。問題是 - 是否有創建方程和變量的更好方法,並且是我獲得的數據最準確的變量?

+1

'e^kt'與'(r + 1)^ t'相同,只是不同的常量('r = e^k-1') - 即我不擔心Excel有不同的表單,並且可以使用該公式來查看是否獲得與Excel相同的結果。 – Rawling

+0

@Rawling哦,好的,謝謝你。我嘗試用70的規則複製常數k,其中k = ln(2)/ T和我得到了一條非常相似的線,雖然它有更多的增長。我會嘗試比較圖表對彼此。乾杯! – manicmonkey21421

回答

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; 
} 
+0

謝謝你的回答,我會放棄它。非常感謝。 – manicmonkey21421

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(); 

    } 
+0

非常感謝您使用之前提供的JAVA,並將其與我的原始函數進行比較,並且它們看起來非常相似,但我嘗試使用轉換後的代碼並查看圖形的外觀。乾杯 – manicmonkey21421

+0

只是想指出代碼中的地方「.Add(i ++);」使用時應改爲「.Add(i);」或者你會雙倍增加你的指數,導致更小的集合。試圖編輯答案來反映,但編輯必須至少有6個字符的變化。 :) – ASeale

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 + at,這樣k=ax(0)=e^b