我有一个载体,例如
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
但这看起来有点麻烦。任何更有效的方法?
答案 0 :(得分:39)
尝试
repmat([1 2 3],1,3)
我将让您查看repmat
的文档。
答案 1 :(得分:19)
这是比repmat
或reshape
更快的方法
执行此类操作的最佳方法之一是使用Tony's Trick. Repmat和Reshape通常比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
。
编辑:回复@ Li-aung Yip的疑虑
我进行了一次小型Matlab测试,以检查repmat
和tony's trick
之间的速度差异。使用下面提到的代码,我计算了从基础向量A=[1:N]
构造相同平铺向量的时间。结果显示,YES,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
下面给出了两种方法的时间(以秒为单位);
我的RAM不允许我超过N = 10000。我相信,对于N = 100000,两种方法之间的时差会更加显着。我知道,这些时间对于不同的机器可能会有所不同,但是时间数量级的相对差异将会存在。此外,我知道,平均时间可能是一个更好的指标,但我只是想显示两种方法之间的时间消耗的数量级差异。我的机器/操作系统详情如下:
相关机器/ OS / Matlab详细信息:Athlon i686 Arch,Ubuntu 11.04 32位,3gb内存,Matlab 2011b
答案 2 :(得分: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
随意使用您的所有数据测试该功能并给我反馈。如果你发现了一些甚至可以改进它的东西,请告诉我。