Reshaping a 4D array to 2D

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Reshaping a 4D array to 2D

BGreen
Hello all,

I need to reshape a 4D array H indexed as H(x,y,n,data) to a 2D array D indexed as D(u,data) where u consolidates the indices x, y and n. I can do this with a simple demonstration matrix as follows:

for x=1:2
for y=1:3
for n=1:4
for data=1:5
H(x,y,n,data) = x*1000+y*100+n*10+data;
end
end
end
end
D = reshape(H,24,5)

It is critical that the last index, data, is not rearranged in any way - H(x,y,n,1) and H(x,y,n,2) must be reshaped to D(u,1) and D(u,2) so that (1) they are indexed by the same number for data, and (2) there is a consistent mapping x,y,n -> u, so that u depends only on x,y,n and not on data.

reshape appears to satisfy both of these - the columns of D share the same value for data, and each row of D has the same values for x,y,n for all entries. The documentation simply states that column-major order is used, which if I understand correctly preserves the last index (in the case of a matrix the column, in this case data), as I wanted.

I have never worked with reshaping arrays before, so I will continue to try to understand why this works. In the meantime, would someone who understands better be able to confirm for me that reshape does indeed satisfy both the requirements I mentioned above?

- Brett Green


Reply | Threaded
Open this post in threaded view
|

Re: Reshaping a 4D array to 2D

nrjank
On Thu, Mar 12, 2020 at 3:47 PM Brett Green <[hidden email]> wrote:
Hello all,

I need to reshape a 4D array H indexed as H(x,y,n,data) to a 2D array D indexed as D(u,data) where u consolidates the indices x, y and n. I can do this with a simple demonstration matrix as follows:

for x=1:2
for y=1:3
for n=1:4
for data=1:5
H(x,y,n,data) = x*1000+y*100+n*10+data;
end
end
end
end
D = reshape(H,24,5)

It is critical that the last index, data, is not rearranged in any way - H(x,y,n,1) and H(x,y,n,2) must be reshaped to D(u,1) and D(u,2) so that (1) they are indexed by the same number for data, and (2) there is a consistent mapping x,y,n -> u, so that u depends only on x,y,n and not on data.

reshape appears to satisfy both of these - the columns of D share the same value for data, and each row of D has the same values for x,y,n for all entries. The documentation simply states that column-major order is used, which if I understand correctly preserves the last index (in the case of a matrix the column, in this case data), as I wanted.

I have never worked with reshaping arrays before, so I will continue to try to understand why this works. In the meantime, would someone who understands better be able to confirm for me that reshape does indeed satisfy both the requirements I mentioned above?


Just to confirm - the script for the small array you wrote above provides the mapping that you're looking for? If so are you concerned that something about the reshape might not scale to larger arrays? If not, what do you actually want it to look like? can you provide a desired output example?


Reply | Threaded
Open this post in threaded view
|

Re: Reshaping a 4D array to 2D

Octave - General mailing list
In reply to this post by BGreen
On 3/12/20 3:42 PM, Brett Green wrote:
> The documentation simply states that column-major order is used, which
> if I understand correctly preserves the last index (in the case of a
> matrix the column, in this case data), as I wanted.

What do you mean by 'preserving the last index'?  Column-major means
that the first index changes first, i.e. for a square matrice reshape()
picks elements down the first column, then second column, etc.:

reshape([1 2 ;3 4],1,4)
ans =

    1   3   2   4

For your 4-dimensional array, the elements are taken in this order:
H(1,1,1,1),H(2,1,1,1),H(3,1,1,1), etc. and put in the reshaped array
also in the 'first column, then second column, and so on' order.

  reshape([1 2 ;3 4;5 6;7 8],2,4)
ans =

    1   5   2   6
    3   7   4   8



Reply | Threaded
Open this post in threaded view
|

Re: Reshaping a 4D array to 2D

BGreen
On Thu, Mar 12, 2020 at 4:17 PM Nicholas Jankowski <[hidden email]> wrote:

Just to confirm - the script for the small array you wrote above provides the mapping that you're looking for? If so are you concerned that something about the reshape might not scale to larger arrays? If not, what do you actually want it to look like? can you provide a desired output example?
 
On Thu, Mar 12, 2020 at 4:29 PM Przemek Klosowski via Help-octave <[hidden email]> wrote:
On 3/12/20 3:42 PM, Brett Green wrote:
> The documentation simply states that column-major order is used, which
> if I understand correctly preserves the last index (in the case of a
> matrix the column, in this case data), as I wanted.

What do you mean by 'preserving the last index'?  Column-major means
that the first index changes first, i.e. for a square matrice reshape()
picks elements down the first column, then second column, etc.:

reshape([1 2 ;3 4],1,4)
ans =

    1   3   2   4

For your 4-dimensional array, the elements are taken in this order:
H(1,1,1,1),H(2,1,1,1),H(3,1,1,1), etc. and put in the reshaped array
also in the 'first column, then second column, and so on' order.

  reshape([1 2 ;3 4;5 6;7 8],2,4)
ans =

    1   5   2   6
    3   7   4   8

Nicholas Jankowski:
Yes, that's correct. I'm in practice going to be dealing with m by n by 4 by 10 arrays where m and n are ~100.

Przemek Klosowski:
I see; so they are taken and then populated in the same order - H(1,1,1,1), H(2,1,1,1), H(3,1,1,1) are reshaped into D(1,1), D(2,1), D(3,1). In both cases the indices are increased from left to right or first to last. I can see why this satisfies both of the properties I need - thank you!