在C#中矢量化运算符

时间:2009-10-29 13:51:46

标签: c# arrays operators

我花了很多时间在R或MATLAB中编程。这些语言通常用于操作数组和矩阵,因此,它们具有向量运算符,用于加法,等式等。

例如,在MATLAB中,添加两个数组

[1.2 3.4 5.6] + [9.87 6.54 3.21]

返回一个大小相同的数组

ans =
        11.07         9.94         8.81

切换到C#,我们需要一个循环,感觉就像很多代码。

double[] a = { 1.2, 3.4, 5.6 };
double[] b = { 9.87, 6.54, 3.21 };
double[] sum = new double[a.Length];
for (int i = 0; i < a.Length; ++i)
{
  sum[i] = a[i] + b[i];
}

我应该如何使用C#实现矢量化运算符?这些应该适用于所有数字数组类型(和bool[])。为多维数组工作是一个奖励。

我的第一个想法是直接重载System.Double[]等运算符。但是这有很多问题。首先,如果内置类不像预期的那样,它可能会引起混淆和可维护性问题。其次,我不确定是否有可能改变这些内置类的行为。

所以我的下一个想法是从每个数字类型派生一个类并重载那里的运算符。这会造成从double[]转换为MyDoubleArray并返回的麻烦,这减少了我减少打字的好处。

另外,我真的不想为每种数字类型重复几乎相同的功能。这导致了我对通用运算符类的下一个想法。事实上,其他人也有这个想法:Jon Skeet的MiscUtil库中有一个泛型运算符类。

这为操作提供了类似方法的前缀语法,例如

double sum = Operator<double>.Add(3.5, -2.44); // 1.06

问题是,由于数组类型不支持添加,你不能只做像

这样的事情
double[] sum = Operator<double[]>.Add(a, b);  // Throws InvalidOperationException

我已经没想完了。你能想到任何有用的东西吗?

4 个答案:

答案 0 :(得分:4)

创建一个Vector类(实际上我将它变成一个结构体)并重载该类的算术运算符......如果你进行谷歌搜索,这可能已经完成了,有很多点击...这里有一个看起来很有希望Vector class ......

要处理任意维度的向量,我会:

  1. 设计内部数组,该数组将保留每个浮点数 向量维值是一个任意大小的数组列表,
  2. 使Vector构造函数将维度作为构造函数参数
  3. 在算术运算符重载中,添加一个验证,即添加或减去的两个向量具有相同的维度。

答案 1 :(得分:2)

您应该创建一个Vector类,它在内部包装数组并重载算术运算符。有一个不错的matrix/vector code library here

但是如果由于某种原因你真的需要在裸阵列上运行,你可以使用LINQ:

var a1 = new double[] { 0, 1, 2, 3 };
var a2 = new double[] { 10, 20, 30, 40 };

var sum = a1.Zip( a2, (x,y) => Operator<double>.Add( x, y ) ).ToArray();

答案 2 :(得分:1)

看看CSML。它是一个相当完整的c#矩阵库。我已经将它用于一些事情并且效果很好。

答案 3 :(得分:0)

XNA Framework包含您可以使用的课程。您可以像在.NET的任何其他部分一样在应用程序中使用它。只需抓住XNA redistributable并代码离开。

顺便说一句,你不需要做任何特别的事情(比如让游戏工作室或加入创作者俱乐部)在你的应用程序中使用它。