Skip to content

Commit b463f2b

Browse files
HolgerPeterstwiecki
authored andcommitted
Include pymc.model in documentation (#2885)
* Add API docs for the model module to sphinx docs * Fix docstring, so that code is properly rendered * Fix markup in docstrings in pymc3.model * Unpacking operators are not part of the name, and sphinx assumes they are markup. * Small changes, such as replacing markdown-style single backticks for marking up identifiers with proper RST style double backticks * Constructor should be documented in the class docstring * Remove defaults from docstring and use RST instead of markdown * Reformatting of the code-example's comments * Create a sphinx _static dir that is tracked by git Avoids warning of sphinx that the directory does not exist
1 parent 7327f9d commit b463f2b

File tree

4 files changed

+111
-94
lines changed

4 files changed

+111
-94
lines changed

docs/source/_static/.gitignore

Whitespace-only changes.

docs/source/api.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ API Reference
1818
api/backends
1919
api/math
2020
api/data
21+
api/model

docs/source/api/model.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Model
2+
-----
3+
4+
.. currentmodule:: pymc3.model
5+
.. automodule:: pymc3.model
6+
:members:
7+

pymc3/model.py

Lines changed: 103 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -491,81 +491,89 @@ class Model(six.with_metaclass(InitContextMeta, Context, Factor, WithMemoization
491491
"""Encapsulates the variables and likelihood factors of a model.
492492
493493
Model class can be used for creating class based models. To create
494-
a class based model you should inherit from `Model` and
495-
override `__init__` with arbitrary definitions
496-
(do not forget to call base class `__init__` first).
494+
a class based model you should inherit from :class:`~.Model` and
495+
override :meth:`~.__init__` with arbitrary definitions (do not
496+
forget to call base class :meth:`__init__` first).
497497
498498
Parameters
499499
----------
500-
name : str, default '' - name that will be used as prefix for
501-
names of all random variables defined within model
502-
model : Model, default None - instance of Model that is
503-
supposed to be a parent for the new instance. If None,
504-
context will be used. All variables defined within instance
505-
will be passed to the parent instance. So that 'nested' model
506-
contributes to the variables and likelihood factors of
507-
parent model.
508-
theano_config : dict, default=None
500+
name : str
501+
name that will be used as prefix for names of all random
502+
variables defined within model
503+
model : Model
504+
instance of Model that is supposed to be a parent for the new
505+
instance. If ``None``, context will be used. All variables
506+
defined within instance will be passed to the parent instance.
507+
So that 'nested' model contributes to the variables and
508+
likelihood factors of parent model.
509+
theano_config : dict
509510
A dictionary of theano config values that should be set
510511
temporarily in the model context. See the documentation
511-
of theano for a complete list. Set `compute_test_value` to
512-
`raise` if it is None.
512+
of theano for a complete list. Set config key
513+
``compute_test_value`` to `raise` if it is None.
513514
514515
Examples
515516
--------
516-
# How to define a custom model
517-
class CustomModel(Model):
518-
# 1) override init
519-
def __init__(self, mean=0, sd=1, name='', model=None):
520-
# 2) call super's init first, passing model and name to it
521-
# name will be prefix for all variables here
522-
# if no name specified for model there will be no prefix
523-
super(CustomModel, self).__init__(name, model)
524-
# now you are in the context of instance,
525-
# `modelcontext` will return self
526-
# you can define variables in several ways
527-
# note, that all variables will get model's name prefix
528-
529-
# 3) you can create variables with Var method
530-
self.Var('v1', Normal.dist(mu=mean, sd=sd))
531-
# this will create variable named like '{prefix_}v1'
532-
# and assign attribute 'v1' to instance
533-
# created variable can be accessed with self.v1 or self['v1']
534-
535-
# 4) this syntax will also work as we are in the context
536-
# of instance itself, names are given as usual
537-
Normal('v2', mu=mean, sd=sd)
538-
539-
# something more complex is allowed too
540-
Normal('v3', mu=mean, sd=HalfCauchy('sd', beta=10, testval=1.))
541-
542-
# Deterministic variables can be used in usual way
543-
Deterministic('v3_sq', self.v3 ** 2)
544-
# Potentials too
545-
Potential('p1', tt.constant(1))
546-
547-
# After defining a class CustomModel you can use it in several ways
548-
549-
# I:
550-
# state the model within a context
551-
with Model() as model:
552-
CustomModel()
553-
# arbitrary actions
554-
555-
# II:
556-
# use new class as entering point in context
557-
with CustomModel() as model:
558-
Normal('new_normal_var', mu=1, sd=0)
559-
560-
# III:
561-
# just get model instance with all that was defined in it
562-
model = CustomModel()
563-
564-
# IV:
565-
# use many custom models within one context
566-
with Model() as model:
567-
CustomModel(mean=1, name='first')
568-
CustomModel(mean=2, name='second')
517+
518+
How to define a custom model
519+
520+
.. code-block:: python
521+
522+
class CustomModel(Model):
523+
# 1) override init
524+
def __init__(self, mean=0, sd=1, name='', model=None):
525+
# 2) call super's init first, passing model and name
526+
# to it name will be prefix for all variables here if
527+
# no name specified for model there will be no prefix
528+
super(CustomModel, self).__init__(name, model)
529+
# now you are in the context of instance,
530+
# `modelcontext` will return self you can define
531+
# variables in several ways note, that all variables
532+
# will get model's name prefix
533+
534+
# 3) you can create variables with Var method
535+
self.Var('v1', Normal.dist(mu=mean, sd=sd))
536+
# this will create variable named like '{prefix_}v1'
537+
# and assign attribute 'v1' to instance created
538+
# variable can be accessed with self.v1 or self['v1']
539+
540+
# 4) this syntax will also work as we are in the
541+
# context of instance itself, names are given as usual
542+
Normal('v2', mu=mean, sd=sd)
543+
544+
# something more complex is allowed, too
545+
half_cauchy = HalfCauchy('sd', beta=10, testval=1.)
546+
Normal('v3', mu=mean, sd=half_cauchy)
547+
548+
# Deterministic variables can be used in usual way
549+
Deterministic('v3_sq', self.v3 ** 2)
550+
551+
# Potentials too
552+
Potential('p1', tt.constant(1))
553+
554+
# After defining a class CustomModel you can use it in several
555+
# ways
556+
557+
# I:
558+
# state the model within a context
559+
with Model() as model:
560+
CustomModel()
561+
# arbitrary actions
562+
563+
# II:
564+
# use new class as entering point in context
565+
with CustomModel() as model:
566+
Normal('new_normal_var', mu=1, sd=0)
567+
568+
# III:
569+
# just get model instance with all that was defined in it
570+
model = CustomModel()
571+
572+
# IV:
573+
# use many custom models within one context
574+
with Model() as model:
575+
CustomModel(mean=1, name='first')
576+
CustomModel(mean=2, name='second')
569577
"""
570578
def __new__(cls, *args, **kwargs):
571579
# resolves the parent instance
@@ -738,7 +746,7 @@ def Var(self, name, dist, data=None, total_size=None):
738746
If data is provided, the variable is observed. If None,
739747
the variable is unobserved.
740748
total_size : scalar
741-
upscales logp of variable with :math:`coef = total_size/var.shape[0]`
749+
upscales logp of variable with ``coef = total_size/var.shape[0]``
742750
743751
Returns
744752
-------
@@ -833,8 +841,8 @@ def __getitem__(self, key):
833841
raise e
834842

835843
def makefn(self, outs, mode=None, *args, **kwargs):
836-
"""Compiles a Theano function which returns `outs` and takes the variable
837-
ancestors of `outs` as inputs.
844+
"""Compiles a Theano function which returns ``outs`` and takes the variable
845+
ancestors of ``outs`` as inputs.
838846
839847
Parameters
840848
----------
@@ -853,7 +861,7 @@ def makefn(self, outs, mode=None, *args, **kwargs):
853861
mode=mode, *args, **kwargs)
854862

855863
def fn(self, outs, mode=None, *args, **kwargs):
856-
"""Compiles a Theano function which returns the values of `outs`
864+
"""Compiles a Theano function which returns the values of ``outs``
857865
and takes values of model vars as arguments.
858866
859867
Parameters
@@ -868,7 +876,7 @@ def fn(self, outs, mode=None, *args, **kwargs):
868876
return LoosePointFunc(self.makefn(outs, mode, *args, **kwargs), self)
869877

870878
def fastfn(self, outs, mode=None, *args, **kwargs):
871-
"""Compiles a Theano function which returns `outs` and takes values
879+
"""Compiles a Theano function which returns ``outs`` and takes values
872880
of model vars as a dict as an argument.
873881
874882
Parameters
@@ -884,7 +892,7 @@ def fastfn(self, outs, mode=None, *args, **kwargs):
884892
return FastPointFunc(f)
885893

886894
def profile(self, outs, n=1000, point=None, profile=True, *args, **kwargs):
887-
"""Compiles and profiles a Theano function which returns `outs` and
895+
"""Compiles and profiles a Theano function which returns ``outs`` and
888896
takes values of model vars as a dict as an argument.
889897
890898
Parameters
@@ -895,7 +903,7 @@ def profile(self, outs, n=1000, point=None, profile=True, *args, **kwargs):
895903
point : point
896904
Point to pass to the function
897905
profile : True or ProfileStats
898-
*args, **kwargs
906+
args, kwargs
899907
Compilation args
900908
901909
Returns
@@ -914,10 +922,11 @@ def profile(self, outs, n=1000, point=None, profile=True, *args, **kwargs):
914922

915923
def flatten(self, vars=None, order=None, inputvar=None):
916924
"""Flattens model's input and returns:
917-
FlatView with
925+
926+
FlatView with
918927
* input vector variable
919-
* replacements `input_var -> vars`
920-
* view {variable: VarMap}
928+
* replacements ``input_var -> vars``
929+
* view `{variable: VarMap}`
921930
922931
Parameters
923932
----------
@@ -966,7 +975,7 @@ def _repr_latex_(self, name=None, dist=None):
966975

967976

968977
def fn(outs, mode=None, model=None, *args, **kwargs):
969-
"""Compiles a Theano function which returns the values of `outs` and
978+
"""Compiles a Theano function which returns the values of ``outs`` and
970979
takes values of model vars as arguments.
971980
972981
Parameters
@@ -983,7 +992,7 @@ def fn(outs, mode=None, model=None, *args, **kwargs):
983992

984993

985994
def fastfn(outs, mode=None, model=None):
986-
"""Compiles a Theano function which returns `outs` and takes values of model
995+
"""Compiles a Theano function which returns ``outs`` and takes values of model
987996
vars as a dict as an argument.
988997
989998
Parameters
@@ -1005,7 +1014,7 @@ def Point(*args, **kwargs):
10051014
10061015
Parameters
10071016
----------
1008-
*args, **kwargs
1017+
args, kwargs
10091018
arguments to build a dict
10101019
"""
10111020
model = modelcontext(kwargs.pop('model', None))
@@ -1361,22 +1370,22 @@ def Potential(name, var, model=None):
13611370

13621371

13631372
class TransformedRV(TensorVariable):
1373+
"""
1374+
Parameters
1375+
----------
1376+
1377+
type : theano type (optional)
1378+
owner : theano owner (optional)
1379+
name : str
1380+
distribution : Distribution
1381+
model : Model
1382+
total_size : scalar Tensor (optional)
1383+
needed for upscaling logp
1384+
"""
13641385

13651386
def __init__(self, type=None, owner=None, index=None, name=None,
13661387
distribution=None, model=None, transform=None,
13671388
total_size=None):
1368-
"""
1369-
Parameters
1370-
----------
1371-
1372-
type : theano type (optional)
1373-
owner : theano owner (optional)
1374-
name : str
1375-
distribution : Distribution
1376-
model : Model
1377-
total_size : scalar Tensor (optional)
1378-
needed for upscaling logp
1379-
"""
13801389
if type is None:
13811390
type = distribution.type
13821391
super(TransformedRV, self).__init__(type, owner, index, name)
@@ -1427,8 +1436,8 @@ def as_iterargs(data):
14271436

14281437

14291438
def all_continuous(vars):
1430-
"""Check that vars not include discrete variables, excepting ObservedRVs.
1431-
"""
1439+
"""Check that vars not include discrete variables, excepting
1440+
ObservedRVs. """
14321441
vars_ = [var for var in vars if not isinstance(var, pm.model.ObservedRV)]
14331442
if any([var.dtype in pm.discrete_types for var in vars_]):
14341443
return False

0 commit comments

Comments
 (0)