tags:

views:

51

answers:

3

I have a matrix and i want to create a new matrix which will be the old matrix, but without the first row and first column. is there a way to do this without using loops?

A: 

Simply put: no. But if you do not use jagged arrays but instead use multi-dim arrays, and if you take some time to study the memory layout of arrays in .NET, you could do it with unsafe pointers and erasing a part of the memory and moving the starting pointer of the multi-dim array. But it'd be still dependent on how you design your arrays and your matrixes whether this works or not.

However, I'd highly advice against it. There's a big chance you screw up the type and confuse the garbage collector if you do so.

Alternatively, if you like to do this exercise, use C++/CLI for this task. In C++, you have more control and it's easier to manipulate memory and move pointers directly. You also have more control over the destructor and finalizers, which may come in handy here. But, that said, then you still need marshaling. If you'd do all this for performance, I'd advice to go back to the simple loops, it'll perform faster in most cases.

Abel
i can do it with loops, but i just want to know if there is an elegant way to do this...
@aharont: unfortunately, no. Unless in speed-optimized native code where you need to do trillions of matrix operations and it is worth to squeeze out every ms. But all other solutions, even the ones that don't *look like* loops, will be implemented using loops and copying (PS: some consider that elegant...).
Abel
A: 

Maybe you should have a look at using a maths library with good support for Matrix operations? Here's a thread which mentions a few:

http://stackoverflow.com/questions/840360/matrix-library-for-net

theburningmonk
While good, that lib will do the loops, still ;)
Abel
+1  A: 

i want to create a new matrix

From this it sounds to me like you want a new T[,] object.

which will be the old matrix, but without the first row and first column

I interpret this to mean you want the new T[,] object to contain the same values as the original, excepting the first row/column.

is there a way to do this without using loops?

If I've interpreted your question correctly, then no, not really. You will need to copy elements from one array to another; this requires enumeration. But that doesn't mean you can't abstract the implementation of this method into a reusable method (in fact, this is what you should do).

public static T[,] SubMatrix(this T[,] matrix, int xstart, int ystart)
{
    int width = matrix.GetLength(0);
    int height = matrix.GetLength(1);

    if (xstart < 0 || xstart >= width)
    {
        throw new ArgumentOutOfRangeException("xstart");
    }
    else if (ystart < 0 || ystart >= height)
    {
        throw new ArgumentOutOfRangeException("ystart");
    }

    T[,] submatrix = new T[width - xstart, height - ystart];

    for (int i = xstart; i < width; ++i)
    {
        for (int j = ystart; j < height; ++j)
        {
            submatrix[i - xstart, j - ystart] = matrix[i, j];
        }
    }

    return submatrix;
}

The above code isn't pretty, but once it's in place you'll be able to use it quite neatly:

T[,] withoutFirstRowAndColumn = originalMatrix.SubMatrix(1, 1);

Now, if I misinterpreted your question, and you are not dead-set on creating a new T[,] object, you can improve the efficiency of this approach by not allocating a new T[,] at all; you could take Abel's idea (along with its caveats) and use unsafe code to essentially simulate a T[,] with indices pointing to the elements of the original matrix. Come to think of it, you could even achieve this without resorting to unsafe code; you'd simply need to define an interface for the functionality you'd want to expose (a this[int, int] property comes to mind) and then implement that functionality (your return type wouldn't be a T[,] in this case, but what I'm getting at is that it could be something like it).

Dan Tao
+1, good coverage of the subject matter (and thanks for the pointer ;)
Abel