没有for循环的矩阵赋值元素
Assignment element of matrix without for-loop
我正在尝试构建一个我将与 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
对于 i
和 j
有没有更好的方法来做到这一点?我可以在任何地方使用 for 循环,但约束的数量取决于变量的数量,所以我的代码充满了 for 循环。定义与 linprog
一起使用的约束矩阵的标准方法是什么?
您要查找的是 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 具有相同数量的元素。
一个vectorized
approach with bsxfun
-
A(bsxfun(@plus,ii(:),(jj-1)*size(A,1))) = x
您需要 expansion
和 bsxfun
,因为行索引数与列索引数不匹配。
此外,请注意,我已将变量名称 i
替换为 ii
并将 j
替换为 jj
为 i
和 j
也与复数一起使用,否则可能会导致一些 冲突 。
样本运行-
>> 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
它有两个好处:
避免使用 原始版本 调用 sub2ind
,因为 more efficient with runtime
.
不使用任何循环或repmat
在内部完成的扩展分别保存了循环或另一个函数调用。
这是另一种方法,利用 sparse
:
A = full(sparse(repmat(ii,size(jj,1),1).', jj ,x));
我使用 ii
和 jj
作为变量名,而不是 i
和 j
,如 .
我正在尝试构建一个我将与 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
对于 i
和 j
有没有更好的方法来做到这一点?我可以在任何地方使用 for 循环,但约束的数量取决于变量的数量,所以我的代码充满了 for 循环。定义与 linprog
一起使用的约束矩阵的标准方法是什么?
您要查找的是 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 具有相同数量的元素。
一个vectorized
approach with bsxfun
-
A(bsxfun(@plus,ii(:),(jj-1)*size(A,1))) = x
您需要 expansion
和 bsxfun
,因为行索引数与列索引数不匹配。
此外,请注意,我已将变量名称 i
替换为 ii
并将 j
替换为 jj
为 i
和 j
也与复数一起使用,否则可能会导致一些 冲突 。
样本运行-
>> 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
它有两个好处:
避免使用 原始版本 调用
sub2ind
,因为more efficient with runtime
.不使用任何循环或
repmat
在内部完成的扩展分别保存了循环或另一个函数调用。
这是另一种方法,利用 sparse
:
A = full(sparse(repmat(ii,size(jj,1),1).', jj ,x));
我使用 ii
和 jj
作为变量名,而不是 i
和 j
,如