Matlab:基于索引向量化矩阵中值的赋值

时间:2015-09-02 22:28:24

标签: arrays matlab matrix vectorization

如果这个问题是重复的,或者如果在Matlab中解决这个问题非常简单,请提前道歉。我有一个M x N矩阵A,一个1 x M向量ind和另一个向量val。例如,

A = zeros(6,5);
ind = [3 4 2 4 2 3];
val = [1 2 3];

我想矢量化以下代码:

for i = 1 : size(A,1)
    A(i, ind(i)-1 : ind(i)+1) = val;
end

>> A

A =

 0     1     2     3     0
 0     0     1     2     3
 1     2     3     0     0
 0     0     1     2     3
 1     2     3     0     0
 0     1     2     3     0

也就是说,对于A的第i行,我想在某个位置插入向量val,由ind的第i个条目指定。在没有for循环的情况下,在Matlab中执行此操作的最佳方法是什么?

2 个答案:

答案 0 :(得分:3)

可以使用 bsxfun的屏蔽功能来完成:构建一个掩码,告诉值将放在哪里,然后填入这些值。这样做,更容易使用列而不是行(因为Matlab的列主要顺序),并在最后进行转置。

以下代码确定最终A中的最小列数,以便所有值都适合指定的位置。

您的示例相对于-1应用ind的置换。该代码包含通用位移,可以修改。

%// Data
ind = [3 4 2 4 2 3]; %// indices
val = [1 2 3]; %// values
d = -1; %// displacement for indices. -1 in your example

%// Let's go
n = numel(val);
m = numel(ind);
N = max(ind-1) + n + d;  %// number of rows in A (rows before transposition)
mask = bsxfun(@ge, (1:N).', ind+d) & bsxfun(@le, (1:N).', ind+n-1+d); %// build mask
A = zeros(size(mask)); %/// define A with zeros
A(mask) = repmat(val(:), m, 1); %// fill in values as indicated by mask
A = A.'; %// transpose

结果示例:

A =
     0     1     2     3     0
     0     0     1     2     3
     1     2     3     0     0
     0     0     1     2     3
     1     2     3     0     0
     0     1     2     3     0

结果为d = 0(无位移):

A =
     0     0     1     2     3     0
     0     0     0     1     2     3
     0     1     2     3     0     0
     0     0     0     1     2     3
     0     1     2     3     0     0
     0     0     1     2     3     0

答案 1 :(得分:1)

如果你可以处理一些bsxfun 过量,那么bsxfun's 添加功能

N = numel(ind);
A(bsxfun(@plus,N*[-1:1]',(ind-1)*N + [1:N])) = repmat(val(:),1,N)

示例运行 -

>> ind
ind =
     3     4     2     4     2     3
>> val
val =
     1     2     3
>> A = zeros(6,5);
>> N = numel(ind);
>> A(bsxfun(@plus,N*[-1:1]',(ind-1)*N + [1:N])) = repmat(val(:),1,N)
A =
     0     1     2     3     0
     0     0     1     2     3
     1     2     3     0     0
     0     0     1     2     3
     1     2     3     0     0
     0     1     2     3     0