3

Below is the output from the Matlab's console. Both of the strings are the same: '@TBMA3'. Yet Matlab's strcmp function returns 0 when comparing them. Why?

K>> str='@TBMA3'
str =
@TBMA3

K>> method.fhandle
ans = 
@TBMA3

K>> strcmp(method.fhandle, str)
ans =
     0
Robert Seifert
  • 25,078
  • 11
  • 68
  • 113
cerebrou
  • 5,353
  • 15
  • 48
  • 80

1 Answers1

8

The most likely reason is that method.fhandle is not a string, but a function handle. Check if class(method.fhandle) gives

ans =
function_handle

In that case, the comparison gives 0 because a string (str) cannot be equal to a function handle (method.fhandle).

In order to check for equality, you would need to convert method.fhandle to a string, or str to a function handle. The first option is not adequate, because char(function_handle) would give 'TBMS3', without '@'. So use the second option, and compare using isequal:

isequal(method.fhandle, str2func(str))

should give 1.

This isequal comparison works because both method.fhandle and str2func(str) point to the same already-defined function TBMA3. Compare with f = @(x)x; g = @(x)x, isequal(f,g), which gives 0. This behaviour is explained in the documentation. Thanks to @knedlsepp for helping clarify this.

Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
  • To compare you could do: `strcmp ( func2str(method.fhandle), 'TBMA3' )`. The other _possibility_ is that one of the strings has whitespace after it... – matlabgui Apr 02 '15 at 14:39
  • @matlabgui Thanks. I was precisely editing my answer in that regard. But you would need to remove the `'@`' from `str`. I think it's better the other way around: convert `str` to a function handle (and then compare with `isequal`; see edited answer) – Luis Mendo Apr 02 '15 at 14:40
  • @LuisMendo: I don't think you can compare function handles for equality 'by value'. `isequal(@(x) x, @(x) x)` fails for me. Edit: Hm, ok if it's an m.file this might work, as the handle is compared as reference. Point taken. – knedlsepp Apr 02 '15 at 14:42
  • @knedlsepp `@(x) x` is not a function handle, but an anonymous function. It works with function handles in this case: `f = @cos; g = @cos, isequal(f,g)`. Strangely, it doesn't work in this case: `f = @(x) x; g = @(x) x, isequal(f,g)` – Luis Mendo Apr 02 '15 at 14:47
  • @knedlsepp I see your edited comment now. Does it make sense to you that the comparison works for `f = @cos` but not for `f = @(x) x`? – Luis Mendo Apr 02 '15 at 14:50
  • @LuisMendo: In this case `f` and `g` are both function handles pointing to different anonymous functions. `f = @(x) x` is equal to `g` defined by `g = f` as both point to the same anonymous function. But it doesn't really matter here I guess. I suppose the OP wants to use the function handles with handles to m-files anyway. – knedlsepp Apr 02 '15 at 14:52
  • @knedlsepp Got it. `f = @cos; g = @cos` point to the same (already defined) function, whereas `f = @(x) x` and `g = @(x) x` don't – Luis Mendo Apr 02 '15 at 14:54
  • 1
    Absolutely. But as OP probably wants to compare some non-anonymous functions, so not converting to string is certainly the best way! – knedlsepp Apr 02 '15 at 14:56
  • @knedlsepp I've added a footnote to clarify this (with due credit) – Luis Mendo Apr 02 '15 at 15:00
  • 1
    @knedlsepp It turns out this is explained in the documentation: http://es.mathworks.com/help/matlab/matlab_prog/advanced-operations-on-function-handles.html#brlptk1-4 – Luis Mendo Apr 02 '15 at 15:18
  • There are simple examples why they probably gave up implementing a real `isequal` for anonymous functions: `sin=@(x)(sin); sin2=@(x)(sin)` These functions are not equal. – Daniel Apr 02 '15 at 15:21
  • @Daniel Yes, the doc recognises that "_MATLAB may underestimate the equality of function handles. That is, a test for equality may return false even when the functions happen to behave the same_". So this is seen as a failure of `isequal`, not as intended behaviour. For objects, `isequal` tests "_if objects have equal property values, even if those objects are different handles_". This rule is simply broken with function handles – Luis Mendo Apr 02 '15 at 15:23