这个问题已经在这里有一个答案:
- 八度/ Matlab的:扩展使其重演的载体? 2个回答
我有一个载体,例如
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
或reshape
通过一个数量级
一个做这样的事情的最好方法之一是使用托尼的把戏。 Repmat重塑通常被认为比Tony的伎俩更慢,因为它直接使用Matlabs固有的索引。 要回答你的问题,
比方说,要瓦片行矢量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
的。
编辑:回复@立昂业的疑虑
我进行了一个小Matlab的测试,以检查之间的速度差repmat
和tony's trick
。 使用下述的代码,我所计算的时间用于从基本矢量构成同一瓷砖矢量A=[1:N]
结果表明:YES,Tony's帽子戏法,是快了一个数量级,特别是对于较大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更显著。 我知道,这些时间可能是不同的机器不同,但为了数量级的时间相对差会受不了。 另外,我知道,时代的魅力可能是一个更好的指标,但我只是想显示幅度差的两种方法之间的时间消耗的顺序。 我的机器/ OS详情如下:
相关的机器/ OS / Matlab的详细信息 :速龙i686的拱的,Ubuntu 11.04 32位,3GB内存,Matlab的2011B
基于阿比纳夫的答案和一些测试,我写了一个函数,它总是比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
请随意测试您的所有数据的功能,并给我反馈。 当你找到了能够甚至改善它,请告诉我。