2015-09-02 117 views
4

如果这个问题是重复的,或者如果这个问题的解决方案在Matlab中非常简单,则事先道歉。我有一个M×N矩阵A,1个M矢量ind,以及另一个矢量val。例如,Matlab:基于索引向量化矩阵中值的赋值

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 

也就是说,对于第i A行,我要插入载体val在一定的位置,通过如specificied ind的第i个条目。在没有for循环的情况下,在Matlab中执行此操作的最佳方法是什么?

+1

问得好... – robertevansanders

回答

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

如果你能处理有点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 
+0

哈哈!我偷了你的答案! :-) –

+0

@LuisMendo我害怕我偷走了你的!完全脱离主题让我思考前几天,我从来没有想过'bsxfun'会在meta post中发挥作用,但是你在10-M Questions的最新帖子中做过这件事,所以也要感谢你! :)顺便说一句,我喜欢'掩蔽能力'这个术语,听起来像bsxfun有一个超级大国,这在某种程度上是真的! ;) – Divakar

+0

这是你的名词,你创造了它!是的,'bsxfun'理应得到一个meta post,所以你做到了! :-D –