2
$\begingroup$

I have an expression that I want to use in a function definition. For concreteness let's take Gamma[k + 4]/k!. I know this can be simplified to (1 + k) (2 + k) (3 + k), but I don't want to have to copy-paste the simplified expression into my function definion like this

copypaste[k_] := (1 + k) (2 + k) (3 + k)

so instead I write

slow[k_] := FullSimplify[Gamma[k + 4]/k!]

This second function is not only slow, but Mathematica will redo the simplification each time I want to evaluate this function.

Solution so far

A way to solve this is to use

evaluated[k_] = FullSimplify[Gamma[k + 4]/k!]
simplerandfaster[k_] := evaluated[k]

This works, but it feels like a not-so-neat workaround to me. If I have to do this trick several times for different functions in one notebook I'll have a bunch of function names like evaluated which I will only ever use once. Is there a better way? I guess I could add ClearAll@evaluated at the end or put everything inside a Module block, but I'm hoping there's a better way.

$\endgroup$
2
  • $\begingroup$ I would use Pochhammer[k + 1, 3] instead. $\endgroup$ Feb 2 '21 at 16:44
  • 1
    $\begingroup$ In a notebook, you can use evaluate-in-place as well. Just select the bit of code you want to evaluate (so FullSimplify[Gamma[k + 4]/k!]) and then hit Ctrl + Shift + Enter. Other than that, evaluated[k_] = FullSimplify[Gamma[k + 4]/k!] is the idiomatic way to do it. If you want to be on the same side, put Block[{k}, ...] around it. There's no need for simplerandfaster[k_] := evaluated[k] either, it doesn't really do anything. $\endgroup$ Feb 2 '21 at 20:28
3
$\begingroup$

Let us see. This

slow[k_] := FullSimplify[Gamma[k + 4]/k!];
AbsoluteTiming[slow[n]]

(*  {0.0000689, (1 + n) (2 + n) (3 + n)}  *)

yields the timing 6.9 10^-5 s. This is a ten times faster:

faster[k_] := Evaluate[FullSimplify[Gamma[k + 4]/k!]];
AbsoluteTiming[faster[n]]

(*  {5.7*10^-6, (1 + n) (2 + n) (3 + n)}  *)

yielding 5.7 10^-6 s.

This is approximately the same

faster2[k_] = FullSimplify[Gamma[k + 4]/k!];
AbsoluteTiming[faster2[n]]

(*  {6.*10^-6, (1 + n) (2 + n) (3 + n)}   *)

This

copypaste[k_] := (1 + k) (2 + k) (3 + k);
AbsoluteTiming[copypaste[n]]

(* {9.4*10^-6, (1 + n) (2 + n) (3 + n)} *)

also yields about 10^-5.

My conclusion is that the second and third methods are equally fast and are the best that I can offer.

$\endgroup$
3
$\begingroup$

To add on to Alexei's answer:

In[645]:= Clear[slow];
slow[k_] := Evaluate[FullSimplify[Gamma[k + 4]/k!]]

In[647]:= DownValues[slow]

Out[647]= {HoldPattern[slow[k_]] :> (1 + k) (2 + k) (3 + k)}
$\endgroup$

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.