MathGroup Archive 2000

[Date Index] [Thread Index] [Author Index]

Search the Archive

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/
>
>






  • Prev by Date: Re: To color surfaces using z values with ContourPlot3D
  • Next by Date: Re: Pattern Matching
  • Previous by thread: Re: Functional Expression Meaning (was:A Functional Expression Trick)
  • Next by thread: RE: Re: Functional Expression Meaning (was:A Functional Expression Trick)