19

私はベクトルを持っています、例えば

vector = [1 2 3]

それ自体をn回複製したいと思います。つまり、n = 3の場合、次のようになります。

vector = [1 2 3 1 2 3 1 2 3]

nの任意の値に対してこれをどのように達成できますか?私は次のことができることを知っています:

newvector = vector;
for i = 1 : n-1
    newvector = [newvector vector];
end

しかし、これは少し面倒なようです。より効率的な方法はありますか?

4

3 に答える 3

39

試す

repmat([1 2 3],1,3)

のドキュメントを確認するためにあなたに任せますrepmat

于 2012-04-25T12:59:34.417 に答える
20

repmatこれは、reshape桁違いに高速な方法です。

そのようなことを行うための最良の方法の1つは、Tony'sTrickを使用することですRepmatとReshapeは通常、Matlabs固有のインデックスを直接使用するため、Tonyのトリックよりも遅いことがわかります。あなたの質問に答えるために、

r=[1 2 3] Nたとえば、行ベクトルの時間を次のようr=[1 2 3 1 2 3 1 2 3...]に並べて表示したいとします。

c=r'
cc=c(:,ones(N,1));
r_tiled = cc(:)';

reshapeこの方法は、大規模なものに対して、またはrepmat大規模なものに対して大幅な時間の節約になりNます。

編集:@Li-aungYipの疑問に返信する

repmatとの間の速度差を確認するために、小さなMatlabテストを実行しましたtony's trick。下記のコードを使用して、ベースベクトルから同じタイルベクトルを構築するための時間を計算しましたA=[1:N]。結果は、はい、Tony's-Trickは、特に大きいNの場合、桁違いに高速であることを示しています。人々はそれを自分で試すことができます。このような操作をループで実行する必要がある場合は、この時間差が重要になる可能性があります。これが私が使用した小さなスクリプトです。

N= 10 ;% ASLO Try for values N= 10, 100, 1000, 10000

% time for tony_trick
tic;
A=(1:N)';
B=A(:,ones(N,1));
C=B(:)';
t_tony=toc;
clearvars -except t_tony N

% time for repmat
tic;
A=(1:N);
B=repmat(A,1,N);
t_repmat=toc;
clearvars -except t_tony t_repmat N

両方の方法の時間(秒単位)を以下に示します。

  • N = 10、time_repmat = 8e-5、time_tony = 3e-5
  • N = 100、time_repmat = 2.9e-4、time_tony = 6e-5
  • N = 1000、time_repmat = 0.0302、time_tony = 0.0058
  • N = 10000、time_repmat = 2.9199、time_tony = 0.5292

私のRAMは、N=10000を超えることを許可しませんでした。N = 100000の場合、2つの方法の時間差はさらに大きくなると確信しています。これらの時間はマシンごとに異なる可能性があることは知っていますが、時間の大きさの相対的な違いは有効です。また、時間の平均がより良いメトリックであった可能性があることも知っていますが、2つのアプローチ間の時間消費の大きさの違いのオーダーを示したかっただけです。私のマシン/OSの詳細を以下に示します:

関連するマシン/OS/ Matlabの詳細:Athlon i686 Arch、Ubuntu 11.04 32ビット、3GB RAM、Matlab 2011b

于 2012-04-26T05:18:51.550 に答える
4

Abhinavの回答といくつかのテストに基づいて、repmat()よりも常に高速な関数を作成しました。

行列ではなくベクトルでなければならない最初のパラメーターを除いて、同じパラメーターを使用します。

function vec = repvec( vec, rows, cols )
%REPVEC Replicates a vector.
%   Replicates a vector rows times in dim1 and cols times in dim2.
%   Auto optimization included.
%   Faster than repmat()!!!
%   
%   Copyright 2012 by Marcel Schnirring

    if ~isscalar(rows) || ~isscalar(cols)
        error('Rows and cols must be scaler')
    end

    if rows == 1 && cols == 1
        return  % no modification needed
    end

    % check parameters
    if size(vec,1) ~= 1 && size(vec,2) ~= 1
        error('First parameter must be a vector but is a matrix or array')
    end

    % check type of vector (row/column vector)
    if size(vec,1) == 1
        % set flag
        isrowvec = 1;
        % swap rows and cols
        tmp = rows;
        rows = cols;
        cols = tmp;
    else
        % set flag
        isrowvec = 0;
    end

    % optimize code -> choose version
    if rows == 1
        version = 2;
    else
        version = 1;
    end

    % run replication
    if version == 1
        if isrowvec
            % transform vector
            vec = vec';
        end

        % replicate rows
        if rows > 1
            cc = vec(:,ones(1,rows));
            vec = cc(:);
            %indices = 1:length(vec);
            %c = indices';
            %cc = c(:,ones(rows,1));
            %indices = cc(:);
            %vec = vec(indices);
        end

        % replicate columns
        if cols > 1
            %vec = vec(:,ones(1,cols));
            indices = (1:length(vec))';
            indices = indices(:,ones(1,cols));
            vec = vec(indices);
        end

        if isrowvec
            % transform vector back
            vec = vec';
        end
    elseif version == 2
        % calculate indices
        indices = (1:length(vec))';

        % replicate rows
        if rows > 1
            c = indices(:,ones(rows,1));
            indices = c(:);
        end

        % replicate columns
        if cols > 1
            indices = indices(:,ones(1,cols));
        end

        % transform index when row vector
        if isrowvec
            indices = indices';
        end

        % get vector based on indices
        vec = vec(indices);
    end
end

すべてのデータを使用して関数をテストし、フィードバックをお寄せください。それをさらに改善する何かを見つけたら、教えてください。

于 2012-08-26T18:06:05.677 に答える