【问题标题】:Analog of Maple "unapply" or Mathematica "Function" in MaximaMaxima 中 Maple “unapply”或 Mathematica “Function”的模拟
【发布时间】:2018-10-06 15:18:38
【问题描述】:

在 Wolfram Mathematica 中,我们可以定义一个作用于函数(即返回函数的函数)的运算符,例如至于在下面的例子中作用于两个参数的函数的第一个参数的乘法运算符

X[f_] = Function[{x, y}, x*f[x, y]]

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

In[2]:= X[g][z, t]

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

Maple 也有类似的构造

X:=proc(f) option operator; local x,y;

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

end;

与应用方式类似

> X(g)(z,t);

  z g(z, t)

在千里马我试过这个

X(f):=lambda([x,y],x*f(x,y));

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

(%i5) X(g)(z,t)

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

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

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

在 Maple 和 Mathematica 的情况下,这种类型的运算符有助于使用线性微分运算符进行操作

【问题讨论】:

    标签: maxima


    【解决方案1】:

    Maxima lambda 不计算其主体内的任何表达式,因此不计算 f(到 g)。这就是您所看到的行为。我可以看到它的动机是 lambda 正文可能包含在某些变量具有值之前没有预期效果的表达式,例如lengthfor ...print

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

    (%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,它实际上是一个替换函数,它引用(不计算)被替换的表达式。

    (%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

    (%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 做任何有用的事情,这是意料之中的。

    (%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,在定义baz 时评估print(所以x 是输出),但在评估baz(5) 时不会再次评估——这种行为是意料之中的因为evlambda 会评估它的参数。

    【讨论】:

    • 好吧,这行得通!但我还有另一个问题:如何定义此类运算符的组合?在 Mathematica 中我们使用@*,在 Maple 中我们使用@。例如,要获得 x 乘法和 x 微分运算符的交换子,在 Maple 中我们写为 X@dX-dX@X。我们如何在 Maxima 中做到这一点?
    • @Truffaldino 您的“另一个问题”可以作为一个新问题提出。如果这个解决方案如你所说的那样有效,最好的办法是点击“接受”,这样以后的读者就会看到问题已经解决了。用户的声望也会小幅提升,您也会获得 +2。每个人都赢了! :-)
    • @Truffaldino 我同意最好将其作为一个单独的新问题提出。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-22
    • 1970-01-01
    • 1970-01-01
    • 2016-12-02
    相关资源
    最近更新 更多