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
精彩评论