4

I have a class that has a function handle as one of its properties.

classdef MyClass
    properties
        hfun %function handle 
    end

    methods
        function obj = Myclass(hfun,...)
            %PROBLEM: validate that the input argument hfun is the right kind of function
            if ~isa(hfun,'function_handle') || nargin(hfun)~=1 || nargout(hfun)~=1
                error('hfun must be a function handle with 1 input and 1 output');
            end
            obj.hfun = hfun;
        end
    end
end

I'd like to make sure that the input argument hfun is a function handle with 1 input and 1 output, otherwise it should error. If I could get even more specific I'd like this function to take an Nx3 array as an input argument and return an Nx3 array as the output argument.

The above code works for built-in functions like f = @sqrt but if I try to put in an anonymous function like f = @(x) x^(0.5), then nargout(hfun) is -1 because it treats anonymous functions as [varargout] = f(x). Furthermore if you input the handle to a class method like f = @obj.methodFun, then it converts the function to the form [varargout] = f(varargin) which returns -1 for both nargin and nargout.

Has anyone figured out a convenient way to validate a function handle as an input argument? Independent of what kind of function handle it's from?

chappjc
  • 30,359
  • 6
  • 75
  • 132
joshkarges
  • 111
  • 1
  • 7
  • You can use `functions` function to extract more info about the function handle. http://www.mathworks.se/help/matlab/ref/functions.html – Mohsen Nosratinia Sep 25 '13 at 20:49
  • What's the practical use for that? – Oleg Sep 25 '13 at 22:39
  • There's a couple uses I'd like to use it for. I'm writing an A* class which computes the shortest path on a node-edge graph, but I'd like to give the user the ability to customize the heuristic function instead of just using the default euclidean distance to the goal. Another use would be in my RRT class which implements the Rapidly-exploring Random Tree algorithm to build a node-edge graph. I'd like to give the user the ability to customize a motion constraint on the node expansion. The user would be able to input this motion constraint as a function handle. – joshkarges Sep 26 '13 at 02:30

2 Answers2

2

The closest I've come to validating the inputs and outputs of a function handle is inside a try/catch statement.

function bool = validateFunctionHandle(fn)
    %pass an example input into the function
    in = blahBlah; %exampleInput
    try
        out = fn(in);
    catch err
        err
        bool = false;
        return;
    end

    %check the output argument
    if size(out)==correctSize and class(out)==correctType
        bool=true;
    else
        bool=false;
    end
end
joshkarges
  • 111
  • 1
  • 7
1

You can use class to tell whether a variable is a function handle but there is no easy way to validate the type of input and output because MATLAB is loosely typed and a variable can contain anything so long as it can figure out how to interpret the commands at runtime. As Mohsen pointed out, you can also functions to get more info but it won't help you too much.

Here is the closest I think you can get:

fn = @(x,y) x + x*2

if strcmpi(class(fn), 'function_handle')
    functionInfo = functions(fn)
    numInputs =  nargin(fn)
    numOutputs = nargout(fn)
end

If speed is not an issue, you could create a class with member functions run that runs the function and geInfo that returns whatever details you need. Then you always pass a class to you function that will have the info built into it. However, this will be slow and inconvenient.

Steve
  • 3,957
  • 2
  • 26
  • 50
  • I can use `isa(fn,'function_handle')` to detect if it's a function handle, but the `nargin` and `nargout` are variable depending on whether the function is builtin, class method, anonymous, etc. The `functions(fn)` command gives the name, type, and file but it doesn't say anything about the input/output arguments. – joshkarges Sep 26 '13 at 02:40