Matlab function switching return/no return - matlab

In Matlab, I've got a function that is called after some special points are found on an image. Depending on how the nearby pixels of that "special point" are, the function must return a structure with many parameters or return nothing.
Is it possible to have a function that by deafult will return something but, in some cases, nothing should be returned? How that "return nothing"'s code should be like? Thank you.

One common trick in matlab is to use the empty matrix [] to indicate nothing. You could write your function something like (untested code):
function result = analyze(image, special_point)
% your code here
if pixels_are_ok
result.a = 1;
result.b = 2;
else
result = [];
end
If you call this function from your other code, you can use isempty to see if you got a result or not:
result = analyze(image, special_point)
if isempty(result)
display('did not find anything')
else
display('found some interesting results')
display(result)
end

Related

Output of Matlab function is an empty array

I have a Matlab function which returns an array with probability alpha and nothing (i.e. an empty array) with probability 1-alpha:
function [binary_array_e1 , binary_array_e2 ] = croiser(binary_array_p1,binary_array_p2,alpha )
binary_array_e1=[];
binary_array_e2=[];
compt=1;
if (rand <= alpha)
% some stuff that will put sth in binary_array_e1 and binary_array_e2
end
My question is: how should I manage the fact that the function could return empty arrays at the call of the function? Is something like:
[binary_array_e1 , binary_array_e2]=croiser(binary_array_p1,binary_array_p2,alpha);
be sufficient?
If you want to return an empty variable from a function call, you are totally allowed to do it and you are on the right path. Initialize your variables as empty at the beginning of the function...
function [binary_array_e1 , binary_array_e2 ] = croiser(binary_array_p1,binary_array_p2,alpha )
binary_array_e1=[];
binary_array_e2=[];
% ...
end
and then just check the outcome whenever you need to do it, for example:
[binary_array_e1,binary_array_e2] = croiser(binary_array_p1,binary_array_p2,alpha);
if (isempty(binary_array_e1))
% do something 1...
elseif (isempty(binary_array_e2))
% do something 2...
else
% do something 3...
end
Of course, in order to check the outcome, both variables must be returned and evaluated. But if you are returning two empty arrays in one case and two non-empty arrays in the other case, you could also check only one array:
if (isempty(binary_array_e1))
% do something...
else
% do something else...
end
Anyway... there are so many ways to obtain the same result. For example, you could also return a 'logical' variable that tells you immediately if your arrays have been filled with something or not, or you could return a 'struct' filled with your data in order to make everything more compact (I can elaborate on these solutions if you want). It's up to you but I see nothing wrong in your approach!
Yes, that should be fine. You can later check if the output is an empty array using the function isempty

Function with different return variables

Is there a way to have one function that can return two different variables, but only one at a time AND knowing which one is returned in the function call?
example:
I have the following function in which only one of the outputs is valid (the other one would be [])
function [a,b] = AlternatingOutput (input)
if input == 1
return ONLY A
else
return ONLY B
end
end
and i call it in a script
[a,b] = AlternatingOutput (input)
i want a way to say the following (pseudocode):
if (function outputs a)
[a,~] = AlternatingOutput(input)
elseif (function outputs b)
[~,b] = AlternatingOutput(input)
end
the script is run in a loop, and later i need the newest Valid values for a and b, so i cannot overwrite one of the two with []
I do understand that I could just write a function that checks which variable will be output, but I was wondering if there is a more elegant way.
I hope I have made my question clear, and I hope someone can answer me :)
There is no way to tell if an output argument is actually used. You may check the number of output arguments using nargout and it would allow to distinguish between [a] = AlternatingOutput(input) and [~,b] = AlternatingOutput(input)
I don't know the full context of your problem, but maybe you can put all your variables into a struct? Simply pass this struct everytime you call the function and let it decide which variables to manipulate. (This might be slow in some programming languages, but not in matlab).
How about retuning a cell?
function [ ab ] = testfun( input )
if input
ab={'ax'};
else
ab={2};
end
end
No worries about what is in the cell.
thb you could return what ever you want, Matlab does not check the type anyways
If only one of the outputs from the function AlternatingOutput is valid, then you only need to return one output:
function [X] = AlternatingOutput(input)
if input == 1
X = A;
else
X = B;
end
end
To allocate the retured value to either a or b in the loop, put them into a cell:
C = {AlternatingOutput(1), AlternatingOutput(2)};
and then use input to determine which value is change. If input is either 1 or 2 you can just do
for counter = ...
input = mod(input,2)+1;
C{input}=AlternatingOutput(input);
end
If your function doesn't mind accepting more input variables, why not pass a and b as input:
function [a,b] = AlternatingOutput(a,b,input)
if input == 1
a = new_value_for_a;
% b retains its former value
else
% a retains its former value
b = new_value_for_b;
end
end
Then it can be easily called from your script in a loop:
for i= ...
[a,b] = AlternatingOutput(a,b,input);
...
...
end

MatLab function, variable output

function [ muln, varargout ] = my_mul( varargin )
%MY_MUL This function is used to multiply numbers.
% My_mul function multiplies array of entered numbers, and outputs single
% solution.
% For example: my_mul(12, 2, 3, 5) gives ans = 360
if nargout >=1
disp('Error, wrong number of output arguments');
varargout{1} = 0;
return
end
if nargin <= 1
disp('Error, small number of input argumnets');
return
else
muln = 1;
for i = 1:nargin
muln = muln*varargin{i};
end
end
end
Hi, everyone, I'm just doing my assignment for uni and have a qiuck question.
How can I make this function to give an error if it is called with more than one output.(It meant to give only one) Thanks!
In your function definition, you have defined your function to allow for an unlimited number of outputs. The keyword varargout is a place-holder for a variable number of outputs.
As you have stated in your question, you only want one possible output which in your case looks to be muln. So if you simply remove varargout from your function definition, MATLAB should automatically throw an error if too many outputs are requested
function muln = my_mul(varargin)
If you ever do need to use varargout but want to place constraints on how many outputs are provided for any given scenario, you can check the number of output arguments that were requested using nargout and then throw an error with the error function.
if nargout > 4
error('my_mul:TooManyOutputs', 'Too many outputs requested');
end
My opinion is that if a return value is expected the function needs to throw. Otherwise the caller (function calling this function) will expect everything to be ok. Note that disp('Error') gives information to the developer, but it does not give the program any indication on what happens. More importantly, the information does not give any indication of where the error occurs. This can force the developer to do heavy debugging just to find the error, which is completely unnecessary.
The use of variable output arguments should only be used in case a different number of output arguments should be expected. An example is some customized plot function
function varargout = myplot(varargin)
filename = '';
idx = find(strcmp(varargin,'filename'));
if (~isempty(idx) && length(varargin)<idx+1 && ~ischar(varargin{idx+1}))
error('filename property must be followed by a directory');
elseif(~isempty(idx))
filename = varargin{idx+1};
varargin([idx,idx+1]) = [];
end
h = plot(varargin{:});
varagout{1} = h;
if (~isempty(idx))
save(filename, h);
end
varagout{2} = filename;
This function works as plot except it saves the figure to file in case a filename is specified. In case the developer needs the handle it will be returned and in case the developer wants the save directory it can be returned as well. None of these arguments are necessary though. The developer may want to use this function as a standard plot function and this means that the user may want to call myplot as myplot(x,y);which does not return a value. Further note that even if 'filename' is not specified, the function can still return 2 outputs. The second output may be an empty array of char, but two outputs for the caller will never cause a crash.
Also, note that no further error handling is required. The only unchecked crashes are in plot and save. How this is handled may be different for different users and this means that it only is reasonable to let the user catch the error and handle it (as he would have done if save or plot would have thrown).
Apart from this you may also want to have a check so that the number of output variables are within the correct range (in this case 0,1 or 2 outputs).

Dynamically check for existence of structure field name with hierarchy

As a follow-up to my previous question about how to assign fields to a structure variable with a dynamic hierarchy, I would now like to be able to query those fields with isfield. However, isfield will only take one argument, not a list as with setfield.
To summarize my problem:
I have a function that organizes data into a structure variable. Depending on certain flags, the data is saved into the substructures with a different number of levels.
For instance, the accepted answer to my previous question has me doing this to build my structure:
foo = struct();
% Pick one...
true_false_statement = true;
% true_false_statement = false;
if true_false_statement
extra_level = {};
else
extra_level = {'baz'};
end
foo = setfield(foo, extra_level{:}, 'bar1', 1);
which gives me foo.bar1 = 1 if true_false_statement is true, and foo.baz.bar1 = 1 otherwise.
Now I want to test for the existence of the field (for instance to pre-allocate an array). If I do this:
if ~isfield(foo, extra_levels{:}, 'bar1')
foo = setfield(foo, extra_level{:}, 'bar1', zeros(1,100));
end
I get an error because isfield will only accept two arguments.
The best I've been able to come up with is to write a separate function with a try...catch block.
function tf = isfield_dyn(structure_variable, intervening_levels, field)
try
getfield(structure_variable, intervening_levels{:}, field);
tf = true;
catch err
if strcmpi(err.identifier, 'MATLAB:nonExistentField')
tf = false;
else
rethrow(err);
end
end
As mentioned below in the comments, this is a hacky hack way to do this, and it doesn't even work all that well.
Is there a more elegant built-in way to do this, or some other more robust way to write a custom function to do this?
You might find the private utility functions getsubfield, setsubfield, rmsubfield, and issubfield from the FieldTrip toolbox very handy. From the documentation of getsubfield:
% GETSUBFIELD returns a field from a structure just like the standard
% GETFIELD function, except that you can also specify nested fields
% using a '.' in the fieldname. The nesting can be arbitrary deep.
%
% Use as
% f = getsubfield(s, 'fieldname')
% or as
% f = getsubfield(s, 'fieldname.subfieldname')
%
% See also GETFIELD, ISSUBFIELD, SETSUBFIELD
I am somewhat confused because
isfield(foo, 'bar1')
isfield(foo, 'baz')
seem to work just fine on your example struct.
Of course, if you want to test more fields, just write a loop over those fieldnames and test them one by one. That may not look vectorized, but is definitely better than abusing a try-catch block to guide your flow.

Use variable number of output while assigning to varargout

I'm making a generic subsref for my classA, which has an attribute attrA that is a classB instance.
So far, it's working, it lets me do things like
x = objA.attr1.methB(),
which was what I was trying to do to do in the first place.
function this = Class1(varargin)
this.attrA = ClassB()
this = class(this,'ClassA')
function this = ClassB()
this.AttrB1 = 'valueB1'
this.AttrB2 = 'valueB2'
function out = methB
out = this.AttrB2
The problem I stumbled upon is this:
when the call to a method is executed in my subsref, I do it like this (detecting that it's a method etc is done before):
methName = index(1).subs;
args = index(2).subs;
if iscell(args)
varargout = {feval(methName,this,args{:})};
else
varargout = {feval(methName,this,args)};
end %end if iscell
The problem is that when the methName method supports variable number of outputs, this varargout is not equivalent to [x,y,...] (the number of outputs should be assigned in the call to subsref, so methName always returns a single output, which is not always what I want (almost, but not always).
How would I let methName know how many outputs I want? (I don't want to have to pass N as a parameter).
I'm thinking something like creating a string str='[out1,out2,out3...]'
and then doing something like
eval([
str ...
'= {feval(methName,this,args{:})};'...
])
But I keep thinking there must be a more elegant way of doing it.
If the number of outputs you expect is dependent on the output arguments requested from your subsref, you can simply use nargout like this:
[varargout{1:nargout}] = feval(methName,this,args{:});
This solution worked, but I needed to add a little something for single outputs:
if iscell(args)
[argout{:}] = feval(methName,this,args{:});
else
[argout{:}]= {feval(methName,this,args)};
end %end if iscell`
if isSingleCell(argout) && iscell(argout{1})`
v = argout{1};
argout{1}=v{1};
end
I'm not sure, but it may be that the last bit was only necessary to fix something else ( I had to fix a lot of other things to make this work). I'll get back to it when I finish what I was trying to do with this class