私はベクトルを持っています、例えば.
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
ただし、これは少し面倒です。より効率的な方法はありますか?
試して
repmat([1 2 3],1,3)
repmat
のドキュメントを確認してください。
これはrepmat
またはreshape
よりも大きさのオーダーで高速な方法です
このようなことを行うための最良の方法の1つは、 [Tony's Trick。 を使用することです。通常、Matlabs固有のインデックス作成を直接使用するため、RepmatおよびReshapeはTonyのトリックよりも遅いことがわかります。あなたの質問に答えるために、
たとえば、行ベクトルをr=[1 2 3]
のようにr=[1 2 3 1 2 3 1 2 3...]
N
回並べたい場合、
c=r'
cc=c(:,ones(N,1));
r_tiled = cc(:)';
このメソッドは、reshape
または大きなrepmat
のN
に対して大幅に時間を節約します。
編集:@ Li-aung Yipの疑問に返信
repmat
とtony's trick
の速度差を確認するために、小さなMatlabテストを実施しました。下記のコードを使用して、ベースベクトルA=[1:N]
から同じタイルベクトルを構築する時間を計算しました。その結果、YES、トニーのトリックはマグニチュードのオーダーにより速く、特により大きな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
両方の方法の時間(秒)を以下に示します。
私のRAMは、N = 10000を超えることを許可しませんでした。2つの方法の時間差は、N = 100000でさらに重要になります。これらの時間は、マシンごとに異なりますが、時間の大きさの相対的な違いはそのままです。また、時間の平均がより良いメトリックである可能性がありますが、時間の大きさの違いの順序を表示したかっただけです。私のマシン/ OSの詳細を以下に示します:
関連マシン/ OS/Matlabの詳細:Athlon i686 Arch、Ubuntu 11.04 32ビット、3GB RAM、Matlab 2011b
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
すべてのデータを使用して関数をテストし、フィードバックをお寄せください。さらに改善するものを見つけたら、教えてください。