Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Suppose we're given the expression f*g+h, where f,g,h are all pure functions. How can we evaluate this expression on some x? If there were only one operation, say f+g, we could simply use Through[(f+g)[x]], but Through only deals with one operation, as far as I can see. How is this done?

share|improve this question
    
To clarify, you are asking for through to apply the pure functions at the most nested level to x? Your example is Plus[Times[f,g],h], so the functions you want applied to x are Level[f*g + h, {-1}]? –  VF1 Jul 4 '13 at 6:44
    
Apply[(f[##] g[##] + h[##]) &, {arguments}], crude version of what Mr. Wizard have showed. –  Kuba Jul 4 '13 at 6:57
    
Ah, yes, that is what I want @VF1 –  Nilay Kumar Jul 4 '13 at 7:03
add comment

3 Answers

up vote 9 down vote accepted

Edit:

Mr.Wizard helped to refine my old function to:

SetAttributes[Through2, HoldFirst]
Through2[head_[args___]] := Replace[head, s : _Function | _Symbol :> s[args], -1]

This locates the most nested functions and symbols and evaluates their value for the parameter arguments.

Below is my older, less robust function:

SetAttributes[Through2, HoldFirst]
Through2[expr_] := 
 With[{head = Head@expr, arg = First@expr}, 
  With[{funcs = Cases[head, _Function | _Symbol, -1]}, 
   head /. Thread[funcs -> Through[funcs[arg]]]]]
Through2[(f*g + h)[x]]
(* f[x] g[x] + h[x] *)
Through2[(f*g + (h*Minus)^2)[x]]
(* f[x] g[x] + x^2 h[x]^2 *)
Through2[{Re, Im + Re}[x]]
(* {Re[x], Im[x] + Re[x]} *)
share|improve this answer
    
Interesting interpretation. +1 I still wonder what the OP actually wants however. –  Mr.Wizard Jul 4 '13 at 7:00
    
This works great, thanks! –  Nilay Kumar Jul 4 '13 at 8:07
add comment

Perhaps you want something like this?

apply = (# /. s_Symbol /; Context[s] =!= "System`" :> s[##2]) &;

apply[f*g + h, x]
f[x] g[x] + h[x]

This is a limited implementation but it can be extended if this is in fact the kind of operation you desire. The idea is to recognize any Symbol not belonging to the System` context as a function to apply to x. Alternatively one could apply only symbols in the Global` context using Context[s] === "Global`".

share|improve this answer
    
Yes, I'd say that our functions do the same thing (with yours being more elegant and direct). In hindsight, Cases and then ReplaceAll does seem a bit redundant - and dangerous, too, if one of the pure functions is used on a higher level in the expression. Your solution will be more robust. –  VF1 Jul 4 '13 at 7:13
    
@VF1 Thanks for the check. If you'd like to put this in your answer instead that's fine with me; it was your idea to look at the levelspec. –  Mr.Wizard Jul 4 '13 at 7:22
    
Will do. Thanks. –  VF1 Jul 4 '13 at 7:24
    
@VF1 It just occurred to me that my {-1} code is broken for Function as that will not be found at level {-1}; Please use the Heads -> False code, assuming that isn't broken. –  Mr.Wizard Jul 4 '13 at 7:26
    
Is there a difference between Yours apply and @VF1 's Through2 exept that the latter works for 1 argument only (after edit it works for many) and Yours can not handle Minus and other System context functions? –  Kuba Jul 4 '13 at 7:29
show 6 more comments

For example...

f=#&;
g=2#^2&;
h=-Sqrt[#]&;

Using substitution rule...

f*g+h /. z:(f|g|h)->z[3]

Gives...

54-Sqrt[3]
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.