views:

106

answers:

4

I spend much of my time programming in R or MATLAB. These languages are typically used for manipulating arrays and matrices, and consequently, they have vectorised operators for addition, equality, etc.

For example, in MATLAB, adding two arrays

[1.2 3.4 5.6] + [9.87 6.54 3.21]

returns an array of the same size

ans =
        11.07         9.94         8.81

Switching over to C#, we need a loop, and it feels like a lot of code.

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];
}

How should I implement vectorised operators using C#? These should preferably work for all numeric array types (and bool[]). Working for multidimensional arrays is a bonus.

The first idea I had was to overload the operators for System.Double[], etc. directly. This has a number of problems though. Firstly, it could cause confusion and maintainability issues if built-in classes do not bahave as expected. Secondly, I'm not sure if it is even possible to change the behaviour of these built-in classes.

So my next idea was to derive a class from each numerical type and overload the operators there. This creates the hassle of converting from double[] to MyDoubleArray and back, which reduces the benefit of me doing less typing.

Also, I don't really want to have to repeat a load of almost identical functionality for every numeric type. This lead to my next idea of a generic operator class. In fact, someone else had also had this idea: there's a generic operator class in Jon Skeet's MiscUtil library.

This gives you a method-like prefix syntax for operations, e.g.

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

The trouble is, since the array types don't support addition, you can't just do something like

double[] sum = Operator<double[]>.Add(a, b);  // Throws InvalidOperationException

I've run out of ideas. Can you think of anything that will work?

+4  A: 

Create a Vector class (actually I'd make it a struct) and overload the arithmentic operators for that class... This has probably been done already if you do a google search, there are numerous hits... Here's one that looks promising Vector class...

To handle vectors of arbitrary dimension, I'd:

  1. design the internal array which would persist the individual floats for each of the vectors dimension values an array list of arbitrary size,
  2. make the Vector constructor take the dimension as an constructor parameter,
  3. In the arithmentic operator overloads, add a validation that the two vectors being added, or subtracted have the same dimension.
Charles Bretana
Thanks, but wouldn't I still need to create lots of derived classes (DoubleVector, IntVector, BoolVector, etc.), since object + object deosn't work.
Richie Cotton
A generic Vector<T> then?
peSHIr
@peSHIr: This would be ideal, but in the Add(T a, T b) method, you have to add individual elements using, e.g., for(i ...){sum[i] = (T)a[i] + (T)b[i];}, i.e. adding two objects of type T, which doesn't compile.
Richie Cotton
+1  A: 

Take a look at CSML. It's a fairly complete matrix library for c#. I've used it for a few things and it works well.

Nestor
This seems pretty useful. It gets around the problem of dealing with different types by storing everything as an ArrayList of ArrayLists of 'Complex' values (effectively a pair of doubles).
Richie Cotton
+2  A: 

You should probably create a Vector class that internally wraps an array and overloads the arithmetic operators. There's a decent matrix/vector code library here.

But if you really need to operate on naked arrays for some reason, you can use 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();
LBushkin
Cheers. I've only recently upgraded to using 3.5 Framework, and have been putting off learning LINQ. I guess this is my reason to go for it. Quick question: Where does the Zip method come from?
Richie Cotton
Zip is available with either the MoreLINQ library (see URL) or with .NET 4.0. It's the easiest way to merge two sequences. MoreLINQ: http://code.google.com/p/morelinq/
LBushkin
A: 

The XNA Framework has the classes you may be able to use. You can use it in your application like any other part of .NET. Just grab the XNA redistributable and code away.

BTW, you don't need to do anything special (like getting the game studio or joining the creator's club) to use it in your application.

Will