Re: Functional Expression Meaning (was:A Functional Expression Trick)
- To: mathgroup at smc.vnet.net
- Subject: [mg23926] Re: Functional Expression Meaning (was:[mg23859] A Functional Expression Trick)
- From: "Allan Hayes" <hay at haystack.demon.co.uk>
- Date: Fri, 16 Jun 2000 00:57:05 -0400 (EDT)
- References: <8i9pvg$2l2@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
Dear David and Hartmut, I have come across some problems with Hartmut's solution, toFunc, as written up by David. I offer new version, toFunc2 Hartmut's solution is toFunc::usage = "toFunc[expr] will convert an expression of pure functions into a pure function."; toFunc[expr_] := Module[{e}, Off[Pattern::patv]; Off[Function::flpar]; e = ReleaseHold[ Evaluate[ expr /. {Function[({var__} | var_), body_] :> Block[{var}, Hold[body] /. Thread[Rule[{var}, Array[Slot, {Length[{var}]}]]]], Function -> Hold}] &]; On[Pattern::patv]; On[Function::flpar]; e] I am always wary when replacement reaches inside scoping constructs like Function, With ...., because it does not respect the scoping. With toFunc we get toFunc[Function[x, With[{x = 5}, a + x^2]]] With[{#1 = 5}, a + #1\^2] &\) Also, constant functiions give trouble: toFunc[Function[{}, a + x]] Block::"lvsym": "Local variable specification \!\({\({}\)}\) contains \ \!\({}\) which is not a symbol or an assignment to a symbol." Block[{{}}, a + x /.\[InvisibleSpace]Thread[{{}} -> Array[Slot, {Length[{{}}]}]]] & Func2, below, uses the functions themselves to introduce the slots, rather than replacement. It also avoids generating messages. toFunc2[expr_] := ReleaseHold[Function @@ ({expr} /. (F_ /; F === Function)[vars_, body_] :> Apply[F[vars, Hold[body]], Slot /@ Range[Last[Dimensions[Unevaluated[{vars}]]]]] )] With this we get toFunc2[Function[x, With[{x = 5}, a + x^2]]] With[{x = 5}, a + x^2] & toFunc2[Function[{}, a + x]] a + x & -- Allan --------------------- Allan Hayes Mathematica Training and Consulting Leicester UK www.haystack.demon.co.uk hay at haystack.demon.co.uk Voice: +44 (0)116 271 4198 Fax: +44 (0)870 164 0565 "David Park" <djmp at earthlink.net> wrote in message news:8i9pvg$2l2 at smc.vnet.net... > Dear Hartmut, > > It is always a good day when you reply to one of my postings. Then I learn > how things should be done. > > I slightly rewrote your routine which changes a functional expression into a > function. I turned the unwanted error messages Off and On within the routine > and added a usage message. Here it is in plain text for those who may wish > to use it. > > toFunc::usage = > "toFunc[expr] will convert an expression of pure functions into a pure \ > function."; > toFunc[expr_] := > Module[{e}, > Off[Pattern::patv]; > Off[Function::flpar]; > e = > eHold[ > Evaluate[expr /. {Function[({var__} | var_), body_] :> > Block[{var}, > Hold[body] /. > Thread[Rule[{var}, > Array[Slot, {Length[{var}]}]]]], > Function -> Hold}] &]; > On[Pattern::patv]; > On[Function::flpar]; > e] > > It might be of interest to see the problem that prompted my posting. The problem is the very first problem in the very first section of O'Neill's Elementary Differential Geometry. Here it is: > > Let f = x^2 y and g = y Sin[z] be functions on E^3. Express the following functions in terms of x, y and z. > a) f g^2 > b) (df/dx)g + (dg/dy)f > c) d^2(f g)/(dy dz) > d) (d Sin[f])/dy > > Of course, one could just write f and g as expressions in x,y,z and perform the indicated operations. But the whole spirit of the discussion was in terms of representing things as functions which would be applied to a Euclidean point p. So O'Neill had definitions such as (f g)[p] = f[p]g[p], and he had introduced x,y and z as coordinate functions (x[px,py,pz]=px) and not as simple variables. So I wanted to do the problem in that spirit. I can't say how many times I have come back to this simple problem and never been satisfied. This is one of the things that Mathematica should be good at, and is good at, i f we can only learn how to employ it properly. So this is how I would do it using your routine. I would be interested if others can present a clear approach which retains the functional flavor of the problem. > > f := #1^2*#2 & > g := #2*Sin[#3] & > x := #1 & > y := #2 & > z := #3 & > > p = {px, py, pz}; > > a) > toFunc[f*g^2][x, y, z] > toFunc[%] @@ p > (#1 & )^2*(#2 & )^3*Sin[#3 & ]^2 > px^2*py^3*Sin[pz]^2 > > b) > toFunc[Derivative[1, 0, 0][f]g + Derivative[0, 1, 0][g]f][x, y, z] > toFunc[%] @@ p > (#1 & )^2*(#2 & )*Sin[#3 & ] + 2*(#1 & )*(#2 & )^2*Sin[#3 & ] > px^2*py*Sin[pz] + 2*px*py^2*Sin[pz] > > c) > Derivative[0, 1, 1][toFunc[f g]][x, y, z] > toFunc[%] @@ p > 2*Cos[#3 & ]*(#1 & )^2*(#2 & ) > 2*px^2*py*Cos[pz] > > d) > Derivative[0, 1, 0][toFunc[Sin[f]]][x, y, z] > toFunc[%] @@ p > Cos[(#1 & )^2*(#2 & )]*(#1 & )^2 > px^2*Cos[px^2*py] > > or > > Derivative[0, 1, 0][Composition[Sin, f ]][x, y, z] > toFunc[%] @@ p > Cos[(#1 & )^2*(#2 & )]*(#1 & )^2 > px^2*Cos[px^2*py] > > Thanks again, Hartmut, for your valuable advice. > > David Park > djmp at earthlink.net > http://home.earthlink.net/~djmp/ > >