MathGroup Archive 1994

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

Search the Archive

Re: Combining pure functions..

  • To: mathgroup at christensen.cybernetics.net
  • Subject: [mg361] Re: [mg349] Combining pure functions..
  • From: villegas (Robert Villegas)
  • Date: Mon, 26 Dec 1994 22:37:40 -0600

Hello Al,


> However, there is not a unique solution here without specifying what the
> external relationship between the arguments to pure functions should be.  
In
> other words should an expression e[f1,f2] involving: f1 =
> Function[{x1},body1] and f2 = Function[{x2},body2] which involve dummy
> variables x1 and x2 respectively be mapped to
> Function[{x1,x2},e[f1[x1],f2[x2]] or in the simplest form:
> Function[x,e[f1[x],f2[x]]].


   Indeed, the longer you consider this, the more possibilities come up!  I
hadn't given much thought to dealing with the other syntax of Function.
Start throwing attributes in there, and it gets even more complicated
(and the user could specify hopelessly incompatible functions if not
very careful with those).


If you're using named variables in your functions, and you want:

(1) different names to represent distinct variables in the overall function

(2) the same name in different Function's to represent the same variable
    in the overall function

then it's easy to combine the formulae again, but I don't think there's
a natural way for the program to decide which variable names come
before others in the final calling syntax.  For instance, if you have

Function[x, x^2] + Function[y, y^3]/Function[z, Arg[z]]

then do you want your final function's ordering of variables to be
f[x, y, z], or f[y, x, z], or something else?  A particular application
might impose restrictions on what variables can be used and have some
canonical ordering on them (like only 'x', 'y', and 'z', and always
assumed in that order).  But a general-purpose combiner of pure functions
wouldn't have any way of knowing the desired ordering.


   One solution is to have the user supply the list of variable names.  This
is a fairly standard thing for Mathematica functions to do, in fact. 


Examples:


In[1]:= Attributes[CombineFunctions] = HoldFirst

Out[1]= HoldFirst

In[2]:= CombineFunctions[vars_List, func_] := Function @@
          (Hold[vars, func] /. Literal @ Function[_, body_] :> body)

In[3]:= funcExpr = Function[x, x^2] + Function[{y}, y^3]/Function[z, Arg[z]]

                                          3
                     2     Function[{y}, y ]
Out[3]= Function[x, x ] + -------------------
                          Function[z, Arg[z]]

In[4]:= CombineFunctions[{y, x, z}, funcExpr]

                                    3
                             2     y
Out[4]= Function[{y, x, z}, x  + ------]
                                 Arg[z]


Possibly this would be a useful tool, since a person might use the same
name for the same thing throughout some computations.  I am not sure it
would be widely useful, but potentially in certain circumstances. 

Again, I haven't tried to tackle any difficult needs here, like pure
functions within pure functions, or operators composed of pure
functions, as I mentioned before.


> Here is a solution invoking the latter assumption in which the dummy
> variables are presumed identical.
> 

> ComposePureFunctions[e_] :=
>         With[{body$ = e/.p:Function[__] :> p[dummy$]},
>               f$[dummy$,body$]/.f$->Function];


   There are a couple of problems with this approach.  One is that you end
up actually evaluating the functions when you feed them dummy$ as an
argument.  Since Function objects are frozen formulae waiting to be
called, it would be best for the combined function to preserve the
originals.  There are cases where evaluation will lose the intended
formula completely, such as this one where the pure functions involve
integrating the argument (which the user plans to be a function of x):

In[7]:= ComposePureFunctions[ (Integrate[#, {x, -1, 1}]&) +  
(Integrate[ArcTan[#], {x, -1, 1}]&) ]

Out[7]= Function[dummy$, 2 dummy$ + 2 ArcTan[dummy$]]

Or the formulae might have side-effects like assigning counters or other
variables, or printing things, all of which you wouldn't want prematurely
evaluated.


   Another problem is that the functions might have more than one
variable, in which case the single dummy$ won't be enough to fill the
slots.  Of course, this part could be remedied without too much trouble
by having the program count the variables and generate the right number
of dummy variables.


Robby Villegas
Wolfram Research


  • Prev by Date: Mutiple delete in lists
  • Next by Date: Generating Lottery Numbers
  • Previous by thread: Combining pure functions..
  • Next by thread: Alternating Series Construct