2

I am working a n-dimensional matrix (which being stored as a single dimensional array), I wish to reorder in its dimensions such that the leading dimension is now the last dimension.

eg. if Dimensions(A) = 3 x 4 x 5 x 6 , I would want to change it to 4 x 5 x 6 x 3. This is similar to a transpose function for a 2-D matrix.

It can be implemented using permute function in Matlab for n dimensional matrix A. I want the following tranformation

A=permute(A,[2:n 1])

How could I do it in C?

P.S. I am not looking to reshape the matrix but to actually move the elements in order to get the next dimension as the leading dimension.

Permute can be defined as

B = PERMUTE(A,ORDER) rearranges the dimensions of A so that they
%   are in the order specified by the vector ORDER.  The array produced
%   has the same values as A but the order of the subscripts needed to 
%   access any particular element are rearranged as specified by ORDER.
%   For an N-D array A, numel(ORDER)>=ndims(A). All the elements of 
%   ORDER must be unique.
  • You'll need `realloc` or use a static size with each dimension as big as worst case. – Fiddling Bits Jul 23 '14 at 17:49
  • @FiddlingBits Could you please elaborate? The problem is similar to rotating the cuboid( for a 3D matrix )in order to have the left face in front. – user2899427 Jul 23 '14 at 17:52
  • If you `malloc` each dimension to a certain length, you can use `realloc` to resize its length. If you use a compiled array with a static size, you'll need to make each dimension's length as big as the biggest possible length. – Fiddling Bits Jul 23 '14 at 17:54
  • If you have a `3 x 4 x 5 x 6` and want to change it to a `4 x 5 x 6 x 7`, where should the additional elements come from? This is not what `A=permute(A,[2:n 1])` does! – Daniel Jul 23 '14 at 17:58
  • @Daniel Sorry, that was 3 x 4 x 5 x 6 to 4 x 5 x 6 x 3 – user2899427 Jul 23 '14 at 18:04
  • @FiddlingBits I don't want to resize the existing order of elements but transpose the order of elements, also please check the correction that was 3 x 4 x 5 x 6 to 4 x 5 x 6 x 3 – user2899427 Jul 23 '14 at 18:08
  • You can do it by [using a dope vector](http://stackoverflow.com/questions/30409991/use-a-dope-vector-to-access-arbitrary-axial-slices-of-a-multidimensional-array). – luser droog May 27 '15 at 17:47

1 Answers1

0

I wouldn't want to try doing it in-place, but copying to a new array would be just a little more complicated than what you're already doing. I wrote a similar function for my apl interpreter.

If you have operations which can convert a list of indices and a list of dimensions into a single 1D index, and the reverse, converting a single index and a list of dimensions into a list of indices; then you just iterate through the 1D array, generate the index list using the source dimensions, apply the permutation to the index list, convert back to a single index using the destination dimensions and store the result in the destination array.

dest dimensions = permute source dimensions
for each element in source
    generate source indices from source index and source dimensions
    dest indices = permute source indices 
    generate dest index from dest indices and dest dimensions
    dest[dest index] = source[source index]

The pseudocode describes the algorithm, but here is an implementation: array.c:transposea(). That function changes its argument, so for the above semantics, it should call clone() first and copy() after, to actually move the data around and leave the original undisturbed.

luser droog
  • 18,988
  • 3
  • 53
  • 105