# memoization based on function expression?

I want to create a function $f$ which takes as a parameter a function $h$, and calculates its integral between $a$ and $b$.

But I want to apply memoization to this, by only calculating the integral the first time it is called for a particular function of $h$.

If we have a normal function that takes a real number (instead of another function), then we simply do:

g[x_]:=g[x]=...


How do we do this memoization for $f$, where the argument is the expression for a function?

• Have you tried doing it the same way? Jan 19, 2018 at 19:41
• @JohnDoty, honestly no, because I'm still confused as to how mathematica works internally, and I'm not how to even pass a function-expression, or how mathematica knows that I'm trying to pass the expression instead of the value. Jan 19, 2018 at 19:59

As a pure function:

f1[h_, a_, b_] := f1[h, a, b] = Integrate[h[x], {x, a, b}]
f1[#^2 &, 1, 2]


As a function of x:

f2[h_, a_, b_] := f2[h, a, b] = Integrate[h, {x, a, b}]
f2[x^2, 1, 2]


As a function of any variable var:

f3[h_, var_, a_, b_] := f3[h, var, a, b] = Integrate[h, {var, a, b}]
f3[y^2, y, 1, 2]


All give

7/3

Implicitly, this works best if you express $h$ as a pure function, but it's relatively straightforwards. If you are interested in evaluating the integral from $a$ to $b$ precisely once, then this should work:

f[h_] := f[h] = Function[{a,b},Evaluate[Integrate[h[x],{x,a,b}]]];


This defines f as a function which takes a parameter h (which will need to be a function itself to work properly), and then memoizes its result. Its result is a function representing the evaluated integral of h[x], to within Mathematica's abilities.

For example, f[Sin] (note that this is not f[Sin[x]]) will return:

Function[{a$,b$}, Cos[a$] - Cos[b$]]


This represents a function of a$ and b$ and contains the evaluated integral of Sin. From here f[Sin][1,3] will equal Cos[1]-Cos[3], which is equal to Integrate[Sin[x],{x,1,3}].

To evaluate a more arbitrary function, using pure functions is prudent. For example, to find the integral of $x^2$ once, write it as a pure function:

f[#^2 &]
(* Function[{a$,b$},-a$^3/3+b$^3/3] *)

f[#^2 &][1,2]
(* 7/3 *)

• Thank you. I am wondering, why doesn't it work to simply do: f[h_] := (Integrate[h[x], {x, a, b}])[0, 1]; h[x_] := x^2; f[h]? If I do this, it still returns the function, instead of the evaluation of the integral between 0 and 1. Jan 19, 2018 at 20:21
• @Programmer2134: You've dropped the Function declaration there, so you simply have some integral with a [0,1] attached to the end of it. Mathematica interprets that the same way it interprets 3[4]. If you want it to be specifically between 0 and 1, then you could do something like: f[h_] := f[h] = Integrate[h[x],{x,0,1}], and there's no need to return a function which accepts input. Jan 19, 2018 at 20:25
• Yet if I write >f[h_] := Function[{a, b}, Evaluate[Integrate[h[x], {x, a, b}]]][0, 1]; then it still gives me a function output. It's not that I need to write it like that necessarily, I am just still confused by how mathematica works inside, as it seems to me that this should simply output the number... Jan 20, 2018 at 18:29
• @Programmer2134 using that code exactly and entering f[Sin] I get 1-Cos[1], which seems to be the intended output. Are you using a pure function as the input (i.e. a function referenced by name without an input value, or an anonymous function like #^2& without a [x] attached to it)? Jan 20, 2018 at 19:13
• Yes I did, however, when I added "ClearAll[h,f]" in front of the code, it suddenly worked. I should get in the habbit of always doing that. The fact that mathematica "remembers" earlier, already removed definitions of symbols, seems to be a source of bugs for me. Thanks for the help! Jan 20, 2018 at 19:54