A Functional Expression Trick

*To*: mathgroup at smc.vnet.net*Subject*: [mg23859] A Functional Expression Trick*From*: "David Park" <djmp at earthlink.net>*Date*: Mon, 12 Jun 2000 01:17:53 -0400 (EDT)*Sender*: owner-wri-mathgroup at wolfram.com

Dear MathGroup, Mathematica provides for functional expressions, but the standard exposition (Section 2.2.5 - Section 2.2.9 in the Mathematica Book) does not make it easy to work with them. The principal problem is that an expression of pure functions is not itself a pure function. Here are two pure functions: f = #1*#3^2 & ; g = Cos[#2]*#3 & ; I defined these functions so that they use consistent variables. The slot numbers refer to the same variables in the two functions. If we form an expression from these pure functions, we obtain an object that is not easy to work with. fexpr = f*g^2 + 2*f + Sin[f*g] 2*(#1*#3^2 & ) + (Cos[#2]*#3 & )^2*(#1*#3^2 & ) + Sin[(Cos[#2]*#3 & )*(#1*#3^2 & )] For example, try to evaluate: fexpr[x, y, z] 2*(#1*#3^2 & ) + (Cos[#2]*#3 & )^2*(#1*#3^2 & ) + Sin[(Cos[#2]*#3 & )*(#1*#3^2 & )])[x, y, z] You can try to use Through on this expression, but you probably won't like the results. (I developed the PushThrough package to handle cases like this, but now I am going to present a different method.) Or suppose we wish to take derivatives of fexpr: Derivative[1, 0, 1][fexpr][x, y, z] Derivative[1, 0, 1][2*(#1*#3^2 & ) + (Cos[#2]*#3 & )^2*(#1*#3^2 & ) + Sin[(Cos[#2]*#3 & )*(#1*#3^2 & )]][x, y, z] This won't evaluate because Mathematica expects fexpr to be a pure function or function name. If we have defined our pure functions with consistent slot numbers, then it is simple enough to convert the expression into a pure function. Simply remove all the &s in the middle and put one at the end. The following function does this: funexpr[expr_] := Function[Evaluate[expr /. Function -> Identity]] Now, it is very easy to evaluate expressions involving fexpr. funexpr[fexpr][x, y, z] 2*x*z^2 + x*z^4*Cos[y]^2 + Sin[x*z^3*Cos[y]] Derivative[1, 0, 1][funexpr[fexpr]][x, y, z] 4*z + 4*z^3*Cos[y]^2 + 3*z^2*Cos[y]*Cos[x*z^3*Cos[y]] - 3*x*z^5*Cos[y]^2*Sin[x*z^3*Cos[y]] There is another standard method for converting a functional expression into a pure function but it involves much more typing and somewhat undermines the convenience of functional expressions. fgfunc = Function[{x, y, z}, f[x, y, z]*g[x, y, z]^2 + 2*f[x, y, z] + Sin[f[x, y, z]*g[x, y, z]]]; fgfunc[x, y, z] 2*x*z^2 + x*z^4*Cos[y]^2 + Sin[x*z^3*Cos[y]] Derivative[1, 0, 1][fgfunc][x, y, z] 4*z + 4*z^3*Cos[y]^2 + 3*z^2*Cos[y]*Cos[x*z^3*Cos[y]] - 3*x*z^5*Cos[y]^2*Sin[x*z^3*Cos[y]] David Park djmp at earthlink.net http://home.earthlink.net/~djmp/