steppyngstounes.scaledStepper

Classes

class steppyngstounes.scaledStepper.ScaledStepper(start, stop, size=None, minStep=None, inclusive=False, record=False, growFactor=1.2, shrinkFactor=0.5)

Bases: Stepper

Adaptive stepper that adjusts the step by fixed factors.

Calculates a new step as

\[\Delta_{n+1} = f_\text{grow} \Delta_n\]

where \(\Delta_n\) is the step size for step \(n\) and \(f_\text{grow}\) is the factor by which to grow the step size.

On failure, retries with

\[\Delta_{n} = f_\text{shrink} \Delta_n\]

where \(f_\text{shrink}\) is the factor by which to shrink the step size.

Parameters:
  • start (float) – Beginning of range to step over.

  • stop (float) – Finish of range to step over.

  • size (float) – Suggested step size to try (default None).

  • minStep (float) –

    Smallest step to allow (default (stop - start) * eps).

  • inclusive (bool) – Whether to include an evaluation at start (default False)

  • record (bool) – Whether to keep history of steps, errors, values, etc. (default False).

  • growFactor (float) – Growth factor \(f_\text{grow}\) (default 1.2).

  • shrinkFactor (float) – Shrinkage factor \(f_\text{shrink}\) (default 0.5).

Examples

>>> import numpy as np
>>> from steppyngstounes import ScaledStepper

We’ll demonstrate using an artificial function that changes abruptly, but smoothly, with time,

\[\tanh\frac{\frac{t}{t_\mathrm{max}} - \frac{1}{2}} {2 w}\]

where \(t\) is the elapsed time, \(t_\mathrm{max}\) is total time desired, and \(w\) is a measure of the step width.

>>> totaltime = 1000.
>>> width = 0.01

The scaled “error” will be a measure of how much the solution has changed since the last step, | new - old | / errorscale).

>>> errorscale = 1e-2

Iterate over the stepper from start to stop (inclusive of calculating a value at start).

>>> old = -1.
>>> stepper = ScaledStepper(start=0., stop=totaltime, inclusive=True,
...                         record=True)
>>> for step in stepper:
...     new = np.tanh((step.end / totaltime - 0.5) / (2 * width))
...
...     error = abs(new - old) / errorscale
...
...     if step.succeeded(value=new, error=error):
...         old = new
>>> s = "{} succesful steps in {} attempts"
>>> print(s.format(stepper.successes.sum(),
...                len(stepper.steps)))
296 succesful steps in 377 attempts
>>> steps = stepper.steps[stepper.successes]
>>> ix = steps.argsort()
>>> values = stepper.values[stepper.successes][ix]
>>> errors = abs(values[1:] - values[:-1]) / errorscale

Check that the post hoc error satisfies the desired tolerance.

>>> print(max(errors) < 1.)
True

(Source code)

(Source code, png, hires.png, pdf)

Plot of successful steps and trajectory of attempts.
property errors

ndarray of the “error” at each step attempt.

The user-determined “error” scalar value (positive and normalized to 1) at each step attempt is passed to Stepper via succeeded().

next()

Return the next step.

Note

Legacy Python 2.7 support.

Return type:

Step

Raises:

StopIteration – If there are no further steps to take

property sizes

ndarray of the step size at each step attempt.

property steps

ndarray of values of the control variable attempted so far.

succeeded(step, value=None, error=None)

Test if step was successful.

Stores data about the last step.

Parameters:
  • step (Step) – The step to test.

  • value (float, optional) – User-determined scalar value that characterizes the last step. Whether this parameter is required depends on which Stepper is being used. (default None).

  • error (float, optional) – User-determined error (positive and normalized to 1) from the last step. Whether this parameter is required depends on which Stepper is being used. (default None).

Returns:

Whether step was successful.

Return type:

bool

property successes

ndarray of whether the step was successful at each step attempt.

property values

ndarray of the “value” at each step attempt.

The user-determined scalar value at each step attempt is passed to Stepper via succeeded().