MATLAB:通过重复向量的元素来创建一个大矩阵,每个列的步幅越来越大

Del*_*aIV 2 matlab matrix vectorization repeat

在MATLAB中,我有一个长度为n的向量x,其中n通常是O(10),我想构建一个大小为[n ^ m,m]的高矩阵A,其中m再次为0(10).矩阵具有一种特殊的形式:如果n = 4且m = 6,则让

x=[x1; x2; x3; x4]
Run Code Online (Sandbox Code Playgroud)

那么A是

   x1 x1 x1 x1 x1 x1
   x2 x1 x1 x1 x1 x1
   x3 x1 x1 x1 x1 x1
   x4 x1 x1 x1 x1 x1
   x1 x2 x1 x1 x1 x1
   x2 x2 x1 x1 x1 x1
   x3 x2 x1 x1 x1 x1
   x4 x2 x1 x1 x1 x1
   x1 x3 x2 x1 x1 x1
   .               .         
   .               . 
   .               .
   x4 x4 x4 x4 x4 x4
Run Code Online (Sandbox Code Playgroud)

实际上,每列都是通过重复x的元素获得的,每列的步幅越来越大.我怎样才能做到这一点?如果可能的话,我更喜欢有效的(矢量化)解决方案,因为正如您所看到的,A的行数随m呈指数增长.非常感谢,

塞尔吉奥

编辑:哎呀,对不起!我忘了我还需要建立一个大小为[n ^ m,1]的向量V,基于具有相同长度x的向量w

w=[w1; w2; w3; w4]
Run Code Online (Sandbox Code Playgroud)

V是

   w1^6
   w2*w1^5
   w3*w1^5
     .
     .
     .
   w4^6
Run Code Online (Sandbox Code Playgroud)

希望蹩脚的图形足够清晰.无论如何,V是长度为n ^ m的列向量.猜猜我可以用w创建矩阵B,就像从x创建矩阵A一样,然后使用prod(B,2)?

Div*_*kar 5

使用allcomb tool from MATLAB file-exchange生成指数的可能的组合[1 2 3 4],然后利用它们来索引x-

v = repmat({1:numel(x)},1,m);
A = x(fliplr(allcomb(v{:})));
Run Code Online (Sandbox Code Playgroud)

此外,它似乎而不是使用fliplr,你可以使用 - allcomb(v{:},'matlab')而不是.

对于问题的编辑部分,您可以使用它的修改版本 -

V = prod(x(allcomb(v{:})),2)
Run Code Online (Sandbox Code Playgroud)

标杆

请注意,这些是针对此处发布的可运行解决方案.

基准代码

%// Parameters and input x
n = 10; m = 6;num_runs = 20; x =  randi(9,n,1);

disp('-------- With allcomb')
tic
for runs = 1:num_runs
    v = repmat({1:numel(x)},1,m);
    A = x(fliplr(allcomb(v{:})));
end
toc,    clear v A

disp('-------- With bsxfun')
tic
for runs = 1:num_runs
    A = x(floor(mod(bsxfun(@rdivide, (0:n^m-1).', n.^[0:m-1] ), n)+1)); %//'
end
toc,    clear A

disp('-------- With ttable')
tic
for runs = 1:num_runs
    I = ttable(n*ones(1,m));
    A = x(I);
end
toc,    clear I A

disp('-------- With arrayfun')
tic
for runs = 1:num_runs
    A = cell2mat(arrayfun(@(i)...
        (repmat(reshape(repmat(x',n^(i-1),1),[],1),n^(m-i),1)),1:m,'uni',0));
end
toc
Run Code Online (Sandbox Code Playgroud)

结果

-------- With allcomb
Elapsed time is 6.544981 seconds.
-------- With bsxfun
Elapsed time is 11.547062 seconds.
-------- With ttable
Elapsed time is 15.729932 seconds.
-------- With arrayfun
Elapsed time is 4.319048 seconds.
Run Code Online (Sandbox Code Playgroud)