2

精简版

如何concatMap在 MATLAB 中进行操作?我正在尝试从一系列更小、不同大小的向量中构建一个向量。我知道我可以做到:

result = [];
for i=1:N
    result = [result nextPart(i)];
end

但这会严重影响速度,必须有更聪明的方法concatMap


长版

我正在尝试编写一个返回块的对角线的 MATLAB 函数。例如,如果您有块:

1 2 4
3 5 7
6 8 9

然后counterDiagonals(block)应该返回[1 2 3 4 5 6 7 8 9]

我有一个函数可以找到一个块的单个对角线。即counterDiagonal(x, 3)会回来[4 5 6]

因此,counterDiagonals应该像concatMap counterDiagonal(x, i) (1:N)where Nis一样简单(2*length(block)-1)。如何在 MATLAB 中以有效的方式做到这一点?

4

3 回答 3

4

公认答案的一个问题:如果矩阵A有零,它们将被错误地从结果中删除。相反,您应该处理元素的索引:

A = [0 2 4; 3 5 7; 6 8 9];               %# Sample matrix (contains zeros)

ind = reshape(1:numel(A), size(A));      %# indices of elements
ind = fliplr( spdiags( fliplr(ind) ) );  %# get the anti-diagonals (or use ROT90)
ind(ind==0) = [];                        %# keep non-zero indices
result = A(ind);                         %# get elements in desired order

这与我在上一个问题中给出的答案非常相似(不同之处在于,反二甘醇的顺序相反)。

于 2010-11-29T15:28:49.177 回答
3

我相信您想要做的事情可以使用ROT90SPDIAGS功能来完成:

A = [1 2 4; 3 5 7; 6 8 9];  %# Sample matrix
result = rot90(A);          %# Rotate the matrix counter-clockwise
result = spdiags(result);   %# Find all the diagonals
result = result(result ~= 0).';  %'# Remove zero padding and format the results
                                  %#   into a row vector

你应该以result = [1 2 3 4 5 6 7 8 9].

编辑:正如 Amro 在评论中提到的,上面的代码假设原始矩阵中没有零A。如果原始矩阵中有零,一种解决方案是将它们替换为您知道不会出现在原始矩阵中的非零标志值(例如,NaN),运行上面的代码,然后替换结果中的标志值:

A = [0 2 4; 3 0 7; 6 8 0];  %# Sample matrix
result = rot90(A);          %# Rotate the matrix counter-clockwise
result(result == 0) = nan;  %# Replace zeroes with NaN
result = spdiags(result);   %# Find all the diagonals
result = result(result ~= 0).';  %'# Remove zero padding and format the results
                                  %#   into a row vector
result(isnan(result)) = 0;  %# Put the original zeroes back
于 2010-11-29T03:34:48.073 回答
1

精简版:

如果你预先分配你的result数组,一切都会快得多。

result = zeros(1,knownLengthOfResultsArray); %# such as "numel(block)"
ct = 1;
for i=1:N
    tmp = nextPart(i);
    nTmp = length(tmp);
    result(ct:ct+nTmp-1) = tmp;
    ct = ct + nTmp;
end

长版:

然而,重写你的算法可能更有效。请参阅例如这个问题的答案(fliplr首先在您的阵列上使用)或@gnovice 的答案

于 2010-11-29T03:40:18.320 回答