Is it possible to have a recursive anonymous function in MATLAB? [duplicate]
Asked Answered
K

1

3

I repeatedly want to apply a function, using a past output as the new input. For readability (I'm writing from a mathematics perspective, not a programmer's perspective), I would like to define it as a simple anonymous function instead of a full function block. So, instead of something like

function f=myfun(x,n)
    if n>1
        f=myfun(myfun(x,n-1),1);
    else
        f=expression(x);
    end
end

I would like to be able to write

f=@(x,n) ????

Is there any way this is possible?

Keystone answered 30/3, 2016 at 13:42 Comment(1)
You can but I doubt you want to. Have a look at Loren Shure's article on functional programming using anonymous functions particularly at the "inline conditionals" section.Megathere
I
9

The only way to have a recursive anonymous function in MATLAB is to pass the function handle to itself as an input. You can then call it from within the anonymous function.

%// The first input f is going to be an anonymous function
myfun = @(f,x,n) f(f, x, n+1);

%// Then use your anonymous function like this (note the first input)
out = myfun(myfun, x, n);

This will obviously result in infinite recursion since you don't have any branching logic. If you want to simulate the branching logic, you would need to implement another anonymous function to do this (iif function borrowed from here):

%// Anonymous function to simulate if/elseif/else
iif = @(varargin) varargin{2*find([varargin{1:2:end}], 1, 'first')}();

%// Your anonymous function that is recursive AND has branching
myfun = @(f,x,n)iif(n > 1, ...                      % if n > 1
                    @()f(f, f(f, x, n-1), 1), ...   % Recurse
                    true, ...                       % else
                    @()expression(x));              % Execute expression()

There is a really solid series of blog entries on the Mathworks site that goes over this sort of functional programming using anonymous functions.

A Word of Caution

While this is an interesting exercise, I definitely wouldn't recommend using this if you want anybody to understand your code easily. It is far clearer and easier to debug a standard function. Then if you really need an anonymous function, wrap the call to that function in an anonymous function.

myanonfunc = @(varargin)myfunc(varargin{:});

Or just create a function handle to the function

myfunchandle = @myfunc;
Indulgence answered 30/3, 2016 at 13:45 Comment(4)
@sanchises The only way I know of to perform branching logic is the second way. I definitely would discourage doing this sort of functional programming in MATLAB and would stick to standard functions as it definitely hurts readability. The blog entries are definitely an interesting read though.Indulgence
Yes they are - thanks a lot, and I will not use it for what I'm currently doing but it's certainly worth considering for other projects.Keystone
@sanchises I have updated it. There was a small bug but it should now duplicate the output of your original function.Indulgence
I used your answer over at ppcg: codegolf.stackexchange.com/a/137547/32352, it was possibly to golf this down quite a bit :)Keystone

© 2022 - 2024 — McMap. All rights reserved.