矩阵的赋值元素没有for-loop

时间:2015-04-26 15:51:00

标签: matlab for-loop matrix vectorization linear-programming

我正在尝试构建一个我将与linprog一起使用的约束矩阵,并且我努力在不使用for循环的情况下有效地构建它。以下是我试图实现的一个例子:

A = zeros(3, 3); % Constraint matrix
i = [1 3]; % row indexes
j = [1 2 ; 1 3]; % column indexes
x = [1 2 ; 3 4]; % values to assign

转让后的预期结果:

A = [1 2 0 ; 0 0 0 ; 3 0 4]

我想执行以下操作:

A(i(1), j(1,:)) = x(1,:)
A(i(2), j(2,:)) = x(2,:)

目前,我正在使用for循环:

for k=1:length(i)
    A(i(k), j(k,:)) = x(k,:);
end

对于任何ij,还有更好的方法吗?我可以在任何地方使用for循环,但约束的数量取决于变量的数量,所以我的代码用for循环填充。定义与linprog一起使用的约束矩阵的标准方法是什么?

3 个答案:

答案 0 :(得分:4)

您正在寻找的是sub2ind功能。以下是改进矩阵创建的方法:

>> indx = sub2ind(size(A),[1 3 1 3]',j(:))
indx =

   1
   3
   4
   9

>> A(indx)=x(:)
A =

   1   2   0
   0   0   0
   3   0   4

请注意,您必须稍微调整 i 定义,以便 i j 具有相同数量的元素。

答案 1 :(得分:3)

使用vectorized - {/ p>进行一次bsxfun方法

A(bsxfun(@plus,ii(:),(jj-1)*size(A,1))) = x

您需要expansion bsxfun,因为行索引的数量与列索引的数量不匹配。

另请注意,我已将变量名i替换为iij替换为jj ij为也用于复数,因为这可能会导致一些冲突

示例运行 -

>> ii(:)    %// Row indices
ans =
     1
     3
>> jj       %// Column indices
jj =
     1     2     4
     1     3     5
>> x        %// Values to assign
x =
     1     2     6
     3     4     8
>> A        %// Output
A =
     1     2     0     6     0
     0     0     0     0     0
     3     0     4     0     8

它有两个好处:

  1. 使用原始版本来避免对sub2ind的调用,因为more efficient with runtime

  2. 扩展在内部完成,不使用任何循环或repmat分别保存循环或其他函数调用。

答案 2 :(得分:1)

这是另一种方式,利用sparse

A = full(sparse(repmat(ii,size(jj,1),1).', jj ,x));

我使用iijj作为变量名称,而不是ij,如Divakar's answer