首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Maxima中Maple "unapply“或Mathematica "Function”的模拟

Maxima中Maple "unapply“或Mathematica "Function”的模拟
EN

Stack Overflow用户
提问于 2018-10-06 23:18:39
回答 1查看 153关注 0票数 3

在Wolfram Mathematica中,我们可以定义作用于函数的运算符(即返回函数的函数),例如,对于作用于下面示例中具有两个自变量的函数的第一个自变量的乘法运算符

代码语言:javascript
复制
X[f_] = Function[{x, y}, x*f[x, y]]

然后,我们可以将该运算符应用于具有任意2个参数的任何函数

代码语言:javascript
复制
In[2]:= X[g][z, t]

Out[2]= z g[z, t]

在Maple中也有类似的结构

代码语言:javascript
复制
X:=proc(f) option operator; local x,y;

unapply(x*f(x,y),x,y)

end;

使用类似的应用模式

代码语言:javascript
复制
> X(g)(z,t);

  z g(z, t)

在Maxima中,我尝试了这个

代码语言:javascript
复制
X(f):=lambda([x,y],x*f(x,y));

但是当我尝试应用它时,我得到了

代码语言:javascript
复制
(%i5) X(g)(z,t)

(%o5) z*f(z,t)

所以,当我使用lambda时,看起来f没有被识别为函数X的参数。

有没有办法解决这个问题?

在Maple和Mathematica的情况下,这种类型的运算符对线性微分运算符的操作有很大帮助

EN

回答 1

Stack Overflow用户

发布于 2018-10-07 01:13:48

Maxima lambda不会对其主体中的任何表达式求值,因此不会对f求值(到g)。这就是你所看到的行为。我能看到的动机是,lambda主体可能包含一些表达式,这些表达式只有在一些变量有值之前才会产生预期的效果,例如lengthfor ...print等。

您可以通过在主体中进行替换来获得预期的行为。这里有两种方法可以做到这一点。第一个使用函数subst,我认为这个函数可能是最明显的。

代码语言:javascript
复制
(%i1) X(f):= subst ('f = f, lambda([x,y],x*f(x,y)));
(%o1)   X(f) := subst('f = f, lambda([x, y], x f(x, y)))
(%i2) X(g);
(%o2)               lambda([x, y], x g(x, y))
(%i3) X(g)(z, t);
(%o3)                       z g(z, t)

第二个使用函数buildq,这是一个有效的替换函数,它引用(不求值)要替换的表达式。

代码语言:javascript
复制
(%i4) X(f) := buildq ([f], lambda ([x, y], x*f(x, y)));
(%o4)    X(f) := buildq([f], lambda([x, y], x f(x, y)))
(%i5) X(g);
(%o5)               lambda([x, y], x g(x, y))
(%i6) X(g)(z, t);
(%o6)                       z g(z, t)

最后,如果您对更频繁地使用求值表达式创建lambda表达式感兴趣,您可以为此创建自己的lambda类型。我在这里称它为evlambda

代码语言:javascript
复制
(%i11) evlambda (a, b) := apply (lambda, [a, b]);
(%o11)         evlambda(a, b) := apply(lambda, [a, b])
(%i12) X(f) := evlambda ([x, y], x*f(x, y));
(%o12)           X(f) := evlambda([x, y], x f(x, y))
(%i13) X(g);
(%o13)                lambda([x, y], x g(x, y))
(%i14) X(g)(z, t);
(%o14)                        z g(z, t)

这里的关键是evlambda被定义为一个普通函数,所以它的参数被计算出来。因此,在应用lambda时,b已经过评估,因此它包含g

请注意,此evlambda不会对lengthfor ...print执行任何有用的操作,这是意料之中的。

代码语言:javascript
复制
(%i15) foo : evlambda ([l], 1 + length(l));
length: argument cannot be a symbol; found l
 -- an error. To debug this try: debugmode(true);
(%i16) bar : evlambda ([n], for i thru n do print (i));
Unable to evaluate predicate 1 > n
 -- an error. To debug this try: debugmode(true);
(%i17) baz : evlambda ([x], print (x));
x
(%o17)                    lambda([x], x)
(%i18) baz(5);
(%o18)                           5     

最后一个函数使用print,在定义了print时计算baz (因此x是输出),但在计算baz(5)时不会再次计算--由于evlambda计算其参数,因此这种行为是意料之中的。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52680489

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档