Skip to content

Commit

Permalink
improving distribution docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrew McCluskey committed Apr 23, 2020
1 parent 4806a1d commit f69180a
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 38 deletions.
7 changes: 6 additions & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,6 @@
html_logo = "logo/uravu_logo.png"
html_theme_options = {"logo_only": True}


# -- Extension configuration -------------------------------------------------

# -- Options for todo extension ----------------------------------------------
Expand All @@ -189,3 +188,9 @@

def setup(app):
app.add_css_file('custom.css')

# Looks for objects in external projects
intersphinx_mapping = {
'pint': ('https://pint.readthedocs.io/en/0.11/', None),
'scipy': ('https://docs.scipy.org/doc/scipy/reference/', None),
}
21 changes: 21 additions & 0 deletions docs/source/faq.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
FAQ
===

- How does one assign units to a :py:class:`~uravu.distribution.Distribution` object?

:py:mod:`~uravu` allows the use of the :py:mod:`~pint` module for the definition of units to be associated with :py:class:`~uravu.distribution.Distribution` objects.
The :func:`uravu.distribution.Distribution.__init__()` function includes a keyword argument :py:attr:`unit` where the :py:class:`~pint.unit.Unit` object should be assigned.
However, to `avoid creating multiple unit registries`_, :py:mod:`~uravu` is packaged with a :py:class:`~pint.UnitRegistry`.
Therefore, if you wish to create a :py:class:`~uravu.distribution.Distribution` where the :py:attr:`unit` is metres, the following syntax should be used.

.. code-block:: python
import numpy as np
from uravu import UREG
from uravu.distribution import Distribution
sample = np.random.randn(100)
my_distribution = Distribution(sample, name='Random Distribution', units=UREG.meter)
.. _avoid creating multiple unit registries: https://pint.readthedocs.io/en/0.11/tutorial.html#using-pint-in-your-projects
1 change: 1 addition & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ To see which publications you should reference in your work, the :class:`Relatio
installation
getting_started.ipynb
tutorials
faq
api

Searching
Expand Down
64 changes: 27 additions & 37 deletions uravu/distribution.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""
The Distribution class allows the storage and analysis of probability
distributions.
The storage and manipulation of probability distributions is fundamental to the operation of ``uravu`` and Bayesian inference.
The :py:class:`~uravu.distribution.Distribution` class oversees these operations.
"""

# Copyright (c) Andrew R. McCluskey
Expand All @@ -15,27 +15,22 @@

class Distribution:
"""
The storage of probability distributions is fundamental to Bayesian
inference, this class enables this. In addition to storage some basic
analysis of the distribution is possible.
In addition to storage of the probability distribution, this class allows for some basic analysis, such as determination of normality.
Attributes:
samples (array_like): Samples in the distribution.
name (str): A name for the distribution.
ci_points (array_like): The percentiles at which
confidence intervals should be found.
unit (pint.UnitRegistry()): The unit of the values in the
Distribution.
samples (:py:attr:`array_like`): Samples in the distribution.
name (:py:attr:`str`): Distribution name.
ci_points (:py:attr:`array_like`): The percentiles at which confidence intervals should be found.
unit (:py:class:`~pint.unit.Unit`): The unit of the values in the Distribution.
normal (:py:attr:`bool`): Are the samples normally distributed?
Args:
samples (array_like): Sample for the distribution.
name (str, optional): A name to identify the distribution.
Default is `Distribution`.
ci_points (array_like, optional): The percentiles at which
confidence intervals should be found. Default is
`[2.5, 97.5]` (a 95 % confidence interval).
unit (pint.UnitRegistry(), optional) The unit for the
distribution. Default is dimensionless.
samples (:py:attr:`array_like`): Sample for the distribution.
name (:py:attr:`str`, optional): A name to identify the distribution. Default is :py:attr:`'Distribution'`.
ci_points (:py:attr:`array_like`, optional): The two percentiles at which confidence intervals should be found. Default is :py:attr:`[2.5, 97.5]` (a 95 % confidence interval).
unit (:py:class:`~pint.unit.Unit`, optional): The unit for the distribution. For information about unit assignment see the `FAQ`_. Default is :py:attr:`~pint.unit.Unit.dimensionless`.
.. _FAQ: ./faq.html
"""

def __init__(
Expand All @@ -46,7 +41,7 @@ def __init__(
unit=UREG.dimensionless,
):
"""
Initialisation function for a ``Distribution`` object.
Initialisation function for a :py:class:`~uravu.distribution.Distribution` object.
"""
self.name = name
self.unit = unit
Expand All @@ -68,14 +63,13 @@ def size(self):
Get the number of samples in the distribution.
Returns:
(int): Number of samples.
:py:attr:`int`: Number of samples.
"""
return self.samples.size

def check_normality(self):
"""
Uses a Shapiro-Wilks statistical test to evaluate if samples are
normally distributed.
Uses a :func:`scipy.stats.normaltest()` to evaluate if samples are normally distributed and updates the :py:attr:`~uravu.distribution.Distribution.normal` attribute.
"""
alpha = 0.05
if self.size <= 8:
Expand All @@ -92,22 +86,20 @@ def check_normality(self):
@property
def n(self):
"""
Get the median value of the distribution (for a normal distribution
this is the same as the mean).
Get the median value of the distribution (for a normal distribution this is the same as the mean).
Returns:
(float): Median value.
:py:attr:`float`: Median value.
"""
return np.percentile(self.samples, [50])[0]

@property
def s(self):
"""
Get the standard deviation of the distribution. For a non-normal
distribution, this will return ``None``.
Get the standard deviation of the distribution. For a non-normal distribution, this will return :py:attr:`None`.
Returns:
(float, or None): Standard deviation of the distribution.
:py:attr:`float` or :py:attr:`None`: Standard deviation of the distribution.
"""
if self.normal:
return np.std(self.samples)
Expand All @@ -120,17 +112,16 @@ def con_int(self):
Get the extrema of the confidence intervals of the distribution.
Returns:
(array_like): The confidence interval values.
:py:attr:`array_like`: Distribution values at the confidence interval.
"""
return np.percentile(self.samples, self.ci_points)

def __repr__(self):
"""
A custom representation, which is the same as the custom string
representation.
A custom representation, which is the same as the custom string representation.
Returns:
(str): String representation.
:py:attr:`str`: Description of the distribution.
"""
return self.__str__()

Expand All @@ -139,7 +130,7 @@ def __str__(self):
A custom string.
Returns:
(str): Detailed string representation.
:py:attr:`str`: Description of the distribution.
"""
representation = "Distribution: {}\nSize: {}\n".format(
self.name, self.size
Expand Down Expand Up @@ -177,11 +168,10 @@ def __str__(self):

def add_samples(self, samples):
"""
Add samples to the distribution and update values such as median and
uncertainties as appropriate.
Add samples to the distribution.
Args:
samples (array_like): Samples to be added to the distribution.
samples (:py:attr:`array_like`): Samples to be added to the distribution.
"""
self.samples = np.append(self.samples, np.array(samples).flatten())
self.check_normality()

0 comments on commit f69180a

Please sign in to comment.