Why doesn't [] ~=1 yield logical one?

3 visualizzazioni (ultimi 30 giorni)
Michael Van de Graaff
Michael Van de Graaff il 22 Mag 2021
Commentato: Paul il 23 Mag 2021
I'm using matlab r2012B, because the computer is old and disconnected from internet and it runs my experiment and is not to be updated.
I have the following:
a = [];
if a ~= 1
disp('a~=1')
end
Now i ask myself, will the message 'a~=1' be printed? the answer is obviously yes. Why? because the expression 'a~=1' is clearly True. It is True that [] is not equal to 1. one is the number 1, and the other, is NOT the number 1. If I
If this threw an error, I would accept that. That seems reasonable.
Therefore, there must be some reason that this doesn't behave like I expect. What is that reason? Why does it behave the same way for a = 'string' (which evaluates to 0, makes sense) or a = {} (which throws an error, also reasonable).

Risposta accettata

John D'Errico
John D'Errico il 22 Mag 2021
Modificato: John D'Errico il 23 Mag 2021
This has always been true as I recall, probably so since the mid-1980's, when I learned MATLAB.
Note that the result is an EMPTY arrray. Suppose we had performed the test:
a = 1;
x = 0:3;
x ~= a
ans = 1×4 logical array
1 0 1 1
We have compared the scalar value a to EVERY element in the vector x. 3 of the 4 values were not equal, and the other is equal. So we get a completely expected result, true where x is not equal to 1.
The same applies to a vector of length 0, thus an empty vector. Try this comparison:
y = [];
y ~= a
ans = 0×0 empty logical array
Again, every element in y is compared to a. Since there are no elements in y, the result is an empty vector.
Your problem is in how you view an empty array. It is NOT a scalar. That is
whos a x y
Name Size Bytes Class Attributes a 1x1 8 double x 1x4 32 double y 0x0 0 double
We see that y is not the same size as a. So while the comparison to x performs a scalar expansion, the same comparison to y results in a scalar expansion of a, to be the same size and shape as y: EMPTY.
We cannot compare a scalar value to y (an empty array) and expect a result that is either true or false. By the way, this is why the function isempty has been around since the dark ages.
Now, how does this work for a string? I'm not certain what you intended there.
If we do this:
str = '';
str == '1'
ans = 0×0 empty logical array
Then we get the same behavior with an empty string as with an empty array. If we try to compare a non-empty string to an ampty array, it will throw an error.
str = 'string';
str == ''
Error using ==
Arrays have incompatible sizes for this operation.
As you can see, I cannot compare a string VECTOR to an empty array, so it throws an error. I cannot expand an empty array. It is NOT a scalar.
Again, I think you are viewing an empty array as if it is a scalar. It is not so. Likewise, you cannot compare a scalar to a cell array, empty or NOT! But that is not the same issue. Comparisons are not defined like this for a cell array:
{} == 1
Operator '==' is not supported for operands of type 'cell'.
  4 Commenti
Steven Lord
Steven Lord il 23 Mag 2021
@Paul While what you've said is true for the current release, the rules back in release R2012b were stricter than what you posted. That release predates the introduction of implicit expansion, so in R2012b for element-wise operators like ~= to work on two arrays A and B one of the following must be satisfied:
  • A and B are exactly the same size, in which case the result is that common size
  • A is a scalar, in which case the result is the size of B. This is scalar expansion (which might not be "expansion" at all if B is empty.)
  • B is a scalar, in which case the result is the size of A. This is scalar expansion.
Implicit expansion added one more case:
  • For any dimension in which A and B have the same size, the result is that common size in that dimension. For any dimension in which A and B have different sizes, one of the inputs must have size 1 and the result is the size of the other input in that dimension. Remember that arrays are considered to implicitly have size 1 in any dimension past its ndims.
size([1 2; 3 4], 999)
ans = 1
So certain operations that work now would not have worked in R2012b.
x = 1:10
x = 1×10
1 2 3 4 5 6 7 8 9 10
y = randi(10, 10, 1)
y = 10×1
5 6 4 6 4 7 2 3 7 2
x == y % [1 10] and [10 1] errors in R2012b but works in R2021a
ans = 10×10 logical array
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0
x == 5 % works in both R2012b and R2021a
ans = 1×10 logical array
0 0 0 0 1 0 0 0 0 0
Paul
Paul il 23 Mag 2021
In r2012b, would the results from my code snippet be any different? It seems to me that
y ~= a
would still return empty in accordance with your third bullet, and
y ~= x
would presumably throw an error because it's not covered by bullets 1-3.
I realize that based on the OP's restriction to r2012b I shouldn't have brought post-r2012b features into the discussion. I'm just curious if I understand what that older behavior is.

Accedi per commentare.

Più risposte (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by