MATLAB:通过重复向量元素来创建大矩阵,每一列的步幅都增加 [英] MATLAB: create a large matrix by repeating elements of a vector, with increasing stride for each column

查看:597
本文介绍了MATLAB:通过重复向量元素来创建大矩阵,每一列的步幅都增加的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In MATLAB I have a vector x of length n, where n is usually O(10), and I would like to build a tall matrix A of size [n^m,m], where m is again 0(10). The matrix has a peculiar form: if n=4 and m=6, let

x=[x1; x2; x3; x4]

那么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

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

In practice, each column is obtained by repeating the elements of x, with an increasing stride for each column. How can I do that? If possible, I'd prefer an efficient (vectorized) solution, because, as you can see, the number of rows of A increases exponentially with m. Thanks very much,

塞尔吉奥

糟糕,抱歉!我忘记了我还需要基于长度为x的向量w构建大小为[n ^ m,1]的向量V

whoops, sorry! I forgot I also need to build a vector V of size [n^m,1], based on vector w having the same length of x

w=[w1; w2; w3; w4]

V是

   w1^6
   w2*w1^5
   w3*w1^5
     .
     .
     .
   w4^6

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

Hope the crappy graphics is clear enough. Anyway, V is a column vector of lenght n^m. Guess I could create a matrix B from w, in the same way one creates a matrix A from x, and then use prod(B,2)?

推荐答案

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

Use allcomb tool from MATLAB file-exchange to generate the possible combinations of the indices [1 2 3 4] and then use them to index into x -

v = repmat({1:numel(x)},1,m);
A = x(fliplr(allcomb(v{:})));

此外,似乎可以使用-allcomb(v{:},'matlab')代替使用fliplr.

Also, it seems instead of using fliplr, you can use - allcomb(v{:},'matlab') instead.

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

For the edited part of the question, you can use a modified version of it -

V = prod(x(allcomb(v{:})),2)

基准化

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

Benchmarking

Please note that these are for runnable solutions posted here.

基准代码

%// 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

结果

-------- 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.

这篇关于MATLAB:通过重复向量元素来创建大矩阵,每一列的步幅都增加的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆