Chaospy - Toolbox for performing uncertainty quantification.
.. image:: https://github.com/jonathf/chaospy/raw/master/docs/static/chaospylogo.svg :height: 200 px :width: 200 px :align: center
|circleci| |codecov| |readthedocs| |downloads| |pypi| |binder|
.. |circleci| image:: https://img.shields.io/circleci/build/github/jonathf/chaospy/master :target: https://circleci.com/gh/jonathf/chaospy/tree/master .. |codecov| image:: https://img.shields.io/codecov/c/github/jonathf/chaospy :target: https://codecov.io/gh/jonathf/chaospy .. |readthedocs| image:: https://img.shields.io/readthedocs/chaospy :target: https://chaospy.readthedocs.io/en/master/?badge=master .. |downloads| image:: https://img.shields.io/pypi/dm/chaospy :target: https://pypistats.org/packages/chaospy .. |pypi| image:: https://img.shields.io/pypi/v/chaospy :target: https://pypi.org/project/chaospy .. |binder| image:: https://mybinder.org/badge_logo.svg :target: https://mybinder.org/v2/gh/jonathf/chaospy/master?filepath=docs%2Ftutorials
Chaospy is a numerical tool for performing uncertainty quantification using polynomial chaos expansions and advanced Monte Carlo methods implemented in Python.
Documentation_
Interactive tutorials with Binder_
Source code_
Issue tracker_
Code of Conduct_
Contribution Guideline_
Changelog_
Installation should be straight forward using
pip_:
.. code-block:: bash
$ pip install chaospy
For more installation details, see the
installation guide_.
chaospyis created to work well inside numerical Python ecosystem. You therefore typically need to import
Numpy_ along side
chaospy:
.. code-block:: python
>>> import numpy >>> import chaospy
chaospyis problem agnostic, so you can use your own code using any means you find fit. The only requirement is that the output is compatible with
numpy.ndarrayformat:
.. code-block:: python
>>> coordinates = numpy.linspace(0, 10, 100)>>> def forward_solver(coordinates, parameters): ... """Function to do uncertainty quantification on.""" ... param_init, param_rate = parameters ... return param_initnumpy.e**(-param_ratecoordinates)
We here assume that
parameterscontains aleatory variability with known probability. We formalize this probability in
chaospyas a joint probability distribution. For example:
.. code-block:: python
>>> distribution = chaospy.J(chaospy.Uniform(1, 2), chaospy.Normal(0, 2))>>> print(distribution) J(Uniform(lower=1, upper=2), Normal(mu=0, sigma=2))
Most probability distributions have an associated expansion of orthogonal polynomials. These can be automatically constructed:
.. code-block:: python
>>> expansion = chaospy.generate_expansion(8, distribution)>>> print(expansion[:5].round(8)) [1.0 q1 q0-1.5 q0q1-1.5q1 q0*2-3.0q0+2.16666667]
Here the polynomial is defined positional, such that
q0and
q1refers to the uniform and normal distribution respectively.
The distribution can also be used to create (pseudo-)random samples and low-discrepancy sequences. For example to create Sobol sequence samples:
.. code-block:: python
>>> samples = distribution.sample(1000, rule="sobol")>>> print(samples[:, :4].round(8)) [[ 1.5 1.75 1.25 1.375 ] [ 0. -1.3489795 1.3489795 -0.63727873]]
We can evaluating the forward solver using these samples:
.. code-block:: python
>>> evaluations = numpy.array([forward_solver(coordinates, sample) ... for sample in samples.T])>>> print(evaluations[:3, :5].round(8)) [[1.5 1.5 1.5 1.5 1.5 ] [1.75 2.00546578 2.29822457 2.63372042 3.0181921 ] [1.25 1.09076905 0.95182169 0.83057411 0.72477163]]
Having all these components in place, we have enough components to perform point collocation. Or in other words, we can create a polynomial approximation of
forward_solver:
.. code-block:: python
>>> approx_solver = chaospy.fit_regression(expansion, samples, evaluations)>>> print(approx_solver[:2].round(4)) [q0 -0.0002q0q13+0.0051q0q12-0.101q0q1+q0]
Since the model approximations are polynomials, we can do inference on them directly. For example:
.. code-block:: python
>>> expected = chaospy.E(approx_solver, distribution) >>> deviation = chaospy.Std(approx_solver, distribution)>>> print(expected[:5].round(8)) [1.5 1.53092356 1.62757217 1.80240142 2.07915608] >>> print(deviation[:5].round(8)) [0.28867513 0.43364958 0.76501802 1.27106355 2.07110879]
For more extensive guides on this approach an others, see the
tutorial collection_.
.. _tutorial collection: https://chaospy.readthedocs.io/en/master/tutorials