2

There are may operations on arrays that do not depend on the rank of an array. Iterators are also not always a suitable solution. Given the array

double[,] myarray = new double[10,5];

it would be desirable to realize the following workflow:

  1. Reshape an array of Rank>1 to a linear array with rank=1 with the same number of elements. This should happen in place to be runtime efficient. Copying is not allowed.
  2. Pass reshaped array to a method defined for Rank=1 arrays only. e.g. Array.copy()
  3. Reshape result array to original rank and dimensions.

There is a similar question on this topic: How to reshape array in c#. The solutions there use memory copy operation with BlockCopy().

My question are: Can this kind of reshaping be realized without memory copy? Or even in a temporary way like creating a new view on the data?

3
  • I think you're asking for something impossible here... If you want to "Reshape an array" then (AFAIK) you'll always have to copy the elements from the current array to the new "reshaped" array... If "copying is not allowed" then you cannot "reshape" / transform the array. Commented Jul 18, 2018 at 11:54
  • 3
    By asking that it be done "without copying", you're effectively asking for one array to alias another. This is not allowed in managed code. You can, of course, use unsafe code and get a pointer (fixed (double* myflatarray = myarray)), but you won't have an array that can be passed to other functions. If you write your functions to accept Span<double> instead of arrays, you can make the pointer "safe" (new Span<double>(myflatarray, myarray.Length)) but you still won't have an actual array. (And that's just for going to rank 1 -- I have no idea how you'd get back.) Commented Jul 18, 2018 at 11:58
  • @Jeroen: If no one else comes up with a solution in the next days, I suggest that you copy your clarifying statement to an answer. Commented Jul 18, 2018 at 12:21

1 Answer 1

3

There wording to this is a little tough, yet surely pointers unsafe and fixed would work. No memory copy, direct access, add pepper and salt to taste

The CLR just wont let you cast an array like you want, any other method you can think of will require allocating a new array and copy (which mind you can be lightening fast). The only other possibly way to so this is to use fixed, which will give you contiguous 1 dimensional array.

unsafe public static void SomeMethod(int* p, int size)
{
   for (var i = 0; i < 4; i++)
   {
      //Perform any linear operation
      *(p + i) *= 10;
   }
}
...

var someArray = new int[2,2];
someArray[0, 0] = 1;
someArray[0,1] = 2;
someArray[1, 0] = 3;
someArray[1, 1] = 4;

//Reshape an array to a linear array 
fixed (int* p = someArray)
{
     SomeMethod(p, 4);
}

//Reshape result array to original rank and dimensions.

for (int i = 0; i < 2; i++)
{
   for (int j = 0; j < 2; j++)
   {
      Console.WriteLine(someArray[i, j]);
   }
}

Output

10
20
30
40
Sign up to request clarification or add additional context in comments.

1 Comment

@GeorgW. Sure you can, just work work with the pointer and size. Any other way will need a copy, its just the way it is

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.