Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor RandomVariable #164

Merged
Show file tree
Hide file tree
Changes from 46 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
ef0e8e3
Refactor RandomVariable and merge with Distribution
marvinpfoertner Aug 19, 2020
fbf3b1c
Move all random variables into own package
marvinpfoertner Aug 20, 2020
f79c8d3
Fix dependencies
marvinpfoertner Aug 20, 2020
38b7bc5
Fix test
marvinpfoertner Aug 20, 2020
8fabd9b
Fix pylint
marvinpfoertner Aug 20, 2020
b05524e
Bugfixes
marvinpfoertner Aug 21, 2020
50660c2
Fix a few issues from review
marvinpfoertner Aug 21, 2020
315ce40
Make pylint happy
marvinpfoertner Aug 21, 2020
f0da164
Get rid of properties constructor argument
marvinpfoertner Aug 21, 2020
39098a8
Make dtype and shape required constructor args and remove shape infer…
marvinpfoertner Aug 21, 2020
4115321
Make ValueType private
marvinpfoertner Aug 21, 2020
b488c8e
Fix some type annotations
marvinpfoertner Aug 21, 2020
98030cd
Create probnum.core package
marvinpfoertner Aug 24, 2020
a5f2188
Add subclasses for continuous/discrete random variables
marvinpfoertner Aug 24, 2020
63e3432
Normal random variable should cast arguments to floating point dtype
marvinpfoertner Aug 24, 2020
5e2af89
Exclude Normal distributions with operator mean and dense covariance
marvinpfoertner Aug 24, 2020
4b964fc
Add type hints in `probnum.core`
marvinpfoertner Aug 25, 2020
541d709
Only continuous RVs should have pdfs
marvinpfoertner Aug 25, 2020
f5b1bd7
Add additional type hints
marvinpfoertner Aug 26, 2020
26af11b
Move modules in probnum.core to top level
marvinpfoertner Aug 26, 2020
df5a36a
Fix rebase bugs
marvinpfoertner Aug 26, 2020
1c8a91f
Refactor normal to make it even simpler
marvinpfoertner Aug 27, 2020
cd5c487
Fix pylint and black errors
marvinpfoertner Aug 27, 2020
93aebe2
Make random variable properties immutable
marvinpfoertner Aug 27, 2020
c7be87d
Entropy and (log){cdf, pdf, pmf} should only return `np.float_`
marvinpfoertner Aug 27, 2020
c616d62
Moments and median might have different type than outcomes
marvinpfoertner Aug 27, 2020
8b9b4c6
Quantile function return value checking
marvinpfoertner Aug 27, 2020
a23beb8
Bugfix
marvinpfoertner Aug 27, 2020
445ba2a
Fix scipy random variable conversion
marvinpfoertner Aug 27, 2020
40279b0
Fix pylint error
marvinpfoertner Aug 27, 2020
57d9f66
Enable pylint check "missing-module-docstring" in random_variables
marvinpfoertner Aug 27, 2020
6439ce3
Simplify random variable arithmetic
marvinpfoertner Aug 27, 2020
9b029db
Less cyclic imports
marvinpfoertner Aug 28, 2020
65879ec
Clean up typing
marvinpfoertner Aug 28, 2020
2c370c6
Additional value checks for cdf, pdf, pmf
marvinpfoertner Aug 28, 2020
3ad4442
Bugfixes
marvinpfoertner Aug 28, 2020
acf6829
Move Normal - Dirac Arithmetic to _arithmetic to break cyclic imports
marvinpfoertner Aug 28, 2020
71b7817
Make pylint fixme disabled
marvinpfoertner Aug 28, 2020
8630cb5
Fix docs
marvinpfoertner Aug 28, 2020
ebb45fe
Fix symmetric normal sampling
marvinpfoertner Aug 28, 2020
dc2424b
Bugfixes for Jupyter notebooks
marvinpfoertner Aug 28, 2020
5f3fdb1
Further doc fixes
marvinpfoertner Aug 28, 2020
87f9c53
Fix benchmarks
marvinpfoertner Aug 28, 2020
3bb1a9b
Add test case which creates a normal from integer parameters
marvinpfoertner Aug 28, 2020
cec80f6
Fix Dirac cdf
marvinpfoertner Aug 29, 2020
d37ad32
Fix review comment about Cholesky damping
marvinpfoertner Aug 29, 2020
87499db
Refactor notebooks to reflect itended import of random variables
marvinpfoertner Aug 29, 2020
1323161
(Advanced) Indexing, Slicing, and Masking for Linear Operators (via t…
marvinpfoertner Aug 29, 2020
2937310
Add fallback implementations for unary arithmetic operations
marvinpfoertner Aug 30, 2020
7cfa231
Generic fallback for indexing, reshaping and transposition
marvinpfoertner Aug 30, 2020
e082a76
Implement generic random variable operations
marvinpfoertner Aug 30, 2020
147b5d9
Fix bug in univariate normals
marvinpfoertner Aug 30, 2020
dc418dc
Make `_dense_{mean,cov}` public
marvinpfoertner Aug 30, 2020
aac484b
Add some documentation
marvinpfoertner Aug 30, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/pylint_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@
PYPROJECTTOML_FILE = Path("pyproject.toml")
GLOBAL_DISABLES = {
"invalid-name",
"fixme",
"bad-continuation",
"no-else-raise",
"no-else-return",
"no-member",
}


Expand Down
105 changes: 0 additions & 105 deletions benchmarks/distribution.py

This file was deleted.

4 changes: 2 additions & 2 deletions benchmarks/ivpsolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
"""
import numpy as np
from probnum.diffeq import lotkavolterra, probsolve_ivp
from probnum.prob import RandomVariable, Dirac
from probnum.random_variables import Dirac


def load_lotkavolterra():
"""Load LV system as a basic IVP."""
initrv = RandomVariable(distribution=Dirac(np.array([20, 20])))
initrv = Dirac(np.array([20, 20]))
return lotkavolterra(
timespan=[0, 0.55], initrv=initrv, params=(0.5, 0.05, 0.5, 0.05)
)
Expand Down
104 changes: 104 additions & 0 deletions benchmarks/random_variables.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
"""
Benchmarks for random variables.
"""

import numpy as np

from probnum import random_variables as rvs
import probnum.linalg.linops as linops

# Module level variables
rv_names = [
"univar_normal",
"multivar_normal",
"matrixvar_normal",
"symmatrixvar_normal",
"operatorvar_normal",
]


def get_randvar(rv_name):
"""
Return a random variable for a given distribution name
"""
# Distribution Means and Covariances
spd_mat = np.array(
[
[2.3, -2.3, 3.5, 4.2, 1.8],
[-2.3, 3.0, -3.5, -4.8, -1.9],
[3.5, -3.5, 6.9, 5.8, 0.8],
[4.2, -4.8, 5.8, 10.1, 6.3],
[1.8, -1.9, 0.8, 6.3, 12.1],
]
)
mean_0d = np.random.rand()
mean_1d = np.random.rand(5)
mean_2d_mat = spd_mat
mean_2d_linop = linops.MatrixMult(spd_mat)
cov_0d = np.random.rand() + 10 ** -12
cov_1d = spd_mat
cov_2d_kron = linops.Kronecker(A=spd_mat, B=spd_mat)
cov_2d_symkron = linops.SymmetricKronecker(A=spd_mat)

if rv_name == "univar_normal":
randvar = rvs.Normal(mean=mean_0d, cov=cov_0d)
elif rv_name == "multivar_normal":
randvar = rvs.Normal(mean=mean_1d, cov=cov_1d)
elif rv_name == "matrixvar_normal":
randvar = rvs.Normal(mean=mean_2d_mat, cov=cov_2d_kron)
elif rv_name == "symmatrixvar_normal":
randvar = rvs.Normal(mean=mean_2d_mat, cov=cov_2d_symkron)
elif rv_name == "operatorvar_normal":
randvar = rvs.Normal(mean=mean_2d_linop, cov=cov_2d_symkron)

return randvar


class Functions:
"""
Benchmark various functions of distributions.
"""

param_names = ["randvar", "property"]
params = [rv_names, ["pdf", "logpdf", "cdf", "logcdf"]]

def setup(self, randvar, property):
self.randvar = get_randvar(rv_name=randvar)
self.eval_point = np.random.uniform(size=self.randvar.shape)
self.quantile = np.random.uniform(size=self.randvar.shape)

def time_distr_functions(self, randvar, property):
"""Times evaluation of the pdf, logpdf, cdf and logcdf."""
try:
if property == "pdf":
self.randvar.pdf(x=self.eval_point)
elif property == "logpdf":
self.randvar.logpdf(x=self.eval_point)
elif property == "cdf":
self.randvar.cdf(x=self.quantile)
elif property == "logcdf":
self.randvar.logcdf(x=self.quantile)
except NotImplementedError:
pass


class Sampling:
"""
Benchmark sampling routines for various distributions.
"""

param_names = ["randvar"]
params = [rv_names]

def setup(self, randvar):
np.random.seed(42)
self.n_samples = 1000
self.randvar = get_randvar(rv_name=randvar)

def time_sample(self, randvar):
"""Times sampling from this distribution."""
self.randvar.sample(self.n_samples)

def peakmem_sample(self, randvar):
"""Peak memory of sampling process."""
self.randvar.sample(self.n_samples)
2 changes: 1 addition & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ To learn how to use ProbNum check out the `quickstart guide <introduction/quicks
:maxdepth: 1
:caption: API Documentation

public_api/prob
public_api/probnum
public_api/linalg
public_api/quad
public_api/diffeq
Expand Down
120 changes: 56 additions & 64 deletions docs/source/introduction/quickstart.ipynb

Large diffs are not rendered by default.

5 changes: 0 additions & 5 deletions docs/source/public_api/prob.rst

This file was deleted.

7 changes: 7 additions & 0 deletions docs/source/public_api/probnum.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
probnum
=======

probnum.random_variables
************************
.. automodapi:: probnum.random_variables
:no-heading:
19,092 changes: 9,516 additions & 9,576 deletions docs/source/tutorials/adaptive_steps_odefilter.ipynb

Large diffs are not rendered by default.

2,925 changes: 1,430 additions & 1,495 deletions docs/source/tutorials/galerkin_method.ipynb

Large diffs are not rendered by default.

313 changes: 136 additions & 177 deletions docs/source/tutorials/linear_operators.ipynb

Large diffs are not rendered by default.

316 changes: 139 additions & 177 deletions docs/source/tutorials/linear_systems.ipynb

Large diffs are not rendered by default.

3,303 changes: 1,736 additions & 1,567 deletions docs/source/tutorials/random_variables.ipynb

Large diffs are not rendered by default.

438 changes: 207 additions & 231 deletions docs/source/tutorials/uncertainties_odefilter.ipynb

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,15 @@ exclude = '''
# Exceptions suggested from Black: bad-continuation, bad-whitespace
disable = """
invalid-name,
fixme,

bad-continuation,

no-else-return,
no-else-raise,

no-member,

abstract-class-instantiated,
too-many-locals,
too-few-public-methods,
Expand All @@ -50,9 +55,6 @@ too-many-lines,
redefined-builtin,
abstract-method,
too-many-branches,
fixme,
broad-except,
raise-missing-from,
line-too-long,
missing-class-docstring,
unnecessary-pass,
Expand Down
3 changes: 2 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ version = 0.0.1
description = Probabilistic Numerics in Python.
url = https://github.com/probabilistic-numerics/probnum
author = ProbNum Authors
author-email =
author-email =
license = MIT
long-description = file: README.md
long-description-content-type = text/markdown
Expand All @@ -35,6 +35,7 @@ install_requires =
scipy>=1.4
GPy
matplotlib
cached_property; python_version<"3.8"
# The usage of test_requires is discouraged, see `Dependency Management` docs
# tests_require = pytest; pytest-cov
# Require a specific Python version, e.g. Python 2.7 or >= 3.4
Expand Down
4 changes: 3 additions & 1 deletion src/probnum/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@
from . import diffeq
from . import filtsmooth
from . import linalg
from . import prob
from . import quad
from . import random_variables
from . import utils

from .random_variables import asrandvar, RandomVariable

# -*- coding: utf-8 -*-
from pkg_resources import get_distribution, DistributionNotFound

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ def __init__(self, rv_list):
super().__init__(rv_list)

def mean(self):
return np.stack([rv.mean() for rv in self])
return np.stack([rv.mean for rv in self])

def cov(self):
return np.stack([rv.cov() for rv in self])
return np.stack([rv.cov for rv in self])

def var(self):
return np.stack([rv.distribution.var() for rv in self])
return np.stack([rv.var for rv in self])

def std(self):
return np.stack([rv.distribution.std() for rv in self])
return np.stack([rv.std for rv in self])

def __getitem__(self, idx):
"""Make sure to wrap the result into a _RandomVariableList if necessary"""
Expand Down
12 changes: 6 additions & 6 deletions src/probnum/diffeq/ode/ivp.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def hess(t, y):
return log_hess(t, y, params)

def sol(t):
return log_sol(t, params, initrv.mean())
return log_sol(t, params, initrv.mean)

return IVP(timespan, initrv, rhs, jac, hess, sol)

Expand Down Expand Up @@ -263,8 +263,8 @@ class IVP(ODE):
--------
>>> from probnum.diffeq import IVP
>>> rhsfun = lambda t, y, **kwargs: 2.0*y
>>> from probnum.prob import Dirac, Normal, RandomVariable
>>> initrv = RandomVariable(distribution=Dirac(0.1))
>>> from probnum import random_variables as rvs
>>> initrv = rvs.Dirac(0.1)
>>> timespan = (0, 10)
>>> ivp = IVP(timespan, initrv, rhsfun)
>>> print(ivp.rhs(0., 2.))
Expand All @@ -274,7 +274,7 @@ class IVP(ODE):
>>> print(ivp.t0)
0

>>> initrv = RandomVariable(distribution=Normal(0.1, 1.0))
>>> initrv = rvs.Normal(0.1, 1.0)
>>> ivp = IVP(timespan, initrv, rhsfun)
>>> jac = lambda t, y, **kwargs: 2.0
>>> ivp = IVP(timespan, initrv, rhs=rhsfun, jac=jac)
Expand Down Expand Up @@ -310,7 +310,7 @@ def ndim(self):

Depends on the mean of the initial random variable.
"""
if np.isscalar(self.initrv.mean()):
if np.isscalar(self.initrv.mean):
return 1
else:
return len(self.initrv.mean())
return len(self.initrv.mean)
Loading