Somtimes I still get lost in the Hold, HoldAll etc. functions of Mathematica. I want to scale a simple PDF function with a previously calculated variable e.g.

(scale PDF[NormalDistribution[]])[0.5]

where I would expect to get the same output as for

scale (PDF[NormalDistribution[]][0.5])

(* 3.52065 *)

unfortunately I get the unevaluated function with its argument. Another example with Interpolation:

points = {{0, 0}, {1, 1}, {2, 3}, {3, 4}, {4, 3}, {5, 0}};
(10 Interpolation[points])[0.5]

(and yes I know that I can scale the points upfront or could do the evaluation with the brackets around interpolation and the argument. This is not the point. I need to return a scaled pure function at the end without the evaluation with an numeric argument)

Is there an easy way to force the evaluation and return the resulting pure function?

  • 2
    $\begingroup$ Use Composition[]. $\endgroup$ – J. M.'s ennui Jul 10 '15 at 16:34
  • $\begingroup$ May be : scale = 10.0; pureScaledFunction = (scale PDF[NormalDistribution[]][#]) &; pureScaledFunction[0.5] ? $\endgroup$ – andre314 Jul 10 '15 at 16:39
  • $\begingroup$ @Guess who it is. It's a shame that I was not aware of Composition at all. Thanks a lot for this hint! $\endgroup$ – Rainer Jul 10 '15 at 17:07

As I see it, this behavior does not depend on Hold properties. In fact, PDF[NormalDistribution[]] evaluates to a Function, so you can apply it to arguments using []:

(* Function *)

On the other hand, (scale PDF[NormalDistribution[]]) does not evaluate to an expression with head Function; in fact, it evaluates to an expression with head Times:

Head[(scale PDF[NormalDistribution[]])]
(* Times *)

Mathematica then doesn't really know what to do when you ask to apply that to the numerical argument, so it returns the expression unevaluated.

As GuessWhoItIs already mentioned in comments, you may generate a Composition of two functions to apply to the argument (the infix form for Composition is @*):

(Times[#, scale] &@*PDF[NormalDistribution[]])[0.5]
(* Out: 3.52065 *)

For exactly the reasons mentioned in another answer, (scale PDF[NormalDistribution[]])[0.5] doesn't work since the Head of the expression is Times rather than Function. This suggests that we should replace the innards of the Function. Something like

scale = 10;
f = PDF[NormalDistribution[]] /. (Function[b_] :> Function[scale b]);

Then f @ 0.5 results in 3.52065.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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