1

Basically I have an original 128 x 128 x 3 matrix which describes a RGB image (128 * 128 points with each points being a 1x3 vector containing Red, Green, and Blue intensity respectively) , and I also have 16 points chosen from them (this is the easy part), and now I want to do pairwise distance calculations between the 128 x 128 x 3 matrix and the 16 points.

But the problem is the Matlab function for that, "pdist2" only takes 2 matrices of size M1 x N and M2 x N and not anything else, so I plan to convert the 128 x 128 x 3 matrix to a (128 * 128) x 3 one. Later on, after some calculations with the newly transformed matrix, I need to convert it back to the original size in order to display the image and check the results. But I'm not sure if the elements will remain in their place or will they be shuffled around ? Please help me thank you very much!

Dang Manh Truong
  • 795
  • 2
  • 10
  • 35

2 Answers2

6

From the documentation

The data type and number of elements in B are the same as the data type and number of elements in A. The elements in B preserve their column-wise ordering from A.

If you need the result to be the same size as the original, just store the size before the initial transformation and use this as the input to reshape after performing your manipulation of the data.

% Store the original size
originalSize = size(data);

% Reshape it to your new 2D array
data = reshape(data, [], 3);

% Do stuff

% Reshape it back to it's original size
data = reshape(data, originalSize);

In the 2D version, the elements won't technically be in the same position as they were in the 3D matrix because...well..it's 2D not 3D. But, if you reshape it back to the 3D (without moving elements around), the element ordering would be the same as the original 3D matrix.

Update

You can easily check this for yourself.

R = rand([10, 20, 3]);
isequal(R, reshape(reshape(R, [], 3), size(R)))

The reason for why this is is because reshape does not actually change the underlying data but rather the way in which it is accessed. We can easily check this by using format debug to see where the data is stored.

We can also use a little anonymous function I wrote to see where in memory a given variable is stored.

format debug;
memoryLocation = @(x)regexp(evalc('disp(x)'), '(?<=pr\s*=\s*)[a-z0-9]*', 'match')

Ok so let's create a matrix and check where MATLAB stored it in memory

A = rand(10);
memoryLocation(A)
%   7fa58f2ed9c0

Now let's reshape it and check the memory location again to see if it is in a different place (i.e. the order or values were modified)

B = reshape(A, [], 10);
memoryLocation(B)
%   7fa58f2ed9c0

As you can see, the memory location hasn't changed meaning that the ordering of elements has to be the same otherwise MATLAB would have needed to make a copy in memory.

Community
  • 1
  • 1
Suever
  • 64,497
  • 14
  • 82
  • 101
0

Underlying data representation and why Suever's answer is correct:

The underlying array data in MATLAB is essentially an array of double precision floating point. In c++ it would be a:

double *array_data;

MATLAB stores data in column major format. If an arrow had n_rows rows, the element A_{i,j} (i.e. ith row, jth column (zero indexed) would be given by:

array_data[i + j * n_rows]

When you call reshape function, what changes are the variables n_rows, n_cols, etc.... It doesn't change array_data.

Example (no need to touch array data to resize array):

array_data = [1, 2, 3, 4, 5, 6];

With n_rows = 2 and column-major format, this would be:

A = [1, 3, 5
     2, 4, 6]


A11 = array_data[0 + 0 * 2] = array_data[0] = 1
A21 = array_data[1 + 0 * 2] = array_data[1] = 2
A12 = array_data[0 + 1 * 2] = array_data[2] = 3
A22 = array_data[1 + 1 * 2] = array_data[3] = 4
A13 = array_data[0 + 2 * 2] = array_data[4] = 5
A23 = array_data[1 + 2 * 2] = array_data[5] = 6

With n_rows = 3 and the same underlying array_data, you would have:

A = [1, 4
     2, 5
     3, 6]

A11 = array_data[0 + 0 * 3] = array_data[0] = 1
A21 = array_data[1 + 0 * 3] = array_data[1] = 2
A31 = array_data[2 + 0 * 3] = array_data[2] = 3
A12 = array_data[0 + 1 * 3] = array_data[3] = 4
A22 = array_data[1 + 1 * 3] = array_data[4] = 5
A32 = array_data[2 + 1 * 3] = array_data[5] = 6

resize just changes n_rows, n_cols etc...

Matthew Gunn
  • 4,451
  • 1
  • 12
  • 30