通过给定的真值值行索引生成逻辑矩阵的最快方法?

时间:2016-07-16 10:54:45

标签: matlab matrix vectorization

什么是最有效的生成方式

>> A

A =

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

>> B = [2 3; 1 2; 1 3]

B =

     2     3
     1     2
     1     3

在MATLAB中?

B(1, :)[2 3],表示A(2, 1)A(3, 1)true

我的尝试仍然需要一个for循环,遍历B的行。有无循环或更有效的方法吗?

2 个答案:

答案 0 :(得分:2)

这是许多方法中的一种,但sub2ind是其专用功能:

%// given row indices
B = [2 3; 1 2; 1 3]
%// size of row index matrix
[n,m] = size(B)
%// size of output matrix
[N,M] = deal( max(B(:)), n)
%// preallocation of output matrix
A = zeros(N,M)
%// get col indices to given row indices
cols = bsxfun(@times, ones(n,m),(1:n).')
%// set values
A( sub2ind([N,M],B,cols) ) = 1
A =

     0     1     1
     1     1     0
     1     0     1

如果您需要逻辑矩阵,请将以下内容更改为行

A = false(N,M)
A( sub2ind([N,M],B,cols) ) = true

替代解决方案

%// given row indices
B = [2 3; 1 2; 1 3];
%// number if rows
r = 4;  %// e.g. = max(B(:))
%// number if cols
c = 3;  %// size(B,1)

%// preallocation of output matrix
A = zeros(r,c);
%// set values
A( bsxfun(@plus, B.', 0:r:(r*(c-1))) ) = 1;

答案 1 :(得分:2)

这是一种方法,使用sparse函数

delete...

这给出了

A = full(sparse(cumsum(ones(size(B))), B, 1));

如果输出中需要预定义的行数,请说A = 0 1 1 1 1 0 1 0 1 (在您的示例中为r):

r = 4

给出了

A = full(sparse(cumsum(ones(size(B))), B, 1, 4, size(B,1)));

您可以等效使用accumarrray功能

A =
     0     1     1
     1     1     0
     1     0     1
     0     0     0

给出

A = accumarray([repmat((1:size(B,1)).',size(B,2),1), B(:)], 1);

预定义的行数A = 0 1 1 1 1 0 1 0 1

r = 4

给出

A = accumarray([repmat((1:size(B,1)).',size(B,2),1), B(:)], 1, [r size(B,1)]);