Analog of Maple “unapply” or Mathematica “Function” in Maxima

孤者浪人 提交于 2021-02-09 07:41:00

问题


In Wolfram Mathematica we can define an operator acting on a function (i.e. function that returns function) e.g. as for the operator of multiplication by the first argument acting on a functions of two arguments in the example below

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

Then we can apply this operators to any function with any 2 arguments

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

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

There is a similar construction in Maple

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

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

end;

with the similar mode of application

> X(g)(z,t);

  z g(z, t)

In Maxima I tried this

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

but when trying to apply it I get

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

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

so, it looks like f is not recognized as an argument of function X when I used lambda.

Is there any way to solve this problem?

In case of Maple and Mathematica this type of operators helps a lot to manipulate with linear differential operators


回答1:


Maxima lambda doesn't evaluate any of the expressions inside the body of it, so f is not evaluated (to g). That's the behavior you are seeing. The motivation for it that I can see is that the lambda body might contain expressions which don't have the expected effect until some variables have values, e.g. length, for ..., print, etc.

You can get the expected behavior by substituting into the body. Here are two ways to do that. The first uses the function subst which I think is maybe the most obvious.

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

The second uses the function buildq which is effectively a substitution function which quotes (does not evaluate) the expression into which something is substituted.

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

Finally, if you are interested in creating lambda expressions using evaluated expressions more often, you could create your own kind of lambda for that. I'll call it evlambda here.

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

The key here is that evlambda is defined as an ordinary function, so its arguments are evaluated. So by the time lambda is applied, b has been evaluated so it contains g.

Note that this evlambda won't do anything useful with length, for ..., and print, which is to be expected.

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

The last one, with print, evaluates print when baz is defined (so x is the output), but then not again when baz(5) is evaluated -- this behavior is to be expected since evlambda evaluates its arguments.



来源:https://stackoverflow.com/questions/52680489/analog-of-maple-unapply-or-mathematica-function-in-maxima

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!