Loren on the Art of MATLABTurn ideas into MATLAB

This is machine translation

Translated by
Mouseover text to see original. Click the button below to return to the Original version of the page.

How to Suppress Function Output9

Posted by Loren Shure,

You may have noticed that we have some functions that return no output if none is requested, and yet some functions always return something, even if not asked. What's a good way to achieve this in MATLAB?

I do want to point out that while we used to use this programming pattern more often, we have tended to back away from it more recently. For example, you may notice we have two functions for histograms, histogram and histcounts; one for the graphics and one for the computation.

Contents

Example

The function stairs is a prime example.

Compare

array = randperm(50);
stairs(array)


with this

s = stairs(array)
%
% You can see that in each case, we get a plot. Only when we ask explicitly
% for an output do we receive one.

s =
Stair with properties:

Color: [0 0.4470 0.7410]
LineStyle: '-'
LineWidth: 0.5000
Marker: 'none'
MarkerSize: 6
MarkerFaceColor: 'none'
XData: [1×50 double]
YData: [1×50 double]

Use GET to show all properties


Coding Possibility One

In this example, you will see code written the way we used to (and perhaps still do) in MATLAB when we want to return no outputs when called without any output arguments, i.e., when nargout == 0

  function y = attempt1(x)
yy = sin(x);
if nargout > 0 % OR if nargout
y = yy;
end
end

In this case, it's pretty simple. If we want an output, at the end we simply copy the output to the variable with the right output name. If we have many possible output variables, we still need to treat only the first output variable specially.

  function [y,z1,z2,z3] = attempt1a(x)
yy = sin(x);
z1 = yy*17;
z2 = yy+17;
z3 = yy^17;
if nargout > 0 % OR if nargout
y = yy;
end
end

Coding Possibility Two

In the second scheme, we write the code with the variable names we want, and then clearvars either just the entire local workspace, or, if we prefer, just the first one, like above.

  function y = attempt2(x)
y = sin(x);
if ~nargout % if nargout == 0
clearvars % or simply clearvars y
end
end

While I hate using functions or commands like clear in function code, I think in this use case, it's okay. When it is NOT okay is when you are trying to coerce the operating system to give up memory. Since MATLAB calls the OS to manage memory, MATLAB is not in control of the timing when the memory it releases actually is available again outside MATLAB. Another technique for clearing memory that's no longer needed is to set the variable(s) whose memory you want reduced to the empty array, e.g., myvar = [].

Do You Have a Preference? Which code pattern to you prefer? Why? Let us know here.

Get the MATLAB code

Published with MATLAB® R2019a

クリストフ テア replied on : 1 of 9
I prefer the first one, as you wrote I do not like using clear command even if it is OK in this case. In the first possibility, will the memory used by the local variable be released when exiting the function ?
Marcelo Avila replied on : 2 of 9
Hi, Loren, Very interesting your post, I did not know that is necessary to treat just the first output argument in order to suppress all the others. And about the "clear" command, there is a situation that using it is the only solution that I've already found. I use it in callbacks of Simulink blocks to clear variables that I do not want that appear in Matlab Workspace. If there is another possibility, I would like to know. Thank you
Loren Shure replied on : 3 of 9
@Marcelo- Since Simulink works in the base workspace of MATLAB, you have to clear what you don't want, I believe. @クリストフ テア, MATLAB will clear the variables when exiting the function, but the memory may still not get back to the OS immediately. Again, the OS manages the memory movements. --loren
Robert Kagy replied on : 4 of 9
I've always used a third method:
  function varargout = attempt3(x)
y = sin(x);
if nargout > 0 % OR if nargout
varargout = {y};
end
end

I like this because it is clear in the function header an output may not be provided, and clear that it wasn't an accident the output wasn't defined. Is varargout out of favor because it doesn't allow the outputs to be named? Sometimes that is good, if the kind of output returned by the function varies with the input. This has been most useful when the first input is a sub-command.
Rob replied on : 5 of 9
So I do use clear in my functions when I'm done with a variable. It's less about a memory issue for me, and more to avoid me accidentally using that variable later in the function (usually by typo) when I don't intend to. If I've cleared it and I try to use that variable later, then Matlab errors - alerting me that I'm an idiot. If I haven't cleared it and typo it later, then I wouldn't get an error and I may not notice. Just my \$0.02.
Loren Shure replied on : 6 of 9
@Robert Kagy- You can use varargout, but since it's less explicit, it can be less helpful to the code reader later. But it's not out of favor. I wonder what you mean by sub-command? @Rob- Interesting use of clear in the function. Thanks for letting me know. Is the accidental reuse something you found was happening frequently? --loren
Daniel Dolan replied on : 7 of 9
I also prefer Robert Kagy's third method, particularly when the behavior of the function depends on the number of *outputs*. The size command is a good example:
x=rand(3,2);
L=size(x);
[L1,L2]=size(x);

The first call returns a 1x2 array, while the second call returns two 1x1 arrays. My use of varargout has steadily increased, even in simple cases. When the user doesn't explicitly ask for an output, many of my functions will print a formatted result in the command window rather than passing something back to ans.
Rob Wilson replied on : 8 of 9
@Loren. So occasionally in the past I've typo'ed a variable name to another one that previously existed - so my code ran, but I got odd results... took me a long while to debug. I'm way more paranoid now. By clearing the variables as I go there are a few benefits for me and my debugging: 1) I'm less likely to typo something that happens to match a pre-existing variable name without realizing (and if I do typo a non-existent variable name then Matlab gives me an error when I run - which makes it obvious what I've done.) 2) When debugging (for fixing bugs or just speeding up code) by using breakpoints in the code to investigate sections of the code, then when I stop there are simply less variables in my Workspace to keep track of, or see if they really are the right size or correct cast. Fewer listed variables is simply less confusing than a massive list of variables. 3) Much as in #2, I often use code sections (the %% line in my m-file) as I create new m-files and run the code sections one by one to test the code as I go. At the end of each code section I clear all variables that aren't needed in later code sections - again just to keep my workspace tidy and obvious to see what's what with fewer variables.
Loren Shure replied on : 9 of 9
@Rob, Daniel, I also like varargout. Note, if you use varargin, you can't get nice help hints from MATLAB.