Tutorial IntegratorLearner
#
Note
Because this documentation consists of static html, the live_plot
and live_info
widget is not live.
Download the notebook in order to see the real behaviour. 1
import adaptive
adaptive.notebook_extension()
import holoviews as hv
import numpy as np
This learner learns a 1D function and calculates the integral and error of the integral with it. It is based on Pedro Gonnet’s implementation.
Let’s try the following function with cusps (that is difficult to integrate):
def f24(x):
return np.floor(np.exp(x))
xs = np.linspace(0, 3, 200)
hv.Scatter((xs, [f24(x) for x in xs]))
Just to prove that this really is a difficult to integrate function, let’s try a familiar function integrator scipy.integrate.quad
, which will give us warnings that it encounters difficulties (if we run it in a notebook.)
import scipy.integrate
scipy.integrate.quad(f24, 0, 3)
/tmp/ipykernel_2697/484480164.py:3: IntegrationWarning: The maximum number of subdivisions (50) has been achieved.
If increasing the limit yields no improvement it is advised to analyze
the integrand in order to determine the difficulties. If the position of a
local difficulty can be determined (singularity, discontinuity) one will
probably gain from splitting up the interval and calling the integrator
on the subranges. Perhaps a special-purpose integrator should be used.
scipy.integrate.quad(f24, 0, 3)
(17.65947611079367, 0.017039069845928623)
We initialize a learner again and pass the bounds and relative tolerance we want to reach.
Then in the Runner
we pass goal=lambda l: l.done()
where learner.done()
is True
when the relative tolerance has been reached.
from adaptive.runner import SequentialExecutor
learner = adaptive.IntegratorLearner(f24, bounds=(0, 3), tol=1e-8)
# We use a SequentialExecutor, which runs the function to be learned in
# *this* process only. This means we don't pay
# the overhead of evaluating the function in another process.
runner = adaptive.Runner(
learner, executor=SequentialExecutor(), goal=lambda l: l.done()
)
await runner.task # This is not needed in a notebook environment!
runner.live_info()
Now we could do the live plotting again, but lets just wait untill the runner is done.
if not runner.task.done():
raise RuntimeError(
"Wait for the runner to finish before executing the cells below!"
)
print(
"The integral value is {} with the corresponding error of {}".format(
learner.igral, learner.err
)
)
learner.plot()
The integral value is 17.6643835377243 with the corresponding error of 1.764637385684444e-07
- 1
This notebook can be downloaded as
tutorial.IntegratorLearner.ipynb
andtutorial.IntegratorLearner.md
.