LisaB
LisaB

Reputation: 75

Replace specific entries of a multidimensional arrays avoiding loops

I would like to replace the entry corresponding to the column number of an array that is part of a 3D matrix by zero. My matrix is of size IxJxJ. In each column j I can find a matrix of size IxJof which I would like to replace the jth column by zero.

You can find below an example of what I would like using a simple 3D matrix A. This example uses a loop, which is what I am trying to avoid.

A(:,:,1) = randi([1,2],5,3);
A(:,:,2) = randi([3,4],5,3);
A(:,:,3) = randi([5,6],5,3);

for i = 1:3
    B = A(:,i,:);
    B = squeeze(B);
    B(:,i) = 0;
    A(:,i,:) = B;
end

Upvotes: 0

Views: 47

Answers (2)

rahnema1
rahnema1

Reputation: 15837

Use eye to create a logical mask and mutiply it by A.

  A = A .* reshape(~eye(3), 1, 3, 3) ;

Upvotes: 1

David
David

Reputation: 8459

Firstly, you can replace the 4 lines of code in your for loop with just A(:,i,i) = 0;. I don't see any real need to avoid the for loop.

Using linear indexing, you can do

A((1:size(A,1)).'+size(A,1).*(size(A,2)+1).*(0:size(A,2)-1)) = 0

or for older version of Matlab without implicit expansion (pre-R2016b)

A(bsxfun(@plus,(1:size(A,1)).',size(A,1).*(size(A,2)+1).*(0:size(A,2)-1))) = 0

After some very quick testing, it actually looks like the bsxfun solution is fastest, but the differences aren't huge, your results may differ.

Upvotes: 1

Related Questions