Recursive Anonymous Function Matlab

后端 未结 1 2030
囚心锁ツ
囚心锁ツ 2020-11-27 22:20

I know that this is not what anonymous functions are made for, but just as a puzzle I tried to make a recursive function via anonymous functions. The prototype of recursive

相关标签:
1条回答
  • 2020-11-27 22:41

    We found two possibilites now, both rely on the use of cell arrays. Note that this might not work in Octave.

    The key was an implementation of a case distinction. The first one that I found, can be found here.

    This method makes use of matlabs boolean values, true can be evaluated as 1 while false can be evaluated as 0.

    if_ = @( pred_, cond_ ) cond_{ 2 - pred_ }();
    

    Here we have to provide a condition as first argument, and a 2 element cell array as second argument. Each cell element should be a function handle that is called if the condition is true/not true. Our factorial function would look like this:

    fac = @(n,f)if_(n>1,{@()n*f(n-1,f),@()1})
    factorial_=@(n)fac(n,fac);
    factorial_(10)
    

    As @AndrasDeak commented below: The important part here is that we have a cell array of functions and not of values. This provides the short circuiting, as n*f(n-1,f) is not evaluated unless we call the corresponding function @()n*f(n-1,f).

    The second method was found by @beaker and is somewhat more flexible:

    iif = @(varargin) varargin{2*find([varargin{1:2:end}], 1, 'first')}();
    

    This makes use of the fact that you can use varargin (variable amount of arguments) even in anonymous functions. When you call this function you have to alternate conditions and what should be executed if the condition is true. This one even allows a switch construct, or a if ... else if ... else if ... (...) else ... construct. When called, it will look for the first condition that is true ( find([varargin{1:2:end}], 1, 'first') ) and call the corresponding function. Our example of the factorial function looks like this:

    fac = @(n,f)iif(n>1,@()n * f(n-1,f),true,@()1);
    factorial_=@(n)fac(n,fac);
    factorial_(10)
    

    EDIT: Fun fact: What we are doing with the line

     factorial_=@(n)fac(n,fac);
    

    is also known as applying the Y-combinator. In fact we can write that as

     Y = @(f)@(x)f(x,f);
     factorial_=Y(f);
    
    0 讨论(0)
提交回复
热议问题