重复连接向量的更快方法

3

有没有更快的方法来连接像下面这样的矩阵?这些代码将被调用数千次,因此非常耗时。对于1658880次调用,我仅得到一个片段需要15秒!(我大约有2000个片段,所以总调用次数将是1658880 * 2000次!)

a=rand(1,100);
b=rand(1,100);
c=rand(1,100);
d=rand(1,100);

k=([b; b; b; d; ones(100); c; a; a; a]);

编辑

Dev-iL提出的建议(使用repmat函数):

k=zeros(9,100);
k(1:3,:)=repmat(b,3,1);
k(4,:)=d;
k(5,:)=ones(size(a));
k(6,:)=d;
k(7:9,:)=repmat(a,3,1);

没有 repmat

k=zeros(9,100);
k(1,:)=b;
k(2,:)=b;
k(3,:)=b;
k(4,:)=d;
k(5,:)=ones(size(a));
k(6,:)=d;
k(7,:)=a;
k(8,:)=a;
k(9,:)=a;

使用`repmat`函数时,速度比原始代码慢了11秒。如果不使用`repmat`函数,实际上可以比原来快15秒!我会非常感谢任何进一步的建议和帮助!提前致谢!

1
为什么不预先分配最终大小,然后通过索引将元素放在正确的位置?您还可以使用多维数组来实现这一点。 - Dev-iL
谢谢回复!你能告诉我更多关于索引的信息吗?我可以从那里开始。 - Gregor Isack
最好将a,b,c,d作为列向量,并将它们连接成[b b b d ones(100) c a a a]。 此外,正如@Dev-iL建议的那样,预分配k可能会很有用。 - rahnema1
1
使用您的示例数据,您可以使用 k = zeros(9,100); 然后 k(1:3,:) = repmat(b, ...); k(4,:) = d; 等方式进行操作。不过,也许不需要使用 repmat,只需使用 k(1,:) = b; k(2,:) = b; ... 更好。这需要进行基准测试。 - Dev-iL
没有使用repmat,我快了15秒!我修改了问题,请看一下 :) - Gregor Isack
显示剩余3条评论
1个回答

2
由于在MATLAB中数据以列优先的方式存储,所以最好将a,b,c,d生成为列向量并将它们连接起来,如下:
a=rand(100,1);
b=rand(100,1);
c=rand(100,1);
d=rand(100,1);
one = ones(100);
k= [b b b d one c a a a];

相反,您可以预先分配 k 并填充它,如下所示:
k = ones(100,108); %preallocation
%in the loop you can fill it:
k(:,1)=b;
k(:,2)=b;
k(:,3)=b;
k(:,4)=d;
k(:,105)=c;
k(:,106)=a;
k(:,107)=a;
k(:,108)=a;

很好的发现,作为一个扩展,这对其他操作是否有可行性?例如,rand(100,1).*rand(100,1)比rand(1,100).*rand(1,100)更快吗? - Durkee
对于向量,我认为没有区别,但当我们想将它们连接成矩阵时就有所不同。 - rahnema1
谢谢,我进行了一些测试,似乎对于点乘法至少没有统计学上的改进。不过学习这些小技巧总是很好的。 - Durkee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接