Skip to content

Commit 15b8595

Browse files
ColCarrolltwiecki
authored andcommitted
Numpy docs hmc (#2405)
* Conform to numpy style docstrings in hmc submodule * Accidentally messed with pylintrc * Comments * Rebase * Rebase again
1 parent fbf5cb9 commit 15b8595

File tree

7 files changed

+415
-19
lines changed

7 files changed

+415
-19
lines changed

pymc3/step_methods/hmc/base_hmc.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
1+
import numpy as np
2+
13
from pymc3.model import modelcontext, Point
24
from pymc3.step_methods import arraystep
3-
from .quadpotential import quad_potential, QuadPotentialDiagAdapt
45
from pymc3.step_methods.hmc import integration
56
from pymc3.theanof import inputvars, floatX
67
from pymc3.tuning import guess_scaling
7-
import numpy as np
8+
from .quadpotential import quad_potential, QuadPotentialDiagAdapt
89

910

1011
class BaseHMC(arraystep.GradientSharedStep):
12+
"""Superclass to implement Hamiltonian/hybrid monte carlo."""
13+
1114
default_blocked = True
1215

1316
def __init__(self, vars=None, scaling=None, step_scale=0.25, is_cov=False,
1417
model=None, blocked=True, potential=None,
1518
integrator="leapfrog", dtype=None, **theano_kwargs):
16-
"""Superclass to implement Hamiltonian/hybrid monte carlo
19+
"""Set up Hamiltonian samplers with common structures.
1720
1821
Parameters
1922
----------

pymc3/step_methods/hmc/hmc.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
1-
'''
2-
Created on Mar 7, 2011
1+
import numpy as np
32

4-
@author: johnsalvatier
5-
'''
63
from ..arraystep import metrop_select, Competence
74
from .base_hmc import BaseHMC
85
from pymc3.vartypes import discrete_types
96
from pymc3.theanof import floatX
10-
import numpy as np
117

128

139
__all__ = ['HamiltonianMC']
@@ -22,11 +18,17 @@ def unif(step_size, elow=.85, ehigh=1.15):
2218

2319

2420
class HamiltonianMC(BaseHMC):
21+
R"""A sampler for continuous variables based on Hamiltonian mechanics.
22+
23+
See NUTS sampler for automatically tuned stopping time and step size scaling.
24+
"""
25+
2526
name = 'hmc'
2627
default_blocked = True
2728

2829
def __init__(self, vars=None, path_length=2., step_rand=unif, **kwargs):
29-
"""
30+
"""Set up the Hamiltonian Monte Carlo sampler.
31+
3032
Parameters
3133
----------
3234
vars : list of theano variables
@@ -57,6 +59,7 @@ def __init__(self, vars=None, path_length=2., step_rand=unif, **kwargs):
5759
self.step_rand = step_rand
5860

5961
def astep(self, q0):
62+
"""Perform a single HMC iteration."""
6063
e = floatX(self.step_rand(self.step_size))
6164
n_steps = int(self.path_length / e)
6265

@@ -76,6 +79,7 @@ def astep(self, q0):
7679

7780
@staticmethod
7881
def competence(var):
82+
"""Check how appropriate this class is for sampling a random variable."""
7983
if var.dtype in discrete_types:
8084
return Competence.INCOMPATIBLE
8185
return Competence.COMPATIBLE

pymc3/step_methods/hmc/integration.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@
88

99

1010
class CpuLeapfrogIntegrator(object):
11+
"""Optimized leapfrog integration using numpy."""
12+
1113
def __init__(self, ndim, potential, logp_dlogp_func):
14+
"""Leapfrog integrator using CPU."""
1215
self._ndim = ndim
1316
self._potential = potential
1417
self._logp_dlogp_func = logp_dlogp_func
@@ -19,6 +22,7 @@ def __init__(self, ndim, potential, logp_dlogp_func):
1922
% (self._potential.dtype, self._dtype))
2023

2124
def compute_state(self, q, p):
25+
"""Compute Hamiltonian functions using a position and momentum."""
2226
if q.dtype != self._dtype or p.dtype != self._dtype:
2327
raise ValueError('Invalid dtype. Must be %s' % self._dtype)
2428
logp, dlogp = self._logp_dlogp_func(q)
@@ -28,6 +32,23 @@ def compute_state(self, q, p):
2832
return State(q, p, v, dlogp, energy)
2933

3034
def step(self, epsilon, state, out=None):
35+
"""Leapfrog integrator step.
36+
37+
Half a momentum update, full position update, half momentum update.
38+
39+
Parameters
40+
----------
41+
epsilon: float, > 0
42+
step scale
43+
state: State namedtuple,
44+
current position data
45+
out: (optional) State namedtuple,
46+
preallocated arrays to write to in place
47+
48+
Returns
49+
-------
50+
None if `out` is provided, else a State namedtuple
51+
"""
3152
pot = self._potential
3253
axpy = linalg.blas.get_blas_funcs('axpy', dtype=self._dtype)
3354

pymc3/step_methods/hmc/nuts.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
from collections import namedtuple
22
import warnings
33

4+
import numpy as np
5+
import numpy.random as nr
6+
from scipy import stats, linalg
7+
import six
8+
49
from ..arraystep import Competence
510
from pymc3.exceptions import SamplingError
611
from .base_hmc import BaseHMC
712
from pymc3.theanof import floatX
813
from pymc3.vartypes import continuous_types
914

10-
import numpy as np
11-
import numpy.random as nr
12-
from scipy import stats, linalg
13-
import six
14-
1515
__all__ = ['NUTS']
1616

1717

@@ -28,7 +28,7 @@ class NUTS(BaseHMC):
2828
sample. A detailed description can be found at [1], "Algorithm 6:
2929
Efficient No-U-Turn Sampler with Dual Averaging".
3030
31-
Nuts provides a number of statistics that can be accessed with
31+
NUTS provides a number of statistics that can be accessed with
3232
`trace.get_sampler_stats`:
3333
3434
- `mean_tree_accept`: The mean acceptance probability for the tree
@@ -70,6 +70,7 @@ class NUTS(BaseHMC):
7070
.. [1] Hoffman, Matthew D., & Gelman, Andrew. (2011). The No-U-Turn Sampler:
7171
Adaptively Setting Path Lengths in Hamiltonian Monte Carlo.
7272
"""
73+
7374
name = 'nuts'
7475

7576
default_blocked = True
@@ -92,7 +93,8 @@ def __init__(self, vars=None, Emax=1000, target_accept=0.8,
9293
max_treedepth=10, on_error='summary',
9394
early_max_treedepth=8,
9495
**kwargs):
95-
R"""
96+
R"""Set up the No-U-Turn sampler.
97+
9698
Parameters
9799
----------
98100
vars : list of Theano variables, default all continuous vars
@@ -171,6 +173,7 @@ def __init__(self, vars=None, Emax=1000, target_accept=0.8,
171173
self.report = NutsReport(on_error, max_treedepth, target_accept)
172174

173175
def astep(self, q0):
176+
"""Perform a single NUTS iteration."""
174177
p0 = self.potential.random()
175178
start = self.integrator.compute_state(q0, p0)
176179

@@ -229,6 +232,7 @@ def astep(self, q0):
229232

230233
@staticmethod
231234
def competence(var):
235+
"""Check how appropriate this class is for sampling a random variable."""
232236
if var.dtype in continuous_types:
233237
return Competence.IDEAL
234238
return Competence.INCOMPATIBLE

0 commit comments

Comments
 (0)