Reputation: 12107
I am starting to use the Math.net
numerics library and I can't find examples, so I'm running into a few issues:
To make a simple example, I have two arrays of double
s. I want to divide one by the other and then calculate the moving average.
So, the code looks like this:
var VD1 = Vector<double>.Build.Dense(Data1.ToArray());
var VD2 = Vector<double>.Build.Dense(Data2.ToArray());
var R = VD1 / VD2;
var SMA = R.MovingAverage(15);
The problem is that, on the way, the data type changes. It starts as 2 Vector
s, the division result is a Vector
and the SMA
result is not, it's an IEnumerable<double>
.
So, now if I want to plug that result into more functions, for example multiply it by another array, I can't. I have to rebuild a Vector
from the result.
Am I somehow doing this wrong? I can't imagine that the API would bounce back and forth between different but similar types.
Upvotes: 2
Views: 380
Reputation: 3235
You are doing it right. That is how MathNet
is designed. E.g., var R = VD1 / VD2;
calls
// Summary: Pointwise divides two Vectors.
public static Vector<T> operator /(Vector<T> dividend, Vector<T> divisor);
and returns Vector<T>
.
var SMA = R.MovingAverage(15);
calls
public static IEnumerable<double> MovingAverage(this IEnumerable<double> samples, int windowSize);
and returns IEnumerable<double>
.
You can call MovingAverage
with Vector<double>
R
, because Vector<double>
implements IEnumerable<double>
and you get implicit casting. But MovingAverage
does not know its argument is Vector<double>
, it's designed to return IEnumerable<double>
.
And that makes sense. As far as I remember from colledge, moving average is about time series and it has no explicit relationship to vectors.
But you can have some workarounds. For example your own overload for MovingAverage
:
static class VectorHeplper
{
public static Vector<double> MovingAverage(this Vector<double> samples, int windowSize)
{
return DenseVector.OfEnumerable(samples.AsEnumerable().MovingAverage(windowSize));
}
}
Then var SMA = R.MovingAverage(15);
is Vector<double>
.
Anyway, building a new instance of Vector
is the right and logical way.
Upvotes: 3