矢量化需要补充二进制数组的某些元素的代码

时间:2017-07-06 15:58:14

标签: arrays matlab performance matrix vectorization

我有一个维度A的矩阵m - 由 - n由0和1组成,矩阵J由维m - 由-1报告来自[1,...,n]的一些整数。

我想构建一个维B的矩阵m - by - n,以便i = 1,...,m

    {li> B(i,j) = A(i,j) j=1,...,n-1
  1. B(i,n) = abs(A(i,n)-1)
  2. 如果sum(B(i,:)) 奇数,则B(i,J(i)) = abs(B(i,J(i))-1)
  3. 这段代码符合我的要求:

    m = 4;
    n = 5;
    A = [1 1 1 1 1; ...
       0 0 1 0 0; ...
       1 0 1 0 1; ...
       0 1 0 0 1];
    J = [1;2;1;4];
    B = zeros(m,n);
    for i = 1:m
        B(i,n) = abs(A(i,n)-1);
        for j = 1:n-1
            B(i,j) = A(i,j);
        end
        if mod(sum(B(i,:)),2)~=0
           B(i,J(i)) = abs(B(i,J(i))-1);
        end
     end
    

    您能否提出更有效的算法,不使用嵌套循环?

2 个答案:

答案 0 :(得分:4)

您的问题不需要for循环。它只需要有效地使用colon运算符和逻辑索引,如下所示:

% First initialize B to all zeros
B = zeros(size(A));
% Assign all but last columns of A to B
B(:, 1:end-1) = A(:, 1:end-1);
% Assign the last column of B based on the last column of A
B(:, end) = abs(A(:, end) - 1);
% Set all cells to required value
% Original code which does not work: B(oddRow, J(oddRow)) = abs(B(oddRow, J(oddRow)) - 1);
% Correct code:
% Find all rows in B with an odd sum
oddRow = find(mod(sum(B, 2), 2) ~= 0);
for ii = 1:numel(oddRow)
    B(oddRow(ii), J(oddRow(ii))) = abs(B(oddRow(ii), J(oddRow(ii))) - 1);
end

我想最后一部分最好使用for循环。

编辑:通过EBH查看完整的技巧,在没有for循环的情况下完成最后一部分

答案 1 :(得分:2)

只需添加到@ammportal good answer,最后一部分也可以在没有使用linear indices的循环的情况下完成。为此,sub2ind很有用。因此,采用上一个答案的最后一部分,可以做到这一点:

% Find all rows in B with an odd sum
oddRow = find(mod(sum(B, 2), 2) ~= 0);
% convert the locations to linear indices
ind = sub2ind(size(B),oddRow,J(oddRow));
B(ind) = abs(B(ind)- 1);