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
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.
Related
I got a strange piece of code to debug which to my opinion should throw an exception but instead it produced totally odd results. Reduced it to these two lines:
EDU>> A={0,0}
A =
[0] [0]
EDU>> A{1:2}==A{2:1}
ans =
1
Why is the comparison of two non equal comma separated lists true?
The line of code A{1:2}==A{2:1} is not checking the equality of two comma-separated lists because 2:1 is an empty array. I think the intended indexing was 2:-1:1; this will create a comma-separated list but also throw an error since == cannot handle the list.
However, it is odd that A{1:2}==A{2:1} produces a valid output of any kind in my mind. The code is literally saying A{1:2} == A{[]}, and the question is "what is A{[]}?" According to my MATLAB R2014b, nothing, which makes some sense, but even a simple double array with an empty index returns an empty double. I guess the actual content, which is what is retreived by { and }, is nothing so, yeah.
But then how is MATLAB producing the answer of true?
Consider the following code from the command window:
>> A = {0,0}; A{1:2} == A{[]}
ans =
1
>> A = {0,1}; A{1:2} == A{[]}
ans =
0
From that, I surmise that MATLAB places the comma-separated list as the first two arguments to eq and appends A{[]} nothing to it and interpret it simply as
eq(0,0,A{[]})
eq(0,1,A{[]})
which is, apparently, valid syntax (eq(a,b,) is not). It is very interesting for a binary operation on elements of a cell array. This also works:
>> A = {[2,3],[3,2]};
>> A{1:2} .* A{[]}
ans =
6 6
>> A{1:2} ./ A{[]}
ans =
0.6667 1.5000
And just for fun, because I'm finding this quite interesting:
>> A = {rand(2),rand(2,1)};
>> A{1:2} \ A{[]}
ans =
0.8984
-0.7841
But I guess it makes sense. The parser finds a token, followed by an infix operator, followed by another token. It resolves the infix operator to its function, and then places the left and right tokens into the argument list in turn.
I guess I just find it a odd about the existence of "nothing"; although that would explain how [1,2,3,] is valid syntax.
That said, I'm sure this is a quirk of the language and not a bug nor a feature.
Of course, the only way to know what is actually going on is to have an intimate knowledge of how MATLAB is interpreting the cell array expansion and application of the operator. Of course, I do not have this experience nor the source required (I'd imagine).
Since both are 0. Try A = {1, 2} then you will get ans = 0
This issue appeared when I was answering this question. It should be some stupid error I am doing, but I can't get what error it is…
myMatrix = [22 33; 44 55]
Returns:
>> subsref(myMatrix, struct('type','()','subs',{{[1 2]}} ) );
ans =
22 44
While using it with cells:
myCell = {2 3; 4 5}
Returns:
>> subsref(myCell,struct('type','{}','subs',{{[1 2]}} ) );
ans =
2 % WHATTT?? Shouldn't this be 2 and 4 Matlab??
Checking the subsref documentation, we see:
See how MATLAB calls subsref for the expression:
A{1:2} The syntax A{1:2} calls B = subsref(A,S) where S.type='{}' and
S.subs={[1 2]}.
This seems not to be true because the returned value by subsref is just the first argument, not all arguments.
Then if one does:
>> [a,b]=subsref(myCell,struct('type','{}','subs',{{[1 2]}} ) )
a =
2
b =
4 % Surprise!
But this is not the same as myCell{[2 4]} which will automatically return:
>> myCell{[1 2]}
ans =
2
ans =
4
I would need to use subsref with one output for every index I use access myCell, or am I missing something?
When the curly braces ({}) are used for indexing a cell array, the output is a comma-separated list. This implicitly calls subsref but the behavior is slightly different from invoking it directly.
subsref by itself is a technically a function, and the comma-separated list returned by the curly braces simply behaves like varargout in this case. This means that you should specify an appropriate "sink" for all desired output results, just like you would do with any other function returning multiple parameters, otherwise they would be ignored.
dont ask me why, this is just something I tried:
myOutput=subsref(myCell,struct('type','()','subs',{{[1 2]}} ) )
note the 'type','()'!
this gives me:
myOutput =
[2] [4]
with myOutput as cell. Converting back:
>> myOutput=cell2mat(subsref(myCell,struct('type','()','subs',{{[1 2]}})))
myOutput =
2 4
This is just a "fast" answer, that will need some improvements or some background-info as well...
I was further investigating #EitanH answer and managed to find more details.
Yeah, it returns a comma separed list, but the function subsref should return a comma separed list just the A{:} does. Here is an example where the functions behave different, but this is an expected behavior, I would like the class .get method to return a list and one class common function to behave as common functions getting only the first argument from the cell.
classdef ListReturn
properties(Access = private)
a
end
properties(Dependent)
getA
end
methods
function self = ListReturn(a)
self.a = a;
end
function varargout = get.getA(self)
varargout = {self.a};
end
function varargout = getAFcn(self)
varargout = {self.a};
end
end
end
There is a substantial difference when calling the functions, exactly as the .get:
k=[ListReturn(2) ListReturn(3) ListReturn(4) ListReturn(5)]
>> k.getAFcn
ans =
2
>> k.getA
ans =
2
ans =
3
ans =
4
ans =
5
So it seems that using A{1:2} or A{:} works like a Cell.get(), whereas the subsref works as a common matlab function, returning only one argument when the output arguments are not specified, as one function in C,java,C++ would do. Anyway, I just feel like subsref should work as the .get.
I'm looking for a completely general way to convert any value to a string in MATLAB.
Basically, I want to be able to write something like
x = disp(y);
The above fails with the error Too many output arguments. (I was not able to find the source code for disp.)
Is there a single MATLAB function for converting any value into a string?
(Note that this function should behave like the identity when passed a string.)
Basically I'm looking for MATLAB's equivalent of Python's str. I thought it might be char, but (for example) char(Inf) fails to produce anything like the string 'Inf'. (Note: that was just an example. It does not begin to cover all the possibilities.)
pm89's answer has the right idea, but doesn't work because evalc requires a string as input. I suggest making your own function like so:
function str = anything2string(thing)
str = evalc('disp(thing)');
It works for anything that Matlab can display:
>> anything2string(3)
ans =
3
>> anything2string(Inf)
ans =
Inf
>> anything2string('hi')
ans =
hi
>> anything2string(1:4)
ans =
1 2 3 4
It's not quite the same as Python's str, but num2str works with Inf and handles strings as input.
num2str(Inf)
ans = Inf
num2str('some string')
ans = some string
You could get the exact same string as you see in your command window using evalc (evaluate and capture the result):
x = evalc('disp(y)'); % y could be anything displayable by Matlab!
I have no idea what's going on here. I'm using R2006b. Any chance someone out there with a newer version could test to see if they get the same behavior, before I file a bug report?
code: (bug1.m)
function bug1
S = struct('nothing',{},'something',{});
add_something(S, 'boing'); % does what I expect
add_something(S.something,'test'); % weird behavior
end
function add_something(X,str)
disp('X=');
disp(X);
disp('str=');
disp(str);
end
output:
>> bug1
X=
str=
boing
X=
test
str=
??? Input argument "str" is undefined.
Error in ==> bug1>add_something at 11
disp(str);
Error in ==> bug1 at 4
add_something(S.something,'test');
It looks like the emptiness/nothingness of S.something allows it to shift the arguments for a function call. This seems like Very Bad Behavior. In the short term I want to find away around it (I'm trying to make a function that adds items to an initially empty cell array that's a member of a structure).
Edit:
Corollary question: so there's no way to construct a struct literal containing any empty cell arrays?
As you already discovered yourself, this isn't a bug but a "feature". In other words, it is the normal behavior of the STRUCT function. If you pass empty cell arrays as field values to STRUCT, it assumes you want an empty structure array with the given field names.
>> s=struct('a',{},'b',{})
s =
0x0 struct array with fields:
a
b
To pass an empty cell array as an actual field value, you would do the following:
>> s = struct('a',{{}},'b',{{}})
s =
a: {}
b: {}
Incidentally, any time you want to set a field value to a cell array using STRUCT requires that you encompass it in another cell array. For example, this creates a single structure element with fields that contain a cell array and a vector:
>> s = struct('strings',{{'hello','yes'}},'lengths',[5 3])
s =
strings: {'hello' 'yes'}
lengths: [5 3]
But this creates an array of two structure elements, distributing the cell array but replicating the vector:
>> s = struct('strings',{'hello','yes'},'lengths',[5 3])
s =
1x2 struct array with fields:
strings
lengths
>> s(1)
ans =
strings: 'hello'
lengths: [5 3]
>> s(2)
ans =
strings: 'yes'
lengths: [5 3]
ARGH... I think I found the answer. struct() has multiple behaviors, including:
Note If any of the values fields is
an empty cell array {}, the MATLAB
software creates an empty structure
array in which all fields are also
empty.
and apparently if you pass a member of a 0x0 structure as an argument, it's like some kind of empty phantom that doesn't really show up in the argument list. (that's still probably a bug)
bug2.m:
function bug2(arg1, arg2)
disp(sprintf('number of arguments = %d\narg1 = ', nargin));
disp(arg1);
test case:
>> nothing = struct('something',{})
nothing =
0x0 struct array with fields:
something
>> bug2(nothing,'there')
number of arguments = 2
arg1 =
>> bug2(nothing.something,'there')
number of arguments = 1
arg1 =
there
This behaviour persists in 2008b, and is in fact not really a bug (although i wouldn't say the designers intended for it):
When you step into add_something(S,'boing') and watch the first argument (say by selecting it and pressing F9), you'd get some output relating to the empty structure S.
Step into add_something(S.something,'test') and watch the first argument, and you'd see it's in fact interpreted as 'test' !
The syntax struct.fieldname is designed to return an object of type 'comma separated list'. Functions in matlab are designed to receive an object of this exact type: the argument names are given to the values in the list, in the order they are passed. In your case, since the first argument is an empty list, the comma-separated-list the function receives starts really at the second value you pass - namely, 'test'.
Output is identical in R2008b:
>> bug1
X=
str=
boing
X=
test
str=
??? Input argument "str" is undefined.
Error in ==> bug1>add_something at 11
disp(str);
Error in ==> bug1 at 4
add_something(S.something,'test'); % weird behavior
I have a function that returns one or more variables, but as it changes (depending on whether the function is successful or not), the following does NOT work:
[resultA, resultB, resultC, resultD, resultE, resultF] = func(somevars);
This will sometimes return an error, varargout{2} not defined, since only the first variable resultA is actually given a value when the function fails. Instead I put all the output in one variable:
output = func(somevars);
However, the variables are defined as properties of a struct, meaning I have to access them with output.A. This is not a problem in itself, but I need to count the number of properties to determine if I got the proper result.
I tried length(output), numel(output) and size(output) to no avail, so if anyone has a clever way of doing this I would be very grateful.
length(fieldnames(output))
There's probably a better way, but I can't think of it.
It looks like Matthews answer is the best for your problem:
nFields = numel(fieldnames(output));
There's one caveat which probably doesn't apply for your situation but may be interesting to know nonetheless: even if a structure field is empty, FIELDNAMES will still return the name of that field. For example:
>> s.a = 5;
>> s.b = [1 2 3];
>> s.c = [];
>> fieldnames(s)
ans =
'a'
'b'
'c'
If you are interested in knowing the number of fields that are not empty, you could use either STRUCTFUN:
nFields = sum(~structfun(#isempty,s));
or a combination of STRUCT2CELL and CELLFUN:
nFields = sum(~cellfun('isempty',struct2cell(s)));
Both of the above return an answer of 2, whereas:
nFields = numel(fieldnames(s));
returns 3.