Tech Off Thread
10 postsarray to matrix in c# ?

Is it possible in c# to transform an array to a matrix with a minimal impact on memory ? Because the array can ben very big.
For exemple:
int[] a = new int[100]; int[,] m = a.ToMatrix(10, 10);

Here one way.
static class ext { public static T[,] To2D<T>(this T[] thisArray,int width,int height) { if ((width * height) < thisArray.Length) { throw new System.ArgumentOutOfRangeException("The 2D array is too small to contain the 1D array."); } else { T[,] New2DArrayOfT = new T[ width, height]; thisArray.AsParallel().Select((e, i) => { New2DArrayOfT[i % width, i / height] = thisArray[i]; return e; }); // for (int i = 0; i < thisArray.Length; i++) //{ // New2DArrayOfT[i % width, i / height] = thisArray[i]; //} return New2DArrayOfT; } } }

But I don't think that will solve the OP's problem, which is that there might not be enough memory to keep both structures in memory at once. I can't see a way around this because int[] is not resizable so you can't dispose of it until you have completely created the 2D array.
If it was a List<int> instead of int[] then maybe you can size it down while creating the new 2D array one row at a time in order to keep overall memory usage down.

If you're running with super large arrays in memory to do Matrix transforms, then you shouldn't convert it to a Matrix  you should just do your Matrix transforms in place on the array manually. If you want OOP you can define a class thus:
class MyAwesomeMatrix { int[][] values; public MyAwesomeMatrix(int[][] inplacevalues) { this.values = inplacevalues; // check array is valid here } public MyAwesomeMatrix Clone() { int[][] newValues = new int[values.Length, values[0]Length]; for(int i = 0; i < newValues.getLength(1); i++) { newValues[i] = new int[values[i].Length]; Array.Copy(newValues[i], values[i], values[i].Length]; } return new MyAwesomeMatrix(newValues); } public void InvertInPlace() { // insert your favourite matrix inversion here } public MyAwesomeMatrix Inverse { get { MyAwesomeMatrix m = Clone(); m.InvertInPlace(); return m; } } }
If you're arrays are actually quite small (i.e. less than about 4K x 4K) then optimising for memory at this early stage isn't worth it.
Also if your arrays are horrendously large (gigs of data) then you should probably research ways of doing the matrix operation that you want in a more efficient way. Matrix adding can be streamed easilly, Matrix multiplication can be made faster if you know things like matrix density (e.g. sparse matrix multiplication algorithms exist which are faster on sparse matricies), and if you need this to be fast (e.g. for graphics) or you're going to be dedicating CPUmonths to this project (e.g. you're simulating the climate) then you can consider looking at DirectX to see if you can get your GPU to take the burden.

I'd like to add that in .NET, multidimensional arrays are actually less efficient than jagged arrays (despite being 'safer'), and both are slower than a singledimensional array where you manage index offsets yourself (stupid, I know, but that's what the CLR does internally).

@cro: mmh, the most efficient way to transform an array to a matrix is to not transform it at all. You could mimic a matrix over an array by wrapping the array in an object that gives you a access via twodimensional indexer property. You could also implement virtual matrix operation without changing the original array. But Idon't know whether it's suitable in your scenario.

@section31: +1
I have done this before. You'll get a small performance hit as you have to perform a little arithmatic conversion for each call, but you won't need any extra memory.
e.g.
for matrix[x,y] access array index[x*matrixwidth + y]
I did once use this for matrices that were symmetrical on the diagonal (so long since I've used matrices that I've forgotten the term  'upper matrix'?), the maths was a little more complex but it's too early in the morning for me to remember/figure it out
Herbie

@Dr Herbie: Yeah I just did remember an assignment at University when we had to implement matrix multiplication in assembler and we also used a trick with the indexer to come up with a simple solution.

@W3bbo:I don't think jagged arrays are more efficient anymore. At least our testing (with .Net 4.0) seems to indicate that multidims are as efficient. I have even converted some loops to use unsafe pointers and not seen measurable and consistent improvement over [,] arrays. Plus the interop much more nicely.

@C9Matt:DirectX s.b. DirectCompute, right?
Comments closed
Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.