Reputation: 1577
I have the following example (that doesn't work!)
a(1, 1:2, 1:2) = [1 2; 3 4];
a(2, 1:2, 1:2) = [5 6; 7 8];
b=a;
for i=1:2
b(a(i,:,:).*b(i,:,:) < 5.0) = 3*circshift(a(i,:,:), [1 0]);
end
So the idea is that all the places where a(i,:,:).*b(i,:,:)
is less than five, b(i,:,:)
should get the value of 3*circshift(a, [1 0])
at that place. Is that possible?
I can of course do it with a bunch of for
-loops, but that doesn't seem like the most optimal solution.
Upvotes: 0
Views: 44
Reputation: 4563
This is possible using the following:
b( (a.*b)<5 ) = [value you want];
Applied to your code:
a(1, 1:2, 1:2) = [1 2; 3 4];
a(2, 1:2, 1:2) = [5 6; 7 8];
b=a;
c = 3*circshift( a( (a.*b)<5 ), [1 0]); % first change a
b( (a.*b)<5 ) = c( (a.*b)<5 ); % then store c where (a.*b)<5 in b where (a.*b)<5
Notice I use (a.*b)<5
in a( (a.*b)<5 )
. A command like x( condition ) = value;
can be used to tell MATLAB to let x
be value
where condition
is true. This is called logical indexing.
The same effect can be achieved with a for-loop, which can be easier to read for people that know some programming languages, but not MATLAB, but for-loops usually are slower than logical indexing. Another method would be using the find
function to first find the indices of b
where the condition (a.*b)<5
is true, then replacing those indices with the desired value. This too is slower than logical indexing and it needs more code.
Upvotes: 2