diff --git a/.gitignore b/.gitignore
index f57e109d9..096b0504a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,8 @@ run_outputs*
data
.data
results
+docs/source/examples/
+docs/source/tutorials/
examples/*/processed
examples/*/results
examples/*/raw
diff --git a/docs/source/_static/img/pyro_logo_wide.png b/docs/source/_static/img/pyro_logo_wide.png
new file mode 100644
index 000000000..cdd87ba01
Binary files /dev/null and b/docs/source/_static/img/pyro_logo_wide.png differ
diff --git a/docs/source/_templates/breadcrumbs.html b/docs/source/_templates/breadcrumbs.html
new file mode 100644
index 000000000..c49d12ad3
--- /dev/null
+++ b/docs/source/_templates/breadcrumbs.html
@@ -0,0 +1,28 @@
+{%- extends "sphinx_rtd_theme/breadcrumbs.html" %}
+
+{% set display_vcs_links = display_vcs_links if display_vcs_links is defined else True %}
+
+{% block breadcrumbs_aside %}
+
+ {% if hasdoc(pagename) and display_vcs_links %}
+ {% if display_github %}
+ {% if check_meta and 'github_url' in meta %}
+
+ {{ _('Edit on GitHub') }}
+ {% else %}
+ {% if 'examples/index' in pagename %}
+ {{ _('Edit on GitHub') }}
+ {% elif 'examples/' in pagename %}
+ {{ _('Edit on GitHub') }}
+ {% else %}
+ {{ _('Edit on GitHub') }}
+ {% endif %}
+ {% endif %}
+ {% elif show_source and source_url_prefix %}
+ {{ _('View page source') }}
+ {% elif show_source and has_source and sourcename %}
+ {{ _('View page source') }}
+ {% endif %}
+ {% endif %}
+
+{% endblock %}
diff --git a/docs/source/conf.py b/docs/source/conf.py
index 73949c96e..42bfdb1ed 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -1,7 +1,9 @@
# Copyright Contributors to the Pyro project.
# SPDX-License-Identifier: Apache-2.0
+import glob
import os
+import shutil
import sys
import sphinx_rtd_theme
@@ -32,8 +34,17 @@
# The short X.Y version
version = u"0.0"
+
+if "READTHEDOCS" not in os.environ:
+ # if developing locally, use funsor.__version__ as version
+ from funsor import __version__ # noqaE402
+
+ version = __version__
+
+ html_context = {"github_version": "master"}
+
# The full version, including alpha/beta/rc tags
-release = u"0.0"
+release = version
# -- General configuration ---------------------------------------------------
@@ -46,11 +57,13 @@
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
+ "nbsphinx",
"sphinx.ext.autodoc",
"sphinx.ext.doctest",
"sphinx.ext.intersphinx",
"sphinx.ext.mathjax",
"sphinx.ext.viewcode",
+ "sphinx_gallery.gen_gallery",
]
# Disable documentation inheritance so as to avoid inheriting
@@ -76,7 +89,13 @@
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
-source_suffix = ".rst"
+source_suffix = [".rst", ".ipynb"]
+
+# do not execute cells
+nbsphinx_execute = "never"
+
+# Don't add .txt suffix to source files:
+html_sourcelink_suffix = ""
# The master toctree document.
master_doc = "index"
@@ -91,7 +110,7 @@
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path .
-exclude_patterns = []
+exclude_patterns = [".ipynb_checkpoints", "examples/*ipynb", "examples/*py"]
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = "sphinx"
@@ -100,6 +119,73 @@
# do not prepend module name to functions
add_module_names = False
+
+# This is processed by Jinja2 and inserted before each notebook
+nbsphinx_prolog = r"""
+{% set docname = 'tutorials/' + env.doc2path(env.docname, base=None).split('/')[-1] %}
+:github_url: https://github.com/pyro-ppl/funsor/blob/master/{{ docname }}
+
+.. raw:: html
+
+
+ Interactive online version:
+
+
+
+
+
+
+""" # noqa: E501
+
+
+# -- Copy notebook files
+# NB: tutorials and examples can be added to `index.rst` file using the paths
+# tutorials/foo
+# examples/foo
+# without extensions .ipynb or .py
+# TODO: find a solution for an example subfolder, e.g. examples/mixed_hmm folder
+#
+# To add thumbnail images for tutorials/examples in funsor docs, using
+# .. nbgallery:: instead of .. toctree:: and add png thumnail images
+# with corresponding names in _static/img/tutorials or _static/img/examples folders.
+# For example, we can add minipyro.png to _static/img/examples/ folder.
+
+if not os.path.exists("tutorials"):
+ os.makedirs("tutorials")
+
+for src_file in glob.glob("../../tutorials/*.ipynb"):
+ dst_file = os.path.join("tutorials", src_file.split("/")[-1])
+ shutil.copy(src_file, "tutorials/")
+
+
+# -- Convert scripts to notebooks
+
+sphinx_gallery_conf = {
+ "examples_dirs": ["../../examples"],
+ "gallery_dirs": ["examples"],
+ # only execute files beginning with plot_
+ "filename_pattern": "/plot_",
+ # 'ignore_pattern': '(minipyro|__init__)',
+ # not display Total running time of the script because we do not execute it
+ "min_reported_time": 1,
+}
+
+
+# -- Add thumbnails images
+
+nbsphinx_thumbnails = {}
+
+for src_file in glob.glob("../../tutorials/*.ipynb") + glob.glob("../../examples/*.py"):
+ toctree_path = "tutorials/" if src_file.endswith("ipynb") else "examples/"
+ filename = os.path.splitext(src_file.split("/")[-1])[0]
+ png_path = "_static/img/" + toctree_path + filename + ".png"
+ # use Pyro logo if not exist png file
+ if not os.path.exists(png_path):
+ png_path = "_static/img/pyro_logo_wide.png"
+ nbsphinx_thumbnails[toctree_path + filename] = png_path
+
+
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
@@ -157,7 +243,7 @@
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
- (master_doc, "Funsor.tex", u"Funsor Documentation", u"Uber AI Labs", "manual"),
+ (master_doc, "Funsor.tex", u"Funsor Documentation", u"Uber AI Labs", "manual")
]
# -- Options for manual page output ------------------------------------------
@@ -180,7 +266,7 @@
"Funsor",
"Functional analysis + tensors + symbolic algebra.",
"Miscellaneous",
- ),
+ )
]
diff --git a/docs/source/index.rst b/docs/source/index.rst
index 16b7f6252..230a68b5d 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -32,6 +32,20 @@ Funsor is a tensor-like library for functions and distributions
minipyro
einsum
+.. toctree::
+ :maxdepth: 1
+ :caption: Tutorials and Examples
+ :name: tutorials-and-examples
+
+ examples/discrete_hmm
+ examples/eeg_slds
+ examples/kalman_filter
+ examples/minipyro
+ examples/pcfg
+ examples/sensor
+ examples/slds
+ examples/vae
+
Indices and tables
==================
diff --git a/examples/README.rst b/examples/README.rst
new file mode 100644
index 000000000..ab2ec2739
--- /dev/null
+++ b/examples/README.rst
@@ -0,0 +1,5 @@
+Code Examples
+=============
+
+Please check out `Sphinx-Gallery syntax `_
+for how to structure Python scripts to generate nicely rendered example pages.
diff --git a/examples/discrete_hmm.py b/examples/discrete_hmm.py
index f2bfc8fea..8618f9bd0 100644
--- a/examples/discrete_hmm.py
+++ b/examples/discrete_hmm.py
@@ -1,6 +1,12 @@
# Copyright Contributors to the Pyro project.
# SPDX-License-Identifier: Apache-2.0
+"""
+Example: Discrete HMM
+=====================
+
+"""
+
import argparse
from collections import OrderedDict
diff --git a/examples/eeg_slds.py b/examples/eeg_slds.py
index e826912c7..05f20b0c5 100644
--- a/examples/eeg_slds.py
+++ b/examples/eeg_slds.py
@@ -2,6 +2,9 @@
# SPDX-License-Identifier: Apache-2.0
"""
+Example: Switching Linear Dynamical System EEG
+==============================================
+
We use a switching linear dynamical system [1] to model a EEG time series dataset.
For inference we use a moment-matching approximation enabled by
`funsor.interpretation(funsor.terms.moment_matching)`.
@@ -10,6 +13,7 @@
[1] Anderson, B., and J. Moore. "Optimal filtering. Prentice-Hall, Englewood Cliffs." New Jersey (1979).
"""
+
import argparse
import time
from collections import OrderedDict
diff --git a/examples/kalman_filter.py b/examples/kalman_filter.py
index f839566c0..1782edc3a 100644
--- a/examples/kalman_filter.py
+++ b/examples/kalman_filter.py
@@ -1,6 +1,12 @@
# Copyright Contributors to the Pyro project.
# SPDX-License-Identifier: Apache-2.0
+"""
+Example: Kalman Filter
+======================
+
+"""
+
import argparse
import torch
diff --git a/examples/minipyro.py b/examples/minipyro.py
index ff022f0f5..15cae9847 100644
--- a/examples/minipyro.py
+++ b/examples/minipyro.py
@@ -1,6 +1,12 @@
# Copyright Contributors to the Pyro project.
# SPDX-License-Identifier: Apache-2.0
+"""
+Example: Mini Pyro
+==================
+
+"""
+
import argparse
import torch
diff --git a/examples/mixed_hmm/model.py b/examples/mixed_hmm/model.py
index 4baabea8f..b79fcc00e 100644
--- a/examples/mixed_hmm/model.py
+++ b/examples/mixed_hmm/model.py
@@ -24,10 +24,7 @@ def __init__(self, config):
def initialize_params(self):
# dictionary of guide random effect parameters
- params = {
- "eps_g": {},
- "eps_i": {},
- }
+ params = {"eps_g": {}, "eps_i": {}}
N_state = self.config["sizes"]["state"]
@@ -153,8 +150,7 @@ def initialize_params(self):
)
params["eps_g"]["scale"] = Tensor(
- torch.ones((N_state, N_state)),
- OrderedDict([("y_prev", Bint[N_state])]),
+ torch.ones((N_state, N_state)), OrderedDict([("y_prev", Bint[N_state])])
)
# initialize individual-level random effect parameters
@@ -164,12 +160,7 @@ def initialize_params(self):
params["e_i"]["probs"] = Tensor(
pyro.param(
"probs_e_i",
- lambda: torch.randn(
- (
- N_c,
- N_v,
- )
- ).abs(),
+ lambda: torch.randn((N_c, N_v)).abs(),
constraint=constraints.simplex,
),
OrderedDict([("g", Bint[N_c])]), # different value per group
@@ -329,8 +320,7 @@ def __call__(self):
# initialize gamma to uniform
gamma = Tensor(
- torch.zeros((N_state, N_state)),
- OrderedDict([("y_prev", Bint[N_state])]),
+ torch.zeros((N_state, N_state)), OrderedDict([("y_prev", Bint[N_state])])
)
N_v = self.config["sizes"]["random"]
diff --git a/examples/pcfg.py b/examples/pcfg.py
index 82bfd1047..fe5fd5144 100644
--- a/examples/pcfg.py
+++ b/examples/pcfg.py
@@ -1,6 +1,12 @@
# Copyright Contributors to the Pyro project.
# SPDX-License-Identifier: Apache-2.0
+"""
+Example: PCFG
+=============
+
+"""
+
import argparse
import math
from collections import OrderedDict
diff --git a/examples/sensor.py b/examples/sensor.py
index 16af482ae..3e23e4dca 100644
--- a/examples/sensor.py
+++ b/examples/sensor.py
@@ -1,6 +1,12 @@
# Copyright Contributors to the Pyro project.
# SPDX-License-Identifier: Apache-2.0
+"""
+Example: Biased Kalman Filter
+=============================
+
+"""
+
import argparse
import itertools
import math
diff --git a/examples/slds.py b/examples/slds.py
index 10aaed8ff..b9f36eb73 100644
--- a/examples/slds.py
+++ b/examples/slds.py
@@ -1,6 +1,12 @@
# Copyright Contributors to the Pyro project.
# SPDX-License-Identifier: Apache-2.0
+"""
+Example: Switching Linear Dynamical System
+==========================================
+
+"""
+
import argparse
import torch
@@ -19,10 +25,7 @@ def main(args):
)
trans_noise = funsor.Tensor(
torch.tensor(
- [
- 0.1, # low noise component
- 1.0, # high noisy component
- ],
+ [0.1, 1.0], # low noise component # high noisy component
requires_grad=True,
)
)
diff --git a/examples/vae.py b/examples/vae.py
index 3f938e34e..343d413e4 100644
--- a/examples/vae.py
+++ b/examples/vae.py
@@ -1,6 +1,12 @@
# Copyright Contributors to the Pyro project.
# SPDX-License-Identifier: Apache-2.0
+"""
+Example: VAE MNIST
+==================
+
+"""
+
import argparse
import os
from collections import OrderedDict
diff --git a/funsor/__init__.py b/funsor/__init__.py
index 4372f1bad..ec70808cc 100644
--- a/funsor/__init__.py
+++ b/funsor/__init__.py
@@ -43,7 +43,10 @@
testing,
)
+__version__ = "0.4.0"
+
__all__ = [
+ "__version__",
"Array",
"Bint",
"Cat",
diff --git a/scripts/update_headers.py b/scripts/update_headers.py
index 8faa7dd8b..37a78522d 100644
--- a/scripts/update_headers.py
+++ b/scripts/update_headers.py
@@ -8,10 +8,7 @@
root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
blacklist = ["/build/", "/dist/"]
-file_types = [
- ("*.py", "# {}"),
- ("*.cpp", "// {}"),
-]
+file_types = [("*.py", "# {}"), ("*.cpp", "// {}")]
parser = argparse.ArgumentParser()
parser.add_argument("--check", action="store_true")
diff --git a/setup.py b/setup.py
index e94d4e205..d0b6de0e0 100644
--- a/setup.py
+++ b/setup.py
@@ -27,27 +27,13 @@
description="A tensor-like library for functions and distributions",
packages=find_packages(include=["funsor", "funsor.*"]),
url="https://github.com/pyro-ppl/funsor",
- project_urls={
- "Documentation": "https://funsor.pyro.ai",
- },
+ project_urls={"Documentation": "https://funsor.pyro.ai"},
author="Uber AI Labs",
python_requires=">=3.6",
- install_requires=[
- "makefun",
- "multipledispatch",
- "numpy>=1.7",
- "opt_einsum>=2.3.2",
- ],
+ install_requires=["makefun", "multipledispatch", "numpy>=1.7", "opt_einsum>=2.3.2"],
extras_require={
- "torch": [
- "pyro-ppl>=1.5.2",
- "torch>=1.7.0",
- ],
- "jax": [
- "numpyro>=0.2.4",
- "jax>=0.1.57",
- "jaxlib>=0.1.37",
- ],
+ "torch": ["pyro-ppl>=1.5.2", "torch>=1.7.0"],
+ "jax": ["numpyro>=0.2.4", "jax>=0.1.57", "jaxlib>=0.1.37"],
"test": [
"black",
"flake8",
@@ -63,11 +49,13 @@
"black",
"flake8",
"isort>=5.0",
+ "nbsphinx",
"pandas",
"pytest==4.3.1",
"pytest-xdist==1.27.0",
"scipy",
"sphinx>=2.0",
+ "sphinx-gallery",
"sphinx_rtd_theme",
"torchvision",
],
diff --git a/tutorials/README.md b/tutorials/README.md
new file mode 100644
index 000000000..a415f9b39
--- /dev/null
+++ b/tutorials/README.md
@@ -0,0 +1 @@
+# Notebook tutorials