【问题标题】:How to vectorize matrix subsetting such that find() returns a matrix?如何向量化矩阵子集,以便 find() 返回一个矩阵?
【发布时间】:2012-11-29 15:46:51
【问题描述】:

给定一个矩阵A,我需要找到对应于值 1 和 2 的索引。我可以按如下顺序执行此操作:

>> B

B =

     1     2     3
     4     1     6
     7     8     9
     4     5     1

>> find(B==1)

ans =

     1
     6
    12

>> find(B==2)

ans =

     5

但是如果我循环执行这种操作,Matlab 将只使用我处理器的一个内核。如何对其进行矢量化,以便从find 获得矩阵?我想要这个结果:

>> my_find( B, [1 2] )

ans =

    1 5
    6 0
   12 0

(或其他一些填充)

我怎样才能得到这个?

【问题讨论】:

  • 您的数据格式有多灵活?如果单元格数组没问题,您可以尝试 arrayfun(@(x) find(B==x), [1 2], 'UniformOutput', false)
  • @mars 谢谢!我想我可以弄清楚如何从那里获取矩阵。
  • 使用 find 不会使 MATLAB 使用更多 CPU 内核 - here is a list 的内部函数可以受益于并行性。所以你不妨使用一个循环。
  • 为什么find(B==1 | B==2) 不够用?甚至,如果您的应用程序允许,跳过find 并只使用逻辑索引:B==1 | B==2。遗憾的是,我认为这不会并行完成……恐怕您必须为此编写自己的 MEX 文件。
  • 另外,我假设您有一些更大的矩阵要比较?因为对于这么小的矩阵,启动两个线程的开销可能会使这个比单线程版本...

标签: matlab octave vectorization


【解决方案1】:

只是不要使用find

B==1

ans =

 1     0     0
 0     1     0
 0     0     0
 0     0     1

B==2

ans =

 0     1     0
 0     0     0
 0     0     0
 0     0     0

然后将它们相加或逻辑或。

(B==1) + (B==2)

ans =

 1     1     0
 0     1     0
 0     0     0
 0     0     1

(B==1) | (B==2)

ans =

 1     1     0
 0     1     0
 0     0     0
 0     0     1

【讨论】:

  • +1,虽然我建议使用& 而不是+,以便数据类型保持逻辑。
  • 在这种情况下实际上需要是一个逻辑或|
  • 是的,这是正确的。我之前写过&| 来强调逻辑操作,但在编辑时删除了错误的:)
【解决方案2】:

[i, j] = ind2sub(size(B), find(逻辑(sum(bsxfun(@eq, B(:), [1 2]), 2))))

【讨论】:

  • 有了这个,我认为无法辨别哪些匹配1,哪些匹配2
  • 当然是;只需将其分成多行: Bprime = B(:); inds = find(logical(sum(bsxfun(@eq, Bprime, [1 2]), 2))); Bprime(inds) 将为您提供与 inds 中每个返回索引匹配的值。
猜你喜欢
  • 1970-01-01
  • 2018-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-18
相关资源
最近更新 更多