How does function work regarding to the memory usage? - matlab

When you are using function in MATLAB you have just the output of the function in the work space and all the other variables that maybe created or used in the body of that function are not shown. I am wondering how does function work? Does it clear all other variables from memory and just save the output?

function acts like a small, isolated programming environment. At the front end you insert your input (e.g. variables, strings, name-value pairs etc). After the function has finished, only the output is available, discarding all temporarily created variables.
function [SUM] = MySum(A)
for ii = 1:length(A)-1
SUM(ii) = A(ii)+A(ii+1);
kk(ii) = ii;
end
end
>> A=1:10
>> MySum(A)
This code just adds two consecutive values for the input array A. Note that the iteration number, stored in kk, is not output and is thus discarded after the function has completed. In MATLAB kk(ii) = ii; will be underlined orange, since it 'might be unused'.
Say you want to also retain kk, just add it to the function outputs:
function [SUM,kk] = MySum(A)
and keep the rest the same.
If you have large variables that you only use up to a certain point and wish them not clogging up your memory whilst the function is running, use clear for that:
function [SUM] = MySum(A)
for ii = 1:length(A)-1
SUM(ii) = A(ii)+A(ii+1);
kk(ii) = ii;
end
clear kk
end

Related

What does the code '[~, width ] = size(I);'mean?I can't undestand '~'especially [duplicate]

Is it possible to get the 'nth' return value from a function without having to create dummy variables for all n-1 return values before it?
Let's say, I have the following function in MATLAB:
function [a,b,c,d] = func()
a = 1;
b = 2;
c = 3;
d = 4;
Now suppose, I'm only interested in the third return value. This can be accomplished by creating one dummy variable:
[dummy, dummy, variableThatIWillUse, dummy] = func;
clear dummy;
But I think this is kind of ugly. I would think that you might be able to do something like one of the following things, but you can't:
[_, _, variableThatIWillUse, _] = func;
[, , variableThatIWillUse, ] = func;
variableThatIWillUse = func(3);
variableThatIWillUse = func()(3);
Are there any elegant ways to do this that do work?
So far, the best solution is to simply use the variableThatIWillUse as a dummy variable. This saves me from having to create a real dummy variable that pollutes the work-space (or that I would need to clear). In short: the solution is to use the variableThatIWillUse for every return value up until the interesting one. Return values after can simply be ignored:
[variableThatIWillUse, variableThatIWillUse, variableThatIWillUse] = func;
I still think this is very ugly code.
With MATLAB Version 7.9 (R2009b) you can use a ~, e.g.,
[~, ~, variableThatIWillUse] = myFunction();
Note that the , isn't optional. Just typing [~ ~ var] will not work, and will throw an error.
See the release notes for details.
This is somewhat of a hack, but it works:
First a quick example function:
Func3 = #() deal(1,2,3);
[a,b,c]=Func3();
% yields a=1, b=2, c=3
Now the key here is that if you use a variable twice on the left-hand side of a multiple-expression assignment, an earlier assignment is clobbered by the later assignment:
[b,b,c]=Func3();
% yields b=2, c=3
[c,c,c]=Func3();
% yields c=3
(Just to check, I also verified that this technique works with [mu,mu,mu]=polyfit(x,y,n) if all you care about from polyfit is the third argument.)
There's a better approach; see ManWithSleeve's answer instead.
If you wish to use a style where a variable will be left to fall into the bit bucket, then a reasonable alternative is
[ans, ans, variableThatIWillUse] = myfun(inputs);
ans is of course the default junk variable for MATLAB, getting overwritten often in the course of a session.
While I do like the new trick that MATLAB now allows, using a ~ to designate an ignored return variable, this is a problem for backwards compatibility, in that users of older releases will be unable to use your code.
I generally avoid using new things like that until at least a few MATLAB releases have been issued to ensure there will be very few users left in the lurch. For example, even now I find people are still using an old enough MATLAB release that they cannot use anonymous functions.
Here's another option you can use. First make a cell array to capture all the outputs (you can use the NARGOUT function to determine how many outputs a given function returns):
a = cell(1,3); % For capturing 3 outputs
% OR...
a = cell(1,nargout(#func)); % For capturing all outputs from "func"
Then call the function as follows:
[a{:}] = func();
Then simply remove the element from a that you want, and overwrite a:
a = a{3}; % Get the third output
I wrote a kth out function:
function kth = kthout(k, ffnc, varargin)
% kthout: take the kth varargout from a func call %FOLDUP
%
% kth = kthout(k, ffnc, varargin)
%
% input:
% k which varargout to get
% ffnc function to call;
% varargin passed to ffnc;
% output:
% kth the kth argout;
[outargs{1:k}] = feval(ffnc, varargin{:});
kth = outargs{k};
end %function
You can then call
val_i_want = kthout(3, #myfunc, func_input_1, func_input_2);
You could also wrap up the function like:
func_i_want = #(varargin)(kthout(3, #myfunc,varargin{:})); % Assuming you want the third output.
After which you use
val_i_want = func_i_want(func_input_1, func_input_2);
Note that there is overhead associated with using anonymous functions like this, and this is not something I would do in code that would be called thousands of times.
In MATLAB 2010a, I found a neat way of doing what you are asking for.
It is simply to use the character "~" (without the quotes of course) as your dummy variable (as many as you want when returning multiple parameters). This also works for input parameters to functions if the functions are designed to handle missing data.
I don't know if this existed in previous versions, but I just came across it recently.
You can make a function (or anonymous function) that only returns selected outputs, e.g.
select = #(a,b) a(b);
Then you can call your function like this:
select(func,2);
select(func,1:3);
Or you can assign the output to a variable:
output(1,2:4) = select(func,1:3);
I don't see any reason not to use ans(n). Like this:
size(rand([5 10 20 40]));
b = ans(2);
It gives b = 10, and this way would be compatible with all MATLAB versions. Note that size() here is just used to represent any function that has multiple return variables.
Furthermore, this works to get the second output argument when you don't know how many arguments there will be! Whereas, if you do this:
[~, b] = size(a);
Then b = 8000! (You need to end with ~, to catch more arguments!)

can a matlab function detect if it has been called with semicolon [duplicate]

In a Matlab script I call a user-defined function (m-function). My function returns a value while printing the value to the command window using disp and/or fprintf calls.
When writing an expression or a statement, one puts ; at its end to suppress printing. When the expression calls my function, the ; can suppress the printing of the returned value. However, this does not effect the disp output from within the function called.
I want to eliminate the display output of the function when appropriate. Is there a way to determine whether a function call was made in an expression ending with ;?
I like the spirit of what you're trying to do, but I think that it probably goes against the common programming patterns in Matlab. As you correctly state, the purpose of the terminating semicolon is to supress printing of returned values. Trying to get it to incorporate your other feature might well require some deep hacking and ugly hard-to-maintain code. The standard way to implement what you describe is via property name-value pair arguments. For example, Matlab's optimization suite has a property called 'Display' that can be set to various values to indicate the desired level of verbosity (see optimset).
If you want to try looking for a way to check for terminating semicolons, you might look into the undocumented mint, mlintmex, and mtree functions – read more here. Unfortunately, using mlint to simply check for the "Terminate statement with semicolon to suppress output" warning (see this function on the MatlabCental File Exchange) won't work in all cases as a function call by itself doesn't produce this warning.
Update
Here's an attempt at code that could be inserted into a called function to determine if the line of the caller is terminated by a semicolon. You should be aware that this has not been thoroughly tested and is likely very fragile. I have not tested it with sub-functions or anonymous functions and I know that it fails if you wrap a line over multiple lines using ....
st = dbstack('-completenames'); % M-file of caller and line number
caller = st(2);
str = mlint('-lex',caller.file); % Struct containing parsed data
isSemicolon = false; % Assume no semicolon
for i = 1:length(str)
% Find end-of-line corresponding to function call
c = strsplit(str(i).message,'/');
if str2double(c{1}) == caller.line && strcmp(c{2}(end-5:end-1),'<EOL>')
% Check for comments
j = i-1;
if ~isempty(strfind(str(j).message,'%'))
j = j-1;
end
% Check for semicolon
if strcmp(str(j).message(end-2),';')
isSemicolon = true; % Semicolon found
break;
end
end
end
In other words, play around with this to learn, but I would not recommend actually using it.
I'm afraid that the answer to your question is no. That information is simply not passed on to the function being called.
You shouldn't think about adding the semicolon as a means to "suppress printing", but rather that the lack of a semicolon instructs MATLAB to call the display function on the output variables of the function call. In other words, MATLAB interprets this code:
y = myFunc(x)
as:
y = myFunc(x);
display(y);
I think adding a 'print' or 'verbose' parameter to your function is your best bet for achieving what you want.
I think the simplest method to achieve the results you want (i.e. whether or not disp's get displayed) is to add an extra function input or output. For example, adding an input (optional, you can set default behaviour):
function y=myFunc(a,displayResults)
if nargin==1
displayResults=true; %// set the default behaviour
end
%// if you want to print something
if displayResults
disp(a)
end
end
Or an extra output. In this case foo produces no output to the screen, but all the messages are saved into a cell array, which can be accessed if desired:
function [x,m] = foo(a)
m={}; %// initialise cell array of output messages
x=a;
m{length(m)+1}=a; %// some message
m{length(m)+1}='another message'; %// another message
end
I think the first option will be better, the second will not deal with fprintf well, and displaying elements of m could be tricky depending on what it contains. The first method is very simple, and does not even require you to change existing code, as you can make the displayResults input optional and set the default to be what you want.
You may suppress disp outputs by locally redefining it at the beginning of the function:
function [] = hideDisplay()
%[
% Override `disp` behavior
disp = #(x)doNothing;
% Next `disp` calls will no longer appear in matlab console
disp('Hello')
disp('World!')
%]
end
%% ---
function [] = doNothing()
%[
%]
end
Here's a possible workaround (to be clear - this is not a real answer to the question per-se, just a way to avoid the unwanted behaviour). Say my function is:
function y = prt_test(x)
y = x + 1;
disp('IN PRT_TEST')
end
Calling:
>> % Regular use - message and output are displayed:
>> y = prt_test(1)
IN PRT_TEST
y =
2
>> % Regular use w/ ";" - only message is displayed:
>> y = prt_test(2);
IN PRT_TEST
>> % Use "evalc()" - message and output are displayed:
>> evalc('y = prt_test(3)')
ans =
IN PRT_TEST
y =
4
>> % Use "evalc()" w/ func ";" - only message is displayed:
>> evalc('y = prt_test(4);')
ans =
IN PRT_TEST
>> % Use "evalc();" - no output:
>> evalc('y = prt_test(5)');
>> % Use "evalc();" w/ func ";" - no output:
>> evalc('y = prt_test(6);');
>>

Looping a Function in Matlab

total newbie here. I'm having problems looping a function that I've created. I'm having some problems copying the code over but I'll give a general idea of it:
function[X]=Test(A,B,C,D)
other parts of the code
.
.
.
X = linsolve(K,L)
end
where K,L are other matrices I derived from the 4 variables A,B,C,D
The problem is whenever I execute the function Test(1,2,3,4), I can only get one answer out. I'm trying to loop this process for one variable, keep the other 3 variables constant.
For example, I want to get answers for A = 1:10, while B = 2, C = 3, D = 4
I've tried the following method and they did not work:
Function[X] = Test(A,B,C,D)
for A = 1:10
other parts of the code...
X=linsolve(K,L)
end
Whenever I keyed in the command Test(1,2,3,4), it only gave me the output of Test(10,2,3,4)
Then I read somewhere that you have to call the function from somewhere else, so I edited the Test function to be Function[X] = Test(B,C,D) and left A out where it can be assigned in another script eg:
global A
for A = 1:10
Test(A,2,3,4)
end
But this gives an error as well, as Test function requires A to be defined. As such I'm a little lost and can't seem to find any information on how can this be done. Would appreciate all the help I can get.
Cheers guys
I think this is what you're looking for:
A=1:10; B=2; C=3; D=4;
%Do pre-allocation for X according to the dimensions of your output
for iter = 1:length(A)
X(:,:,iter)= Test(A(iter),B,C,D);
end
X
where
function [X]=Test(A,B,C,D)
%other parts of the code
X = linsolve(K,L)
end
Try this:
function X = Test(A,B,C,D)
% allocate output (it is faster than changing the size in every loop)
X = {};
% loop for each position in A
for i = 1:numel(A);
%in the other parts you have to use A(i) instead of just A
... other parts of code
%overwrite the value in X at position i
X{i} = linsolve(K,L);
end
end
and run it with Test(1:10,2,3,4)
To answer what went wrong before:
When you loop with 'for A=1:10' you overwrite the A that was passed to the function (so the function will ignore the A that you passed it) and in each loop you overwrite the X calculated in the previous loop (that is why you can only see the answer for A=10).
The second try should work if you have created a file named Test.m with the function X = (A,B,C,D) as the first code in the file. Although the global assignment is unnecessary. In fact I would strongly recommend you not to use global variables as it gets very messy very fast.

MATLAB Return value of first non-empty argument (built-in COALESCE function)

Is there something inbuilt in MATLAB which functions similar to the SQL COALESCE function. I want that function to return the first 'existing' value from all the arguments.
For example,
clear A B; C=10; COALESCE(A,B,C)
should return value of C (because A and B are unassigned/don't exist).
I know it would be very easy to code, and I am just being lazy here. But, I would be surprised if MATLAB doesn't have a similar function.
As far as I know there is no built-in function for that. But you can easily write your own.
Note that it is not possible in Matlab to pass a variable that has not been defined prior of using it. Therefore your proposed call clear A B; C=10; COALESCE(A,B,C) is invalid and will throw an error. Instead we can define an empty variable using var=[].
The following code creates two empty variables A, B and and assigns C=10. Inside the function coalesce we assume at the beginning that all variables are empty. In the for-loop we return the first non-empty variable. In the version without for-loop we get the index of the first non-zero element and then return the corresponding content of the cell if a non-zero element exists.
If you want the function to be accessible from everywhere within Matlab, see the documentation here.
function testcoalesce
A = [];
B = [];
C = 10;
COALESCE(A,B)
COALESCE(A,B,C)
end
% with for-loop (much faster)
function out = COALESCE(varargin)
out = [];
for i = 1:length(varargin)
if ~isempty(varargin{i})
out = varargin{i};
return;
end
end
end
% without for-loop (slower)
function out = COALESCE(varargin)
out = [];
ind = find(cellfun('isempty', varargin)==0, 1);
if ~isempty(ind);
out = varargin{ind};
end
end
The output is as expected:
ans =
[]
ans =
10
Timing the two functions showed, that the first solution using the for-loop is approximately 48% faster than the function without loop.
(10 samples, 1'000'000 iterations, 3 variables & 20 variables)

How to elegantly ignore some return values of a MATLAB function

Is it possible to get the 'nth' return value from a function without having to create dummy variables for all n-1 return values before it?
Let's say, I have the following function in MATLAB:
function [a,b,c,d] = func()
a = 1;
b = 2;
c = 3;
d = 4;
Now suppose, I'm only interested in the third return value. This can be accomplished by creating one dummy variable:
[dummy, dummy, variableThatIWillUse, dummy] = func;
clear dummy;
But I think this is kind of ugly. I would think that you might be able to do something like one of the following things, but you can't:
[_, _, variableThatIWillUse, _] = func;
[, , variableThatIWillUse, ] = func;
variableThatIWillUse = func(3);
variableThatIWillUse = func()(3);
Are there any elegant ways to do this that do work?
So far, the best solution is to simply use the variableThatIWillUse as a dummy variable. This saves me from having to create a real dummy variable that pollutes the work-space (or that I would need to clear). In short: the solution is to use the variableThatIWillUse for every return value up until the interesting one. Return values after can simply be ignored:
[variableThatIWillUse, variableThatIWillUse, variableThatIWillUse] = func;
I still think this is very ugly code.
With MATLAB Version 7.9 (R2009b) you can use a ~, e.g.,
[~, ~, variableThatIWillUse] = myFunction();
Note that the , isn't optional. Just typing [~ ~ var] will not work, and will throw an error.
See the release notes for details.
This is somewhat of a hack, but it works:
First a quick example function:
Func3 = #() deal(1,2,3);
[a,b,c]=Func3();
% yields a=1, b=2, c=3
Now the key here is that if you use a variable twice on the left-hand side of a multiple-expression assignment, an earlier assignment is clobbered by the later assignment:
[b,b,c]=Func3();
% yields b=2, c=3
[c,c,c]=Func3();
% yields c=3
(Just to check, I also verified that this technique works with [mu,mu,mu]=polyfit(x,y,n) if all you care about from polyfit is the third argument.)
There's a better approach; see ManWithSleeve's answer instead.
If you wish to use a style where a variable will be left to fall into the bit bucket, then a reasonable alternative is
[ans, ans, variableThatIWillUse] = myfun(inputs);
ans is of course the default junk variable for MATLAB, getting overwritten often in the course of a session.
While I do like the new trick that MATLAB now allows, using a ~ to designate an ignored return variable, this is a problem for backwards compatibility, in that users of older releases will be unable to use your code.
I generally avoid using new things like that until at least a few MATLAB releases have been issued to ensure there will be very few users left in the lurch. For example, even now I find people are still using an old enough MATLAB release that they cannot use anonymous functions.
Here's another option you can use. First make a cell array to capture all the outputs (you can use the NARGOUT function to determine how many outputs a given function returns):
a = cell(1,3); % For capturing 3 outputs
% OR...
a = cell(1,nargout(#func)); % For capturing all outputs from "func"
Then call the function as follows:
[a{:}] = func();
Then simply remove the element from a that you want, and overwrite a:
a = a{3}; % Get the third output
I wrote a kth out function:
function kth = kthout(k, ffnc, varargin)
% kthout: take the kth varargout from a func call %FOLDUP
%
% kth = kthout(k, ffnc, varargin)
%
% input:
% k which varargout to get
% ffnc function to call;
% varargin passed to ffnc;
% output:
% kth the kth argout;
[outargs{1:k}] = feval(ffnc, varargin{:});
kth = outargs{k};
end %function
You can then call
val_i_want = kthout(3, #myfunc, func_input_1, func_input_2);
You could also wrap up the function like:
func_i_want = #(varargin)(kthout(3, #myfunc,varargin{:})); % Assuming you want the third output.
After which you use
val_i_want = func_i_want(func_input_1, func_input_2);
Note that there is overhead associated with using anonymous functions like this, and this is not something I would do in code that would be called thousands of times.
In MATLAB 2010a, I found a neat way of doing what you are asking for.
It is simply to use the character "~" (without the quotes of course) as your dummy variable (as many as you want when returning multiple parameters). This also works for input parameters to functions if the functions are designed to handle missing data.
I don't know if this existed in previous versions, but I just came across it recently.
You can make a function (or anonymous function) that only returns selected outputs, e.g.
select = #(a,b) a(b);
Then you can call your function like this:
select(func,2);
select(func,1:3);
Or you can assign the output to a variable:
output(1,2:4) = select(func,1:3);
I don't see any reason not to use ans(n). Like this:
size(rand([5 10 20 40]));
b = ans(2);
It gives b = 10, and this way would be compatible with all MATLAB versions. Note that size() here is just used to represent any function that has multiple return variables.
Furthermore, this works to get the second output argument when you don't know how many arguments there will be! Whereas, if you do this:
[~, b] = size(a);
Then b = 8000! (You need to end with ~, to catch more arguments!)