Tech Off Thread

10 posts

Forum Read Only

This forum has been made read only by the site admins. No new threads or comments can be added.

array to matrix in c# ?

Back to Forum: Tech Off
  • User profile image
    cro

    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);
    

  • User profile image
    Adam​Speight2008

    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;
                }
            }
        }

  • User profile image
    BitFlipper

    @AdamSpeight2008:

    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.

  • User profile image
    C9Matt

    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.

  • User profile image
    W3bbo

    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).

  • User profile image
    bitdisaster

    @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.

  • User profile image
    Dr Herbie

    @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 Perplexed

    Herbie

  • User profile image
    bitdisaster

    @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.

  • User profile image
    mozzis

    @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.

  • User profile image
    mozzis

    @C9Matt:DirectX s.b. DirectCompute, right?

Conversation locked

This conversation has been locked by the site admins. No new comments can be made.