2016-01-15 63 views
4

我在這裏是新的,我希望或許專家能幫助我: 我想通過C#中的庫「math.net numerics」來適應竇功能f(x) = a *sin(b* (x+c))+dMath.Net Numerics - 擬合竇功能

在開始的時候我嘗試下面的示例代碼:

// data points: we compute y perfectly but then add strong random noise to it 
var rnd = new Random(1); 
var omega = 1.0d 
var xdata = new double[] { -1, 0, 0.1, 0.2, 0.3, 0.4, 0.65, 1.0, 1.2, 2.1, 4.5, 5.0, 6.0 }; 
var ydata = xdata.Select(x => 5 + 2 * Math.Sin(omega*x + 0.2) + 2*(rnd.NextDouble()-0.5)).ToArray(); 

// build matrices 
var X = DenseMatrix.OfColumns(new[] { 
new DenseVector(1), 
new DenseVector(xdata.Select(t => Math.Sin(omega*t)).ToArray()), 
new DenseVector(xdata.Select(t => Math.Cos(omega*t)).ToArray())}); 
var y = new DenseVector(ydata); 

// solve 
var p = X.QR().Solve(y); 
var a = p[0]; 
var b = SpecialFunctions.Hypotenuse(p[1], p[2]); 
var c = Math.Atan2(p[2], p[1]); 

但結果是,該程序返回以下錯誤:

"Matrix dimensions must agree: 1x3".

你能不能給我一個提示我所能要解決這個問題嗎?

+1

僅供參考'歐米茄* X + 0.2'會首先做乘法,然後加入。根據你的公式,它看起來應該是'omega *(x + 0.2)'。 – juharr

+0

@juharr tThanks for your answer - 但錯誤仍然是一樣的:-( –

+0

你打算用'new DenseVector(1)'表示什麼意思? –

回答

2

您正在向具有不同長度的矩陣(X)添加3列。

第一個矢量長度爲1,而第二個和第三個矢量長度爲xdata.Length

如果您打算爲第一載體有xdata.Length的長度,但可以用1填充然後執行以下操作:

var X = DenseMatrix.OfColumns(new[] 
{ 
    new DenseVector(Enumerable.Repeat(1d , xdata.Length).ToArray()), 
    new DenseVector(xdata.Select(t => Math.Sin(omega*t)).ToArray()), 
    new DenseVector(xdata.Select(t => Math.Cos(omega*t)).ToArray()) 
}); 
+0

感謝Yacoub你救了我的生命 –

+0

附加問題:上面的代碼是函數f(x)= a + b * sin(c + omega * x)在代碼中我必須改變什麼,所以函數f(x)= a * sin(b *( x + c))+ d? –

+0

@Biläl,如果你把這個作爲另一個問題的細節來發佈會更好,這樣,我們有更多的上下文來回答這個問題。 –