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