The sparse convolution algorithm is an effective way to generate a noise signal, which can among other things then be used to simulate noisy inputs. The original presentation by Lewis (1989), as well as most subsequent implementations, focus on applications to computer graphics. Here the implementation is geared more towards scientific applications; in this context we find the sparse convolution algorithm convenient for a number of reasons:
- The returned noise function is dense (or solid): it can be evaluated at any t.
- The algorithm allows quite a lot of control over the statistics of the noise, and in particular of its autocorrelation function.
- The algorithm does not rely on performing FFTs, and thus avoids all the pitfalls those entail. It is also faster to evaluate, and does not struggle with long time traces.
For more information on how this works, see the doc page.
In applications, often we characterize signals by their autocorrelation function; when we want to characterize them by a single number, that number is generally the correlation time, describing the width the of autocorrelation function. Computing the autocorrelation function for a given stochastic system is often a difficult analytical problem. Therefore, an algorithm which promises to solve the inverse problem – going from autocorrelation function to a noise – is a valuable tool in the practitioner’s toolkit. This is what the sparse convolution algorithm purports to offer.
This particular implementation focuses on the case where a user desires to generate noise with a particular correlation time. At present only a single class is provided, which generates noise signals with Gaussian autocorrelation. In use one simply specifies the desired time range, correlation time and noise strength:
from colored_noise_sc import ColoredNoise
noise = ColoredNoise(0, 10, scale=2.4, corr_time=1.2)
Then one simply evaluates the noise at any time t
:
noise(t)
Specifying values with pint
units is supported, which can be an effective way to sanity-check your calculations.
Conveniently, because the produced noise is dense, it can even be used in integration schemes like adaptive Runge-Kutta, where the required time points are not known ahead of time.
The noise
object has a few convenience methods, most notably autocorr
which evaluates the theoretical autocorrelation.
Noise parameters can be specified with Pint units, which can be an effective way to validate calculations. This does add measurable overhead (it is about 15x slower per call), so for performance-critical code, one will see significant speed-up by switching to plain NumPy arrays.
(Note that pint
's overhead is not that large. So the fact that we see such a large speed-up is more a reflection of the efficiency with which the sparse convolution algorithm can be implemented.)
If JAX is installed, ColoredNoise
will use JAX arrays and operations in its noise generation call. This allows it to be jitted with jax.jit
.
Jitting the noise generator on its own does not provide much benefit (it is already quite efficient), but this allows it to be used within a larger function, and still jit that entire function. This is useful for example to compile differential equations which will then be integrated with an ODE solver.
-
From PyPI
This package can be installed from PyPI with the usual command:
pip install colored-noise-sc
If all you need is a colored noise with Gaussian autocorrelation, a pip install
is certainly the easiest method.
That said, if you need anything more, you are encouraged to use one of the methods below to include the source file directly into your code base. This has a few advantages:
-
It makes it easy to make modifications to add new functionality.
-
It ensures that people who download your code always get the current version of
colored-noise-sc
, with any potential patches. -
It encourages you to take ownership of the code, and maybe peek inside if things don’t work exactly as you expect.
-
Direct copy Everything is contained in the file colored_noise.py – about 150 lines of code and 400 lines of documentation & validation. So a very reasonably option is actually to just copy the file into your project and import it as any other module.
-
As a subrepo A more sophisticated option is to clone this repo directly into your project with git-subrepo:
git subrepo clone https://github.com/alcrene/colored-noise my-project/colored-noise`
This creates a directory under my-project/colored-noise containing the files in this repo – effectively colored-noise becomes a subpackage of your own. You can then import the noise class as with any subpackage:
from colored_noise import ColoredNoise
or
from my_project.colored_noise import ColoredNoise
The main advantage of a subrepo installation is that it makes it easy to pull code updates:
git subrepo pull my-project/colored-noise
It also makes it easier to open pull requests.
The only dependencies are NumPy. If you want to build the docs yourself, they you also need:
- SciPy
- HoloViews
- Matplotlib
- Pint
- Jupytext
- Jupyter-Book
- ghp-import (optional)
First make sure that the above dependencies are installed, and then that Jupyter Notebook version of the code file colored_noise exists. The occurs automatically when you open it in the Jupyter Lab interface with "Open as notebook"1, and then click "Save". Alternatively, you can run jupytext --sync colored_noise.py
.
The actual build command is then
jb build colored_noise.ipynb
This will produce some HTML files inside a _build folder. For this package we build the docs in a separate gh-pages
branch, so that users can pull the source without pulling the docs. This is done automatically by ghp-import
:
ghp-import -n -p _build/_page/colored_noise/html
See the Jupyter Book docs for more information.
Footnotes
-
The "Open as notebook" context menu item is provided by the Jupytext plugin. ↩