Source code for aceso.decay
"""A suite of decay functions to simulate demand dropoff as distance increases.
All decay functions operate on one-dimensional numpy arrays.
"""
# TODO: Add the standard gravity decay function d**(-beta).
# TODO: Add linear decay (or other polynomial interpolation).
import math
import numpy as np
[docs]def parabolic_decay(distance_array, scale):
"""
Transform a measurement array using the Epanechnikov (parabolic) kernel.
Some sample values. Measurements are in multiple of ``scale``; decay value are in fractions of
the maximum value:
+---------------+---------------+
| measurement | decay value |
+===============+===============+
| 0.0 | 1.0 |
+---------------+---------------+
| 0.25 | 0.9375 |
+---------------+---------------+
| 0.5 | 0.75 |
+---------------+---------------+
| 0.75 | 0.4375 |
+---------------+---------------+
| 1.0 | 0.0 |
+---------------+---------------+
"""
return np.maximum(
(scale**2 - distance_array**2) / scale**2,
np.zeros(shape=distance_array.shape)
)
[docs]def gaussian_decay(distance_array, sigma):
"""
Transform a measurement array using a normal (Gaussian) distribution.
Some sample values. Measurements are in multiple of ``sigma``; decay value are in fractions of
the maximum value:
+---------------+---------------+
| measurement | decay value |
+===============+===============+
| 0.0 | 1.0 |
+---------------+---------------+
| 0.7582 | 0.75 |
+---------------+---------------+
| 1.0 | 0.60647 |
+---------------+---------------+
| 1.17 | 0.5 |
+---------------+---------------+
| 2.0 | 0.13531 |
+---------------+---------------+
"""
return np.exp(-(distance_array**2 / (2.0 * sigma**2)))
[docs]def raised_cosine_decay(distance_array, scale):
"""
Transform a measurement array using a raised cosine distribution.
Some sample values. Measurements are in multiple of ``scale``; decay value are in fractions of
the maximum value:
+---------------+---------------+
| measurement | decay value |
+===============+===============+
| 0.0 | 1.0 |
+---------------+---------------+
| 0.25 | 0.853553 |
+---------------+---------------+
| 0.5 | 0.5 |
+---------------+---------------+
| 0.75 | 0.146447 |
+---------------+---------------+
| 1.0 | 0.0 |
+---------------+---------------+
"""
masked_array = np.clip(a=distance_array, a_min=0.0, a_max=scale)
return (1.0 + np.cos((masked_array / scale) * math.pi)) / 2.0
[docs]def get_decay_function(name):
"""
Return the decay function with the given name.
Parameters
----------
name : str
The name of the requested decay function.
Available names:
- ``'uniform'``
- ``'raised_cosine'``
- ``'gaussian'``
- ``'parabolic'``
"""
return NAME_TO_FUNCTION_MAP[name.lower()]
NAME_TO_FUNCTION_MAP = {
'uniform': uniform_decay,
'raised_cosine': raised_cosine_decay,
'gaussian': gaussian_decay,
'parabolic': parabolic_decay,
'epanechnikov': parabolic_decay
}