递归匿名函数Matlab [英] Recursive Anonymous Function Matlab

查看:84
本文介绍了递归匿名函数Matlab的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这不是为匿名函数创建的,但就像一个难题,我试图通过匿名函数创建递归函数.递归函数的原型显然是阶乘函数.问题在于,很难在匿名函数的内部中进行区分大小写.到目前为止,我设法做到的是:

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 functions obviously is the factorial function. The problem is that it is difficult to make a case distinction within the anonymous functions. What I managed to do so far is following:

f=@(cn,n,f)eval('if n>1; f(cn*n,n-1,f);else;ans=cn;end');
f=@(n)f(1,n,f);

或者:

f=@(cn,n,f)eval('if n>1; f(cn*n,n-1,f);else;disp(cn);end');
f=@(n)f(1,n,f);

不能令人满意的是,直接分配时仍然不能使用此功能,由于eval无法获取值,因此a=f(3)仍然会产生错误.

What is not very satisfactory is that you still cannot use this function when directly assigning, a=f(3) still produces an error, since eval does not get a value.

所以我的问题是,您实际上可以通过匿名函数来执行递归函数吗?以允许的方式计算阶乘a=f(3)仅依赖于本机matlab函数(或您可以在命令行中创建的函数,如我在示例中所做的那样)?

So my question is, can you actually do a recursive function via anonymous functions that e.g. calculates factorial in a way that allows e.g. a=f(3) with relying only on native matlab functions (or functions you can create in the command line, as I did in my example)?

PS:我知道这没有实际用途,这只是对您可以弯曲和滥用Matlab语法的挑战.

PS: I know this does not have any practical use, it is just a challenge on how much you can bend and abuse Matlab's syntax.

推荐答案

我们现在发现了两个可能,都依赖于单元格阵列的使用.请注意,这可能无法在八度中使用.

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.

此方法利用matlabs布尔值,可以将true评估为1,将false评估为0.

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_ }();

在这里,我们必须提供一个条件作为第一个参数,并提供一个2元素单元格数组作为第二个参数.每个单元元素都应该是一个函数句柄,如果条件为真/不为真,则将调用该函数句柄.我们的阶乘函数如下所示:

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)

@AndrasDeak在下面评论:这里重要的是我们有一个 functions 而不是 values 的单元格数组.这提供了短路,因为除非我们调用相应的功能@()n*f(n-1,f),否则不会评估n*f(n-1,f).

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')}();

这利用了即使在匿名函数中也可以使用varargin(可变数量的参数)这一事实.调用此函数时,您必须替换条件以及条件为真时应执行的操作.这个甚至允许使用switch构造或if ... else if ... else if ... (...) else ...构造.调用时,它将查找第一个为true的条件(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)


有趣的事实:我们在处理生产线


Fun fact: What we are doing with the line

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

也称为应用 Y组合器.实际上,我们可以将其写为

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

 Y = @(f)@(x)f(x,f);
 factorial_=Y(f);

这篇关于递归匿名函数Matlab的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆