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