Search code examples
matlabequation-solvingfunction-handle

Operations with function handle in matlab


Could you please help me with the following issue: I have the following function handle:

r1 = @(lambda) b + lambda*(r - b); % r and b are vectors of return data

I want to find the optimal lambdas that set me a mean function to zero, for a given set of powers within that function. What I tried to do and didn't work, as it returns me an error for undefined operators for input arguments of type 'function_handle' is:

lambda0 = 0.3;
for a = 2:10    %power coefficient
S1(a) = fzero(mean((r - b)*r1.^(1/(a - 1))),lambda0);
end

Any suggestion as to how to go about this problem is highly appreciated! Thank you in advance.


Solution

  • fzero accepts a function handle as the first input. As you currently have it, you're trying to pass a statement as the first input. This statement can't even be properly evaluated because you are trying to perform numerical operations on a function handle (more on this in a bit).

    You need to instead do something like this where we create a new function handle that evaluates the original function handle and performs the other operations you need.

    S1(a) = fzero(@(lambda)mean((r - b)*r1(lambda).^(1/(a - 1))),lambda0);
    

    Further Explanation

    Performing operations on a function handle is not the same as performing them on the result.

    So for example, if we had a function handle:

    func = @(x)2*x;
    

    If we evaluation this, by calling it with an input value for x

    func(2)
    
        4
    

    This works as we would expect. If now we really want the value (2*x)^2, we could try to write it the way that you wrote your statement in your question

    func2 = func^2;
    

    We will get an error!

    Undefined operator '^' for input arguments of type 'function_handle'.

    This does not work because MATLAB attempts to apply the ^ operation to the function handle itself and not the value of the evaluated function handle.

    Instead, we would need to create a new function handle that essentially wraps the other one and performs any additional options:

    func2 = @(x)func(x)^2;
    func2(2)
    
        16
    

    Bringing it Full-Circle

    So if we go back to your question, you defined your anonymous function r1 like this.

    r1 = @(lambda) b + lambda*(r - b); % r and b are vectors of return data
    

    This all looks great. You have one input argument and you reference r and b from the parent workspace.

    Now when you call fzero you try to perform operations on this function handle in hopes of creating a new function handle.

    mean((r - b)*r1.^(1/(a - 1)))
    

    Like we just showed this will result in a very similar error

    Undefined operator .^ for input arguments of type 'function_handle'

    So we need to wrap this into a new function.

    newfunc = @(lambda)mean((r - b)*r1(lambda).^(1 / (a - 1)));
    

    Now we can safely pass this to fzero.

    result = fzero(newfunc, lambda0);