如果重塑一次然后重塑回原始大小,Matlab 矩阵会改变吗?
Will Matlab matrix change if reshaped once then reshaped back to the original size?
基本上我有一个原始的 128 x 128 x 3 矩阵,它描述了一个 RGB 图像(128 * 128 点,每个点是一个分别包含红色、绿色和蓝色强度的 1x3 向量),我还有 16 个点从中选择(这是最简单的部分),现在我想在 128 x 128 x 3 矩阵和 16 个点之间进行成对距离计算。
但问题是 Matlab 函数,"pdist2" 只需要 2 个大小为 M1 x N 和 M2 x N 的矩阵,而不是其他任何东西,所以我打算转换 128 x 128 x 3 矩阵到 (128 * 128) x 3 一个。稍后,在对新转换的矩阵进行一些计算后,我需要将其转换回原始大小以显示图像并检查结果。但我不确定这些元素是否会保留在它们的位置,或者它们会被洗牌吗?请帮帮我,非常感谢!
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.
如果您需要结果与原始大小相同,只需在 初始转换之前存储大小 并在之后将其用作 reshape
的输入执行您对数据的操作。
% 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);
在 2D 版本中,元素在技术上不会与它们在 3D 矩阵中的位置相同,因为......好吧......它是 2D 而不是 3D。 但是,如果你将它重塑回 3D(不移动元素),元素顺序将与原始 3D 矩阵相同。
更新
您可以轻松地自己检查一下。
R = rand([10, 20, 3]);
isequal(R, reshape(reshape(R, [], 3), size(R)))
为什么 这是因为 reshape
实际上并没有改变底层数据,而是改变了访问数据的方式。我们可以通过使用 format debug
查看数据的存储位置来轻松检查这一点。
我们还可以使用 查看给定变量在内存中的存储位置。
format debug;
memoryLocation = @(x)regexp(evalc('disp(x)'), '(?<=pr\s*=\s*)[a-z0-9]*', 'match')
好的,让我们创建一个矩阵并检查 MATLAB 将其存储在内存中的位置
A = rand(10);
memoryLocation(A)
% 7fa58f2ed9c0
现在让我们重塑它并再次检查内存位置,看看它是否在不同的地方(即修改了顺序或值)
B = reshape(A, [], 10);
memoryLocation(B)
% 7fa58f2ed9c0
如您所见,内存位置没有改变,这意味着元素的顺序 必须 相同,否则 MATLAB 需要在内存中制作副本。
底层数据表示以及 Suever 的回答正确的原因:
MATLAB中的底层数组数据本质上是一个双精度浮点数数组。在 C++ 中它将是:
double *array_data;
MATLAB 以列主要格式存储数据。如果箭头有 n_rows
行,则元素 A_{i,j}
(即第 i 行,第 j 列(零索引)将由:
给出
array_data[i + j * n_rows]
当你调用reshape
函数时,变量n_rows
、n_cols
等有什么变化....它不会 改变 array_data
.
示例(无需触摸数组数据即可调整数组大小):
array_data = [1, 2, 3, 4, 5, 6];
使用 n_rows = 2
和列优先格式,这将是:
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
如果 n_rows = 3 和相同的基础 array_data,您将拥有:
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
调整大小只是更改 n_rows
、n_cols
等...
基本上我有一个原始的 128 x 128 x 3 矩阵,它描述了一个 RGB 图像(128 * 128 点,每个点是一个分别包含红色、绿色和蓝色强度的 1x3 向量),我还有 16 个点从中选择(这是最简单的部分),现在我想在 128 x 128 x 3 矩阵和 16 个点之间进行成对距离计算。
但问题是 Matlab 函数,"pdist2" 只需要 2 个大小为 M1 x N 和 M2 x N 的矩阵,而不是其他任何东西,所以我打算转换 128 x 128 x 3 矩阵到 (128 * 128) x 3 一个。稍后,在对新转换的矩阵进行一些计算后,我需要将其转换回原始大小以显示图像并检查结果。但我不确定这些元素是否会保留在它们的位置,或者它们会被洗牌吗?请帮帮我,非常感谢!
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.
如果您需要结果与原始大小相同,只需在 初始转换之前存储大小 并在之后将其用作 reshape
的输入执行您对数据的操作。
% 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);
在 2D 版本中,元素在技术上不会与它们在 3D 矩阵中的位置相同,因为......好吧......它是 2D 而不是 3D。 但是,如果你将它重塑回 3D(不移动元素),元素顺序将与原始 3D 矩阵相同。
更新
您可以轻松地自己检查一下。
R = rand([10, 20, 3]);
isequal(R, reshape(reshape(R, [], 3), size(R)))
为什么 这是因为 reshape
实际上并没有改变底层数据,而是改变了访问数据的方式。我们可以通过使用 format debug
查看数据的存储位置来轻松检查这一点。
我们还可以使用
format debug;
memoryLocation = @(x)regexp(evalc('disp(x)'), '(?<=pr\s*=\s*)[a-z0-9]*', 'match')
好的,让我们创建一个矩阵并检查 MATLAB 将其存储在内存中的位置
A = rand(10);
memoryLocation(A)
% 7fa58f2ed9c0
现在让我们重塑它并再次检查内存位置,看看它是否在不同的地方(即修改了顺序或值)
B = reshape(A, [], 10);
memoryLocation(B)
% 7fa58f2ed9c0
如您所见,内存位置没有改变,这意味着元素的顺序 必须 相同,否则 MATLAB 需要在内存中制作副本。
底层数据表示以及 Suever 的回答正确的原因:
MATLAB中的底层数组数据本质上是一个双精度浮点数数组。在 C++ 中它将是:
double *array_data;
MATLAB 以列主要格式存储数据。如果箭头有 n_rows
行,则元素 A_{i,j}
(即第 i 行,第 j 列(零索引)将由:
array_data[i + j * n_rows]
当你调用reshape
函数时,变量n_rows
、n_cols
等有什么变化....它不会 改变 array_data
.
示例(无需触摸数组数据即可调整数组大小):
array_data = [1, 2, 3, 4, 5, 6];
使用 n_rows = 2
和列优先格式,这将是:
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
如果 n_rows = 3 和相同的基础 array_data,您将拥有:
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
调整大小只是更改 n_rows
、n_cols
等...