我开始使用Math.net
数字库,但找不到示例,因此遇到了一些问题:
举一个简单的例子,我有两个double
数组。我想一个除以另一个,然后计算移动平均值。
因此,代码如下所示:
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);
问题在于,数据类型在不断变化。它开始于2个Vector
,除法结果是Vector
,而SMA
结果不是,它是IEnumerable<double>
。
所以,现在,如果我想将结果插入更多函数中,例如将其乘以另一个数组,就不能了。我必须从结果中重建一个Vector
。
我以某种方式做错了吗?我无法想象API会在不同但相似的类型之间来回跳动。
答案 0 :(得分:2)
您做对了。这就是MathNet
的设计方式。例如var R = VD1 / VD2;
个通话
// Summary: Pointwise divides two Vectors.
public static Vector<T> operator /(Vector<T> dividend, Vector<T> divisor);
并返回Vector<T>
。
var SMA = R.MovingAverage(15);
通话
public static IEnumerable<double> MovingAverage(this IEnumerable<double> samples, int windowSize);
并返回IEnumerable<double>
。
您可以使用MovingAverage
Vector<double>
来调用R
,因为Vector<double>
实现了IEnumerable<double>
,并且您得到了隐式强制转换。但是MovingAverage
不知道其参数为Vector<double>
,它的设计目的是返回IEnumerable<double>
。
这是有道理的。据我记得,移动平均线是关于时间序列的,它与向量没有明确的关系。
但是您可以有一些解决方法。例如,MovingAverage
自己的重载:
static class VectorHeplper
{
public static Vector<double> MovingAverage(this Vector<double> samples, int windowSize)
{
return DenseVector.OfEnumerable(samples.AsEnumerable().MovingAverage(windowSize));
}
}
然后var SMA = R.MovingAverage(15);
是Vector<double>
。
无论如何,建立新的Vector
实例是正确且合乎逻辑的方式。