无环矩阵优化重组
Optimize Reorganization of Matrix without Loops
TL;DR: 我正在尝试在 Matlab 中优化以下短代码。因为涉及到大矩阵的循环,所以速度太慢了。
for i = 1:sz,
for j = 1:sz,
if X(j) == Q(i) && Y(j) == R(i),
S(i) = Z(j);
break
end
end
end
细节:基本上,我从 x、y 和 z 数据的三个向量开始,我想将它们绘制为一个表面。我生成了 x 和 y 数据的网格,然后使用
为相应的 z 值制作了一个矩阵
[X, Y] = meshgrid(x, y);
Z = griddata(x, y, z, X, Y);
因为数据是按随机顺序收集的,所以在生成曲面图时,连接都是错误的,并且该图看起来全是三角剖分的,如下例所示。
因此,为了确保 Matlab 连接正确的点,我随后使用
重新组织了 X 和 Y 矩阵
[R, R_indx] = sort(Y);
[Q, Q_indx] = sort(X, 2);
从这里开始,我认为根据矩阵 X 和 Y 的排序索引重组矩阵 Z 将是一个简单的问题。但是我 运行 遇到了麻烦,因为无论我如何使用索引,我无法生成正确的矩阵。例如,我试过
S = Z(R_indx); % to match the rearrangement of Y
S = S(Q_indx); % to match the rearrangement of X
我得到了这个条形码...
运行 第一个代码块给我 "desired" 结果如图所示。但是,这需要很长时间,因为它是一个非常大的矩阵的双循环。
问题:如何在没有 for 循环的情况下优化矩阵 Z 的重排?
请查看以下解决方案,并使用您的矩阵进行测试。他们表现得更快吗? array indexing 解决方案可以满足您的要求,即矩阵的重新排列。 向量索引可能更好,因为它对原始向量而不是矩阵进行排序,并直接从那里生成输出。
% Parameters.
dim = 4;
% Test input.
x = [2, -2, 5, 4];
y = [1, -4, 6, -2];
z = rand(dim);
[X, Y] = meshgrid(x, y);
Z = griddata(x, y, z, X, Y);
[R, R_indx] = sort(Y);
[Q, Q_indx] = sort(X, 2);
% Initialize output.
S = zeros(dim);
% Provided solution using loop.
for i = 1:numel(z)
for j = 1:numel(z)
if (X(j) == Q(i) && Y(j) == R(i))
S(i) = Z(j);
break
end
end
end
% Output.
S
% Solution using array indexing; output.
S_array = reshape(((X(:) == Q(:).') & (Y(:) == R(:).')).' * Z(:), dim, dim)
% Solution using vector indexing; output.
[r, r_indx] = sort(y);
[q, q_indx] = sort(x);
[X, Y] = meshgrid(q, r);
Z = griddata(q, r, z, X, Y);
idx = (ones(dim, 1) * ((q_indx - 1) * dim) + r_indx.' * ones(1, dim));
S_vector = Z(idx)
示例输出:
S =
0.371424 0.744220 0.777214 0.778058
0.580353 0.686495 0.356647 0.577780
0.436699 0.217288 0.883900 0.800133
0.594355 0.405309 0.544806 0.085540
S_array =
0.371424 0.744220 0.777214 0.778058
0.580353 0.686495 0.356647 0.577780
0.436699 0.217288 0.883900 0.800133
0.594355 0.405309 0.544806 0.085540
S_vector =
0.371424 0.744220 0.777214 0.778058
0.580353 0.686495 0.356647 0.577780
0.436699 0.217288 0.883900 0.800133
0.594355 0.405309 0.544806 0.085540
TL;DR: 我正在尝试在 Matlab 中优化以下短代码。因为涉及到大矩阵的循环,所以速度太慢了。
for i = 1:sz,
for j = 1:sz,
if X(j) == Q(i) && Y(j) == R(i),
S(i) = Z(j);
break
end
end
end
细节:基本上,我从 x、y 和 z 数据的三个向量开始,我想将它们绘制为一个表面。我生成了 x 和 y 数据的网格,然后使用
为相应的 z 值制作了一个矩阵[X, Y] = meshgrid(x, y);
Z = griddata(x, y, z, X, Y);
因为数据是按随机顺序收集的,所以在生成曲面图时,连接都是错误的,并且该图看起来全是三角剖分的,如下例所示。
因此,为了确保 Matlab 连接正确的点,我随后使用
重新组织了 X 和 Y 矩阵[R, R_indx] = sort(Y);
[Q, Q_indx] = sort(X, 2);
从这里开始,我认为根据矩阵 X 和 Y 的排序索引重组矩阵 Z 将是一个简单的问题。但是我 运行 遇到了麻烦,因为无论我如何使用索引,我无法生成正确的矩阵。例如,我试过
S = Z(R_indx); % to match the rearrangement of Y
S = S(Q_indx); % to match the rearrangement of X
我得到了这个条形码...
运行 第一个代码块给我 "desired" 结果如图所示。但是,这需要很长时间,因为它是一个非常大的矩阵的双循环。
问题:如何在没有 for 循环的情况下优化矩阵 Z 的重排?
请查看以下解决方案,并使用您的矩阵进行测试。他们表现得更快吗? array indexing 解决方案可以满足您的要求,即矩阵的重新排列。 向量索引可能更好,因为它对原始向量而不是矩阵进行排序,并直接从那里生成输出。
% Parameters.
dim = 4;
% Test input.
x = [2, -2, 5, 4];
y = [1, -4, 6, -2];
z = rand(dim);
[X, Y] = meshgrid(x, y);
Z = griddata(x, y, z, X, Y);
[R, R_indx] = sort(Y);
[Q, Q_indx] = sort(X, 2);
% Initialize output.
S = zeros(dim);
% Provided solution using loop.
for i = 1:numel(z)
for j = 1:numel(z)
if (X(j) == Q(i) && Y(j) == R(i))
S(i) = Z(j);
break
end
end
end
% Output.
S
% Solution using array indexing; output.
S_array = reshape(((X(:) == Q(:).') & (Y(:) == R(:).')).' * Z(:), dim, dim)
% Solution using vector indexing; output.
[r, r_indx] = sort(y);
[q, q_indx] = sort(x);
[X, Y] = meshgrid(q, r);
Z = griddata(q, r, z, X, Y);
idx = (ones(dim, 1) * ((q_indx - 1) * dim) + r_indx.' * ones(1, dim));
S_vector = Z(idx)
示例输出:
S =
0.371424 0.744220 0.777214 0.778058
0.580353 0.686495 0.356647 0.577780
0.436699 0.217288 0.883900 0.800133
0.594355 0.405309 0.544806 0.085540
S_array =
0.371424 0.744220 0.777214 0.778058
0.580353 0.686495 0.356647 0.577780
0.436699 0.217288 0.883900 0.800133
0.594355 0.405309 0.544806 0.085540
S_vector =
0.371424 0.744220 0.777214 0.778058
0.580353 0.686495 0.356647 0.577780
0.436699 0.217288 0.883900 0.800133
0.594355 0.405309 0.544806 0.085540