# What’s “if” “all” about? 12

Posted by **Loren Shure**,

I recently posted about a GOTCHA with the expression `a < x < b` in MATLAB and Matt's comments made me look to see if I had ever devoted a post to the behavior of `all` (or its companion `any`). So today I will explain how `all` works and why you need to take care when you use arrays for testing conditions in `if` and `while` statements. This is especially true if you do **not** use them with functions such as `any` or `all` since they can reduce expressions to scalar `true` and `false` values.

### Contents

#### Misconception

Sometimes I see code that was written assuming the expression for an `if` statement will be a scalar. It's possible to then be confused if the expression is an array. If you were to loop through each element in the expression (for example, by placing the `if` statement inside a for loop), then each element would be evaluated separately and the expression would only execute the statements contained in the `if` portion for nonzero (or `true`) expression elements. However, once you hand the array over as an entity to `if`, you should be aware that **ALL** elements must be `true` for the expression to be `true`, and for the `if` body statements to execute.

It's also possible that users think that the statements contained within the body of the `if` statement will only be executed for elements that were true in the expression controlling the `if` statement. This is also not true.

#### Behavior of Conditional Statements with Array Input

The important thing you need to know is this, quoted from the MATLAB documentation.

**"An evaluated expression is true when the result is nonempty and contains all nonzero elements (logical or real numeric). Otherwise, the expression is false."**

This means that for an expression to trigger the execution of the body of an `if` statement, `all` of the elements in the expression be `true`. The following two code segments therefore give the same results.

if A > 0 doSomething end

if all(A(:) > 0) doSomething end

#### Illustration of the Issue

I will first show code that does not work on only the "relevant" elements of the `if` expression, and then show two ways to achieve the desired result.

Create an input array with integers between 0 and some maximum value.

intData = randperm(8); intData(randperm(8) > 5) = 0

intData = 7 0 3 0 5 0 1 2

Start with an output array of constant values, the same size as the input array.

outDataVec = 42*ones(size(intData));

Try replacing output values with 17 where the input array is nonzero.

if intData outDataVec = 17; end outDataVec

outDataVec = 42 42 42 42 42 42 42 42

This didn't change my output since the expression isn't true! Since that didn't work, let's try another way.

outDataVec1 = 42*ones(size(intData)); if intData outDataVec1(:) = 17; % see if we can just replace the "selected" elements end outDataVec1

outDataVec1 = 42 42 42 42 42 42 42 42

That didn't work either, since `X(:)` simply turns the array `X` into a column vector. And the input expression is still not all true.

#### One Working Way (for loop)

outDataFor = 42*ones(size(intData)); for ind = 1:length(intData) if intData(ind) outDataFor(ind) = 17; end end outDataFor

outDataFor = 17 42 17 42 17 42 17 17

#### Another Way for This Simple Problem

Of course, there's another better way to calculate the output represented by `outDataFor`, in a vectorized way, using logical indexing.

outDataArray = 42*ones(size(intData)); outDataArray(intData > 0) = 17

outDataArray = 17 42 17 42 17 42 17 17

Just to show that the `for` loop calculation matches the one using logical indexing.

isequal(outDataFor, outDataArray)

ans = 1

#### Other Relevant Blogs

Here are a couple of links to other posts that cover issues related to these topics.

#### Have You Tripped on Arrays with "if" or "while" Statements?

Has the expression for an `if` or `while` statement bitten you? How did you figure it out and what did you do to resolve it? I'd love to see your thoughts here.

Get
the MATLAB code

Published with MATLAB® 7.14

**Category:**- Common Errors

## 12 CommentsOldest to Newest

**1**of 12

if A > 0

doSomething

end

this should mean

if all(A > 0)%assuming we do ‘all’ in every dimension so if gets a scalar value

doSomething

end

The question is: why ‘if A>0’ does not mean ‘if all(A>0)’?

**2**of 12

I have been tripped up by the behavior of ‘all’ with arrays. My intuition is that all(true(4)) should return a single true since all the entries are indeed true. But as you know, it returns a row vector of 4 true’s. This leads to unexpected behavior depending on whether the item tested is a scalar or an array.

**3**of 12

I’m believe your example should read

if all(A(:) > 0)

and not

if all(A(:)) > 0

**4**of 12

This is one of the few places in MATLAB where I’m not happy with its general attitude of “give me an array and I’ll try to do something meaningful with it”. Personally, I always force the condition to be scalar (by using “all” or some other reduction operation) and avoid the implied array logic. In my experience, many people are puzzled that negating the (element-wise) test is not equivalent to switching the if and else block.

Note that there is a bug in your first code snippet, where

if all(A(:)) > 0

should have been

if all(A(:) > 0)

(the outer closing parenthesis is in the wrong place).

**5**of 12

Thanks, Martin and Ulrik-

You are right and I fixed the typo.

Tamas-

“The question is: why ‘if A>0′ does not mean ‘if all(A>0)’?”

And Bob, with your true(4) example…

Because any and all, like sum and prod, work down the first non-singleton dimension for arrays, and don’t operate on the whole array at once. If A is a vector, then your 2 statements are equivalent, otherwise not.

–Loren

**6**of 12

Hi Loren,

is there a possibility to combine logical indexing with “classical” indexing?

For example to replace some values in one particular column of a matrix.

C(C(:,4)>5) = 10

… does not work.

Konstantin

**7**of 12

Konstantin-

Yes, it’s possible, but not precisely the way you did it. Your logical array should be the same size/shape as the array being indexed into.

You can mix indexing styles like this, for example.

[r,c] = size(A); A(r>3, [2 5]) = NaN;

–loren

**8**of 12

@Konstantin,

To add to Loren’s response, you would do this to achieve what you’re trying to do.

`C(C(:,4)>5, 4) = 10`

Note that your logical operation will return a column vector of logical values, so you would pass that in as the 1st dimension in the subscripted indexing.

**9**of 12

I’m surprised to see this blog post, since I always thought that “if” only accepted scalars. In fact, I remember a few times I got an error that went something like “Non-scalar logical expression in IF statement”. Maybe it’s an error that can be activated/deactivated (like most warnings), or am I mistaken?

**10**of 12

Jotaf-

Perhaps there is a code analyzer warning, but I am not sure about that. I doubt this was ever an error, and errors can’t be activated/de-activated, unlike warnings.

–Loren

**11**of 12

Loren,

Great post – actually I never knew this was valid

A = true(3);

if A > 0

doSomething

end

and I’m glad to know it is. But I was surprised to see you write this

if intData(ind)

outDataFor(ind) = 17;

end

Of course it’s valid, but I’d have thought you’d prefer to be clear on the distinction between logicals and numeric types. Wouldn’t you prefer to see instead

if intData(ind) ~= 0

outDataFor(ind) = 17;

end

John

**12**of 12

John-

I can’t say I have a strong preference on that – one is slightly clearer, the other has one less overt comparison.

–Loren

## Recent Comments