4

INPUT:一个u长度为 的逻辑行向量n,比如[1,0,1,1,0]; 和一个大小为 m×n 的逻辑矩阵M,比如[1,0,0,1,1;0 0 0 1 1]

OUTPUT:一个大小为 m×n 的逻辑矩阵,其第一行是通过将矩阵的第一行M作为“选择器”应用得到的,即[1,0,0,1,0];第二行同样是[0 0 0 1 0].

行向量为 20000 长,矩阵为 30×20000。这将重复 1000 次,我想要的东西花费不到 1 秒。

我试过repmat,bsxfun和 element-wise 乘法,没有运气。猜猜有一种简单的方法可以一次“选择”这些元素,因为它们都是逻辑值。

4

3 回答 3

1

The fastest I can give you is 4 seconds at the moment (on my machine). I'm not 100% sure if you've tried this or not, but here you go anyway.

I have an m-file randbool.m with these contents, to generate the test data.

function x = randbool(m,n)
x = logical(rand(m,n) < 0.5);

Generate the data for testing:

>> u = randbool(1,20000);
>> M = randbool(30,20000);

I can think of three ways to loop over the rows of M (use bsxfun, use repmat, use a loop) and two ways to pull out the elements you want (conjunction &, or pointwise multiplication with .*). The fastest is the combination of bsxfun and conjunction:

Bsxfun / conjunction

>> tic, for i=1:1000, bsxfun(@and,u,M); end, toc
Elapsed time is 4.068684 seconds.

Bsxfun / multiplication

>> tic, for i=1:1000, bsxfun(@times,u,M); end, toc
Elapsed time is 4.856784 seconds.

Repmat / conjunction

>> tic, for i=1:1000, utmp=repmat(u,30,1); M&utmp; end, toc
Elapsed time is 7.305158 seconds.

Repmat / multiplication

>> tic, for i=1:1000, utmp=repmat(u,30,1); M.*utmp; end, toc
Elapsed time is 8.117164 seconds.

Looping / conjunction

>> tic, for i=1:1000, for j = 1:30, out(j,:)=u&M(j,:); end; end, toc
Elapsed time is 7.110872 seconds.

Looping / multiplication

>> tic, for i=1:1000, for j = 1:30, out(j,:)=u.*M(j,:); end; end, toc
Elapsed time is 8.322888 seconds.
于 2012-11-30T11:53:21.940 回答
0

这看起来像一个按位和操作。也许这样的事情会起作用:

utemp=repmat(u,1,size(m,2));
output=M&utemp;

我应该补充一点,对于这么大的矩阵,您可能会遇到内存问题。本质上,您需要 3 个 600K 元素矩阵的副本,这可能会加起来。

于 2012-11-30T11:34:08.103 回答
0

其他解决方案使事情过于复杂。

您需要做的就是将未选择列中的条目归零...

M(:,~u)=0;

而已。十个微不足道的字符。Chris Taylor 使用 bsxfun 和 @and 的解决方案有点慢,其他方法更糟。

octave:8> u = logical(rand(1,20000)<0.5);
octave:9> M = logical(rand(30,20000)<0.5);
octave:10> tic, for i=1:1000, N=M; N(:,~u)=0; end, toc
Elapsed time is 0.66 seconds.
octave:11> tic, for i=1:1000, N=M; N=bsxfun(@and,u,N); end, toc
Elapsed time is 0.82 seconds.
octave:12> tic, for i=1:1000, N=bsxfun(@and,u,M); end, toc
Elapsed time is 0.8 seconds.

请注意,我使用“N=M”来标准化结果,因为此方法直接作用于向量,但分配并没有对时间添加任何重要的内容。

于 2013-03-16T15:45:29.580 回答