开发者

Concatenate a 2D array

I have t开发者_开发技巧wo arrays mat1 & Mat2. I want to have new_mat=[ma1,mat2]; I have written a function which works. I wonder if there is an efficient function for very large matrix or How can I do it with Array.CopyTo method.

public static double[,] Concatenate_matrix_byCol(double[,] Mat1, double[,] Mat2)
{
    int col1=Mat1.GetLength(1);
    int col2 = Mat2.GetLength(1);
    int row1=Mat1.GetLength(0);
    int row2 = Mat2.GetLength(0);
    int i, j,  y;
    double[,] newMat = new double[row1, col1 + col2];

    for (i = 0; i < row1; i++)
    {
        for (j = 0; j < col1; j++)
        {
            newMat[i, j] = Mat1[i, j];
        }
    }                
    for (i = 0; i < row1; i++)
    {
        for (y = 0; y < col2; y++)
        {
            newMat[i, y+col1] = Mat2[i, y];
        }
    }
    return newMat;
}


You could combine your loops into:

for (i = 0; i < row1; i++)
{
     for (j = 0; j < col1; j++)
         newMat[i, j] = Mat1[i, j];

     for (y = 0; y < col2; y++)
         newMat[i, y+col1] = Mat2[i, y];
}

And maybe use pointers instead (test performance first!) but a library would properly be the best solution. That way you don't have to do micro-optimizations yourself.

There is a lot of libraries for .Net mentioned in this thread: Matrix Library for .NET

Depending on your performance requirement you could also look into parallel algorithms and you may be inspired by http://innovatian.com/2010/03/parallel-matrix-multiplication-with-the-task-parallel-library-tpl/. Again, a well-build library probably already have parallel algorithms.


When moving Arrays, you should look into Array.CopyTo instead of moving the cells one by one.

Also you could create a class that accepts the 2 matrices, and provides a level of abstraction that makes them look like 1 matrix but just keeps them seperate underneath.

For instance M1 = 20x 30 and M2 = 25 x 30 so you have a class M3 that 'looks like' M1 + M2, a 55 x 30 matrix.

When someone asks for M3[28, 23] this class will know that it should redirect to M2[8, 23] because M1 was only 20 positions wide (28-20=8). That way you don't have to copy the memory, that's expensive. Figuring out how to reroute a request to the right matrix is much cheaper. Depends on how much the matrix accessed afterwards obviously.

edit This is what I mean:

class Program {
    static void Main(string[] args) {

        int[,] x = { { 1, 2, 3 }, { 4, 5, 6 } };
        int[,] y = { { 7, 8, 9 }, { 10, 11, 12 } };

        var xy = new StitchMatrix<int>(x, y);

        Console.WriteLine("0,0=" + xy[0, 0]); // 1
        Console.WriteLine("1,1=" + xy[1, 1]); // 5
        Console.WriteLine("1,2=" + xy[1, 2]); // 6
        Console.WriteLine("2,2=" + xy[2, 2]); // 9
        Console.WriteLine("3,2=" + xy[3, 2]); // 12
    }
}

class StitchMatrix<T> {
    private T[][,] _matrices;
    private int[] _lengths;

    public StitchMatrix(params T[][,] matrices) {
        // TODO: check they're all same size          
        _matrices = matrices;

        // call uperbound once for speed
        _lengths = _matrices.Select(m => m.GetUpperBound(0)).ToArray();
    }

    public T this[int x, int y] {
        get {
            // find the right matrix
            int iMatrix = 0;
            while (_lengths[iMatrix] < x) {
                x -= (_lengths[iMatrix] + 1);
                iMatrix++;
            }
            // return value at cell
            return _matrices[iMatrix][x, y];
        }
    }
}

Regards Gert-Jan

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜