问题
I'm new here and I hope that perhaps the experts outthere can help me:
I want to fit the sinus function f(x) = a *sin(b* (x+c))+d via the library "math.net numerics" in C#.
At the beginning I tried the following example code:
// 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]);
But the result was, that the program returned the following error:
"Matrix dimensions must agree: 1x3".
Could you give me a hint what I can do to solve the problem ?
回答1:
You are adding 3 columns to the matrix (X) that have different lengths.
The first vector has length 1, while the second and third vectors have lengths of xdata.Length.
If you intend for the first vector to have the length of xdata.Length but to be filled with 1s then do the following:
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())
});
来源:https://stackoverflow.com/questions/34813285/math-net-numerics-fitting-sinus-function