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);
Loading user information from Channel 9
Something went wrong getting user information from Channel 9
Loading user information from MSDN
Something went wrong getting user information from MSDN
Loading Visual Studio Achievements
Something went wrong getting the Visual Studio Achievements
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 CPU-months 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 single-dimensional 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 two-dimensional 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 multi-dims 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?
Thread Closed
This thread is kinda stale and has been closed but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.