├── cvxpy-mip-helpers ├── __init__.py ├── sos.py └── mip.py ├── docs ├── _build │ ├── html │ │ ├── _static │ │ │ ├── custom.css │ │ │ ├── file.png │ │ │ ├── plus.png │ │ │ ├── minus.png │ │ │ ├── documentation_options.js │ │ │ ├── pygments.css │ │ │ ├── doctools.js │ │ │ ├── underscore.js │ │ │ ├── language_data.js │ │ │ ├── alabaster.css │ │ │ ├── basic.css │ │ │ ├── searchtools.js │ │ │ └── underscore-1.3.1.js │ │ ├── objects.inv │ │ ├── .buildinfo │ │ ├── searchindex.js │ │ ├── _sources │ │ │ └── index.rst.txt │ │ ├── genindex.html │ │ ├── search.html │ │ └── index.html │ └── doctrees │ │ ├── index.doctree │ │ └── environment.pickle ├── index.rst ├── Makefile ├── make.bat └── conf.py ├── .gitignore ├── setup.py ├── examples ├── flappy_bird.py ├── lunar_land.py └── cheb.py └── README.md /cvxpy-mip-helpers/__init__.py: -------------------------------------------------------------------------------- 1 | from .mip import * -------------------------------------------------------------------------------- /docs/_build/html/_static/custom.css: -------------------------------------------------------------------------------- 1 | /* This file intentionally left blank. */ 2 | -------------------------------------------------------------------------------- /docs/_build/html/objects.inv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/philzook58/cvxpy-helpers/master/docs/_build/html/objects.inv -------------------------------------------------------------------------------- /docs/_build/html/_static/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/philzook58/cvxpy-helpers/master/docs/_build/html/_static/file.png -------------------------------------------------------------------------------- /docs/_build/html/_static/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/philzook58/cvxpy-helpers/master/docs/_build/html/_static/plus.png -------------------------------------------------------------------------------- /docs/_build/doctrees/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/philzook58/cvxpy-helpers/master/docs/_build/doctrees/index.doctree -------------------------------------------------------------------------------- /docs/_build/html/_static/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/philzook58/cvxpy-helpers/master/docs/_build/html/_static/minus.png -------------------------------------------------------------------------------- /docs/_build/doctrees/environment.pickle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/philzook58/cvxpy-helpers/master/docs/_build/doctrees/environment.pickle -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled python modules. 2 | *.pyc 3 | 4 | # Setuptools distribution folder. 5 | /dist/ 6 | 7 | # Python egg metadata, regenerated from source files by setuptools. 8 | /*.egg-info -------------------------------------------------------------------------------- /docs/_build/html/.buildinfo: -------------------------------------------------------------------------------- 1 | # Sphinx build info version 1 2 | # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. 3 | config: 7afd6ab376664667c1589a1811f23059 4 | tags: 645f666f9bcd5a90fca523b33c5a78b7 5 | -------------------------------------------------------------------------------- /docs/_build/html/_static/documentation_options.js: -------------------------------------------------------------------------------- 1 | var DOCUMENTATION_OPTIONS = { 2 | URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), 3 | VERSION: '', 4 | LANGUAGE: 'None', 5 | COLLAPSE_INDEX: false, 6 | FILE_SUFFIX: '.html', 7 | HAS_SOURCE: true, 8 | SOURCELINK_SUFFIX: '.txt', 9 | NAVIGATION_WITH_KEYS: false 10 | }; -------------------------------------------------------------------------------- /docs/_build/html/searchindex.js: -------------------------------------------------------------------------------- 1 | Search.setIndex({docnames:["index"],envversion:{"sphinx.domains.c":1,"sphinx.domains.changeset":1,"sphinx.domains.cpp":1,"sphinx.domains.javascript":1,"sphinx.domains.math":2,"sphinx.domains.python":1,"sphinx.domains.rst":1,"sphinx.domains.std":1,sphinx:56},filenames:["index.rst"],objects:{},objnames:{},objtypes:{},terms:{index:0,modul:0,page:0,search:0},titles:["Welcome to cvxpy-helpers\u2019s documentation!"],titleterms:{cvxpy:0,document:0,helper:0,indic:0,tabl:0,welcom:0}}) -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. cvxpy-helpers documentation master file, created by 2 | sphinx-quickstart on Fri May 31 16:24:56 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to cvxpy-helpers's documentation! 7 | ========================================= 8 | 9 | .. toctree:: 10 | :maxdepth: 2 11 | :caption: Contents: 12 | 13 | 14 | 15 | Indices and tables 16 | ================== 17 | 18 | * :ref:`genindex` 19 | * :ref:`modindex` 20 | * :ref:`search` 21 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/index.rst.txt: -------------------------------------------------------------------------------- 1 | .. cvxpy-helpers documentation master file, created by 2 | sphinx-quickstart on Fri May 31 16:24:56 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to cvxpy-helpers's documentation! 7 | ========================================= 8 | 9 | .. toctree:: 10 | :maxdepth: 2 11 | :caption: Contents: 12 | 13 | 14 | 15 | Indices and tables 16 | ================== 17 | 18 | * :ref:`genindex` 19 | * :ref:`modindex` 20 | * :ref:`search` 21 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | 4 | with open("README.md", "r") as fh: 5 | long_description = fh.read() 6 | 7 | setup(name='cvxpy-mip-helpers', 8 | version='0.1', 9 | description='Helper functions for mip formulations in cvxpy', 10 | url='http://github.com/storborg/funniest', 11 | author='Philip Zucker', 12 | author_email='flyingcircus@example.com', 13 | license='MIT', 14 | packages=['cvxpy-mip-helpers'], 15 | install_requires=[ 16 | 'cvxpy', 17 | 'numpy', 18 | ], 19 | zip_safe=False) 20 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SOURCEDIR = . 8 | BUILDDIR = _build 9 | 10 | # Put it first so that "make" without argument is like "make help". 11 | help: 12 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 13 | 14 | .PHONY: help Makefile 15 | 16 | # Catch-all target: route all unknown targets to Sphinx using the new 17 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 18 | %: Makefile 19 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | 13 | if "%1" == "" goto help 14 | 15 | %SPHINXBUILD% >NUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.http://sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /examples/flappy_bird.py: -------------------------------------------------------------------------------- 1 | import cvxpy as cvx 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | 5 | N = 50 # time steps 6 | dt = 0.1 7 | path = cvx.Variable((N, 3)) # x/y pos and vel 8 | f = cvx.Variable(N-1, boolean=True) # force 9 | vx = 1 10 | g = 9.8 11 | j = 10 # impulse factor 12 | recovery = 10 13 | 14 | # unpack variables 15 | x = path[:,0] 16 | y = path[:,1] 17 | 18 | vy = path[:,2] 19 | 20 | c = [] #constraints 21 | c += [f >= 0] # only fire rocket downward 22 | c += [x[0] == 0, vx[0] == 0, y[0] == 10, vy[0] == 0] 23 | 24 | for t in range(N-1): 25 | c += [x[t + 1] == x[t] + vx*dt ] 26 | c += [y[t + 1] == y[t] + vy[t]*dt ] 27 | c += [vy[t + 1] == vy[t] - g * dt + j * f[t] ] 28 | for t in range(N-recovery): 29 | c += [cvx.sum(f[t:t+recovery] <= 1] # not more than one impulse in recovery window. Is there a recovery window? 30 | 31 | c += [y[N-1] == 0] # landed 32 | c += [vy[N-1] == 0] # gently vx[N-1] == 0 33 | 34 | 35 | # keep position inside allowable region. 36 | 37 | objective = cvx.Minimize(cvx.sum(f)) # minimize total fuel use 38 | 39 | prob = cvx.Problem(objective, c) 40 | prob.solve(verbose = True) 41 | plt.plot(y.value, label="height") 42 | plt.plot(f.value, label="force") 43 | plt.legend() 44 | plt.title("Height vs Time") 45 | plt.show() 46 | 47 | -------------------------------------------------------------------------------- /examples/lunar_land.py: -------------------------------------------------------------------------------- 1 | import cvxpy as cvx 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | 5 | N = 50 # time steps 6 | dt = 0.1 7 | path = cvx.Variable((N, 4)) # x/y pos and vel 8 | f = cvx.Variable(N-1) # force 9 | 10 | # unpack variables 11 | x = path[:,0] 12 | y = path[:,1] 13 | vx = path[:,2] 14 | vy = path[:,3] 15 | 16 | c = [] #constraints 17 | c += [f >= 0] # only fire rocket downward 18 | c += [x[0] == 0, vx[0] == 0, y[0] == 10, vy[0] == 0] 19 | 20 | for t in range(N-1): 21 | c += [x[t + 1] == x[t] + vx[t]*dt ] 22 | c += [y[t + 1] == y[t] + vy[t]*dt ] 23 | c += [vx[t + 1] == vx[t]] 24 | c += [vy[t + 1] == vy[t] + (- 9.8 + f[t])*dt ] 25 | 26 | c += [y[N-1] == 0] # landed 27 | c += [vy[N-1] == 0] # gently vx[N-1] == 0 28 | 29 | 30 | objective = cvx.Minimize(cvx.sum(f)) # minimize total fuel use 31 | 32 | prob = cvx.Problem(objective, c) 33 | prob.solve(verbose = True) 34 | plt.plot(y.value, label="height") 35 | plt.plot(f.value, label="force") 36 | plt.legend() 37 | plt.title("Height vs Time") 38 | plt.show() 39 | 40 | ''' 41 | 1d lunear lander 42 | 2d lunar lander - don't do rotational version. 43 | 44 | obstacle lunear lander. 45 | flappy bird mixed integer programming 46 | 0/1 with recovery window. 47 | 48 | partition into convex regions. The pipes make easy boxes though. And in fact the corners are easy also. 49 | NICE 50 | 51 | 52 | 53 | 54 | ''' -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cvxpy-mip-helpers 2 | 3 | A lightweight collection of helpful modelling functions for mixed integer programming. It is based around the cvxpy framework. 4 | 5 | The functions usually will return new variables and also new constraints to add in your constraint set. Don't forget to do that. We could (should?) automate this part by wrapping in more interface. 6 | 7 | 8 | ## Implemented 9 | 10 | 11 | ## Not implemented 12 | * Embedding logical functions 13 | * Unions of convex shapes 14 | * Sums of Squares Programming 15 | * Smart Encodings 16 | * Piecewise Linear Functions 17 | * 18 | 19 | 20 | ## Blog Posts 21 | * http://www.philipzucker.com/2d-robot-arm-inverse-kinematics-using-mixed-integer-programming-in-cvxpy/ 22 | * http://www.philipzucker.com/bouncing-a-ball-with-mixed-integer-programming/ 23 | * http://www.philipzucker.com/trajectory-optimization-of-a-pendulum-with-mixed-integer-linear-programming/ 24 | * http://www.philipzucker.com/solving-the-ising-model-using-a-mixed-integer-linear-program-solver-gurobi/ 25 | * http://www.philipzucker.com/deriving-the-chebyshev-polynomials-using-sum-of-squares-optimization-with-sympy-and-cvxpy/ 26 | 27 | ## Projects of Interest 28 | 29 | * https://github.com/joehuchette/PiecewiseLinearOpt.jl 30 | * https://github.com/rdeits/ConditionalJuMP.jl 31 | * https://github.com/stephane-caron/pypoman 32 | * https://github.com/sadraddini/PWA-Control 33 | * https://github.com/sadraddini/pypolycontain 34 | * https://github.com/JuliaOpt/SumOfSquares.jl 35 | * https://github.com/rdeits/Mayday.jl 36 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # This file only contains a selection of the most common options. For a full 4 | # list see the documentation: 5 | # http://www.sphinx-doc.org/en/master/config 6 | 7 | # -- Path setup -------------------------------------------------------------- 8 | 9 | # If extensions (or modules to document with autodoc) are in another directory, 10 | # add these directories to sys.path here. If the directory is relative to the 11 | # documentation root, use os.path.abspath to make it absolute, like shown here. 12 | # 13 | # import os 14 | # import sys 15 | # sys.path.insert(0, os.path.abspath('.')) 16 | 17 | 18 | # -- Project information ----------------------------------------------------- 19 | 20 | project = 'cvxpy-helpers' 21 | copyright = '2019, Philip Zucker' 22 | author = 'Philip Zucker' 23 | 24 | 25 | # -- General configuration --------------------------------------------------- 26 | 27 | # Add any Sphinx extension module names here, as strings. They can be 28 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 29 | # ones. 30 | extensions = [ 31 | ] 32 | 33 | # Add any paths that contain templates here, relative to this directory. 34 | templates_path = ['_templates'] 35 | 36 | # List of patterns, relative to source directory, that match files and 37 | # directories to ignore when looking for source files. 38 | # This pattern also affects html_static_path and html_extra_path. 39 | exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] 40 | 41 | 42 | # -- Options for HTML output ------------------------------------------------- 43 | 44 | # The theme to use for HTML and HTML Help pages. See the documentation for 45 | # a list of builtin themes. 46 | # 47 | html_theme = 'alabaster' 48 | 49 | # Add any paths that contain custom static files (such as style sheets) here, 50 | # relative to this directory. They are copied after the builtin static files, 51 | # so a file named "default.css" will overwrite the builtin "default.css". 52 | html_static_path = ['_static'] 53 | -------------------------------------------------------------------------------- /docs/_build/html/genindex.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Index — cvxpy-helpers documentation 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |
30 | 31 | 32 |
33 | 34 | 35 |

Index

36 | 37 |
38 | 39 |
40 | 41 | 42 |
43 | 44 |
45 |
46 | 86 |
87 |
88 | 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /examples/cheb.py: -------------------------------------------------------------------------------- 1 | from sympy import * 2 | import cvxpy as cvx 3 | import matplotlib.pyplot as plt 4 | import numpy as np 5 | 6 | #build corresponding cvx variable for sympy variable 7 | def cvxvar(expr, PSD=True): 8 | if expr.func == MatrixSymbol: 9 | i = int(expr.shape[0].evalf()) 10 | j = int(expr.shape[1].evalf()) 11 | return cvx.Variable((i,j), PSD=PSD) 12 | elif expr.func == Symbol: 13 | return cvx.Variable() 14 | 15 | def cvxify(expr, cvxdict): # replaces sympy variables with cvx variables 16 | return lambdify(tuple(cvxdict.keys()), expr)(*cvxdict.values()) 17 | 18 | 19 | xs = np.linspace(-1,1,100) 20 | 21 | for N in range(3,6): 22 | #plot actual chebyshev 23 | chebcoeff = np.zeros(N) 24 | chebcoeff[-1] = 1 25 | plt.plot(xs, np.polynomial.chebyshev.chebval(xs, chebcoeff), color='r') 26 | 27 | cvxdict = {} 28 | # Going to need symbolic polynomials in x 29 | x = Symbol('x') 30 | xn = Matrix([x**n for n in range(N)]); 31 | 32 | def sospoly(varname): 33 | Q = MatrixSymbol(varname, N,N) 34 | p = (xn.T * Matrix(Q) * xn)[0] 35 | return p, Q 36 | 37 | t = Symbol('t') 38 | cvxdict[t] = cvxvar(t) 39 | 40 | #lagrange multiplier polynomial 1 41 | pl1, l1 = sospoly('l1') 42 | cvxdict[l1] = cvxvar(l1) 43 | 44 | #lagrange multiplier polynomial 2 45 | pl2, l2 = sospoly('l2') 46 | cvxdict[l2] = cvxvar(l2) 47 | 48 | #Equation SOS Polynomial 1 49 | peq1, eq1 = sospoly('eq1') 50 | cvxdict[eq1] = cvxvar(eq1) 51 | 52 | #Equation SOS Polynomial 2 53 | peq2, eq2 = sospoly('eq2') 54 | cvxdict[eq2] = cvxvar(eq2) 55 | 56 | a = MatrixSymbol("a", N,1) 57 | pa = Matrix(a).T*xn #sum([polcoeff[k] * x**k for k in range(n)]); 58 | pa = pa[0] 59 | cvxdict[a] = cvxvar(a, PSD=False) 60 | 61 | 62 | constraints = [] 63 | 64 | 65 | # Rough Derivation for upper constraint 66 | # pol <= t 67 | # 0 <= t - pol + lam * (x+1)(x-1) # relax constraint with lambda 68 | # eq1 = t - pol + lam 69 | # 0 = t - pol + lam - eq1 70 | z1 = t - pa + pl1 * (x+1)*(x-1) - peq1 71 | z1 = Poly(z1, x).all_coeffs() 72 | constraints += [cvxify(expr, cvxdict) == 0 for expr in z1] 73 | 74 | # Derivation for lower constraint 75 | # -t <= pol 76 | # 0 <= pol + t + lam * (x+1)(x-1) # relax constraint with lambda 77 | # eq2 = pol + t + lam # eq2 is SOS 78 | # 0 = t - pol + lam - eq2 #Rearrange to equal zero. 79 | z2 = pa + t + pl2 * (x+1)*(x-1) - peq2 80 | z2 = Poly(z2, x).all_coeffs() 81 | constraints += [cvxify(expr, cvxdict) == 0 for expr in z2] 82 | 83 | constraints += [cvxdict[a][N-1,0] == 2**(N-2) ] 84 | obj = cvx.Minimize(cvxdict[t]) #minimize maximum absolute value 85 | prob = cvx.Problem(obj,constraints) 86 | prob.solve() 87 | 88 | print(cvxdict[a].value.flatten()) 89 | plt.plot(xs, np.polynomial.polynomial.polyval(xs, cvxdict[a].value.flatten()), color='g') 90 | 91 | 92 | plt.show() -------------------------------------------------------------------------------- /docs/_build/html/search.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Search — cvxpy-helpers documentation 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
32 |
33 |
34 | 35 | 36 |
37 | 38 |

Search

39 |
40 | 41 |

42 | Please activate JavaScript to enable the search 43 | functionality. 44 |

45 |
46 |

47 | From here you can search these documents. Enter your search 48 | words into the box below and click "search". Note that the search 49 | function will automatically search for all of the words. Pages 50 | containing fewer words won't appear in the result list. 51 |

52 |
53 | 54 | 55 | 56 |
57 | 58 |
59 | 60 |
61 | 62 |
63 | 64 |
65 |
66 | 96 |
97 |
98 | 106 | 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /docs/_build/html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Welcome to cvxpy-helpers’s documentation! — cvxpy-helpers documentation 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 |
28 |
29 | 30 | 31 |
32 | 33 |
34 |

Welcome to cvxpy-helpers’s documentation!

35 |
36 |
37 |
38 |
39 |

Indices and tables

40 | 45 |
46 | 47 | 48 |
49 | 50 |
51 |
52 | 92 |
93 |
94 | 105 | 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /docs/_build/html/_static/pygments.css: -------------------------------------------------------------------------------- 1 | .highlight .hll { background-color: #ffffcc } 2 | .highlight { background: #f8f8f8; } 3 | .highlight .c { color: #8f5902; font-style: italic } /* Comment */ 4 | .highlight .err { color: #a40000; border: 1px solid #ef2929 } /* Error */ 5 | .highlight .g { color: #000000 } /* Generic */ 6 | .highlight .k { color: #004461; font-weight: bold } /* Keyword */ 7 | .highlight .l { color: #000000 } /* Literal */ 8 | .highlight .n { color: #000000 } /* Name */ 9 | .highlight .o { color: #582800 } /* Operator */ 10 | .highlight .x { color: #000000 } /* Other */ 11 | .highlight .p { color: #000000; font-weight: bold } /* Punctuation */ 12 | .highlight .ch { color: #8f5902; font-style: italic } /* Comment.Hashbang */ 13 | .highlight .cm { color: #8f5902; font-style: italic } /* Comment.Multiline */ 14 | .highlight .cp { color: #8f5902 } /* Comment.Preproc */ 15 | .highlight .cpf { color: #8f5902; font-style: italic } /* Comment.PreprocFile */ 16 | .highlight .c1 { color: #8f5902; font-style: italic } /* Comment.Single */ 17 | .highlight .cs { color: #8f5902; font-style: italic } /* Comment.Special */ 18 | .highlight .gd { color: #a40000 } /* Generic.Deleted */ 19 | .highlight .ge { color: #000000; font-style: italic } /* Generic.Emph */ 20 | .highlight .gr { color: #ef2929 } /* Generic.Error */ 21 | .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ 22 | .highlight .gi { color: #00A000 } /* Generic.Inserted */ 23 | .highlight .go { color: #888888 } /* Generic.Output */ 24 | .highlight .gp { color: #745334 } /* Generic.Prompt */ 25 | .highlight .gs { color: #000000; font-weight: bold } /* Generic.Strong */ 26 | .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ 27 | .highlight .gt { color: #a40000; font-weight: bold } /* Generic.Traceback */ 28 | .highlight .kc { color: #004461; font-weight: bold } /* Keyword.Constant */ 29 | .highlight .kd { color: #004461; font-weight: bold } /* Keyword.Declaration */ 30 | .highlight .kn { color: #004461; font-weight: bold } /* Keyword.Namespace */ 31 | .highlight .kp { color: #004461; font-weight: bold } /* Keyword.Pseudo */ 32 | .highlight .kr { color: #004461; font-weight: bold } /* Keyword.Reserved */ 33 | .highlight .kt { color: #004461; font-weight: bold } /* Keyword.Type */ 34 | .highlight .ld { color: #000000 } /* Literal.Date */ 35 | .highlight .m { color: #990000 } /* Literal.Number */ 36 | .highlight .s { color: #4e9a06 } /* Literal.String */ 37 | .highlight .na { color: #c4a000 } /* Name.Attribute */ 38 | .highlight .nb { color: #004461 } /* Name.Builtin */ 39 | .highlight .nc { color: #000000 } /* Name.Class */ 40 | .highlight .no { color: #000000 } /* Name.Constant */ 41 | .highlight .nd { color: #888888 } /* Name.Decorator */ 42 | .highlight .ni { color: #ce5c00 } /* Name.Entity */ 43 | .highlight .ne { color: #cc0000; font-weight: bold } /* Name.Exception */ 44 | .highlight .nf { color: #000000 } /* Name.Function */ 45 | .highlight .nl { color: #f57900 } /* Name.Label */ 46 | .highlight .nn { color: #000000 } /* Name.Namespace */ 47 | .highlight .nx { color: #000000 } /* Name.Other */ 48 | .highlight .py { color: #000000 } /* Name.Property */ 49 | .highlight .nt { color: #004461; font-weight: bold } /* Name.Tag */ 50 | .highlight .nv { color: #000000 } /* Name.Variable */ 51 | .highlight .ow { color: #004461; font-weight: bold } /* Operator.Word */ 52 | .highlight .w { color: #f8f8f8; text-decoration: underline } /* Text.Whitespace */ 53 | .highlight .mb { color: #990000 } /* Literal.Number.Bin */ 54 | .highlight .mf { color: #990000 } /* Literal.Number.Float */ 55 | .highlight .mh { color: #990000 } /* Literal.Number.Hex */ 56 | .highlight .mi { color: #990000 } /* Literal.Number.Integer */ 57 | .highlight .mo { color: #990000 } /* Literal.Number.Oct */ 58 | .highlight .sa { color: #4e9a06 } /* Literal.String.Affix */ 59 | .highlight .sb { color: #4e9a06 } /* Literal.String.Backtick */ 60 | .highlight .sc { color: #4e9a06 } /* Literal.String.Char */ 61 | .highlight .dl { color: #4e9a06 } /* Literal.String.Delimiter */ 62 | .highlight .sd { color: #8f5902; font-style: italic } /* Literal.String.Doc */ 63 | .highlight .s2 { color: #4e9a06 } /* Literal.String.Double */ 64 | .highlight .se { color: #4e9a06 } /* Literal.String.Escape */ 65 | .highlight .sh { color: #4e9a06 } /* Literal.String.Heredoc */ 66 | .highlight .si { color: #4e9a06 } /* Literal.String.Interpol */ 67 | .highlight .sx { color: #4e9a06 } /* Literal.String.Other */ 68 | .highlight .sr { color: #4e9a06 } /* Literal.String.Regex */ 69 | .highlight .s1 { color: #4e9a06 } /* Literal.String.Single */ 70 | .highlight .ss { color: #4e9a06 } /* Literal.String.Symbol */ 71 | .highlight .bp { color: #3465a4 } /* Name.Builtin.Pseudo */ 72 | .highlight .fm { color: #000000 } /* Name.Function.Magic */ 73 | .highlight .vc { color: #000000 } /* Name.Variable.Class */ 74 | .highlight .vg { color: #000000 } /* Name.Variable.Global */ 75 | .highlight .vi { color: #000000 } /* Name.Variable.Instance */ 76 | .highlight .vm { color: #000000 } /* Name.Variable.Magic */ 77 | .highlight .il { color: #990000 } /* Literal.Number.Integer.Long */ -------------------------------------------------------------------------------- /cvxpy-mip-helpers/sos.py: -------------------------------------------------------------------------------- 1 | import cvxpy as cvx 2 | from sympy import * 3 | import random 4 | ''' 5 | The idea is to use raw cvxpy and sympy as much as possible for maximum flexibility. 6 | 7 | Construct a sum of sqaures polynomial using sospoly. This returns a variable dictionary mapping sympy variables to cvxpy variables. 8 | You are free to the do polynomial operations (differentiation, integration, algerba) in pure sympy 9 | When you want to express an equality constraint, use poly_eq(), which takes the vardict and returns a list of cvxpy constraints. 10 | Once the problem is solved, use poly_value to get back the solution polynomials. 11 | 12 | That some polynomial is sum of squares can be expressed as the equality with a fresh polynomial that is explicility sum of sqaures. 13 | 14 | With the approach, we get the full unbridled power of sympy (including grobner bases!) 15 | 16 | I prefer manually controlling the vardict to having it auto controlled by a class, just as a I prefer manually controlling my constraint sets 17 | Classes suck. 18 | ''' 19 | 20 | 21 | def cvxify(expr, cvxdict): # replaces sympy variables with cvx variables in sympy expr 22 | return lambdify(tuple(cvxdict.keys()), expr)(*cvxdict.values()) 23 | 24 | def sospoly(terms, name=None): 25 | ''' returns sum of squares polynomial using terms, and vardict mapping to cvxpy variables ''' 26 | if name == None: 27 | name = str(random.getrandbits(32)) 28 | N = len(terms) 29 | xn = Matrix(terms) 30 | Q = MatrixSymbol(name, N,N) 31 | p = (xn.T * Matrix(Q) * xn)[0] 32 | Qcvx = cvx.Variable((N,N), PSD=True) 33 | vardict = {Q : Qcvx} 34 | return p, vardict 35 | 36 | def polyvar(terms,name=None): 37 | ''' builds sumpy expression and vardict for an unknown linear combination of the terms ''' 38 | if name == None: 39 | name = str(random.getrandbits(32)) 40 | N = len(terms) 41 | xn = Matrix(terms) 42 | Q = MatrixSymbol(name, N, 1) 43 | p = (xn.T * Matrix(Q))[0] 44 | print(p) 45 | Qcvx = cvx.Variable((N,1)) 46 | vardict = {Q : Qcvx} 47 | return p, vardict 48 | 49 | def poly_eq(p1, p2 , vardict): 50 | ''' returns a list of cvxpy constraints ''' 51 | dp = p1 - p2 52 | polyvars = list(dp.free_symbols - set(vardict.keys())) 53 | return [ cvxify(expr, vardict) == 0 for expr in poly(dp, gens = polyvars).coeffs()] 54 | 55 | def vardict_value(vardict): 56 | ''' evaluate numerical values of vardict ''' 57 | return {k : v.value for (k, v) in vardict.items()} 58 | 59 | def poly_value(p1, vardict): 60 | ''' evaluate polynomial expressions with vardict''' 61 | return cvxify(p1, vardict_value(vardict)) 62 | 63 | if __name__ == "__main__": 64 | x = symbols('x') 65 | terms = [1, x, x**2] 66 | #p, cdict = polyvar(terms) 67 | p, cdict = sospoly(terms) 68 | c = poly_eq(p, (1 + x)**2 , cdict) 69 | print(c) 70 | prob = cvx.Problem(cvx.Minimize(1), c) 71 | prob.solve() 72 | 73 | print(factor(poly_value(p, cdict))) 74 | 75 | # global poly minimization 76 | vdict = {} 77 | t, d = polyvar([1], name='t') 78 | vdict.update(d) 79 | 80 | p, d = sospoly([1,x,x**2], name='p') 81 | vdict.update(d) 82 | constraints = poly_eq(7 + x**2 - t, p, vdict) 83 | obj = cvx.Maximize( cvxify(t,vdict) ) 84 | prob = cvx.Problem(obj, constraints) 85 | prob.solve() 86 | print(poly_value(t,vdict)) 87 | 88 | 89 | ''' 90 | p, d = sospoly([1,x,x**2,x**3]) 91 | cvxdict += d 92 | 93 | p, d = sospoly( [ x ** i * y ** j for i in range(3) for j in range(3)] ) 94 | cvxdict += d 95 | ''' 96 | 97 | 98 | 99 | ''' 100 | 101 | def sospoly(terms, varname=None): 102 | N = len(terms) 103 | xn = Matrix(terms) 104 | Q = MatrixSymbol(varname, N,N) 105 | p = (xn.T * Matrix(Q) * xn)[0] 106 | Qcvx = cvx.Variable((N,N), PSD=True) 107 | vardict = {Q : Qcvx} 108 | return SOSExpr(p, vardict) 109 | 110 | # Sympy + cvxpy = SOS 111 | 112 | class SOS(): 113 | def __init__(self, ): 114 | cvx. 115 | 116 | def __eq__(self, rhs): 117 | def constraints(self): 118 | 119 | def sospoly( deglist ): 120 | 121 | def sospoly(deglist): 122 | product([deg for (_,deg) in ]) 123 | for (var, deg) 124 | xn = Matrix([x**n for n in range(N)]); 125 | Q = MatrixSymbol(varname, N,N) 126 | p = (xn.T * Matrix(Q) * xn)[0] 127 | return p, Q 128 | 129 | def sospoly(terms) 130 | 131 | def cvxify(expr, cvxdict): # replaces sympy variables with cvx variables 132 | return lambdify(tuple(cvxdict.keys()), expr)(*cvxdict.values()) 133 | class SOSPoly(): 134 | def __init__(self,terms): 135 | #N = product([deg for (_,deg) in deglist]) 136 | #xn = Matrix([x**n for n in range(N)]); 137 | N = len(terms) 138 | xn = Matrix(terms) 139 | Q = MatrixSymbol(varname, N,N) 140 | self.p = (xn.T * Matrix(Q) * xn)[0] 141 | self.vardict = 142 | def __rmul__(self, rhs): 143 | self.p * rhs 144 | def __add__(self,) 145 | 146 | 147 | 148 | 149 | def liftconstpoly(p): 150 | return SOSExpr(p, {}) 151 | 152 | class SOSExpr(): 153 | def __init__(self, expr=0, vardict = {}): 154 | self.vardict = vardict 155 | self.sympy_expr = expr 156 | def __rmul__() 157 | 158 | def value(): 159 | 160 | def cvxify(self): # replaces sympy variables with cvx variables 161 | return lambdify(tuple(self.vardict.keys()), expr)(*(self.vardict.values())) 162 | 163 | 164 | # maybe only off equality. 165 | # SOS is by setting equzl to unknown SOS poly. 166 | 167 | 168 | 169 | 170 | class SOSConstraint(): 171 | def __init__(self, lhs, op, rhs): 172 | if op = "GTE": 173 | vs = getvars(lhs,rhs) 174 | sospoly() 175 | 176 | def to_cvx(self): 177 | z1 = Poly(z1, x).all_coeffs() 178 | constraints += [cvxify(expr, cvxdict) == 0 for expr in z1] 179 | 180 | ''' 181 | -------------------------------------------------------------------------------- /cvxpy-mip-helpers/mip.py: -------------------------------------------------------------------------------- 1 | import cvxpy as cvx 2 | import numpy as np 3 | import pypoman 4 | 5 | def circle(N): 6 | """Builds N sided polygon MIP approximation of circle. returns x, y, constraints""" 7 | x = cvx.Variable() 8 | y = cvx.Variable() 9 | l = cvx.Variable(N) #interpolation variables 10 | segment = cvx.Variable(N,boolean=True) #segment indicator variables, relaxing the boolean constraint gives the convex hull of the polygon 11 | 12 | angles = np.linspace(0, 2*np.pi, N, endpoint=False) 13 | xs = np.cos(angles) #we're using a VRep 14 | ys = np.sin(angles) 15 | 16 | constraints = [] 17 | constraints += [x == l*xs, y == l*ys] # x and y are convex sum of the corner points 18 | constraints += [cvx.sum(l) == 1, l <= 1, 0 <= l] #interpolations variables. Between 0 and 1 and sum up to 1 19 | constraints += [cvx.sum(segment) == 1] # only one indicator variable can be nonzero 20 | 21 | constraints += [l[N-1] <= segment[N-1] + segment[0]] #special wrap around case 22 | for i in range(N-1): 23 | constraints += [l[i] <= segment[i] + segment[i+1]] # interpolation variables suppressed 24 | return x, y, constraints 25 | 26 | # one encoding for a relu 27 | # Another possible one is to use rays. lam(1,0) + (1-lam)(1,1) = (x,y) 28 | # https://arxiv.org/pdf/1711.07356.pdf 29 | def relu(x, M=100): 30 | y = cvx.Variable(x.shape) 31 | z = cvx.Variable(x.shape, boolean=True) 32 | notz = 1 - z 33 | constraints = [] 34 | constraints += [y >= 0, y >= x] 35 | constraints += [x <= M * z,- M * notz <= x] 36 | constraints += [y <= M * z, y <= x + 2 * M * notz] 37 | return y, constraints 38 | 39 | def curveMIP(pts): 40 | d = pts.shape[1] 41 | N = pts.shape[0] 42 | x = cvx.Variable(d) 43 | l = cvx.Variable(N) #interpolation variables 44 | segment = cvx.Variable(N-1,boolean=True) 45 | constraints = [] 46 | constraints += [x == pts.T@l] 47 | constraints += [cvx.sum(l) == 1, l <= 1, 0 <= l] #interpolations variables. Between 0 and 1 and sum up to 1 48 | constraints += [cvx.sum(segment) == 1] # only one indicator variable can be nonzero 49 | 50 | constraints += [l[0] <= segment[0]] #special cases 51 | constraints += [l[N-1] <= segment[N-2]] 52 | for i in range(1,N-1): 53 | constraints += [l[i] <= segment[i] + segment[i+1]] # interpolation variables suppressed 54 | return x, segments, constraints 55 | 56 | 57 | def functionMIP(f, xs): 58 | ''' samples f at xs (ordered array of positions) to build piecewise linear approximation. Returns a function that can be applied to cvx variables''' 59 | #fs = np.array([f(x) for pt in pts]) 60 | fs = f(xs) #assume f is vectorized 61 | def g(x): 62 | fx, segs, constraints = curveMIP( np.stack(fs,pts).T) 63 | constraints += [x == fx[1]] 64 | return fx[0], constraints 65 | return g 66 | 67 | def notMIP(z): 68 | return 1 - z 69 | 70 | def tableMIP(table): 71 | """ given a table of booleans (a tabulation of a boolean function), outputs a function that uses the first element of the table as the output""" 72 | A, b = pypoman.duality.compute_polytope_halfspaces(np.array(table)) 73 | A1 = A[:,1:] 74 | A2 = A[:,0] 75 | def g(a): # a? or a tuple of as? 76 | z = cvx.Variable(boolean = True) #vectorize? 77 | constraints = [] 78 | constraints += [A1@a + A2*z <= b] 79 | return z, constraints 80 | return g 81 | 82 | def allBools(n): 83 | assert(n >= 0) 84 | if n == 0: 85 | return [] 86 | elif n == 1: 87 | return [(0,),(1,)] 88 | else: 89 | rec = allBools(n-1) 90 | return [(0,) + bs for bs in rec] + [ (1,) + bs for bs in rec] 91 | 92 | def buildTable(f, arity=2): 93 | inputs = allBools(arity) 94 | table = [(f(*bs),) + bs for bs in inputs] 95 | return table 96 | 97 | def mipify(f, arity=2, allowExtra = False): 98 | table = buildTable(f,arity=arity) 99 | return tableMIP(table) 100 | ''' 101 | def g(*args): 102 | assert(len(args) == arity) 103 | assert(args[0].shape == args[1].shape) 104 | z = cvx.Variable(args[0].shape, boolean=True) 105 | return g 106 | ''' 107 | 108 | 109 | 110 | andMIP = mipify(lambda a,b: a * b) 111 | orMIP = mipify(lambda a,b: max(a, b)) 112 | xorMIP = mipify(lambda a, b: int(a == b)) 113 | 114 | print(buildTable(lambda a,b: a * b)) 115 | print(andMIP) 116 | ''' 117 | 118 | 119 | make mip pendulum using circle. Turns pendulum into a sequence of inlcined planes. Possibly a bad approximation 120 | The SHO oscillator sine apporixmation at the stable point is replaced with peicewise parabolas. you could do worse. Although.. piecewise parabolas in cartesian space? 121 | 122 | rather than circle 123 | arbitrary mipcurve 124 | mipclosedcurve 125 | mip surface - given triangualtion of surface, we can mip it 126 | delauney - simple 2d plane areas 127 | union - open union - reify the individal areas and then extrnal sum z == 1 128 | listunion 129 | 130 | functions ~ curves 131 | 132 | def suppressedPair(N): 133 | l = cvx.variable(N) 134 | z = cvx.Variable(N, boolean=True) 135 | constraints = [0 <= l, l <= z] 136 | return l, z, constraints 137 | 138 | 139 | # curve_mip is union of segments. Vrep of a segment is just 2 points. 140 | 141 | 142 | def union_of_vrep(vreps): 143 | nshapes = len(vreps) 144 | c = [] 145 | indicators = cvx.Variable(nshapes, boolean=True) 146 | c += [cvx.sum(indicators) == 1] # in exactly 1 147 | xs = [] 148 | for i,vrep in enumerate(vreps): 149 | (verts, d) = vrep.shape 150 | coordinates = cvx.Variables(verts) 151 | c += [coordinates >= 0, coordinates <= indicator[i]] 152 | xs.append(coordinates * vrep) 153 | x = cvx.Variable(d) 154 | c += [sum(xs) == x] 155 | return x, c 156 | 157 | 158 | #what happened to reify? 159 | # ctx is constraints built so far. We need to this to compute big M. 160 | # and really it would be nice (vital?) to turn off boolean 161 | def reify_halfplane(p, ctx): 162 | pass 163 | 164 | class PolyRel(): 165 | # list of integers 166 | from : List[Int] 167 | to : List[Int] 168 | vars : List[cvx.Variables] # maybe the from to lists should just be these. 169 | constraints = List[Cvx.Expr] ? 170 | 171 | def compose(self, ): 172 | def converse(self, ): 173 | def complement(self): 174 | def __rdiv__() 175 | def __rmul__(self,r): 176 | sefl.compose(r) 177 | def union(self,r): 178 | def intersect(self,r): 179 | def query_sub(self,r): 180 | return prob 181 | def 182 | 183 | 184 | ''' -------------------------------------------------------------------------------- /docs/_build/html/_static/doctools.js: -------------------------------------------------------------------------------- 1 | /* 2 | * doctools.js 3 | * ~~~~~~~~~~~ 4 | * 5 | * Sphinx JavaScript utilities for all documentation. 6 | * 7 | * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. 8 | * :license: BSD, see LICENSE for details. 9 | * 10 | */ 11 | 12 | /** 13 | * select a different prefix for underscore 14 | */ 15 | $u = _.noConflict(); 16 | 17 | /** 18 | * make the code below compatible with browsers without 19 | * an installed firebug like debugger 20 | if (!window.console || !console.firebug) { 21 | var names = ["log", "debug", "info", "warn", "error", "assert", "dir", 22 | "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", 23 | "profile", "profileEnd"]; 24 | window.console = {}; 25 | for (var i = 0; i < names.length; ++i) 26 | window.console[names[i]] = function() {}; 27 | } 28 | */ 29 | 30 | /** 31 | * small helper function to urldecode strings 32 | */ 33 | jQuery.urldecode = function(x) { 34 | return decodeURIComponent(x).replace(/\+/g, ' '); 35 | }; 36 | 37 | /** 38 | * small helper function to urlencode strings 39 | */ 40 | jQuery.urlencode = encodeURIComponent; 41 | 42 | /** 43 | * This function returns the parsed url parameters of the 44 | * current request. Multiple values per key are supported, 45 | * it will always return arrays of strings for the value parts. 46 | */ 47 | jQuery.getQueryParameters = function(s) { 48 | if (typeof s === 'undefined') 49 | s = document.location.search; 50 | var parts = s.substr(s.indexOf('?') + 1).split('&'); 51 | var result = {}; 52 | for (var i = 0; i < parts.length; i++) { 53 | var tmp = parts[i].split('=', 2); 54 | var key = jQuery.urldecode(tmp[0]); 55 | var value = jQuery.urldecode(tmp[1]); 56 | if (key in result) 57 | result[key].push(value); 58 | else 59 | result[key] = [value]; 60 | } 61 | return result; 62 | }; 63 | 64 | /** 65 | * highlight a given string on a jquery object by wrapping it in 66 | * span elements with the given class name. 67 | */ 68 | jQuery.fn.highlightText = function(text, className) { 69 | function highlight(node, addItems) { 70 | if (node.nodeType === 3) { 71 | var val = node.nodeValue; 72 | var pos = val.toLowerCase().indexOf(text); 73 | if (pos >= 0 && 74 | !jQuery(node.parentNode).hasClass(className) && 75 | !jQuery(node.parentNode).hasClass("nohighlight")) { 76 | var span; 77 | var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); 78 | if (isInSVG) { 79 | span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); 80 | } else { 81 | span = document.createElement("span"); 82 | span.className = className; 83 | } 84 | span.appendChild(document.createTextNode(val.substr(pos, text.length))); 85 | node.parentNode.insertBefore(span, node.parentNode.insertBefore( 86 | document.createTextNode(val.substr(pos + text.length)), 87 | node.nextSibling)); 88 | node.nodeValue = val.substr(0, pos); 89 | if (isInSVG) { 90 | var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); 91 | var bbox = node.parentElement.getBBox(); 92 | rect.x.baseVal.value = bbox.x; 93 | rect.y.baseVal.value = bbox.y; 94 | rect.width.baseVal.value = bbox.width; 95 | rect.height.baseVal.value = bbox.height; 96 | rect.setAttribute('class', className); 97 | addItems.push({ 98 | "parent": node.parentNode, 99 | "target": rect}); 100 | } 101 | } 102 | } 103 | else if (!jQuery(node).is("button, select, textarea")) { 104 | jQuery.each(node.childNodes, function() { 105 | highlight(this, addItems); 106 | }); 107 | } 108 | } 109 | var addItems = []; 110 | var result = this.each(function() { 111 | highlight(this, addItems); 112 | }); 113 | for (var i = 0; i < addItems.length; ++i) { 114 | jQuery(addItems[i].parent).before(addItems[i].target); 115 | } 116 | return result; 117 | }; 118 | 119 | /* 120 | * backward compatibility for jQuery.browser 121 | * This will be supported until firefox bug is fixed. 122 | */ 123 | if (!jQuery.browser) { 124 | jQuery.uaMatch = function(ua) { 125 | ua = ua.toLowerCase(); 126 | 127 | var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || 128 | /(webkit)[ \/]([\w.]+)/.exec(ua) || 129 | /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || 130 | /(msie) ([\w.]+)/.exec(ua) || 131 | ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || 132 | []; 133 | 134 | return { 135 | browser: match[ 1 ] || "", 136 | version: match[ 2 ] || "0" 137 | }; 138 | }; 139 | jQuery.browser = {}; 140 | jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; 141 | } 142 | 143 | /** 144 | * Small JavaScript module for the documentation. 145 | */ 146 | var Documentation = { 147 | 148 | init : function() { 149 | this.fixFirefoxAnchorBug(); 150 | this.highlightSearchWords(); 151 | this.initIndexTable(); 152 | if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) { 153 | this.initOnKeyListeners(); 154 | } 155 | }, 156 | 157 | /** 158 | * i18n support 159 | */ 160 | TRANSLATIONS : {}, 161 | PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; }, 162 | LOCALE : 'unknown', 163 | 164 | // gettext and ngettext don't access this so that the functions 165 | // can safely bound to a different name (_ = Documentation.gettext) 166 | gettext : function(string) { 167 | var translated = Documentation.TRANSLATIONS[string]; 168 | if (typeof translated === 'undefined') 169 | return string; 170 | return (typeof translated === 'string') ? translated : translated[0]; 171 | }, 172 | 173 | ngettext : function(singular, plural, n) { 174 | var translated = Documentation.TRANSLATIONS[singular]; 175 | if (typeof translated === 'undefined') 176 | return (n == 1) ? singular : plural; 177 | return translated[Documentation.PLURALEXPR(n)]; 178 | }, 179 | 180 | addTranslations : function(catalog) { 181 | for (var key in catalog.messages) 182 | this.TRANSLATIONS[key] = catalog.messages[key]; 183 | this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); 184 | this.LOCALE = catalog.locale; 185 | }, 186 | 187 | /** 188 | * add context elements like header anchor links 189 | */ 190 | addContextElements : function() { 191 | $('div[id] > :header:first').each(function() { 192 | $('\u00B6'). 193 | attr('href', '#' + this.id). 194 | attr('title', _('Permalink to this headline')). 195 | appendTo(this); 196 | }); 197 | $('dt[id]').each(function() { 198 | $('\u00B6'). 199 | attr('href', '#' + this.id). 200 | attr('title', _('Permalink to this definition')). 201 | appendTo(this); 202 | }); 203 | }, 204 | 205 | /** 206 | * workaround a firefox stupidity 207 | * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 208 | */ 209 | fixFirefoxAnchorBug : function() { 210 | if (document.location.hash && $.browser.mozilla) 211 | window.setTimeout(function() { 212 | document.location.href += ''; 213 | }, 10); 214 | }, 215 | 216 | /** 217 | * highlight the search words provided in the url in the text 218 | */ 219 | highlightSearchWords : function() { 220 | var params = $.getQueryParameters(); 221 | var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; 222 | if (terms.length) { 223 | var body = $('div.body'); 224 | if (!body.length) { 225 | body = $('body'); 226 | } 227 | window.setTimeout(function() { 228 | $.each(terms, function() { 229 | body.highlightText(this.toLowerCase(), 'highlighted'); 230 | }); 231 | }, 10); 232 | $('') 234 | .appendTo($('#searchbox')); 235 | } 236 | }, 237 | 238 | /** 239 | * init the domain index toggle buttons 240 | */ 241 | initIndexTable : function() { 242 | var togglers = $('img.toggler').click(function() { 243 | var src = $(this).attr('src'); 244 | var idnum = $(this).attr('id').substr(7); 245 | $('tr.cg-' + idnum).toggle(); 246 | if (src.substr(-9) === 'minus.png') 247 | $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); 248 | else 249 | $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); 250 | }).css('display', ''); 251 | if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { 252 | togglers.click(); 253 | } 254 | }, 255 | 256 | /** 257 | * helper function to hide the search marks again 258 | */ 259 | hideSearchWords : function() { 260 | $('#searchbox .highlight-link').fadeOut(300); 261 | $('span.highlighted').removeClass('highlighted'); 262 | }, 263 | 264 | /** 265 | * make the url absolute 266 | */ 267 | makeURL : function(relativeURL) { 268 | return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; 269 | }, 270 | 271 | /** 272 | * get the current relative url 273 | */ 274 | getCurrentURL : function() { 275 | var path = document.location.pathname; 276 | var parts = path.split(/\//); 277 | $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { 278 | if (this === '..') 279 | parts.pop(); 280 | }); 281 | var url = parts.join('/'); 282 | return path.substring(url.lastIndexOf('/') + 1, path.length - 1); 283 | }, 284 | 285 | initOnKeyListeners: function() { 286 | $(document).keyup(function(event) { 287 | var activeElementType = document.activeElement.tagName; 288 | // don't navigate when in search box or textarea 289 | if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') { 290 | switch (event.keyCode) { 291 | case 37: // left 292 | var prevHref = $('link[rel="prev"]').prop('href'); 293 | if (prevHref) { 294 | window.location.href = prevHref; 295 | return false; 296 | } 297 | case 39: // right 298 | var nextHref = $('link[rel="next"]').prop('href'); 299 | if (nextHref) { 300 | window.location.href = nextHref; 301 | return false; 302 | } 303 | } 304 | } 305 | }); 306 | } 307 | }; 308 | 309 | // quick alias for translations 310 | _ = Documentation.gettext; 311 | 312 | $(document).ready(function() { 313 | Documentation.init(); 314 | }); 315 | -------------------------------------------------------------------------------- /docs/_build/html/_static/underscore.js: -------------------------------------------------------------------------------- 1 | // Underscore.js 1.3.1 2 | // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. 3 | // Underscore is freely distributable under the MIT license. 4 | // Portions of Underscore are inspired or borrowed from Prototype, 5 | // Oliver Steele's Functional, and John Resig's Micro-Templating. 6 | // For all details and documentation: 7 | // http://documentcloud.github.com/underscore 8 | (function(){function q(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return a==String(c);case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source== 9 | c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&q(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&q(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c, 10 | h)&&!f--)break;g=!f}}d.pop();return g}var r=this,G=r._,n={},k=Array.prototype,o=Object.prototype,i=k.slice,H=k.unshift,l=o.toString,I=o.hasOwnProperty,w=k.forEach,x=k.map,y=k.reduce,z=k.reduceRight,A=k.filter,B=k.every,C=k.some,p=k.indexOf,D=k.lastIndexOf,o=Array.isArray,J=Object.keys,s=Function.prototype.bind,b=function(a){return new m(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else r._=b;b.VERSION="1.3.1";var j=b.each= 11 | b.forEach=function(a,c,d){if(a!=null)if(w&&a.forEach===w)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e2;a== 12 | null&&(a=[]);if(y&&a.reduce===y)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(z&&a.reduceRight===z)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect= 13 | function(a,c,b){var e;E(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(A&&a.filter===A)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(B&&a.every===B)return a.every(c,b);j(a,function(a,g,h){if(!(e= 14 | e&&c.call(b,a,g,h)))return n});return e};var E=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(C&&a.some===C)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return n});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return p&&a.indexOf===p?a.indexOf(c)!=-1:b=E(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck= 15 | function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;bd?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a, 17 | c,d){d||(d=b.identity);for(var e=0,f=a.length;e>1;d(a[g])=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e=0;d--)b=[a[d].apply(this,b)];return b[0]}}; 24 | b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=J||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.defaults=function(a){j(i.call(arguments, 25 | 1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return q(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=o||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)}; 26 | b.isArguments=function(a){return l.call(a)=="[object Arguments]"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!b.has(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"}; 27 | b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return I.call(a,b)};b.noConflict=function(){r._=G;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.mixin=function(a){j(b.functions(a), 28 | function(c){K(c,b[c]=a[c])})};var L=0;b.uniqueId=function(a){var b=L++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var t=/.^/,u=function(a){return a.replace(/\\\\/g,"\\").replace(/\\'/g,"'")};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape||t,function(a,b){return"',_.escape("+ 29 | u(b)+"),'"}).replace(d.interpolate||t,function(a,b){return"',"+u(b)+",'"}).replace(d.evaluate||t,function(a,b){return"');"+u(b).replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e.call(this,a,b)}};b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var v=function(a,c){return c?b(a).chain():a},K=function(a,c){m.prototype[a]= 30 | function(){var a=i.call(arguments);H.call(a,this._wrapped);return v(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return v(d,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return v(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain= 31 | true;return this};m.prototype.value=function(){return this._wrapped}}).call(this); 32 | -------------------------------------------------------------------------------- /docs/_build/html/_static/language_data.js: -------------------------------------------------------------------------------- 1 | /* 2 | * language_data.js 3 | * ~~~~~~~~~~~~~~~~ 4 | * 5 | * This script contains the language-specific data used by searchtools.js, 6 | * namely the list of stopwords, stemmer, scorer and splitter. 7 | * 8 | * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. 9 | * :license: BSD, see LICENSE for details. 10 | * 11 | */ 12 | 13 | var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"]; 14 | 15 | 16 | /* Non-minified version JS is _stemmer.js if file is provided */ 17 | /** 18 | * Porter Stemmer 19 | */ 20 | var Stemmer = function() { 21 | 22 | var step2list = { 23 | ational: 'ate', 24 | tional: 'tion', 25 | enci: 'ence', 26 | anci: 'ance', 27 | izer: 'ize', 28 | bli: 'ble', 29 | alli: 'al', 30 | entli: 'ent', 31 | eli: 'e', 32 | ousli: 'ous', 33 | ization: 'ize', 34 | ation: 'ate', 35 | ator: 'ate', 36 | alism: 'al', 37 | iveness: 'ive', 38 | fulness: 'ful', 39 | ousness: 'ous', 40 | aliti: 'al', 41 | iviti: 'ive', 42 | biliti: 'ble', 43 | logi: 'log' 44 | }; 45 | 46 | var step3list = { 47 | icate: 'ic', 48 | ative: '', 49 | alize: 'al', 50 | iciti: 'ic', 51 | ical: 'ic', 52 | ful: '', 53 | ness: '' 54 | }; 55 | 56 | var c = "[^aeiou]"; // consonant 57 | var v = "[aeiouy]"; // vowel 58 | var C = c + "[^aeiouy]*"; // consonant sequence 59 | var V = v + "[aeiou]*"; // vowel sequence 60 | 61 | var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 62 | var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 63 | var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 64 | var s_v = "^(" + C + ")?" + v; // vowel in stem 65 | 66 | this.stemWord = function (w) { 67 | var stem; 68 | var suffix; 69 | var firstch; 70 | var origword = w; 71 | 72 | if (w.length < 3) 73 | return w; 74 | 75 | var re; 76 | var re2; 77 | var re3; 78 | var re4; 79 | 80 | firstch = w.substr(0,1); 81 | if (firstch == "y") 82 | w = firstch.toUpperCase() + w.substr(1); 83 | 84 | // Step 1a 85 | re = /^(.+?)(ss|i)es$/; 86 | re2 = /^(.+?)([^s])s$/; 87 | 88 | if (re.test(w)) 89 | w = w.replace(re,"$1$2"); 90 | else if (re2.test(w)) 91 | w = w.replace(re2,"$1$2"); 92 | 93 | // Step 1b 94 | re = /^(.+?)eed$/; 95 | re2 = /^(.+?)(ed|ing)$/; 96 | if (re.test(w)) { 97 | var fp = re.exec(w); 98 | re = new RegExp(mgr0); 99 | if (re.test(fp[1])) { 100 | re = /.$/; 101 | w = w.replace(re,""); 102 | } 103 | } 104 | else if (re2.test(w)) { 105 | var fp = re2.exec(w); 106 | stem = fp[1]; 107 | re2 = new RegExp(s_v); 108 | if (re2.test(stem)) { 109 | w = stem; 110 | re2 = /(at|bl|iz)$/; 111 | re3 = new RegExp("([^aeiouylsz])\\1$"); 112 | re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); 113 | if (re2.test(w)) 114 | w = w + "e"; 115 | else if (re3.test(w)) { 116 | re = /.$/; 117 | w = w.replace(re,""); 118 | } 119 | else if (re4.test(w)) 120 | w = w + "e"; 121 | } 122 | } 123 | 124 | // Step 1c 125 | re = /^(.+?)y$/; 126 | if (re.test(w)) { 127 | var fp = re.exec(w); 128 | stem = fp[1]; 129 | re = new RegExp(s_v); 130 | if (re.test(stem)) 131 | w = stem + "i"; 132 | } 133 | 134 | // Step 2 135 | re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; 136 | if (re.test(w)) { 137 | var fp = re.exec(w); 138 | stem = fp[1]; 139 | suffix = fp[2]; 140 | re = new RegExp(mgr0); 141 | if (re.test(stem)) 142 | w = stem + step2list[suffix]; 143 | } 144 | 145 | // Step 3 146 | re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; 147 | if (re.test(w)) { 148 | var fp = re.exec(w); 149 | stem = fp[1]; 150 | suffix = fp[2]; 151 | re = new RegExp(mgr0); 152 | if (re.test(stem)) 153 | w = stem + step3list[suffix]; 154 | } 155 | 156 | // Step 4 157 | re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; 158 | re2 = /^(.+?)(s|t)(ion)$/; 159 | if (re.test(w)) { 160 | var fp = re.exec(w); 161 | stem = fp[1]; 162 | re = new RegExp(mgr1); 163 | if (re.test(stem)) 164 | w = stem; 165 | } 166 | else if (re2.test(w)) { 167 | var fp = re2.exec(w); 168 | stem = fp[1] + fp[2]; 169 | re2 = new RegExp(mgr1); 170 | if (re2.test(stem)) 171 | w = stem; 172 | } 173 | 174 | // Step 5 175 | re = /^(.+?)e$/; 176 | if (re.test(w)) { 177 | var fp = re.exec(w); 178 | stem = fp[1]; 179 | re = new RegExp(mgr1); 180 | re2 = new RegExp(meq1); 181 | re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); 182 | if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) 183 | w = stem; 184 | } 185 | re = /ll$/; 186 | re2 = new RegExp(mgr1); 187 | if (re.test(w) && re2.test(w)) { 188 | re = /.$/; 189 | w = w.replace(re,""); 190 | } 191 | 192 | // and turn initial Y back to y 193 | if (firstch == "y") 194 | w = firstch.toLowerCase() + w.substr(1); 195 | return w; 196 | } 197 | } 198 | 199 | 200 | 201 | 202 | 203 | var splitChars = (function() { 204 | var result = {}; 205 | var singles = [96, 180, 187, 191, 215, 247, 749, 885, 903, 907, 909, 930, 1014, 1648, 206 | 1748, 1809, 2416, 2473, 2481, 2526, 2601, 2609, 2612, 2615, 2653, 2702, 207 | 2706, 2729, 2737, 2740, 2857, 2865, 2868, 2910, 2928, 2948, 2961, 2971, 208 | 2973, 3085, 3089, 3113, 3124, 3213, 3217, 3241, 3252, 3295, 3341, 3345, 209 | 3369, 3506, 3516, 3633, 3715, 3721, 3736, 3744, 3748, 3750, 3756, 3761, 210 | 3781, 3912, 4239, 4347, 4681, 4695, 4697, 4745, 4785, 4799, 4801, 4823, 211 | 4881, 5760, 5901, 5997, 6313, 7405, 8024, 8026, 8028, 8030, 8117, 8125, 212 | 8133, 8181, 8468, 8485, 8487, 8489, 8494, 8527, 11311, 11359, 11687, 11695, 213 | 11703, 11711, 11719, 11727, 11735, 12448, 12539, 43010, 43014, 43019, 43587, 214 | 43696, 43713, 64286, 64297, 64311, 64317, 64319, 64322, 64325, 65141]; 215 | var i, j, start, end; 216 | for (i = 0; i < singles.length; i++) { 217 | result[singles[i]] = true; 218 | } 219 | var ranges = [[0, 47], [58, 64], [91, 94], [123, 169], [171, 177], [182, 184], [706, 709], 220 | [722, 735], [741, 747], [751, 879], [888, 889], [894, 901], [1154, 1161], 221 | [1318, 1328], [1367, 1368], [1370, 1376], [1416, 1487], [1515, 1519], [1523, 1568], 222 | [1611, 1631], [1642, 1645], [1750, 1764], [1767, 1773], [1789, 1790], [1792, 1807], 223 | [1840, 1868], [1958, 1968], [1970, 1983], [2027, 2035], [2038, 2041], [2043, 2047], 224 | [2070, 2073], [2075, 2083], [2085, 2087], [2089, 2307], [2362, 2364], [2366, 2383], 225 | [2385, 2391], [2402, 2405], [2419, 2424], [2432, 2436], [2445, 2446], [2449, 2450], 226 | [2483, 2485], [2490, 2492], [2494, 2509], [2511, 2523], [2530, 2533], [2546, 2547], 227 | [2554, 2564], [2571, 2574], [2577, 2578], [2618, 2648], [2655, 2661], [2672, 2673], 228 | [2677, 2692], [2746, 2748], [2750, 2767], [2769, 2783], [2786, 2789], [2800, 2820], 229 | [2829, 2830], [2833, 2834], [2874, 2876], [2878, 2907], [2914, 2917], [2930, 2946], 230 | [2955, 2957], [2966, 2968], [2976, 2978], [2981, 2983], [2987, 2989], [3002, 3023], 231 | [3025, 3045], [3059, 3076], [3130, 3132], [3134, 3159], [3162, 3167], [3170, 3173], 232 | [3184, 3191], [3199, 3204], [3258, 3260], [3262, 3293], [3298, 3301], [3312, 3332], 233 | [3386, 3388], [3390, 3423], [3426, 3429], [3446, 3449], [3456, 3460], [3479, 3481], 234 | [3518, 3519], [3527, 3584], [3636, 3647], [3655, 3663], [3674, 3712], [3717, 3718], 235 | [3723, 3724], [3726, 3731], [3752, 3753], [3764, 3772], [3774, 3775], [3783, 3791], 236 | [3802, 3803], [3806, 3839], [3841, 3871], [3892, 3903], [3949, 3975], [3980, 4095], 237 | [4139, 4158], [4170, 4175], [4182, 4185], [4190, 4192], [4194, 4196], [4199, 4205], 238 | [4209, 4212], [4226, 4237], [4250, 4255], [4294, 4303], [4349, 4351], [4686, 4687], 239 | [4702, 4703], [4750, 4751], [4790, 4791], [4806, 4807], [4886, 4887], [4955, 4968], 240 | [4989, 4991], [5008, 5023], [5109, 5120], [5741, 5742], [5787, 5791], [5867, 5869], 241 | [5873, 5887], [5906, 5919], [5938, 5951], [5970, 5983], [6001, 6015], [6068, 6102], 242 | [6104, 6107], [6109, 6111], [6122, 6127], [6138, 6159], [6170, 6175], [6264, 6271], 243 | [6315, 6319], [6390, 6399], [6429, 6469], [6510, 6511], [6517, 6527], [6572, 6592], 244 | [6600, 6607], [6619, 6655], [6679, 6687], [6741, 6783], [6794, 6799], [6810, 6822], 245 | [6824, 6916], [6964, 6980], [6988, 6991], [7002, 7042], [7073, 7085], [7098, 7167], 246 | [7204, 7231], [7242, 7244], [7294, 7400], [7410, 7423], [7616, 7679], [7958, 7959], 247 | [7966, 7967], [8006, 8007], [8014, 8015], [8062, 8063], [8127, 8129], [8141, 8143], 248 | [8148, 8149], [8156, 8159], [8173, 8177], [8189, 8303], [8306, 8307], [8314, 8318], 249 | [8330, 8335], [8341, 8449], [8451, 8454], [8456, 8457], [8470, 8472], [8478, 8483], 250 | [8506, 8507], [8512, 8516], [8522, 8525], [8586, 9311], [9372, 9449], [9472, 10101], 251 | [10132, 11263], [11493, 11498], [11503, 11516], [11518, 11519], [11558, 11567], 252 | [11622, 11630], [11632, 11647], [11671, 11679], [11743, 11822], [11824, 12292], 253 | [12296, 12320], [12330, 12336], [12342, 12343], [12349, 12352], [12439, 12444], 254 | [12544, 12548], [12590, 12592], [12687, 12689], [12694, 12703], [12728, 12783], 255 | [12800, 12831], [12842, 12880], [12896, 12927], [12938, 12976], [12992, 13311], 256 | [19894, 19967], [40908, 40959], [42125, 42191], [42238, 42239], [42509, 42511], 257 | [42540, 42559], [42592, 42593], [42607, 42622], [42648, 42655], [42736, 42774], 258 | [42784, 42785], [42889, 42890], [42893, 43002], [43043, 43055], [43062, 43071], 259 | [43124, 43137], [43188, 43215], [43226, 43249], [43256, 43258], [43260, 43263], 260 | [43302, 43311], [43335, 43359], [43389, 43395], [43443, 43470], [43482, 43519], 261 | [43561, 43583], [43596, 43599], [43610, 43615], [43639, 43641], [43643, 43647], 262 | [43698, 43700], [43703, 43704], [43710, 43711], [43715, 43738], [43742, 43967], 263 | [44003, 44015], [44026, 44031], [55204, 55215], [55239, 55242], [55292, 55295], 264 | [57344, 63743], [64046, 64047], [64110, 64111], [64218, 64255], [64263, 64274], 265 | [64280, 64284], [64434, 64466], [64830, 64847], [64912, 64913], [64968, 65007], 266 | [65020, 65135], [65277, 65295], [65306, 65312], [65339, 65344], [65371, 65381], 267 | [65471, 65473], [65480, 65481], [65488, 65489], [65496, 65497]]; 268 | for (i = 0; i < ranges.length; i++) { 269 | start = ranges[i][0]; 270 | end = ranges[i][1]; 271 | for (j = start; j <= end; j++) { 272 | result[j] = true; 273 | } 274 | } 275 | return result; 276 | })(); 277 | 278 | function splitQuery(query) { 279 | var result = []; 280 | var start = -1; 281 | for (var i = 0; i < query.length; i++) { 282 | if (splitChars[query.charCodeAt(i)]) { 283 | if (start !== -1) { 284 | result.push(query.slice(start, i)); 285 | start = -1; 286 | } 287 | } else if (start === -1) { 288 | start = i; 289 | } 290 | } 291 | if (start !== -1) { 292 | result.push(query.slice(start)); 293 | } 294 | return result; 295 | } 296 | 297 | 298 | -------------------------------------------------------------------------------- /docs/_build/html/_static/alabaster.css: -------------------------------------------------------------------------------- 1 | @import url("basic.css"); 2 | 3 | /* -- page layout ----------------------------------------------------------- */ 4 | 5 | body { 6 | font-family: Georgia, serif; 7 | font-size: 17px; 8 | background-color: #fff; 9 | color: #000; 10 | margin: 0; 11 | padding: 0; 12 | } 13 | 14 | 15 | div.document { 16 | width: 940px; 17 | margin: 30px auto 0 auto; 18 | } 19 | 20 | div.documentwrapper { 21 | float: left; 22 | width: 100%; 23 | } 24 | 25 | div.bodywrapper { 26 | margin: 0 0 0 220px; 27 | } 28 | 29 | div.sphinxsidebar { 30 | width: 220px; 31 | font-size: 14px; 32 | line-height: 1.5; 33 | } 34 | 35 | hr { 36 | border: 1px solid #B1B4B6; 37 | } 38 | 39 | div.body { 40 | background-color: #fff; 41 | color: #3E4349; 42 | padding: 0 30px 0 30px; 43 | } 44 | 45 | div.body > .section { 46 | text-align: left; 47 | } 48 | 49 | div.footer { 50 | width: 940px; 51 | margin: 20px auto 30px auto; 52 | font-size: 14px; 53 | color: #888; 54 | text-align: right; 55 | } 56 | 57 | div.footer a { 58 | color: #888; 59 | } 60 | 61 | p.caption { 62 | font-family: inherit; 63 | font-size: inherit; 64 | } 65 | 66 | 67 | div.relations { 68 | display: none; 69 | } 70 | 71 | 72 | div.sphinxsidebar a { 73 | color: #444; 74 | text-decoration: none; 75 | border-bottom: 1px dotted #999; 76 | } 77 | 78 | div.sphinxsidebar a:hover { 79 | border-bottom: 1px solid #999; 80 | } 81 | 82 | div.sphinxsidebarwrapper { 83 | padding: 18px 10px; 84 | } 85 | 86 | div.sphinxsidebarwrapper p.logo { 87 | padding: 0; 88 | margin: -10px 0 0 0px; 89 | text-align: center; 90 | } 91 | 92 | div.sphinxsidebarwrapper h1.logo { 93 | margin-top: -10px; 94 | text-align: center; 95 | margin-bottom: 5px; 96 | text-align: left; 97 | } 98 | 99 | div.sphinxsidebarwrapper h1.logo-name { 100 | margin-top: 0px; 101 | } 102 | 103 | div.sphinxsidebarwrapper p.blurb { 104 | margin-top: 0; 105 | font-style: normal; 106 | } 107 | 108 | div.sphinxsidebar h3, 109 | div.sphinxsidebar h4 { 110 | font-family: Georgia, serif; 111 | color: #444; 112 | font-size: 24px; 113 | font-weight: normal; 114 | margin: 0 0 5px 0; 115 | padding: 0; 116 | } 117 | 118 | div.sphinxsidebar h4 { 119 | font-size: 20px; 120 | } 121 | 122 | div.sphinxsidebar h3 a { 123 | color: #444; 124 | } 125 | 126 | div.sphinxsidebar p.logo a, 127 | div.sphinxsidebar h3 a, 128 | div.sphinxsidebar p.logo a:hover, 129 | div.sphinxsidebar h3 a:hover { 130 | border: none; 131 | } 132 | 133 | div.sphinxsidebar p { 134 | color: #555; 135 | margin: 10px 0; 136 | } 137 | 138 | div.sphinxsidebar ul { 139 | margin: 10px 0; 140 | padding: 0; 141 | color: #000; 142 | } 143 | 144 | div.sphinxsidebar ul li.toctree-l1 > a { 145 | font-size: 120%; 146 | } 147 | 148 | div.sphinxsidebar ul li.toctree-l2 > a { 149 | font-size: 110%; 150 | } 151 | 152 | div.sphinxsidebar input { 153 | border: 1px solid #CCC; 154 | font-family: Georgia, serif; 155 | font-size: 1em; 156 | } 157 | 158 | div.sphinxsidebar hr { 159 | border: none; 160 | height: 1px; 161 | color: #AAA; 162 | background: #AAA; 163 | 164 | text-align: left; 165 | margin-left: 0; 166 | width: 50%; 167 | } 168 | 169 | div.sphinxsidebar .badge { 170 | border-bottom: none; 171 | } 172 | 173 | div.sphinxsidebar .badge:hover { 174 | border-bottom: none; 175 | } 176 | 177 | /* To address an issue with donation coming after search */ 178 | div.sphinxsidebar h3.donation { 179 | margin-top: 10px; 180 | } 181 | 182 | /* -- body styles ----------------------------------------------------------- */ 183 | 184 | a { 185 | color: #004B6B; 186 | text-decoration: underline; 187 | } 188 | 189 | a:hover { 190 | color: #6D4100; 191 | text-decoration: underline; 192 | } 193 | 194 | div.body h1, 195 | div.body h2, 196 | div.body h3, 197 | div.body h4, 198 | div.body h5, 199 | div.body h6 { 200 | font-family: Georgia, serif; 201 | font-weight: normal; 202 | margin: 30px 0px 10px 0px; 203 | padding: 0; 204 | } 205 | 206 | div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; } 207 | div.body h2 { font-size: 180%; } 208 | div.body h3 { font-size: 150%; } 209 | div.body h4 { font-size: 130%; } 210 | div.body h5 { font-size: 100%; } 211 | div.body h6 { font-size: 100%; } 212 | 213 | a.headerlink { 214 | color: #DDD; 215 | padding: 0 4px; 216 | text-decoration: none; 217 | } 218 | 219 | a.headerlink:hover { 220 | color: #444; 221 | background: #EAEAEA; 222 | } 223 | 224 | div.body p, div.body dd, div.body li { 225 | line-height: 1.4em; 226 | } 227 | 228 | div.admonition { 229 | margin: 20px 0px; 230 | padding: 10px 30px; 231 | background-color: #EEE; 232 | border: 1px solid #CCC; 233 | } 234 | 235 | div.admonition tt.xref, div.admonition code.xref, div.admonition a tt { 236 | background-color: #FBFBFB; 237 | border-bottom: 1px solid #fafafa; 238 | } 239 | 240 | div.admonition p.admonition-title { 241 | font-family: Georgia, serif; 242 | font-weight: normal; 243 | font-size: 24px; 244 | margin: 0 0 10px 0; 245 | padding: 0; 246 | line-height: 1; 247 | } 248 | 249 | div.admonition p.last { 250 | margin-bottom: 0; 251 | } 252 | 253 | div.highlight { 254 | background-color: #fff; 255 | } 256 | 257 | dt:target, .highlight { 258 | background: #FAF3E8; 259 | } 260 | 261 | div.warning { 262 | background-color: #FCC; 263 | border: 1px solid #FAA; 264 | } 265 | 266 | div.danger { 267 | background-color: #FCC; 268 | border: 1px solid #FAA; 269 | -moz-box-shadow: 2px 2px 4px #D52C2C; 270 | -webkit-box-shadow: 2px 2px 4px #D52C2C; 271 | box-shadow: 2px 2px 4px #D52C2C; 272 | } 273 | 274 | div.error { 275 | background-color: #FCC; 276 | border: 1px solid #FAA; 277 | -moz-box-shadow: 2px 2px 4px #D52C2C; 278 | -webkit-box-shadow: 2px 2px 4px #D52C2C; 279 | box-shadow: 2px 2px 4px #D52C2C; 280 | } 281 | 282 | div.caution { 283 | background-color: #FCC; 284 | border: 1px solid #FAA; 285 | } 286 | 287 | div.attention { 288 | background-color: #FCC; 289 | border: 1px solid #FAA; 290 | } 291 | 292 | div.important { 293 | background-color: #EEE; 294 | border: 1px solid #CCC; 295 | } 296 | 297 | div.note { 298 | background-color: #EEE; 299 | border: 1px solid #CCC; 300 | } 301 | 302 | div.tip { 303 | background-color: #EEE; 304 | border: 1px solid #CCC; 305 | } 306 | 307 | div.hint { 308 | background-color: #EEE; 309 | border: 1px solid #CCC; 310 | } 311 | 312 | div.seealso { 313 | background-color: #EEE; 314 | border: 1px solid #CCC; 315 | } 316 | 317 | div.topic { 318 | background-color: #EEE; 319 | } 320 | 321 | p.admonition-title { 322 | display: inline; 323 | } 324 | 325 | p.admonition-title:after { 326 | content: ":"; 327 | } 328 | 329 | pre, tt, code { 330 | font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; 331 | font-size: 0.9em; 332 | } 333 | 334 | .hll { 335 | background-color: #FFC; 336 | margin: 0 -12px; 337 | padding: 0 12px; 338 | display: block; 339 | } 340 | 341 | img.screenshot { 342 | } 343 | 344 | tt.descname, tt.descclassname, code.descname, code.descclassname { 345 | font-size: 0.95em; 346 | } 347 | 348 | tt.descname, code.descname { 349 | padding-right: 0.08em; 350 | } 351 | 352 | img.screenshot { 353 | -moz-box-shadow: 2px 2px 4px #EEE; 354 | -webkit-box-shadow: 2px 2px 4px #EEE; 355 | box-shadow: 2px 2px 4px #EEE; 356 | } 357 | 358 | table.docutils { 359 | border: 1px solid #888; 360 | -moz-box-shadow: 2px 2px 4px #EEE; 361 | -webkit-box-shadow: 2px 2px 4px #EEE; 362 | box-shadow: 2px 2px 4px #EEE; 363 | } 364 | 365 | table.docutils td, table.docutils th { 366 | border: 1px solid #888; 367 | padding: 0.25em 0.7em; 368 | } 369 | 370 | table.field-list, table.footnote { 371 | border: none; 372 | -moz-box-shadow: none; 373 | -webkit-box-shadow: none; 374 | box-shadow: none; 375 | } 376 | 377 | table.footnote { 378 | margin: 15px 0; 379 | width: 100%; 380 | border: 1px solid #EEE; 381 | background: #FDFDFD; 382 | font-size: 0.9em; 383 | } 384 | 385 | table.footnote + table.footnote { 386 | margin-top: -15px; 387 | border-top: none; 388 | } 389 | 390 | table.field-list th { 391 | padding: 0 0.8em 0 0; 392 | } 393 | 394 | table.field-list td { 395 | padding: 0; 396 | } 397 | 398 | table.field-list p { 399 | margin-bottom: 0.8em; 400 | } 401 | 402 | /* Cloned from 403 | * https://github.com/sphinx-doc/sphinx/commit/ef60dbfce09286b20b7385333d63a60321784e68 404 | */ 405 | .field-name { 406 | -moz-hyphens: manual; 407 | -ms-hyphens: manual; 408 | -webkit-hyphens: manual; 409 | hyphens: manual; 410 | } 411 | 412 | table.footnote td.label { 413 | width: .1px; 414 | padding: 0.3em 0 0.3em 0.5em; 415 | } 416 | 417 | table.footnote td { 418 | padding: 0.3em 0.5em; 419 | } 420 | 421 | dl { 422 | margin: 0; 423 | padding: 0; 424 | } 425 | 426 | dl dd { 427 | margin-left: 30px; 428 | } 429 | 430 | blockquote { 431 | margin: 0 0 0 30px; 432 | padding: 0; 433 | } 434 | 435 | ul, ol { 436 | /* Matches the 30px from the narrow-screen "li > ul" selector below */ 437 | margin: 10px 0 10px 30px; 438 | padding: 0; 439 | } 440 | 441 | pre { 442 | background: #EEE; 443 | padding: 7px 30px; 444 | margin: 15px 0px; 445 | line-height: 1.3em; 446 | } 447 | 448 | div.viewcode-block:target { 449 | background: #ffd; 450 | } 451 | 452 | dl pre, blockquote pre, li pre { 453 | margin-left: 0; 454 | padding-left: 30px; 455 | } 456 | 457 | tt, code { 458 | background-color: #ecf0f3; 459 | color: #222; 460 | /* padding: 1px 2px; */ 461 | } 462 | 463 | tt.xref, code.xref, a tt { 464 | background-color: #FBFBFB; 465 | border-bottom: 1px solid #fff; 466 | } 467 | 468 | a.reference { 469 | text-decoration: none; 470 | border-bottom: 1px dotted #004B6B; 471 | } 472 | 473 | /* Don't put an underline on images */ 474 | a.image-reference, a.image-reference:hover { 475 | border-bottom: none; 476 | } 477 | 478 | a.reference:hover { 479 | border-bottom: 1px solid #6D4100; 480 | } 481 | 482 | a.footnote-reference { 483 | text-decoration: none; 484 | font-size: 0.7em; 485 | vertical-align: top; 486 | border-bottom: 1px dotted #004B6B; 487 | } 488 | 489 | a.footnote-reference:hover { 490 | border-bottom: 1px solid #6D4100; 491 | } 492 | 493 | a:hover tt, a:hover code { 494 | background: #EEE; 495 | } 496 | 497 | 498 | @media screen and (max-width: 870px) { 499 | 500 | div.sphinxsidebar { 501 | display: none; 502 | } 503 | 504 | div.document { 505 | width: 100%; 506 | 507 | } 508 | 509 | div.documentwrapper { 510 | margin-left: 0; 511 | margin-top: 0; 512 | margin-right: 0; 513 | margin-bottom: 0; 514 | } 515 | 516 | div.bodywrapper { 517 | margin-top: 0; 518 | margin-right: 0; 519 | margin-bottom: 0; 520 | margin-left: 0; 521 | } 522 | 523 | ul { 524 | margin-left: 0; 525 | } 526 | 527 | li > ul { 528 | /* Matches the 30px from the "ul, ol" selector above */ 529 | margin-left: 30px; 530 | } 531 | 532 | .document { 533 | width: auto; 534 | } 535 | 536 | .footer { 537 | width: auto; 538 | } 539 | 540 | .bodywrapper { 541 | margin: 0; 542 | } 543 | 544 | .footer { 545 | width: auto; 546 | } 547 | 548 | .github { 549 | display: none; 550 | } 551 | 552 | 553 | 554 | } 555 | 556 | 557 | 558 | @media screen and (max-width: 875px) { 559 | 560 | body { 561 | margin: 0; 562 | padding: 20px 30px; 563 | } 564 | 565 | div.documentwrapper { 566 | float: none; 567 | background: #fff; 568 | } 569 | 570 | div.sphinxsidebar { 571 | display: block; 572 | float: none; 573 | width: 102.5%; 574 | margin: 50px -30px -20px -30px; 575 | padding: 10px 20px; 576 | background: #333; 577 | color: #FFF; 578 | } 579 | 580 | div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p, 581 | div.sphinxsidebar h3 a { 582 | color: #fff; 583 | } 584 | 585 | div.sphinxsidebar a { 586 | color: #AAA; 587 | } 588 | 589 | div.sphinxsidebar p.logo { 590 | display: none; 591 | } 592 | 593 | div.document { 594 | width: 100%; 595 | margin: 0; 596 | } 597 | 598 | div.footer { 599 | display: none; 600 | } 601 | 602 | div.bodywrapper { 603 | margin: 0; 604 | } 605 | 606 | div.body { 607 | min-height: 0; 608 | padding: 0; 609 | } 610 | 611 | .rtd_doc_footer { 612 | display: none; 613 | } 614 | 615 | .document { 616 | width: auto; 617 | } 618 | 619 | .footer { 620 | width: auto; 621 | } 622 | 623 | .footer { 624 | width: auto; 625 | } 626 | 627 | .github { 628 | display: none; 629 | } 630 | } 631 | 632 | 633 | /* misc. */ 634 | 635 | .revsys-inline { 636 | display: none!important; 637 | } 638 | 639 | /* Make nested-list/multi-paragraph items look better in Releases changelog 640 | * pages. Without this, docutils' magical list fuckery causes inconsistent 641 | * formatting between different release sub-lists. 642 | */ 643 | div#changelog > div.section > ul > li > p:only-child { 644 | margin-bottom: 0; 645 | } 646 | 647 | /* Hide fugly table cell borders in ..bibliography:: directive output */ 648 | table.docutils.citation, table.docutils.citation td, table.docutils.citation th { 649 | border: none; 650 | /* Below needed in some edge cases; if not applied, bottom shadows appear */ 651 | -moz-box-shadow: none; 652 | -webkit-box-shadow: none; 653 | box-shadow: none; 654 | } 655 | 656 | 657 | /* relbar */ 658 | 659 | .related { 660 | line-height: 30px; 661 | width: 100%; 662 | font-size: 0.9rem; 663 | } 664 | 665 | .related.top { 666 | border-bottom: 1px solid #EEE; 667 | margin-bottom: 20px; 668 | } 669 | 670 | .related.bottom { 671 | border-top: 1px solid #EEE; 672 | } 673 | 674 | .related ul { 675 | padding: 0; 676 | margin: 0; 677 | list-style: none; 678 | } 679 | 680 | .related li { 681 | display: inline; 682 | } 683 | 684 | nav#rellinks { 685 | float: right; 686 | } 687 | 688 | nav#rellinks li+li:before { 689 | content: "|"; 690 | } 691 | 692 | nav#breadcrumbs li+li:before { 693 | content: "\00BB"; 694 | } 695 | 696 | /* Hide certain items when printing */ 697 | @media print { 698 | div.related { 699 | display: none; 700 | } 701 | } -------------------------------------------------------------------------------- /docs/_build/html/_static/basic.css: -------------------------------------------------------------------------------- 1 | /* 2 | * basic.css 3 | * ~~~~~~~~~ 4 | * 5 | * Sphinx stylesheet -- basic theme. 6 | * 7 | * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. 8 | * :license: BSD, see LICENSE for details. 9 | * 10 | */ 11 | 12 | /* -- main layout ----------------------------------------------------------- */ 13 | 14 | div.clearer { 15 | clear: both; 16 | } 17 | 18 | /* -- relbar ---------------------------------------------------------------- */ 19 | 20 | div.related { 21 | width: 100%; 22 | font-size: 90%; 23 | } 24 | 25 | div.related h3 { 26 | display: none; 27 | } 28 | 29 | div.related ul { 30 | margin: 0; 31 | padding: 0 0 0 10px; 32 | list-style: none; 33 | } 34 | 35 | div.related li { 36 | display: inline; 37 | } 38 | 39 | div.related li.right { 40 | float: right; 41 | margin-right: 5px; 42 | } 43 | 44 | /* -- sidebar --------------------------------------------------------------- */ 45 | 46 | div.sphinxsidebarwrapper { 47 | padding: 10px 5px 0 10px; 48 | } 49 | 50 | div.sphinxsidebar { 51 | float: left; 52 | width: 230px; 53 | margin-left: -100%; 54 | font-size: 90%; 55 | word-wrap: break-word; 56 | overflow-wrap : break-word; 57 | } 58 | 59 | div.sphinxsidebar ul { 60 | list-style: none; 61 | } 62 | 63 | div.sphinxsidebar ul ul, 64 | div.sphinxsidebar ul.want-points { 65 | margin-left: 20px; 66 | list-style: square; 67 | } 68 | 69 | div.sphinxsidebar ul ul { 70 | margin-top: 0; 71 | margin-bottom: 0; 72 | } 73 | 74 | div.sphinxsidebar form { 75 | margin-top: 10px; 76 | } 77 | 78 | div.sphinxsidebar input { 79 | border: 1px solid #98dbcc; 80 | font-family: sans-serif; 81 | font-size: 1em; 82 | } 83 | 84 | div.sphinxsidebar #searchbox form.search { 85 | overflow: hidden; 86 | } 87 | 88 | div.sphinxsidebar #searchbox input[type="text"] { 89 | float: left; 90 | width: 80%; 91 | padding: 0.25em; 92 | box-sizing: border-box; 93 | } 94 | 95 | div.sphinxsidebar #searchbox input[type="submit"] { 96 | float: left; 97 | width: 20%; 98 | border-left: none; 99 | padding: 0.25em; 100 | box-sizing: border-box; 101 | } 102 | 103 | 104 | img { 105 | border: 0; 106 | max-width: 100%; 107 | } 108 | 109 | /* -- search page ----------------------------------------------------------- */ 110 | 111 | ul.search { 112 | margin: 10px 0 0 20px; 113 | padding: 0; 114 | } 115 | 116 | ul.search li { 117 | padding: 5px 0 5px 20px; 118 | background-image: url(file.png); 119 | background-repeat: no-repeat; 120 | background-position: 0 7px; 121 | } 122 | 123 | ul.search li a { 124 | font-weight: bold; 125 | } 126 | 127 | ul.search li div.context { 128 | color: #888; 129 | margin: 2px 0 0 30px; 130 | text-align: left; 131 | } 132 | 133 | ul.keywordmatches li.goodmatch a { 134 | font-weight: bold; 135 | } 136 | 137 | /* -- index page ------------------------------------------------------------ */ 138 | 139 | table.contentstable { 140 | width: 90%; 141 | margin-left: auto; 142 | margin-right: auto; 143 | } 144 | 145 | table.contentstable p.biglink { 146 | line-height: 150%; 147 | } 148 | 149 | a.biglink { 150 | font-size: 1.3em; 151 | } 152 | 153 | span.linkdescr { 154 | font-style: italic; 155 | padding-top: 5px; 156 | font-size: 90%; 157 | } 158 | 159 | /* -- general index --------------------------------------------------------- */ 160 | 161 | table.indextable { 162 | width: 100%; 163 | } 164 | 165 | table.indextable td { 166 | text-align: left; 167 | vertical-align: top; 168 | } 169 | 170 | table.indextable ul { 171 | margin-top: 0; 172 | margin-bottom: 0; 173 | list-style-type: none; 174 | } 175 | 176 | table.indextable > tbody > tr > td > ul { 177 | padding-left: 0em; 178 | } 179 | 180 | table.indextable tr.pcap { 181 | height: 10px; 182 | } 183 | 184 | table.indextable tr.cap { 185 | margin-top: 10px; 186 | background-color: #f2f2f2; 187 | } 188 | 189 | img.toggler { 190 | margin-right: 3px; 191 | margin-top: 3px; 192 | cursor: pointer; 193 | } 194 | 195 | div.modindex-jumpbox { 196 | border-top: 1px solid #ddd; 197 | border-bottom: 1px solid #ddd; 198 | margin: 1em 0 1em 0; 199 | padding: 0.4em; 200 | } 201 | 202 | div.genindex-jumpbox { 203 | border-top: 1px solid #ddd; 204 | border-bottom: 1px solid #ddd; 205 | margin: 1em 0 1em 0; 206 | padding: 0.4em; 207 | } 208 | 209 | /* -- domain module index --------------------------------------------------- */ 210 | 211 | table.modindextable td { 212 | padding: 2px; 213 | border-collapse: collapse; 214 | } 215 | 216 | /* -- general body styles --------------------------------------------------- */ 217 | 218 | div.body { 219 | min-width: 450px; 220 | max-width: 800px; 221 | } 222 | 223 | div.body p, div.body dd, div.body li, div.body blockquote { 224 | -moz-hyphens: auto; 225 | -ms-hyphens: auto; 226 | -webkit-hyphens: auto; 227 | hyphens: auto; 228 | } 229 | 230 | a.headerlink { 231 | visibility: hidden; 232 | } 233 | 234 | a.brackets:before, 235 | span.brackets > a:before{ 236 | content: "["; 237 | } 238 | 239 | a.brackets:after, 240 | span.brackets > a:after { 241 | content: "]"; 242 | } 243 | 244 | h1:hover > a.headerlink, 245 | h2:hover > a.headerlink, 246 | h3:hover > a.headerlink, 247 | h4:hover > a.headerlink, 248 | h5:hover > a.headerlink, 249 | h6:hover > a.headerlink, 250 | dt:hover > a.headerlink, 251 | caption:hover > a.headerlink, 252 | p.caption:hover > a.headerlink, 253 | div.code-block-caption:hover > a.headerlink { 254 | visibility: visible; 255 | } 256 | 257 | div.body p.caption { 258 | text-align: inherit; 259 | } 260 | 261 | div.body td { 262 | text-align: left; 263 | } 264 | 265 | .first { 266 | margin-top: 0 !important; 267 | } 268 | 269 | p.rubric { 270 | margin-top: 30px; 271 | font-weight: bold; 272 | } 273 | 274 | img.align-left, .figure.align-left, object.align-left { 275 | clear: left; 276 | float: left; 277 | margin-right: 1em; 278 | } 279 | 280 | img.align-right, .figure.align-right, object.align-right { 281 | clear: right; 282 | float: right; 283 | margin-left: 1em; 284 | } 285 | 286 | img.align-center, .figure.align-center, object.align-center { 287 | display: block; 288 | margin-left: auto; 289 | margin-right: auto; 290 | } 291 | 292 | .align-left { 293 | text-align: left; 294 | } 295 | 296 | .align-center { 297 | text-align: center; 298 | } 299 | 300 | .align-right { 301 | text-align: right; 302 | } 303 | 304 | /* -- sidebars -------------------------------------------------------------- */ 305 | 306 | div.sidebar { 307 | margin: 0 0 0.5em 1em; 308 | border: 1px solid #ddb; 309 | padding: 7px 7px 0 7px; 310 | background-color: #ffe; 311 | width: 40%; 312 | float: right; 313 | } 314 | 315 | p.sidebar-title { 316 | font-weight: bold; 317 | } 318 | 319 | /* -- topics ---------------------------------------------------------------- */ 320 | 321 | div.topic { 322 | border: 1px solid #ccc; 323 | padding: 7px 7px 0 7px; 324 | margin: 10px 0 10px 0; 325 | } 326 | 327 | p.topic-title { 328 | font-size: 1.1em; 329 | font-weight: bold; 330 | margin-top: 10px; 331 | } 332 | 333 | /* -- admonitions ----------------------------------------------------------- */ 334 | 335 | div.admonition { 336 | margin-top: 10px; 337 | margin-bottom: 10px; 338 | padding: 7px; 339 | } 340 | 341 | div.admonition dt { 342 | font-weight: bold; 343 | } 344 | 345 | div.admonition dl { 346 | margin-bottom: 0; 347 | } 348 | 349 | p.admonition-title { 350 | margin: 0px 10px 5px 0px; 351 | font-weight: bold; 352 | } 353 | 354 | div.body p.centered { 355 | text-align: center; 356 | margin-top: 25px; 357 | } 358 | 359 | /* -- tables ---------------------------------------------------------------- */ 360 | 361 | table.docutils { 362 | border: 0; 363 | border-collapse: collapse; 364 | } 365 | 366 | table.align-center { 367 | margin-left: auto; 368 | margin-right: auto; 369 | } 370 | 371 | table caption span.caption-number { 372 | font-style: italic; 373 | } 374 | 375 | table caption span.caption-text { 376 | } 377 | 378 | table.docutils td, table.docutils th { 379 | padding: 1px 8px 1px 5px; 380 | border-top: 0; 381 | border-left: 0; 382 | border-right: 0; 383 | border-bottom: 1px solid #aaa; 384 | } 385 | 386 | table.footnote td, table.footnote th { 387 | border: 0 !important; 388 | } 389 | 390 | th { 391 | text-align: left; 392 | padding-right: 5px; 393 | } 394 | 395 | table.citation { 396 | border-left: solid 1px gray; 397 | margin-left: 1px; 398 | } 399 | 400 | table.citation td { 401 | border-bottom: none; 402 | } 403 | 404 | th > p:first-child, 405 | td > p:first-child { 406 | margin-top: 0px; 407 | } 408 | 409 | th > p:last-child, 410 | td > p:last-child { 411 | margin-bottom: 0px; 412 | } 413 | 414 | /* -- figures --------------------------------------------------------------- */ 415 | 416 | div.figure { 417 | margin: 0.5em; 418 | padding: 0.5em; 419 | } 420 | 421 | div.figure p.caption { 422 | padding: 0.3em; 423 | } 424 | 425 | div.figure p.caption span.caption-number { 426 | font-style: italic; 427 | } 428 | 429 | div.figure p.caption span.caption-text { 430 | } 431 | 432 | /* -- field list styles ----------------------------------------------------- */ 433 | 434 | table.field-list td, table.field-list th { 435 | border: 0 !important; 436 | } 437 | 438 | .field-list ul { 439 | margin: 0; 440 | padding-left: 1em; 441 | } 442 | 443 | .field-list p { 444 | margin: 0; 445 | } 446 | 447 | .field-name { 448 | -moz-hyphens: manual; 449 | -ms-hyphens: manual; 450 | -webkit-hyphens: manual; 451 | hyphens: manual; 452 | } 453 | 454 | /* -- hlist styles ---------------------------------------------------------- */ 455 | 456 | table.hlist td { 457 | vertical-align: top; 458 | } 459 | 460 | 461 | /* -- other body styles ----------------------------------------------------- */ 462 | 463 | ol.arabic { 464 | list-style: decimal; 465 | } 466 | 467 | ol.loweralpha { 468 | list-style: lower-alpha; 469 | } 470 | 471 | ol.upperalpha { 472 | list-style: upper-alpha; 473 | } 474 | 475 | ol.lowerroman { 476 | list-style: lower-roman; 477 | } 478 | 479 | ol.upperroman { 480 | list-style: upper-roman; 481 | } 482 | 483 | li > p:first-child { 484 | margin-top: 0px; 485 | } 486 | 487 | li > p:last-child { 488 | margin-bottom: 0px; 489 | } 490 | 491 | dl.footnote > dt, 492 | dl.citation > dt { 493 | float: left; 494 | } 495 | 496 | dl.footnote > dd, 497 | dl.citation > dd { 498 | margin-bottom: 0em; 499 | } 500 | 501 | dl.footnote > dd:after, 502 | dl.citation > dd:after { 503 | content: ""; 504 | clear: both; 505 | } 506 | 507 | dl.field-list { 508 | display: flex; 509 | flex-wrap: wrap; 510 | } 511 | 512 | dl.field-list > dt { 513 | flex-basis: 20%; 514 | font-weight: bold; 515 | word-break: break-word; 516 | } 517 | 518 | dl.field-list > dt:after { 519 | content: ":"; 520 | } 521 | 522 | dl.field-list > dd { 523 | flex-basis: 70%; 524 | padding-left: 1em; 525 | margin-left: 0em; 526 | margin-bottom: 0em; 527 | } 528 | 529 | dl { 530 | margin-bottom: 15px; 531 | } 532 | 533 | dd > p:first-child { 534 | margin-top: 0px; 535 | } 536 | 537 | dd ul, dd table { 538 | margin-bottom: 10px; 539 | } 540 | 541 | dd { 542 | margin-top: 3px; 543 | margin-bottom: 10px; 544 | margin-left: 30px; 545 | } 546 | 547 | dt:target, span.highlighted { 548 | background-color: #fbe54e; 549 | } 550 | 551 | rect.highlighted { 552 | fill: #fbe54e; 553 | } 554 | 555 | dl.glossary dt { 556 | font-weight: bold; 557 | font-size: 1.1em; 558 | } 559 | 560 | .optional { 561 | font-size: 1.3em; 562 | } 563 | 564 | .sig-paren { 565 | font-size: larger; 566 | } 567 | 568 | .versionmodified { 569 | font-style: italic; 570 | } 571 | 572 | .system-message { 573 | background-color: #fda; 574 | padding: 5px; 575 | border: 3px solid red; 576 | } 577 | 578 | .footnote:target { 579 | background-color: #ffa; 580 | } 581 | 582 | .line-block { 583 | display: block; 584 | margin-top: 1em; 585 | margin-bottom: 1em; 586 | } 587 | 588 | .line-block .line-block { 589 | margin-top: 0; 590 | margin-bottom: 0; 591 | margin-left: 1.5em; 592 | } 593 | 594 | .guilabel, .menuselection { 595 | font-family: sans-serif; 596 | } 597 | 598 | .accelerator { 599 | text-decoration: underline; 600 | } 601 | 602 | .classifier { 603 | font-style: oblique; 604 | } 605 | 606 | .classifier:before { 607 | font-style: normal; 608 | margin: 0.5em; 609 | content: ":"; 610 | } 611 | 612 | abbr, acronym { 613 | border-bottom: dotted 1px; 614 | cursor: help; 615 | } 616 | 617 | /* -- code displays --------------------------------------------------------- */ 618 | 619 | pre { 620 | overflow: auto; 621 | overflow-y: hidden; /* fixes display issues on Chrome browsers */ 622 | } 623 | 624 | span.pre { 625 | -moz-hyphens: none; 626 | -ms-hyphens: none; 627 | -webkit-hyphens: none; 628 | hyphens: none; 629 | } 630 | 631 | td.linenos pre { 632 | padding: 5px 0px; 633 | border: 0; 634 | background-color: transparent; 635 | color: #aaa; 636 | } 637 | 638 | table.highlighttable { 639 | margin-left: 0.5em; 640 | } 641 | 642 | table.highlighttable td { 643 | padding: 0 0.5em 0 0.5em; 644 | } 645 | 646 | div.code-block-caption { 647 | padding: 2px 5px; 648 | font-size: small; 649 | } 650 | 651 | div.code-block-caption code { 652 | background-color: transparent; 653 | } 654 | 655 | div.code-block-caption + div > div.highlight > pre { 656 | margin-top: 0; 657 | } 658 | 659 | div.code-block-caption span.caption-number { 660 | padding: 0.1em 0.3em; 661 | font-style: italic; 662 | } 663 | 664 | div.code-block-caption span.caption-text { 665 | } 666 | 667 | div.literal-block-wrapper { 668 | padding: 1em 1em 0; 669 | } 670 | 671 | div.literal-block-wrapper div.highlight { 672 | margin: 0; 673 | } 674 | 675 | code.descname { 676 | background-color: transparent; 677 | font-weight: bold; 678 | font-size: 1.2em; 679 | } 680 | 681 | code.descclassname { 682 | background-color: transparent; 683 | } 684 | 685 | code.xref, a code { 686 | background-color: transparent; 687 | font-weight: bold; 688 | } 689 | 690 | h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { 691 | background-color: transparent; 692 | } 693 | 694 | .viewcode-link { 695 | float: right; 696 | } 697 | 698 | .viewcode-back { 699 | float: right; 700 | font-family: sans-serif; 701 | } 702 | 703 | div.viewcode-block:target { 704 | margin: -1px -10px; 705 | padding: 0 10px; 706 | } 707 | 708 | /* -- math display ---------------------------------------------------------- */ 709 | 710 | img.math { 711 | vertical-align: middle; 712 | } 713 | 714 | div.body div.math p { 715 | text-align: center; 716 | } 717 | 718 | span.eqno { 719 | float: right; 720 | } 721 | 722 | span.eqno a.headerlink { 723 | position: relative; 724 | left: 0px; 725 | z-index: 1; 726 | } 727 | 728 | div.math:hover a.headerlink { 729 | visibility: visible; 730 | } 731 | 732 | /* -- printout stylesheet --------------------------------------------------- */ 733 | 734 | @media print { 735 | div.document, 736 | div.documentwrapper, 737 | div.bodywrapper { 738 | margin: 0 !important; 739 | width: 100%; 740 | } 741 | 742 | div.sphinxsidebar, 743 | div.related, 744 | div.footer, 745 | #top-link { 746 | display: none; 747 | } 748 | } -------------------------------------------------------------------------------- /docs/_build/html/_static/searchtools.js: -------------------------------------------------------------------------------- 1 | /* 2 | * searchtools.js 3 | * ~~~~~~~~~~~~~~~~ 4 | * 5 | * Sphinx JavaScript utilities for the full-text search. 6 | * 7 | * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. 8 | * :license: BSD, see LICENSE for details. 9 | * 10 | */ 11 | 12 | if (!Scorer) { 13 | /** 14 | * Simple result scoring code. 15 | */ 16 | var Scorer = { 17 | // Implement the following function to further tweak the score for each result 18 | // The function takes a result array [filename, title, anchor, descr, score] 19 | // and returns the new score. 20 | /* 21 | score: function(result) { 22 | return result[4]; 23 | }, 24 | */ 25 | 26 | // query matches the full name of an object 27 | objNameMatch: 11, 28 | // or matches in the last dotted part of the object name 29 | objPartialMatch: 6, 30 | // Additive scores depending on the priority of the object 31 | objPrio: {0: 15, // used to be importantResults 32 | 1: 5, // used to be objectResults 33 | 2: -5}, // used to be unimportantResults 34 | // Used when the priority is not in the mapping. 35 | objPrioDefault: 0, 36 | 37 | // query found in title 38 | title: 15, 39 | partialTitle: 7, 40 | // query found in terms 41 | term: 5, 42 | partialTerm: 2 43 | }; 44 | } 45 | 46 | if (!splitQuery) { 47 | function splitQuery(query) { 48 | return query.split(/\s+/); 49 | } 50 | } 51 | 52 | /** 53 | * Search Module 54 | */ 55 | var Search = { 56 | 57 | _index : null, 58 | _queued_query : null, 59 | _pulse_status : -1, 60 | 61 | htmlToText : function(htmlString) { 62 | var htmlElement = document.createElement('span'); 63 | htmlElement.innerHTML = htmlString; 64 | $(htmlElement).find('.headerlink').remove(); 65 | docContent = $(htmlElement).find('[role=main]')[0]; 66 | return docContent.textContent || docContent.innerText; 67 | }, 68 | 69 | init : function() { 70 | var params = $.getQueryParameters(); 71 | if (params.q) { 72 | var query = params.q[0]; 73 | $('input[name="q"]')[0].value = query; 74 | this.performSearch(query); 75 | } 76 | }, 77 | 78 | loadIndex : function(url) { 79 | $.ajax({type: "GET", url: url, data: null, 80 | dataType: "script", cache: true, 81 | complete: function(jqxhr, textstatus) { 82 | if (textstatus != "success") { 83 | document.getElementById("searchindexloader").src = url; 84 | } 85 | }}); 86 | }, 87 | 88 | setIndex : function(index) { 89 | var q; 90 | this._index = index; 91 | if ((q = this._queued_query) !== null) { 92 | this._queued_query = null; 93 | Search.query(q); 94 | } 95 | }, 96 | 97 | hasIndex : function() { 98 | return this._index !== null; 99 | }, 100 | 101 | deferQuery : function(query) { 102 | this._queued_query = query; 103 | }, 104 | 105 | stopPulse : function() { 106 | this._pulse_status = 0; 107 | }, 108 | 109 | startPulse : function() { 110 | if (this._pulse_status >= 0) 111 | return; 112 | function pulse() { 113 | var i; 114 | Search._pulse_status = (Search._pulse_status + 1) % 4; 115 | var dotString = ''; 116 | for (i = 0; i < Search._pulse_status; i++) 117 | dotString += '.'; 118 | Search.dots.text(dotString); 119 | if (Search._pulse_status > -1) 120 | window.setTimeout(pulse, 500); 121 | } 122 | pulse(); 123 | }, 124 | 125 | /** 126 | * perform a search for something (or wait until index is loaded) 127 | */ 128 | performSearch : function(query) { 129 | // create the required interface elements 130 | this.out = $('#search-results'); 131 | this.title = $('

' + _('Searching') + '

').appendTo(this.out); 132 | this.dots = $('').appendTo(this.title); 133 | this.status = $('

 

').appendTo(this.out); 134 | this.output = $('