steppyngstounes / ˈstɛp ɪŋˌstoʊnz /
1. pl. n. [Middle English] Stones used as steps of a stairway; also, stones in a stream used for crossing.1
...while at Calais in 1474 we find 40 'steppyngstounes' bought for the stairways of the town.2
2. n. [chiefly Pythonic] A package that provides iterators for advancing from start to stop, subject to algorithms that depend on user-defined value or error.
Computations that evolve in time or sweep a variable often boil down to a control loop like
or
which works well enough, until the size of the steps needs to change. This can be to save or plot results at some fixed points, or because the computation becomes either harder or easier to perform. The control loop then starts to dominate the script, obscuring the interesting parts of the computation, particularly as different edge cases are accounted for.
Packages like odeint address many of these issues, but do so through callback functions, which effectively turn the computation of interest inside out, again obscuring the interesting bits. Further, because they are often tailored for applications like solving ordinary differential equations, applying them to other stepping problems, even solving partial differential equations, can be rather opaque.
The steppyngstounes package is designed to retain the simplicity of the original control loop, while allowing great flexibility in how steps are taken and automating all of the aspects of increasing and decreasing the step size.
A steppyngstounes control loop can be as simple as
which replicates the while
construct above, but further ensures that totaltime
is not overshot if it isn't evenly divisible by dt
.
Attention
The call to ~steppyngstounes.stepper.Step.succeeded
informs the ~steppyngstounes.stepper.Stepper
to advance, otherwise it will iterate on the same step indefinitely.
Rather than manually incrementing the control variable (e.g., t
), the values of the control variable before and after the step are available as the ~steppyngstounes.stepper.Step
attributes ~steppyngstounes.stepper.Step.begin
and ~steppyngstounes.stepper.Step.end
. The attribute ~steppyngstounes.stepper.Step.size
is a shorthand for step.end - step.begin
.
If the size of the steps should be adjusted by some characteristic of the calculation, such as the change in the value since the last solution, the error (normalized to 1) can be passed to ~steppyngstounes.stepper.Step.succeeded
, causing the ~steppyngstounes.stepper.Stepper
to advance (possibly adjusting the next step size) or to retry the step with a smaller step size.
A hierarchy of ~steppyngstounes.stepper.Stepper
iterations enables saving or plotting results at fixed, possibly irregular, points, while allowing an adaptive ~steppyngstounes.stepper.Stepper
to find the most efficient path between those checkpoints.
from steppyngstounes import CheckpointStepper, SomeStepper
old = initial_condition
for checkpoint in CheckpointStepper(start=0.,
stops=[1e-3, 1, 1e3, 1e6]):
for step in SomeStepper(start=checkpoint.begin,
stop=checkpoint.end,
size=checkpoint.size):
new = do_something_else(step.begin, step.end, step.size)
err = (new - old) / scale
if step.succeeded(error=err):
old = new
# do happy things
else:
# do sad things
save_or_plot()
_ = checkpoint.succeeded()
A variety of stepping algorithms are described and demonstrated in the documentation of the individual steppyngstounes
classes.
Middle English Dictionary, Ed. Robert E. Lewis, et al., Ann Arbor: University of Michigan Press, 1952-2001. Online edition in Middle English Compendium, Ed. Frances McSparran, et al., Ann Arbor: University of Michigan Library, 2000-2018. <https://quod.lib.umich.edu/m/middle-english-dictionary/dictionary/MED42815>. Accessed 16 December 2020.↩
Building in England, Down to 1540: A Documentary History, L. F. Salzman, Clarenden Press, Oxford, 1952. <https://books.google.com/books?id=WtZPAAAAMAAJ&focus=searchwithinvolume&q=steppyngstounes>. Accessed 16 December 2020.↩