# Mathematica-storing functions defined by integrals

• Mathematica
Hi all,
I have a family of functions defined by integrals and indexed by n, e.g
f[x_,n_]=$\int dy e^{ixy}y^n$
Is it possible to evaluate the integrals corresponding to different particular values of n in such a way that mathematica "remembers" that say f[x,4]= some function g[x]?

An additional complication is that my integrands contain Heaviside theta functions of non-trivial arguments, e.g. $\theta(1-y^2)$ that mathematica doesn't seem to like, and so far I've only been able to proceed by breaking up the integration region manually; I'm hoping to work out a way of reparametrising the expression so that I don't have to do this, but if I can't then I'd need a way of piecing different functions together and getting mathematica to understand that the result is equivalent to the original integral.

Thanks in advance.

## Answers and Replies

The http://en.wikipedia.org/wiki/Memoization" [Broken]. Basically you want

f[x_] := f[x] = definition

This constructs a new downvalue for each new x that f is called with. See the above link.

As for the HeavisideTheta, I think that for the purpose of integration, you can replace that with UnitStep and it will be a bit quicker. Mathematica should break up the integral into regions automatically for you. Can you post an example that fails?

Last edited by a moderator:
Thanks for the reply- this is, I think, the same trick that you helped me with in the context of numerical integration, so perhaps I should make my problem clearer.

The integrals in question can be done analytically. I'd like mathematica to remember not previously calculated values, but the function that results from doing the integral for a particular value of n.

The kind of thing I have is
f[\[Beta]_, n_] := (constant)* Integrate[k*BesselJ[0, k*\[Beta]]*BQ[-k^2, n], {k, 0, Infinity}, Assumptions -> (beta real,>0)]

where

BQ[t_, n_] := (n-dependent const)*(HeavisideTheta[-t - 1] (-2)/(n*(n + 2)*t^2) +
HeavisideTheta[1 + t] (-2/(n*(n + 2)* t^2) + (1 + t)^(n/2)
*(Hypergeometric2F1[1, n/2, n/2 + 1,1 + 1/t]/(n*t) + (2 - n*t)/(n*(n + 2)*t^2)) ))

n is an integer and t is always negative. The general integral can't be done for arbitrary n, but for specific values of n the hypergeometric function simplifies to logs and the like. What I want is to be able to associate f[b,n_0] with the function of b that results from doing the tractable integral for some fixed n_0, so that I can evaluate using the the function rather than having Mathematica redo the integral for every value of b.

ok... that was my bad, the memoization works, but the generated downvalue, f[x,n]=..., does not have a pattern in its left-hand-side, so it does not behave like a function. Here's some (simplified) code that will work like you want

Code:
In:= Clear[f, BQ]
BQ[t_, n_] := n  t^2
f[x_, n_Integer] :=
Block[{y},
f[y_, n] = Integrate[Exp[-k y] BQ[k, n], {k, 0, 1}, Assumptions -> x > 0];
f[x, n]]

In:= f[x, 1]

Out= (E^-x (-2 + 2 E^x - x (2 + x)))/x^3

In:= f[y, 2]

Out= (2 E^-y (-2 + 2 E^y - y (2 + y)))/y^3

In:= f[1, 3]

Out= 3 (2 - 5/E)

In:= ?f

Globalf

f[y$_,1]=(E^-y$ (-2+2 E^y$-y$ (2+y$)))/y$^3

f[y$_,2]=(2 E^-y$ (-2+2 E^y$-y$ (2+y$)))/y$^3

f[y$_,3]=(3 (2-E^-y$ (2+2 y$+y$^2)))/y\$^3

f[x_,n_Integer]:=Block[{y},f[y_,n]=Integrate[Exp[-k y] BQ[k,n],{k,0,1},Assumptions->x>0];f[x,n]]

Note that since your actual integral is really slow, you probably want to save the results into an external file. I'd be tempted to do
Code:
Table[f[x,n],{n,nlist}]
Save[FileNameJoin[{NotebookDirectory[], "integrals.dat"}], f]
where nlist={1,2,3...} all of the values of n that you need the integral for, and leave the code running overnight. Then you can load the integrals whenever you need them using
Code:
Save[FileNameJoin[{NotebookDirectory[], "integrals.dat"}]]`

See this stackoverflow question http://stackoverflow.com/q/5287817/421225 for more info on caching/memoization functions with a file or database backend. Although, this is probably overkill for your needs.

As for breaking up your integration range, Mathematica is pretty good at doing that automatically (in fact running your code for f[x,1] gave a convergence warning for the range {0,1} which shows the step function was working...). But you could try to help it by entering "/. HeavisideTheta -> UnitStep // PiecewiseExpand" onto the end of your BQ definition...

Dale
Mentor
2020 Award
Another approach:

f[n_Integer] := f[n] = Function[x, Evaluate[Integrate[Exp[I x y] y^n, y]]]

Then you simply call the function as:
f[n][x]

I haven't had a chance to get on PF in a while; thank you both for your helpful replies (again). I haven't quite been able to get it working yet as Mathematica has seemingly, for reasons best known to itself, developed an aversion to factoring arbitrary constant prefactors in BQ outside of the integral... *sigh*.