Calling local functions from command line - matlab

I have a local function defined in an m-file. For example:
% begining of public_function.m file
function fh = public_function( )
%
% do some computation...
fh = #local_function; % return function handle to local function defined below
function y = local_function( x )
%
% a local function inside public_function.m file
%
% some manipulation on x
y = x;
% end of public_function.m file NOTE THAT local_function is NOT nested
Now, I would like to call local_function from command line (and not from public_function). I was able to do so using the function handle returned from public_function:
>> fh = public_function(); % got handle to local_function
>> y = fh( x ); % calling the local function from command line :-)
My question:
Is there any other way (apart from explicitly pass the function handle) to call local function from command line (or other m-file/functions)?
More precisely, I want a method to access any local function in a file (provided that I know its name). So, if I have public_function.m file (and function) and I know that local_function is local to that file, is there a way to access local_function from command line ?

The official documentation says that:
... you cannot call a local function from the command line or from functions in other files.
According to this, you must pass its handle to the caller in order to allow invoking it indirectly outside its m-file. I believe that there is no documented sensible way to access local functions otherwise.
Oddly though, you can still do this with help:
help public_function>local_function

Related

Calling sub-function (local function) from another file on Matlab

I'm trying to figure out how to properly call a sub function from another .m file. I've searched for documentation, and only found the way of using function handles (as can be seen here: https://www.mathworks.com/help/matlab/matlab_prog/call-local-functions-using-function-handles.html)
The thing is that I think I've managed to find a way to it without using function handles, and want to know what am i doing and how does it works:
on main.m file:
function main
%function main...
end
function z = sub_function(x,y)
%function sub_function...
end
on outside.m file:
function call_to_local_function_from_outside
z = main('sub_function', x,y);
end
Appernalty, this is working, but I need to know why?

deleting a huge matrix after passing its local copy to a function in Matlab

Considering we have a huge matrix called A and we pass it to the function func(A) wherein func I do a set of computations like:
func(A):
B=A;
%% a lot of processes will happen on B here
return B;
end
The fact is that as soon as I pass A to B I would not have anything to do with A anymore in my Matlab session so it takes an unnecessary space in memory. Is it possible to remove its instance in the scope of the script that called func?
Using evalin with the option caller you can evaluate expression clear A:
function A = func(A)
evalin('caller', 'clear A')
A(1) = 5;
end
However we usually don't know the name of the input variable so we can use inputname to get the actual name of the workspace variable:
function A = func(A)
name = inputname(1);
if ~isempty(name)
evalin('caller', ['clear ' name])
end
A(1)=4;
end
1.Here inputname(1) means the actual name of the first argument.
2.Work directly with A because if you copy A into B the function scope will have two copies of A.
If you write your function as
function A = func(A)
% Do lots of processing on A here
and call it as
A = func(A);
Then MATLAB will optimize it such that you work on A in-place, meaning that no copy is made. There is no need to delete A from the workspace.
This behavior is not expressly documented as far as I know, but it is well-known. See for example on Undocumented MATLAB, or on Loren's blog.

Undefined 'VARIABLE' error while defining a function in Octave [duplicate]

I got a problem with running Octave function (ODE), I've tried already present solutions for this problem but nothing is working. I've also tried by saving my filename as egzamin.m but it too not worked.
Code from octave :
function dx=egzamin(x,t)
dx=zeros(4,1);
b=0;
g=9.81;
x1=x(1);
y1=x(2);
Vx=x(3);
Vy=x(4);
dx(1)=Vx;
dx(2)=Vy;
dx(3)=-b*Vx*sqrt(Vx.^2+Vy.^2);
dx(4)=-b*Vy*sqrt(Vx.^2+Vy.^2)-g;
endfunction
N=mod(291813,100);
x1=0;
y1=0;
Vx=20+N;
Vy=20+N;
t=0:0.01:500;
sol=lsode("egzamin",[x1,y1,Vx,Vy],t);
plot(sol(:,1),sol(:,2))
The error is :
error: 'x' undefined near line 5 column 4
error: called from
egzamin at line 5 column 3
Since the file starts with function, it is not a script file,
as explained in the doc:
Unlike a function file, a script file must not begin with the keyword
function
Add any statement (even dummy like 1;) before the function line to get a script file.
# dummy statement to get a script file instead of a function file
1;
function dx=egzamin(x,t)
g = 9.81;
Vx = x(3);
Vy = x(4);
dx = [Vx, Vy, 0, -g];
endfunction
N=mod(291813,100);
x1=0;
y1=0;
Vx=20+N;
Vy=20+N;
t=0:0.01:500;
sol=lsode("egzamin",[x1,y1,Vx,Vy],t);
plot(sol(:,1),sol(:,2))
A very clear explanation of what's going on is given here.
You need to save the function (thus from function to endfunction and naught else) as egzamin.m, and then execute the rest of the code in a script or at the command line. Alternatively, provided Octave does that the same as what MATLAB does nowadays, first put your script (N=(..) to plot()) and then the function.
This is necessary since you are defining your function first, so it doesn't have any inputs yet, as you don't define them until later. The function needs to have its inputs defined before it executes, hence you need to save your function separately.
You can of course save your "script" bit, thus everything which is currently below your function declaration, as a function as well, simply don't give it in- and outputs, or, set all the input parameters here as well. (Which I wouldn't do as it's the same as your
egzamin then.) e.g.
function []=MyFunc()
N=mod(291813,100);
x1=0;
y1=0;
Vx=20+N;
Vy=20+N;
t=0:0.01:500;
sol=lsode("egzamin",[x1,y1,Vx,Vy],t);
plot(sol(:,1),sol(:,2))
endfunction

How to wrap an already existing function with a new function of the same name

Is it possible to create a wrapper around a function that has the exact same name as the original function?
This would be very useful in circumstances where the user wants to do some additional checks on input variables before they are passed on to the built in function How to interrupt MATLAB IDE when it hangs on displaying very large array?
Actually alternatively to slayton's answer you don't need to use openvar. If you define a function with the same name as a matlab function, it will shadow that function (i.e. be called instead).
To then avoid recursively calling your own function, you can call the original function from within the wrapper by using builtin.
e.g.
outputs = builtin(funcname, inputs..);
Simple example, named rand.m and in the matlab path:
function out = main(varargin)
disp('Test wrapping rand... calling rand now...');
out = builtin('rand', varargin{:});
Note that this only works for functions that are found by builtin. For those that are not, slayton's approach is likely necessary.
Yes this is possible but it requires a bit of hacking. It requires that you copy around some function handles.
Using the example provided in the question I will show how to wrap the function openvar in a user defined function that checks the size of the input variable and then allows the user to cancel any open operation for variables that are too large.
Additionally, this should work when the user double clicks a variable in the Workspace pane of the Matlab IDE.
We need to do three things.
Get a handle to the original openvar function
Define the wrapper function that calls openvar
Redirect the original openvar name to our new function.
Example Function
function openVarWrapper(x, vector)
maxVarSize = 10000;
%declare the global variable
persistent openVarHandle;
%if the variable is empty then make the link to the original openvar
if isempty(openVarHandle)
openVarHandle = #openvar;
end
%no variable name passed, call was to setup connection
if narargin==0
return;
end
%get a copy of the original variable to check its size
tmpVar = evalin('base', x);
%if the variable is big and the user doesn't click yes then return
if prod( size( tmpVar)) > maxVarSize
resp = questdlg(sprintf('Variable %s is very large, open anyway?', x));
if ~strcmp(resp, 'Yes')
return;
end
end
if ischar(x) && ~isempty(openVarHandle);
openVarHandle(x);
end
end
Once this function is defined then you simply need to execute a script that
Clears any variables named openvar
run the openVarWrapper script to setup the connection
point the original openVar to openVarWrapper
Example Script:
clear openvar;
openVarWrapper;
openvar = #openVarWrapper;
Finally when you want to clean everything up you can simply call:
clear openvar;
I prefer jmetz's approach using builtin() when it can be applied, because it is clean and to the point. Unfortunately, many many functions are not found by builtin().
I found that I was able to wrap a function using a combination of the which -all and cd commands. I suspect that this approach can be adapted to a wide variety of applications.
In my example case, I wanted to (temporarily) wrap the interp1 function so that I could check for NaN output values. (The interp1 function will, by default, return a NaN under some conditions, such as if a query point is larger than the largest sample point.) Here's what I came up with:
function Vq = interp1(varargin)
persistent interp1_builtin;
if (isempty(interp1_builtin)) % first call: handle not set
toolbox = 'polyfun';
% get a list of all known instances of the function, and then
% select the first such instance that contains the toolbox name
% in its path
which_list = which('interp1','-all');
for ii = 1:length(which_list)
if (strfind(which_list{ii}, [filesep, toolbox, filesep]))
base_path = fileparts(which_list{ii}); % path to the original function
current_path = pwd;
cd(base_path); % go to the original function's directory
interp1_builtin = #interp1; % create a function handle to the original function
cd(current_path); % go back to the working directory
break
end
end
end
Vq = interp1_builtin(varargin{:}); % call the original function
% test if the output was NaN, and print a message
if (any(isnan(Vq)))
dbstack;
disp('ERROR: interp1 returned a NaN');
keyboard
end
end
See also: How to use MATLAB toolbox function which has the same name of a user defined function

What is a function handle and how is it useful?

Can somebody explain to me the meaning of the # (function handle) operator and why to use it?
The function handle operator in MATLAB acts essentially like a pointer to a specific instance of a function. Some of the other answers have discussed a few of its uses, but I'll add another use here that I often have for it: maintaining access to functions that are no longer "in scope".
For example, the following function initializes a value count, and then returns a function handle to a nested function increment:
function fHandle = start_counting(count)
disp(count);
fHandle = #increment;
function increment
count = count+1;
disp(count);
end
end
Since the function increment is a nested function, it can only be used within the function start_counting (i.e. the workspace of start_counting is its "scope"). However, by returning a handle to the function increment, I can still use it outside of start_counting, and it still retains access to the variables in the workspace of start_counting! That allows me to do this:
>> fh = start_counting(3); % Initialize count to 3 and return handle
3
>> fh(); % Invoke increment function using its handle
4
>> fh();
5
Notice how we can keep incrementing count even though we are outside of the function start_counting. But you can do something even more interesting by calling start_counting again with a different number and storing the function handle in another variable:
>> fh2 = start_counting(-4);
-4
>> fh2();
-3
>> fh2();
-2
>> fh(); % Invoke the first handle to increment
6
>> fh2(); % Invoke the second handle to increment
-1
Notice that these two different counters operate independently. The function handles fh and fh2 point to different instances of the function increment with different workspaces containing unique values for count.
In addition to the above, using function handles in conjunction with nested functions can also help streamline GUI design, as I illustrate in this other SO post.
Function handles are an extremely powerful tool in matlab. A good start is to read the online help, which will give you far more than I can. At the command prompt, type
doc function_handle
A function handle is a simple way to create a function in one line. For example, suppose I wished to numerically integrate the function sin(k*x), where k has some fixed, external value. I could use an inline function, but a function handle is much neater. Define a function
k = 2;
fofx = #(x) sin(x*k);
See that I can now evaluate the function fofx at the command line. MATLAB knows what k is, so we can use fofx as a function now.
fofx(0.3)
ans =
0.564642473395035
In fact, we can pass fofx around, effectively as a variable. For example, lets call quad to do the numerical integration. I'll pick the interval [0,pi/2].
quad(fofx,0,pi/2)
ans =
0.999999998199215
As you can see, quad did the numerical integration. (By the way, an inline function would have been at least an order of magitude slower, and far less easy to work with.)
x = linspace(0,pi,1000);
tic,y = fofx(x);toc
Elapsed time is 0.000493 seconds.
By way of comparison, try an inline function.
finline = inline('sin(x*k)','x','k');
tic,y = finline(x,2);toc
Elapsed time is 0.002546 seconds.
A neat thing about a function handle is you can define it on the fly. Minimize the function cos(x), over the interval [0,2*pi]?
xmin = fminbnd(#(x) cos(x),0,2*pi)
xmin =
3.14159265358979
There are many, many other uses for function handles in MATLAB. I've only scratched the surface here.
Disclaimer: code not tested...
The function handle operator allows you to create a reference to a function and pass it around just like any other variable:
% function to add two numbers
function total = add(first, second)
total = first + second;
end
% this variable now points to the add function
operation = #add;
Once you've got a function handle, you can invoke it just like a regular function:
operation(10, 20); % returns 30
One nice thing about function handles is that you can pass them around just like any other data, so you can write functions that act on other functions. This often allows you to easily separate out business logic:
% prints hello
function sayHello
disp('hello world!');
end
% does something five times
function doFiveTimes(thingToDo)
for idx = 1 : 5
thingToDo();
end
end
% now I can say hello five times easily:
doFiveTimes(#sayHello);
% if there's something else I want to do five times, I don't have to write
% the five times logic again, only the operation itself:
function sayCheese
disp('Cheese');
end
doFiveTimes(#sayCheese);
% I don't even need to explicitly declare a function - this is an
% anonymous function:
doFiveTimes(#() disp('do something else'));
The Matlab documentation has a fuller description of the Matlab syntax, and describes some other uses for function handles like graphics callbacks.