Skip to content

Commit

Permalink
Merge pull request #7 from varchasgopalaswamy/main
Browse files Browse the repository at this point in the history
Preliminary Pandas support
  • Loading branch information
varchasgopalaswamy authored Jun 11, 2024
2 parents 31612c1 + 60e697e commit 8c60dc6
Show file tree
Hide file tree
Showing 38 changed files with 3,271 additions and 2,042 deletions.
23 changes: 23 additions & 0 deletions .github/workflows/draft-pdf.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
on: [push]

jobs:
paper:
runs-on: ubuntu-latest
name: Paper Draft
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build draft PDF
uses: openjournals/openjournals-draft-action@master
with:
journal: joss
# This should be the path to the paper within your repo.
paper-path: paper/paper.md
- name: Upload
uses: actions/upload-artifact@v1
with:
name: paper
# This is the output path where Pandoc will write the compiled
# PDF. Note, this should be the same directory as the input
# paper.md
path: paper/paper.pdf
13 changes: 7 additions & 6 deletions .github/workflows/python-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11"]
python-version: ["3.11"]

steps:
- uses: actions/checkout@v3
Expand All @@ -19,11 +19,12 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pylint pytest pytest-cov hypothesis
pip install .[pandas]
- name: Lint with pylint
pip install pre-commit pytest pytest-cov hypothesis
pre-commit install
pip install .[CI]
- name: Run pre-commit checks
run: |
pylint --fail-under=8 auto_uncertainties
pre-commit run --all-files
- name: Test with pytest
run: |
pytest --cov=auto_uncertainties --cov-report=xml --cov-report=html -k "not pandas"
pytest --cov=auto_uncertainties --cov-report=xml --cov-report=html --ignore=tests/pandas
55 changes: 29 additions & 26 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,34 +1,37 @@
repos:

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.0.275
hooks:
- id: ruff
args: [ --fix, --exit-non-zero-on-fix ]

- repo: https://github.com/psf/black.git
rev: 23.1.0
hooks:
- id: black
language_version: python3.9

- repo: https://github.com/pycqa/isort
rev: 5.12.0
- repo: local
hooks:
- id: isort
name: isort (python)

- id: generate-init
name: Generates __init__.py files
language: python
entry: python hooks/generate_init.py
always_run: true
require_serial: true
additional_dependencies: ["mkinit", "ruff"]

- id: fix-line-endings
name: Convert CRLF/CR endings to LF
language: python
require_serial: true
entry: python hooks/fix_line_endings.py
types: ["text"]

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: v4.6.0
hooks:
- id: end-of-file-fixer
- id: fix-encoding-pragma
- id: trailing-whitespace
- id: check-added-large-files
- id: check-ast
- id: check-case-conflict
- id: check-executables-have-shebangs
- id: check-merge-conflict
- id: check-symlinks
- id: debug-statements
- id: mixed-line-ending

- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.4.6
hooks:
#Run the formatter.
- id: ruff-format
types_or: [ python, pyi, jupyter ]
#Run the linter.
- id: ruff
types_or: [ python, pyi, jupyter ]
args: [ --fix, --exit-zero ]
95 changes: 69 additions & 26 deletions README.rst → README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,3 @@
.. image:: https://img.shields.io/pypi/v/auto-uncertainties.svg
:target: https://pypi.org/project/auto-uncertainties/
:alt: Latest Version

.. image:: https://img.shields.io/pypi/l/auto-uncertainties.svg
:target: https://pypi.org/project/auto-uncertainties/
:alt: License

.. image:: https://github.com/varchasgopalaswamy/AutoUncertainties/actions/workflows/python-app.yml/badge.svg
:target: https://github.com/varchasgopalaswamy/AutoUncertainties/actions?query=workflow
:alt: Tests

AutoUncertainties
========================
Expand All @@ -29,75 +18,129 @@ Usage

Creating a scalar Uncertainty variable is relatively simple:

.. code-block:: python
```python
>>> from auto_uncertainties import Uncertainty
>>> value = 1.0
>>> error = 0.1
>>> u = Uncertainty(value,error)
>>> u
1.0 +/- 0.1
```

as is creating a numpy array of Uncertainties:

.. code-block:: python
```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)
auto_uncertainties.uncertainty.ScalarUncertainty

>>> 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)
>>> u
[ 0. 2.5 5. 7.5 10. ] +/- [0.1 0.1 0.1 0.1 0.1]
auto_uncertainties.uncertainty.VectorUncertainty
```

Scalar uncertainties implement all mathematical and logical `dunder methods <https://docs.python.org/3/reference/datamodel.html#object.__repr__>`_ explicitly.

.. code-block:: python
```python

>>> from auto_uncertainties import Uncertainty
>>> u = Uncertainty(10.0, 3.0)
>>> v = Uncertainty(20.0, 4.0)
>>> u + v
30.0 +/- 5.0
```
Array uncertainties implement a large subset of the numpy ufuncs and methods using :code:`jax.grad` or :code:`jax.jacfwd`, depending on the output shape.

.. code-block:: python
```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.00000000e+00 1.21824940e+01 1.48413159e+02 1.80804241e+03
2.20264658e+04] +/- [1.00000000e-01 1.21824940e+00 1.48413159e+01 1.80804241e+02
2.20264658e+03]
Magnitude

1, 12.182, 148.413, 1808.04, 22026.5

Error

0.1, 1.2, 15, 180, 2200
>>> np.sum(u)
25.0 +/- 0.223606797749979
25.0 +/- 0.22
>>> u.sum()
25.0 +/- 0.223606797749979
25.0 +/- 0.22
>>> np.sqrt(np.sum(error**2))
0.223606797749979
```
The mean value and the standard deviation (the measurements are assumed to be normally distributed) can be accessed via

.. code-block:: python
```python

>>> from auto_uncertainties import Uncertainty
>>> u = Uncertainty(10.0, 3.0)
>>> u.value
10.0
>>> u.error
3.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 +/- 0.223606797749979
```
If `np.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(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.array(u)

Exception: The uncertainty is stripped when downcasting to ndarray.
```



Prerequisites
===========

For array support:

* jax
* jaxlib (must be built from source if you are not on Linux machine with AVX instruction sets.)
* jaxlib
* numpy


Expand Down
97 changes: 33 additions & 64 deletions auto_uncertainties/__init__.py
Original file line number Diff line number Diff line change
@@ -1,66 +1,35 @@
# -*- coding: utf-8 -*-
from __future__ import annotations

import numpy as np


class NegativeStdDevError(Exception):
"""An exception for when the standard deviation is negative"""

pass


class NumpyDowncastWarning(RuntimeWarning):
"""An exception for when an uncertainties array is downcast to a numpy array"""

pass


from .uncertainty import Uncertainty # noqa: E402

try:
from .pandas_compat import UncertaintyArray
except ImportError:
UncertaintyArray = None


def nominal_values(x):
# Is an Uncertainty
if hasattr(x, "_nom"):
return x.value
else:
if np.ndim(x) > 0:
try:
x2 = Uncertainty.from_sequence(x)
except Exception:
return x
else:
return x2.value
else:
try:
x2 = Uncertainty(x)
except Exception:
return x
else:
return x2.value


def std_devs(x):
# Is an Uncertainty
if hasattr(x, "_err"):
return x.error
else:
if np.ndim(x) > 0:
try:
x2 = Uncertainty.from_sequence(x)
except Exception:
return np.zeros_like(x)
else:
return x2.error
else:
try:
x2 = Uncertainty(x)
except Exception:
return 0
else:
return x2.error
__private__ = ["util"]
__protected__ = ["numpy"]
import lazy_loader


__getattr__, __dir__, __all__ = lazy_loader.attach_stub(__name__, __file__)

__all__ = [
"DowncastError",
"DowncastWarning",
"NegativeStdDevError",
"ScalarDisplay",
"ScalarUncertainty",
"Uncertainty",
"UncertaintyArray",
"UncertaintyDtype",
"VectorDisplay",
"VectorUncertainty",
"display_format",
"exceptions",
"nominal_values",
"numpy",
"pandas",
"set_compare_error",
"set_display_rounding",
"set_downcast_error",
"std_devs",
"unc_array",
"unc_dtype",
"uncertainty",
"uncertainty_containers",
"util",
]
Loading

0 comments on commit 8c60dc6

Please sign in to comment.