Metadata-Version: 2.2
Name: auto_uncertainties
Version: 0.6.3
Summary: Linear Uncertainty Propagation with Auto-Differentiation
Author-email: Varchas Gopalaswamy <vgop@lle.rochester.edu>, Ethan Mentzer <ementzer@u.rochester.edu>
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.23.0
Requires-Dist: jax>=0.3.14
Requires-Dist: jaxlib>=0.3.14
Requires-Dist: joblib>=1.2.0
Requires-Dist: loguru>=0.6.0
Requires-Dist: lazy_loader==0.4
Provides-Extra: ci
Requires-Dist: pytest; extra == "ci"
Requires-Dist: pytest-cov; extra == "ci"
Requires-Dist: hypothesis; extra == "ci"
Requires-Dist: pylint; extra == "ci"
Requires-Dist: pint; extra == "ci"
Provides-Extra: pandas
Requires-Dist: pandas>=1.5.1; extra == "pandas"
Provides-Extra: docs
Requires-Dist: sphinx>=4.1.2; extra == "docs"
Requires-Dist: sphinx_rtd_theme>=1.0.0; extra == "docs"
Requires-Dist: sphinxcontrib-bibtex>=2.3.1; extra == "docs"
Requires-Dist: sphinxcontrib-napoleon>=0.7; extra == "docs"
Requires-Dist: sphinx-autodoc-typehints; extra == "docs"
Requires-Dist: sphinx-copybutton; extra == "docs"
Requires-Dist: sphinx-design; extra == "docs"
Requires-Dist: graphviz; extra == "docs"
Requires-Dist: sphinx-autoapi; extra == "docs"
Requires-Dist: furo; extra == "docs"


# AutoUncertainties

AutoUncertainties is a package that makes handling linear uncertainty propagation for scientific applications 
straightforward and automatic using auto-differentiation.

* View the [full documentation here](https://autouncertainties.readthedocs.io/en/latest/). 

## Supported Features

- [x] Scalars
- [x] Arrays, with support for most NumPy ufuncs and functions
- [ ] Pandas Extension Type (see [here](https://pandas.pydata.org/docs/reference/api/pandas.api.extensions.ExtensionDtype.html))

## Prerequisites

For array support:

* `jax`
* `jaxlib`
* `numpy`

## Installation

To install, simply run:

```
pip install auto_uncertainties
```

## Build Documentation

To build the documentation locally, clone the repository, create a virtual Python environment 
(if desired), and run the following commands within the repository directory:

```bash
pip install auto_uncertainties[docs]
sphinx-build docs/source docs/build
```

Once built, the docs can be found under the `docs/build` subdirectory.

## Basic Usage

* Creating a scalar `Uncertainty` variable is relatively simple:

  ```python
  >>> from auto_uncertainties import Uncertainty
  >>> value = 1.0
  >>> error = 0.1
  >>> u = Uncertainty(value, error)
  >>> u
  1 +/- 0.1
  ```
  
  As is creating a NumPy array of Uncertainties:

  ```python
  >>> from auto_uncertainties import Uncertainty
  >>> import numpy as np
  >>> value = np.linspace(start=0, stop=10, num=5)
  >>> error = np.ones_like(value)*0.1
  >>> u = Uncertainty(value, error)
  ```

  - (though, they are actually different classes!)

    ```python
    >>> from auto_uncertainties import Uncertainty
    >>> value = 1.0
    >>> error = 0.1
    >>> u = Uncertainty(value, error)
    >>> type(u)
    <class 'auto_uncertainties.uncertainty.uncertainty_containers.ScalarUncertainty'>
    ```

    ```python
    >>> from auto_uncertainties import Uncertainty
    >>> import numpy as np
    >>> value = np.linspace(start=0, stop=10, num=5)
    >>> error = np.ones_like(value)*0.1
    >>> u = Uncertainty(value, error)
    >>> type(u)
    <class 'auto_uncertainties.uncertainty.uncertainty_containers.VectorUncertainty'>
    ```

* Scalar uncertainties implement all mathematical and logical 
  [dunder methods](https://docs.python.org/3/reference/datamodel.html#object.__repr__>) explicitly using linear
  uncertainty propagation.

  ```python
  >>> from auto_uncertainties import Uncertainty
  >>> u = Uncertainty(10.0, 3.0)
  >>> v = Uncertainty(20.0, 4.0)
  >>> u + v
  30 +/- 5
  ```

* Array uncertainties implement a large subset of the NumPy ufuncs and methods using `jax.grad` or 
  `jax.jacfwd`, depending on the output shape.

  ```python
  >>> from auto_uncertainties import Uncertainty
  >>> import numpy as np
  >>> value = np.linspace(start=0, stop=10, num=5)
  >>> error = np.ones_like(value)*0.1
  >>> u = Uncertainty(value, error)
  >>> np.exp(u)
  [1 +/- 0.1, 12.1825 +/- 1.21825, 148.413 +/- 14.8413, 1808.04 +/- 180.804, 22026.5 +/- 2202.65]
  >>> np.sum(u)
  25 +/- 0.223607
  >>> u.sum()
  25 +/- 0.223607
  >>> np.sqrt(np.sum(error**2))
  0.223606797749979
  ```

* The central value, uncertainty, and relative error are available as attributes:

  ```python
  >>> from auto_uncertainties import Uncertainty
  >>> u = Uncertainty(10.0, 3.0)
  >>> u.value
  10.0
  >>> u.error
  3.0
  >>> u.rel
  0.3
  ```

* To strip central values and uncertainty from arbitrary variables, accessor functions `nominal_values`
  and `std_devs` are provided:

  ```python
  >>> from auto_uncertainties import nominal_values, std_devs
  >>> u = Uncertainty(10.0, 3.0)
  >>> v = 5.0
  >>> nominal_values(u)
  10.0
  >>> std_devs(u)
  3.0
  >>> nominal_values(v)
  5.0
  >>> std_devs(v)
  0.0
  ```

* Displayed values are automatically rounded according to the Particle Data Group standard. 
  This can be turned off using `set_display_rounding`:

  ```python
  >>> from auto_uncertainties import set_display_rounding
  >>> set_display_rounding(False)
  >>> from auto_uncertainties import Uncertainty
  >>> import numpy as np
  >>> value = np.linspace(start=0, stop=10, num=5)
  >>> error = np.ones_like(value)*0.1
  >>> u = Uncertainty(value, error)
  >>> np.sum(u)
  25 +/- 0.223607
  ```

* If `numpy.array` is called on an `Uncertainty` object, it will automatically get cast down to a numpy array (and lose 
  uncertainty information!), and emit a warning. To make this an error, use `set_downcast_error`:

  ```python
  >>> from auto_uncertainties import set_downcast_error
  >>> set_downcast_error(True)
  >>> from auto_uncertainties import Uncertainty
  >>> import numpy as np
  >>> value = np.linspace(start=0, stop=10, num=5)
  >>> error = np.ones_like(value)*0.1
  >>> u = Uncertainty(value, error)
  >>> np.array(u)
  Traceback (most recent call last):
      ...
  auto_uncertainties.exceptions.DowncastError: The uncertainty is stripped when downcasting to ndarray.
  ```

## Inspirations

The class structure of `Uncertainty` and the `NumPy` ufunc implementation is heavily inspired by the 
excellent package [Pint](https://github.com/hgrecco/pint).
