1
$\begingroup$

For iterative numerical application (for example NestList) I need to define a function, which depends on a function and outputs a function.

To describe the problem, here I give a simple example:

pint = Function[{ip }, Function[{t}, Integrate[(x + t x - 2 t) ip[x], {x, 0, t} ] ]];

This analytical function might be applied iteratively as expected

pint[Exp[-#]&][t] (*1 - t - E^-t (1 + t^2)*)
pint[pint[Exp[-#] &]][t] (*-9 - t + 1/2 (-3 + t) t^2 + E^-t (9 + 10 t + 7 t^2 + 3 t^3 + t^4)*)

Works fine, syntax seems to be ok.

Now my real problem, thereby I assume the integration can't be evaluated analytically:

Simply changing Integrate to NIntegrate gives

pintN = Function[{ip },Function[{t}, NIntegrate[(x + t x - 2 t) ip[x], {x, 0, t} ] ]] ;      

which evaluates as expected (same result as pint)

Plot[{pint[Exp[-#] &][u], pintN[Exp[-#] &][u]}, {u, 0, 5},PlotStyle -> {Thickness[.01], Automatic}]

enter image description here

Unfortunately the function pintN can't be applied iteratively! For example

Plot[pintN[pintN[Exp[-#] &]][u], {u, 0, 5}]

doesn't work!

How can I make the numerical version run? Thanks!

$\endgroup$
3
  • $\begingroup$ I think pintN = Function[{ip}, Function[{t}, Module[{x}, Quiet@NIntegrate[(x + t x - 2 t) ip[x], {x, 0, t}]]]] works to make the integration variable unique. NIntegrate splutters some messages (hence the Quiet), but I think the answer is correct. Note that pint also seems to suffer from localizations issues with x. $\endgroup$ Jan 11 at 22:00
  • $\begingroup$ @SjoerdSmit Thanks, I tried your modified definition but Plot[Evaluate[pintN[pintN[Exp[-#] &]][t]] , {t, 0, Pi}] doesn't finish evaluation. $\endgroup$ Jan 11 at 22:05
  • $\begingroup$ Ah, but that's because it makes no sense to evaluate a numerical function with at symbolic symbol t, right? You'll need some form of pattern matching to handle that. $\endgroup$ Jan 11 at 22:11
5
$\begingroup$

With numerical functions, you have to be careful that NIntegrate will always get a valid integrand. The easiest way to do this is with pattern matching:

ClearAll[pintN];
pintN[ip_][t_?NumericQ] := Module[{x},
  NIntegrate[(x + t x - 2 t) ip[x], {x, 0, t}]
]

This will now work, but it's very slow:

Plot[pintN[pintN[Exp[-#] &]][u], {u, 0, 5}, PlotPoints -> 20, MaxRecursion -> 0]

Note that sometimes you can cleverly use ParametricNDSolveValue to represent integrals. For example, to represent a function that numerically integrates another function you can use:

int[f_] := Module[{x, y, t},
  ParametricNDSolveValue[
   {y'[x] == f[x], y[0] == 0},
   y[t],
   {x, 0, t},
   t
  ]
]
$\endgroup$
1
  • $\begingroup$ Thanks for your answer. Now I learned how to restrict t_?NumericQin the definition of pintN. It seems to be impossible to restrict t in my original defintion Function[{ip },Function[{t}… Thanks also for your hint concerning NDSolve . $\endgroup$ Jan 12 at 8:37

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.