Vacuous Truth

Mike Croucher on 22 Sep 2025
Latest activity Reply by Stephen23 on 30 Sep 2025

all(logical.empty)
ans = logical
1
Discuss!
Stephen23
Stephen23 on 30 Sep 2025
Paul
Paul on 24 Sep 2025 (Edited on 25 Sep 2025)
The behavior was discussed in this Answer thread.
At least that usage is clearly documented at all (and any).
However, as best I can tell the doc page(s) doesn't explain these results:
all(logical.empty(3,0)) % 1
ans = 1×0 empty logical array
all(logical.empty(3,0),1) % 2
ans = 1×0 empty logical array
all(logical.empty(3,0),2) % 3
ans = 3×1 logical array
1 1 1
all(logical.empty(0,3)) % 4
ans = 1×3 logical array
1 1 1
all(logical.empty(0,3),1) % 5
ans = 1×3 logical array
1 1 1
all(logical.empty(0,3),2) % 6
ans = 0×1 empty logical array
I think those results are all consistent (I had to think about them for a bit), but the doc page is silent on behavior with an empty 2D input with size that's not 0x0 (as was also noted as far back as 2015 in the linked Answer thread).
I think the doc is silent on the following cases as well, and I'm having trouble convincing myself that they are consistent with the original example
all(logical.empty,1)
ans = 1×0 empty logical array
all(logical.empty,2)
ans = 0×1 empty logical array
Steven Lord
Steven Lord on 24 Sep 2025
When you call all or any with one input, except in the case where the input is 0-by-0, the size of the output is the same as the size of the input except in the first dimension whose size is not 1. In that dimension, the result is size 1. From the all documentation page:
  • If A is a multidimensional array, then all(A) acts along the first array dimension whose size does not equal 1 and returns an array of logical values. The size of this dimension becomes 1, while the sizes of all other dimensions remain the same.
While this does call out a multidimensional array, it turns out it also works for every case except the scalar and 0-by-0 empty cases. So:
x1 = all(false(0, 3))
x1 = 1×3 logical array
1 1 1
The size of false(0, 3) is [0 3]. The first element of that size vector that's not 1 is the first, so the result is size [1 3].
x2 = all(false(3, 0))
x2 = 1×0 empty logical array
The input in this case is of size [3 0]. The first element of that size vector that's not 1 is also the first, so the result is size [1 0].
If you call all with a dim input, that dimension is the one whose size becomes 1.
x3 = all(false(3, 0), 2)
x3 = 3×1 logical array
1 1 1
In this case, the result is the same size as the input ([3 0]) except in the second dimension which becomes 1. So x3 is an array of size [3 1].
In the case where the input is a scalar, it doesn't have a dimension whose size does not equal 1. But in that case, it doesn't really matter over which dimension we "reduce" the array: the result is also a scalar.
x4 = all(false)
x4 = logical
0
Yes, I know that turning a dimension of size 0 into a dimension of size 1 isn't technically a "reduction". But it's a reduction in the same sense that adding a scalar to an empty does scalar "expansion".
y = 1 + []
y = []
Paul
Paul on 24 Sep 2025 (Edited on 25 Sep 2025)
"it turns out it also works for every case'
Exactly. Users shouldn't have to assume "it turns out." Seems like a fix is quite simple (even if not the best fix): "If A is a multidimensional array or a two-dimensional empty array with one non-zero dimension, ...." At least I think that covers cases 1 and 4 in my post, from which it would then follow that case 1 should match case 2, and case 4 should match case 5, at least wrt to the dimensions of the output. Keep in mind that "multidimensional array" includes empty arrays of 3 or more dimensions.
What would still be unexplained are the results, i.e., how does one know from the doc page that
all(logical.empty(0,3))
ans = 1×3 logical array
1 1 1
returns true(s) instead of false(s)?
Even with proposed wording, the doc page would still have a gap for this case.
all(logical.empty(0,0),1)
ans = 1×0 empty logical array
Note that the 0x0 input is not a scalar input
isscalar(logical.empty(0,0))
ans = logical
0
I see that the description of dim in R2024b was updated from the description of dim in R2024a, which indicates someone was thinking about this issue, though didn't take it far enough IMO.
Ned Gulley
Ned Gulley on 22 Sep 2025
As Wittgenstein observed, everything that is not the case, is. And vice versa.
Steve Eddins
Steve Eddins on 22 Sep 2025
Well, I learned something new today—the meaning of the phrase vacuous truth.
Since one new thing learned is my daily limit, I'm going back to bed.
Christopher Stapels
Christopher Stapels on 22 Sep 2025
True.