2

短縮版

concatMapMATLABでどのようにできますか?私は、一連のより小さく、異なるサイズのベクトルから単一のベクトルを構築しようとしています。私は私ができることを知っています:

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)ありNます(2*length(block)-1)。これをMATLABで効率的に行うにはどうすればよいですか?

4

3 に答える 3

4

受け入れられた答えに関する1つの問題:行列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。元のマトリックスにゼロがある場合、1つの解決策は、元のマトリックスに表示されないことがわかっているゼロ以外のフラグ値(たとえば、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 に答える