From 72fe904452cbaaeb05de316b2605e303382b7f38 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 17 Aug 2021 20:10:52 +0000 Subject: [PATCH] release/v0.9.77: updating version numbers --- cmdstanpy/_version.py | 2 +- docs/.buildinfo | 2 +- docs/_modules/cmdstanpy/model.html | 768 +++++----- docs/_modules/cmdstanpy/stanfit.html | 1919 +++++++++++++++++++------ docs/_modules/cmdstanpy/utils.html | 716 +++++---- docs/_modules/index.html | 339 +++-- docs/_sources/api.rst.txt | 49 +- docs/_sources/hello_world.rst.txt | 211 +-- docs/_sources/index.rst.txt | 16 +- docs/_sources/installation.rst.txt | 88 +- docs/_sources/overview.rst.txt | 22 +- docs/_static/basic.css | 4 +- docs/_static/css/theme.css | 121 +- docs/_static/doctools.js | 2 + docs/_static/documentation_options.js | 4 +- docs/api.html | 1439 +++++++++++------- docs/genindex.html | 438 +++--- docs/hello_world.html | 686 +++++---- docs/index.html | 444 +++--- docs/installation.html | 505 ++++--- docs/objects.inv | Bin 1225 -> 3378 bytes docs/overview.html | 398 ++--- docs/py-modindex.html | 341 +++-- docs/search.html | 380 ++--- docs/searchindex.js | 2 +- 25 files changed, 5455 insertions(+), 3441 deletions(-) diff --git a/cmdstanpy/_version.py b/cmdstanpy/_version.py index df06fd29..a1380549 100644 --- a/cmdstanpy/_version.py +++ b/cmdstanpy/_version.py @@ -1,3 +1,3 @@ """PyPi Version""" -__version__ = '0.9.76' +__version__ = '0.9.77' diff --git a/docs/.buildinfo b/docs/.buildinfo index 7f8ec36f..3aacd6fa 100644 --- a/docs/.buildinfo +++ b/docs/.buildinfo @@ -1,4 +1,4 @@ # Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: c8ee5db1629a1fd94145e572ed3f29fd +config: e9cabade83bbfdb7441e296941db33e6 tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/_modules/cmdstanpy/model.html b/docs/_modules/cmdstanpy/model.html index 09f1fccc..1351f26a 100644 --- a/docs/_modules/cmdstanpy/model.html +++ b/docs/_modules/cmdstanpy/model.html @@ -1,173 +1,169 @@ - - - - - - - - cmdstanpy.model — CmdStanPy 0.9.76 documentation - - - - - - - - - + + + + + cmdstanpy.model — CmdStanPy 0.9.77 documentation + + + - - + + + + - + + - - - - - - - - + + + - + + + + + + + + + + + + + - - - + - + + + + - -
- -
- - - - - -
- -
- - - - - - - - - - - - - - - - - - -
- -
    - -
  • »
  • - -
  • Module code »
  • - -
  • cmdstanpy.model
  • - - -
  • - -
  • - -
- - -
-
-
-
+ + +
+ +
+

Source code for cmdstanpy.model

 """CmdStanModel"""
 
@@ -180,9 +176,8 @@ 

Source code for cmdstanpy.model

 from collections import OrderedDict
 from concurrent.futures import ThreadPoolExecutor
 from multiprocessing import cpu_count
-from numbers import Real
 from pathlib import Path
-from typing import Any, Dict, List, Union
+from typing import Any, Dict, List, Mapping, Optional, Union
 
 from cmdstanpy.cmdstan_args import (
     CmdStanArgs,
@@ -198,6 +193,7 @@ 

Source code for cmdstanpy.model

     CmdStanMLE,
     CmdStanVB,
     RunSet,
+    from_csv,
 )
 from cmdstanpy.utils import (
     EXTENSION,
@@ -206,7 +202,6 @@ 

Source code for cmdstanpy.model

     cmdstan_path,
     do_command,
     get_logger,
-    scan_sampler_csv,
 )
 
 
@@ -244,13 +239,13 @@ 

Source code for cmdstanpy.model

 
     def __init__(
         self,
-        model_name: str = None,
-        stan_file: str = None,
-        exe_file: str = None,
+        model_name: Optional[str] = None,
+        stan_file: Optional[str] = None,
+        exe_file: Optional[str] = None,
         compile: bool = True,
-        stanc_options: Dict = None,
-        cpp_options: Dict = None,
-        logger: logging.Logger = None,
+        stanc_options: Optional[Dict[str, Any]] = None,
+        cpp_options: Optional[Dict[str, Any]] = None,
+        logger: Optional[logging.Logger] = None,
     ) -> None:
         """
         Initialize object given constructor args.
@@ -261,15 +256,18 @@ 

Source code for cmdstanpy.model

         :param compile: Whether or not to compile the model.
         :param stanc_options: Options for stanc compiler.
         :param cpp_options: Options for C++ compiler.
-        :param logger: Python logger object.
         """
-        self._name = None
+        self._name = ''
         self._stan_file = None
         self._exe_file = None
         self._compiler_options = CompilerOptions(
             stanc_options=stanc_options, cpp_options=cpp_options
         )
-        self._logger = logger or get_logger()
+        if logger is not None:
+            get_logger().warning(
+                "Parameter 'logger' is deprecated."
+                " Control logging behavior via logging.getLogger('cmdstanpy')"
+            )
 
         if model_name is not None:
             if not model_name.strip():
@@ -295,7 +293,7 @@ 

Source code for cmdstanpy.model

                 raise ValueError(
                     'invalid stan filename {}'.format(self._stan_file)
                 )
-            if self._name is None:
+            if not self._name:
                 self._name, _ = os.path.splitext(filename)
             # if program has include directives, record path
             with open(self._stan_file, 'r') as fd:
@@ -318,7 +316,7 @@ 

Source code for cmdstanpy.model

             if not os.path.exists(self._exe_file):
                 raise ValueError('no such file {}'.format(self._exe_file))
             _, exename = os.path.split(self._exe_file)
-            if self._name is None:
+            if not self._name:
                 self._name, _ = os.path.splitext(exename)
             else:
                 if self._name != os.path.splitext(exename)[0]:
@@ -328,23 +326,28 @@ 

Source code for cmdstanpy.model

                         ' found: {}.'.format(self._name, exename)
                     )
 
-        if self._compiler_options is not None:
-            self._compiler_options.validate()
+        self._compiler_options.validate()
 
         if platform.system() == 'Windows':
-            # Add tbb to the $PATH on Windows
-            libtbb = os.environ.get('STAN_TBB')
-            if libtbb is None:
-                libtbb = os.path.join(
-                    cmdstan_path(), 'stan', 'lib', 'stan_math', 'lib', 'tbb'
-                )
-            os.environ['PATH'] = ';'.join(
-                list(
-                    OrderedDict.fromkeys(
-                        [libtbb] + os.environ.get('PATH', '').split(';')
+            try:
+                do_command(['where.exe', 'tbb.dll'])
+            except RuntimeError:
+                # Add tbb to the $PATH on Windows
+                libtbb = os.environ.get('STAN_TBB')
+                if libtbb is None:
+                    libtbb = os.path.join(
+                        cmdstan_path(), 'stan', 'lib', 'stan_math', 'lib', 'tbb'
+                    )
+                get_logger().debug("Adding TBB (%s) to PATH", libtbb)
+                os.environ['PATH'] = ';'.join(
+                    list(
+                        OrderedDict.fromkeys(
+                            [libtbb] + os.environ.get('PATH', '').split(';')
+                        )
                     )
                 )
-            )
+            else:
+                get_logger().debug("TBB already found in load path")
 
         if compile and self._exe_file is None:
             self.compile()
@@ -372,26 +375,26 @@ 

Source code for cmdstanpy.model

         return self._name
 
     @property
-    def stan_file(self) -> str:
+    def stan_file(self) -> Optional[str]:
         """Full path to Stan program file."""
         return self._stan_file
 
     @property
-    def exe_file(self) -> str:
+    def exe_file(self) -> Optional[str]:
         """Full path to Stan exe file."""
         return self._exe_file
 
     @property
-    def stanc_options(self) -> Dict:
+    def stanc_options(self) -> Dict[str, Union[bool, int, str]]:
         """Options to stanc compilers."""
         return self._compiler_options._stanc_options
 
     @property
-    def cpp_options(self) -> Dict:
+    def cpp_options(self) -> Dict[str, Union[bool, int]]:
         """Options to C++ compilers."""
         return self._compiler_options._cpp_options
 
-
[docs] def code(self) -> str: +
[docs] def code(self) -> Optional[str]: """Return Stan program as a string.""" if not self._stan_file: raise RuntimeError('Please specify source file') @@ -401,7 +404,7 @@

Source code for cmdstanpy.model

             with open(self._stan_file, 'r') as fd:
                 code = fd.read()
         except IOError:
-            self._logger.error(
+            get_logger().error(
                 'Cannot read file Stan file: %s', self._stan_file
             )
         return code
@@ -409,8 +412,8 @@

Source code for cmdstanpy.model

 
[docs] def compile( self, force: bool = False, - stanc_options: Dict = None, - cpp_options: Dict = None, + stanc_options: Optional[Dict[str, Any]] = None, + cpp_options: Optional[Dict[str, Any]] = None, override_options: bool = False, ) -> None: """ @@ -457,9 +460,9 @@

Source code for cmdstanpy.model

             exe_time = os.path.getmtime(exe_file)
             if exe_time > src_time and not force:
                 do_compile = False
-                self._logger.info('found newer exe file, not recompiling')
+                get_logger().info('found newer exe file, not recompiling')
                 self._exe_file = exe_file
-                self._logger.info('compiled model file: %s', self._exe_file)
+                get_logger().info('compiled model file: %s', self._exe_file)
         if do_compile:
             compilation_failed = False
             with TemporaryCopiedFile(self._stan_file) as (stan_file, is_copied):
@@ -471,17 +474,17 @@ 

Source code for cmdstanpy.model

                     exe_time = os.path.getmtime(exe_file)
                     if exe_time > src_time and not force:
                         do_compile = False
-                        self._logger.info(
+                        get_logger().info(
                             'found newer exe file, not recompiling'
                         )
 
                 if do_compile:
-                    self._logger.info(
+                    get_logger().info(
                         'compiling stan program, exe file: %s', exe_file
                     )
                     if self._compiler_options is not None:
                         self._compiler_options.validate()
-                        self._logger.info(
+                        get_logger().info(
                             'compiler options: %s', self._compiler_options
                         )
                     make = os.getenv(
@@ -495,11 +498,32 @@ 

Source code for cmdstanpy.model

                         cmd.extend(self._compiler_options.compose())
                     cmd.append(Path(exe_file).as_posix())
                     try:
-                        do_command(cmd, cmdstan_path(), logger=self._logger)
+                        msg = do_command(cmd, cmdstan_path())
+                        if msg is not None and 'Warning or error:' in msg:
+                            msg = msg.split("Warning or error:", 1)[1].strip()
+                            get_logger().warning(
+                                "stanc3 has produced warnings:\n%s", msg
+                            )
+
                     except RuntimeError as e:
-                        self._logger.error(
+                        get_logger().error(
                             'file %s, exception %s', stan_file, str(e)
                         )
+                        if 'PCH file' in str(e):
+                            get_logger().warning(
+                                "%s, %s",
+                                "CmdStan's precompiled header (PCH) files ",
+                                "may need to be rebuilt.",
+                            )
+                            get_logger().warning(
+                                "%s %s",
+                                "If your model failed to compile please run ",
+                                "install_cmdstan(overwrite=True).",
+                            )
+                            get_logger().warning(
+                                "If the issue persists please open a bug report"
+                            )
+
                         compilation_failed = True
 
                 if not compilation_failed:
@@ -519,22 +543,28 @@ 

Source code for cmdstanpy.model

                         shutil.copy(exe_file, self._exe_file)
                     else:
                         self._exe_file = exe_file
-                    self._logger.info('compiled model file: %s', self._exe_file)
+                    get_logger().info('compiled model file: %s', self._exe_file)
                 else:
-                    self._logger.error('model compilation failed')
+ get_logger().error('model compilation failed')
[docs] def optimize( self, - data: Union[Dict, str] = None, - seed: int = None, - inits: Union[Dict, float, str] = None, - output_dir: str = None, - sig_figs: int = None, + data: Union[Mapping[str, Any], str, None] = None, + seed: Optional[int] = None, + inits: Union[Dict[str, float], float, str, None] = None, + output_dir: Optional[str] = None, + sig_figs: Optional[int] = None, save_profile: bool = False, - algorithm: str = None, - init_alpha: float = None, - iter: int = None, - refresh: int = None, + algorithm: Optional[str] = None, + init_alpha: Optional[float] = None, + tol_obj: Optional[float] = None, + tol_rel_obj: Optional[float] = None, + tol_grad: Optional[float] = None, + tol_rel_grad: Optional[float] = None, + tol_param: Optional[float] = None, + history_size: Optional[int] = None, + iter: Optional[int] = None, + refresh: Optional[int] = None, ) -> CmdStanMLE: """ Run the specified CmdStan optimize algorithm to produce a @@ -546,7 +576,7 @@

Source code for cmdstanpy.model

         Unspecified arguments are not included in the call to CmdStan, i.e.,
         those arguments will have CmdStan default values.
 
-        The ``CmdStanMLE`` object records the command, the return code,
+        The :class:`CmdStanMLE` object records the command, the return code,
         and the paths to the optimize method output csv and console files.
         The output files are written either to a specified output directory
         or to a temporary directory which is deleted upon session exit.
@@ -565,7 +595,7 @@ 

Source code for cmdstanpy.model

 
         :param seed: The seed for random number generator. Must be an integer
             between 0 and 2^32 - 1. If unspecified,
-            ``numpy.random.RandomState()`` is used to generate a seed.
+            :class:`numpy.random.RandomState` is used to generate a seed.
 
         :param inits:  Specifies how the sampler initializes parameter values.
             Initialization is either uniform random on a range centered on 0,
@@ -599,15 +629,40 @@ 

Source code for cmdstanpy.model

 
         :param init_alpha: Line search step size for first iteration
 
+        :param tol_obj: Convergence tolerance on changes in objective
+            function value
+
+        :param tol_rel_obj: Convergence tolerance on relative changes
+            in objective function value
+
+        :param tol_grad: Convergence tolerance on the norm of the gradient
+
+        :param tol_rel_grad: Convergence tolerance on the relative
+            norm of the gradient
+
+        :param tol_param: Convergence tolerance on changes in parameter value
+
+        :param history_size: Size of the history for LBFGS Hessian
+            approximation. The value should be less than the dimensionality
+            of the parameter space. 5-10 usually sufficient
+
         :param iter: Total number of iterations
 
         :param refresh: Specify the number of iterations cmdstan will take
-        between progress messages. Default value is 100.
+            between progress messages. Default value is 100.
 
         :return: CmdStanMLE object
         """
         optimize_args = OptimizeArgs(
-            algorithm=algorithm, init_alpha=init_alpha, iter=iter
+            algorithm=algorithm,
+            init_alpha=init_alpha,
+            tol_obj=tol_obj,
+            tol_rel_obj=tol_rel_obj,
+            tol_grad=tol_grad,
+            tol_rel_grad=tol_rel_grad,
+            tol_param=tol_param,
+            history_size=history_size,
+            iter=iter,
         )
 
         with MaybeDictToFilePath(data, inits) as (_data, _inits):
@@ -641,36 +696,35 @@ 

Source code for cmdstanpy.model

     # pylint: disable=too-many-arguments
 
[docs] def sample( self, - data: Union[Dict, str] = None, - chains: Union[int, None] = None, - parallel_chains: Union[int, None] = None, - threads_per_chain: Union[int, None] = None, - seed: Union[int, List[int]] = None, - chain_ids: Union[int, List[int]] = None, - inits: Union[Dict, float, str, List[str]] = None, - iter_warmup: int = None, - iter_sampling: int = None, + data: Union[Mapping[str, Any], str, None] = None, + chains: Optional[int] = None, + parallel_chains: Optional[int] = None, + threads_per_chain: Optional[int] = None, + seed: Union[int, List[int], None] = None, + chain_ids: Union[int, List[int], None] = None, + inits: Union[Dict[str, float], float, str, List[str], None] = None, + iter_warmup: Optional[int] = None, + iter_sampling: Optional[int] = None, save_warmup: bool = False, - thin: int = None, - max_treedepth: float = None, - metric: Union[str, List[str]] = None, - step_size: Union[float, List[float]] = None, + thin: Optional[int] = None, + max_treedepth: Optional[int] = None, + metric: Union[str, List[str], None] = None, + step_size: Union[float, List[float], None] = None, adapt_engaged: bool = True, - adapt_delta: float = None, - adapt_init_phase: int = None, - adapt_metric_window: int = None, - adapt_step_size: int = None, + adapt_delta: Optional[float] = None, + adapt_init_phase: Optional[int] = None, + adapt_metric_window: Optional[int] = None, + adapt_step_size: Optional[int] = None, fixed_param: bool = False, - output_dir: str = None, - sig_figs: int = None, + output_dir: Optional[str] = None, + sig_figs: Optional[int] = None, save_diagnostics: bool = False, save_profile: bool = False, show_progress: Union[bool, str] = False, - validate_csv: bool = True, - refresh: int = None, + refresh: Optional[int] = None, ) -> CmdStanMCMC: """ - Run or more chains of the NUTS sampler to produce a set of draws + Run or more chains of the NUTS-HMC sampler to produce a set of draws from the posterior distribution of a model conditioned on some data. This function validates the specified configuration, composes a call to @@ -679,7 +733,7 @@

Source code for cmdstanpy.model

         Unspecified arguments are not included in the call to CmdStan, i.e.,
         those arguments will have CmdStan default values.
 
-        For each chain, the ``CmdStanMCMC`` object records the command,
+        For each chain, the :class:`CmdStanMCMC` object records the command,
         the return code, the sampler output file paths, and the corresponding
         console outputs, if any. The output files are written either to a
         specified output directory or to a temporary directory which is deleted
@@ -700,7 +754,7 @@ 

Source code for cmdstanpy.model

         :param chains: Number of sampler chains, must be a positive integer.
 
         :param parallel_chains: Number of processes to run in parallel. Must be
-            a positive integer.  Defaults to ``multiprocessing.cpu_count()``.
+            a positive integer.  Defaults to :func:`multiprocessing.cpu_count`.
 
         :param threads_per_chain: The number of threads to use in parallelized
             sections within an MCMC chain (e.g., when using the Stan functions
@@ -710,7 +764,7 @@ 

Source code for cmdstanpy.model

 
         :param seed: The seed for random number generator. Must be an integer
             between 0 and 2^32 - 1. If unspecified,
-            ``numpy.random.RandomState()``
+            :class:`numpy.random.RandomState`
             is used to generate a seed which will be used for all chains.
             When the same seed is used across all chains,
             the chain-id is used to advance the RNG to avoid dependent samples.
@@ -824,13 +878,8 @@ 

Source code for cmdstanpy.model

             If show_progress=='notebook' use tqdm_notebook
             (needs nodejs for jupyter).
 
-        :param validate_csv: If ``False``, skip scan of sample csv output file.
-            When sample is large or disk i/o is slow, will speed up processing.
-            Default is ``True`` - sample csv files are scanned for completeness
-            and consistency.
-
         :param refresh: Specify the number of iterations cmdstan will take
-        between progress messages. Default value is 100.
+            between progress messages. Default value is 100.
 
         :return: CmdStanMCMC object
         """
@@ -872,7 +921,7 @@ 

Source code for cmdstanpy.model

         if parallel_chains is None:
             parallel_chains = max(min(cpu_count(), chains), 1)
         elif parallel_chains > chains:
-            self._logger.info(
+            get_logger().info(
                 'Requesting %u parallel_chains for %u chains,'
                 ' running all chains in parallel.',
                 parallel_chains,
@@ -891,7 +940,7 @@ 

Source code for cmdstanpy.model

                 'Argument threads_per_chain must be a positive integer value, '
                 'found {}.'.format(threads_per_chain)
             )
-        self._logger.debug(
+        get_logger().debug(
             'total threads: %u', parallel_chains * threads_per_chain
         )
         os.environ['STAN_NUM_THREADS'] = str(threads_per_chain)
@@ -900,9 +949,9 @@ 

Source code for cmdstanpy.model

             try:
                 import tqdm
 
-                self._logger.propagate = False
+                get_logger().propagate = False
             except ImportError:
-                self._logger.warning(
+                get_logger().warning(
                     (
                         'Package tqdm not installed, cannot show progress '
                         'information. Please install tqdm with '
@@ -942,7 +991,6 @@ 

Source code for cmdstanpy.model

                 save_profile=save_profile,
                 method_args=sampler_args,
                 refresh=refresh,
-                logger=self._logger,
             )
             runset = RunSet(args=args, chains=chains, chain_ids=chain_ids)
             pbar = None
@@ -967,16 +1015,16 @@ 

Source code for cmdstanpy.model

                                     'issuecomment-384743637 and remember to '
                                     'stop & start your jupyter server.'
                                 )
-                                self._logger.warning(msg)
+                                get_logger().warning(msg)
                                 tqdm_pbar = tqdm.tqdm
                         else:
                             tqdm_pbar = tqdm.tqdm
                         # enable dynamic_ncols for advanced users
                         # currently hidden feature
-                        dynamic_ncols = os.environ.get(
+                        dynamic_ncols_raw = os.environ.get(
                             'TQDM_DYNAMIC_NCOLS', 'False'
                         )
-                        if dynamic_ncols.lower() in ['0', 'false']:
+                        if dynamic_ncols_raw.lower() in ['0', 'false']:
                             dynamic_ncols = False
                         else:
                             dynamic_ncols = True
@@ -994,7 +1042,7 @@ 

Source code for cmdstanpy.model

                 pbar.close()
             if show_progress:
                 # re-enable logger for console
-                self._logger.propagate = True
+                get_logger().propagate = True
 
             if not runset._check_retcodes():
                 msg = 'Error during sampling:\n{}'.format(runset.get_err_msgs())
@@ -1003,27 +1051,27 @@ 

Source code for cmdstanpy.model

                 )
                 raise RuntimeError(msg)
 
-            mcmc = CmdStanMCMC(runset, validate_csv, logger=self._logger)
+            mcmc = CmdStanMCMC(runset)
         return mcmc
[docs] def generate_quantities( self, - data: Union[Dict, str] = None, - mcmc_sample: Union[CmdStanMCMC, List[str]] = None, - seed: int = None, - gq_output_dir: str = None, - sig_figs: int = None, - refresh: int = None, + data: Union[Mapping[str, Any], str, None] = None, + mcmc_sample: Union[CmdStanMCMC, List[str], None] = None, + seed: Optional[int] = None, + gq_output_dir: Optional[str] = None, + sig_figs: Optional[int] = None, + refresh: Optional[int] = None, ) -> CmdStanGQ: """ Run CmdStan's generate_quantities method which runs the generated quantities block of a model given an existing sample. - This function takes a CmdStanMCMC object and the dataset used to - generate that sample and calls to the CmdStan ``generate_quantities`` + This function takes a :class:`CmdStanMCMC` object and the dataset used + to generate that sample and calls to the CmdStan ``generate_quantities`` method to generate additional quantities of interest. - The ``CmdStanGQ`` object records the command, the return code, + The :class:`CmdStanGQ` object records the command, the return code, and the paths to the generate method output csv and console files. The output files are written either to a specified output directory or to a temporary directory which is deleted upon session exit. @@ -1040,13 +1088,13 @@

Source code for cmdstanpy.model

             either as a dictionary with entries matching the data variables,
             or as the path of a data file in JSON or Rdump format.
 
-        :param mcmc_sample: Can be either a ``CmdStanMCMC`` object returned by
-            the ``sample`` method or a list of stan-csv files generated
+        :param mcmc_sample: Can be either a :class:`CmdStanMCMC` object returned
+            by the :meth:`sample` method or a list of stan-csv files generated
             by fitting the model to the data using any Stan interface.
 
         :param seed: The seed for random number generator. Must be an integer
             between 0 and 2^32 - 1. If unspecified,
-            ``numpy.random.RandomState()``
+            :class:`numpy.random.RandomState`
             is used to generate a seed which will be used for all chains.
             *NOTE: Specifying the seed will guarantee the same result for
             multiple invocations of this method with the same inputs.  However
@@ -1067,66 +1115,37 @@ 

Source code for cmdstanpy.model

 
         :return: CmdStanGQ object
         """
-        sample_csv_files = []
-        sample_drawset = None
-        chains = 0
-
         if isinstance(mcmc_sample, CmdStanMCMC):
+            mcmc_fit = mcmc_sample
             sample_csv_files = mcmc_sample.runset.csv_files
-            sample_drawset = mcmc_sample.draws_pd()
-            chains = mcmc_sample.chains
-            chain_ids = mcmc_sample.chain_ids
         elif isinstance(mcmc_sample, list):
             if len(mcmc_sample) < 1:
-                raise ValueError('MCMC sample cannot be empty list')
-            sample_csv_files = mcmc_sample
-            chains = len(sample_csv_files)
-            chain_ids = [x + 1 for x in range(chains)]
+                raise ValueError(
+                    'Expecting list of Stan CSV files, found empty list'
+                )
+            try:
+                sample_csv_files = mcmc_sample
+                sample_fit = from_csv(sample_csv_files)
+                mcmc_fit = sample_fit  # type: ignore
+            except ValueError as e:
+                raise ValueError(
+                    'Invalid sample from Stan CSV files, error:\n\t{}\n\t'
+                    ' while processing files\n\t{}'.format(
+                        repr(e), '\n\t'.join(mcmc_sample)
+                    )
+                ) from e
         else:
             raise ValueError(
                 'MCMC sample must be either CmdStanMCMC object'
-                ' or list of paths to sample csv_files.'
+                ' or list of paths to sample Stan CSV files.'
+            )
+        chains = mcmc_fit.chains
+        chain_ids = mcmc_fit.chain_ids
+        if mcmc_fit.metadata.cmdstan_config['save_warmup']:
+            get_logger().warning(
+                'Sample contains saved warmup draws which will be used '
+                'to generate additional quantities of interest.'
             )
-        try:
-            if sample_drawset is None:  # assemble sample from csv files
-                config = {}
-                # scan 1st csv file to get config
-                try:
-                    config = scan_sampler_csv(sample_csv_files[0])
-                except ValueError:
-                    config = scan_sampler_csv(sample_csv_files[0], True)
-                conf_iter_sampling = None
-                if 'num_samples' in config:
-                    conf_iter_sampling = int(config['num_samples'])
-                conf_iter_warmup = None
-                if 'num_warmup' in config:
-                    conf_iter_warmup = int(config['num_warmup'])
-                conf_thin = None
-                if 'thin' in config:
-                    conf_thin = int(config['thin'])
-                sampler_args = SamplerArgs(
-                    iter_sampling=conf_iter_sampling,
-                    iter_warmup=conf_iter_warmup,
-                    thin=conf_thin,
-                )
-                args = CmdStanArgs(
-                    self._name,
-                    self._exe_file,
-                    chain_ids=chain_ids,
-                    method_args=sampler_args,
-                )
-                runset = RunSet(args=args, chains=chains, chain_ids=chain_ids)
-                runset._csv_files = sample_csv_files
-                sample_fit = CmdStanMCMC(runset)
-                sample_drawset = sample_fit.draws_pd()
-        except ValueError as exc:
-            raise ValueError(
-                'Invalid mcmc_sample, error:\n\t{}\n\t'
-                ' while processing files\n\t{}'.format(
-                    repr(exc), '\n\t'.join(sample_csv_files)
-                )
-            ) from exc
-
         generate_quantities_args = GenerateQuantitiesArgs(
             csv_files=sample_csv_files
         )
@@ -1159,30 +1178,30 @@ 

Source code for cmdstanpy.model

                     msg, runset.__repr__()
                 )
                 raise RuntimeError(msg)
-            quantities = CmdStanGQ(runset=runset, mcmc_sample=sample_drawset)
+            quantities = CmdStanGQ(runset=runset, mcmc_sample=mcmc_fit)
         return quantities
[docs] def variational( self, - data: Union[Dict, str] = None, - seed: int = None, - inits: float = None, - output_dir: str = None, - sig_figs: int = None, + data: Union[Mapping[str, Any], str, None] = None, + seed: Optional[int] = None, + inits: Optional[float] = None, + output_dir: Optional[str] = None, + sig_figs: Optional[int] = None, save_diagnostics: bool = False, save_profile: bool = False, - algorithm: str = None, - iter: int = None, - grad_samples: int = None, - elbo_samples: int = None, - eta: Real = None, + algorithm: Optional[str] = None, + iter: Optional[int] = None, + grad_samples: Optional[int] = None, + elbo_samples: Optional[int] = None, + eta: Optional[float] = None, adapt_engaged: bool = True, - adapt_iter: int = None, - tol_rel_obj: Real = None, - eval_elbo: int = None, - output_samples: int = None, + adapt_iter: Optional[int] = None, + tol_rel_obj: Optional[float] = None, + eval_elbo: Optional[int] = None, + output_samples: Optional[int] = None, require_converged: bool = True, - refresh: int = None, + refresh: Optional[int] = None, ) -> CmdStanVB: """ Run CmdStan's variational inference algorithm to approximate @@ -1194,7 +1213,7 @@

Source code for cmdstanpy.model

         Unspecified arguments are not included in the call to CmdStan, i.e.,
         those arguments will have CmdStan default values.
 
-        The ``CmdStanVB`` object records the command, the return code,
+        The :class:`CmdStanVB` object records the command, the return code,
         and the paths to the variational method output csv and console files.
         The output files are written either to a specified output directory
         or to a temporary directory which is deleted upon session exit.
@@ -1213,7 +1232,7 @@ 

Source code for cmdstanpy.model

 
         :param seed: The seed for random number generator. Must be an integer
             between 0 and 2^32 - 1. If unspecified,
-            ``numpy.random.RandomState()``
+            :class:`numpy.random.RandomState`
             is used to generate a seed which will be used for all chains.
 
         :param inits:  Specifies how the sampler initializes parameter values.
@@ -1311,8 +1330,19 @@ 

Source code for cmdstanpy.model

             errors = re.findall(pat, contents)
             if len(errors) > 0:
                 valid = False
-        if require_converged and not valid:
-            raise RuntimeError('The algorithm may not have converged.')
+        if not valid:
+            if require_converged:
+                raise RuntimeError(
+                    'The algorithm may not have converged.\n'
+                    'If you would like to inspect the output, '
+                    're-call with require_converged=False'
+                )
+            # else:
+            get_logger().warning(
+                '%s\n%s',
+                'The algorithm may not have converged.',
+                'Proceeding because require_converged is set to False',
+            )
         if not runset._check_retcodes():
             msg = 'Error during variational inference:\n{}'.format(
                 runset.get_err_msgs()
@@ -1333,11 +1363,11 @@ 

Source code for cmdstanpy.model

         Spawn process, capture console output to file, record returncode.
         """
         cmd = runset.cmds[idx]
-        self._logger.info('start chain %u', idx + 1)
-        self._logger.debug(
+        get_logger().info('start chain %u', idx + 1)
+        get_logger().debug(
             'threads: %s', str(os.environ.get('STAN_NUM_THREADS'))
         )
-        self._logger.debug('sampling: %s', cmd)
+        get_logger().debug('sampling: %s', cmd)
         try:
             proc = subprocess.Popen(
                 cmd,
@@ -1352,11 +1382,18 @@ 

Source code for cmdstanpy.model

             if pbar:
                 stdout = stdout_pbar + stdout
 
-            self._logger.info('finish chain %u', idx + 1)
+            get_logger().info('finish chain %u', idx + 1)
             runset._set_retcode(idx, proc.returncode)
             if stdout:
                 with open(runset.stdout_files[idx], 'w+') as fd:
-                    fd.write(stdout.decode('utf-8'))
+                    contents = stdout.decode('utf-8')  # bugfix 425
+                    if 'running fixed_param sampler' in contents:
+                        sampler_args = runset._args.method_args
+                        assert isinstance(
+                            sampler_args, SamplerArgs
+                        )  # make the typechecker happy
+                        sampler_args.fixed_param = True
+                    fd.write(contents)
             console_error = ''
             if stderr:
                 console_error = stderr.decode('utf-8')
@@ -1375,14 +1412,18 @@ 

Source code for cmdstanpy.model

                     )
                 if len(console_error) > 0:
                     msg = '{}\n error message:\n\t{}'.format(msg, console_error)
-                self._logger.error(msg)
+                get_logger().error(msg)
 
         except OSError as e:
             msg = 'Chain {} encounted error: {}\n'.format(idx + 1, str(e))
             raise RuntimeError(msg) from e
 
+    # pylint: disable=no-self-use
     def _read_progress(
-        self, proc: subprocess.Popen, pbar: Any, idx: int
+        self,
+        proc: subprocess.Popen,  # [] - Popoen is only generic in 3.9
+        pbar: Any,
+        idx: int,
     ) -> bytes:
         """
         Update tqdm progress bars according to CmdStan console progress msgs.
@@ -1401,7 +1442,7 @@ 

Source code for cmdstanpy.model

 
         try:
             # iterate while process is sampling
-            while proc.poll() is None:
+            while proc.poll() is None and proc.stdout is not None:
                 output = proc.stdout.readline()
                 stdout += output
                 output = output.decode('utf-8').strip()
@@ -1431,7 +1472,7 @@ 

Source code for cmdstanpy.model

                 pbar.close()
 
         except Exception as e:  # pylint: disable=broad-except
-            self._logger.warning(
+            get_logger().warning(
                 'Chain %s: Failed to read the progress on the fly. Error: %s',
                 idx,
                 repr(e),
@@ -1440,47 +1481,38 @@ 

Source code for cmdstanpy.model

         return stdout
-
- -
-
+
+ + +
+ -
+
+ +
+ -
-

- © Copyright 2021, Stan Development Team. +

+
+ + -

-
- + -
-
- -
-
- - - - - - - - - - + + \ No newline at end of file diff --git a/docs/_modules/cmdstanpy/stanfit.html b/docs/_modules/cmdstanpy/stanfit.html index ee999577..f239b4ca 100644 --- a/docs/_modules/cmdstanpy/stanfit.html +++ b/docs/_modules/cmdstanpy/stanfit.html @@ -1,177 +1,174 @@ - - - - - - - - cmdstanpy.stanfit — CmdStanPy 0.9.76 documentation - - - - - - - - - + + + + + cmdstanpy.stanfit — CmdStanPy 0.9.77 documentation + + + - - + + + + - + + - - - - - - - - + + + - + + + + + + + + + + + + + - - - + - + + + + - -
- - -
- - - - -
- -
- - - - - - - - - - - - - - - - - - -
- -
    - -
  • »
  • - -
  • Module code »
  • - -
  • cmdstanpy.stanfit
  • - - -
  • - -
  • - -
- - -
-
-
-
+ + +
+ +
+

Source code for cmdstanpy.stanfit

 """Container objects for results of CmdStan run(s)."""
 
 import copy
+import glob
 import logging
 import math
 import os
@@ -180,13 +177,35 @@ 

Source code for cmdstanpy.stanfit

 from collections import Counter, OrderedDict
 from datetime import datetime
 from time import time
-from typing import Dict, List, Tuple
+from typing import (
+    Any,
+    Dict,
+    Hashable,
+    List,
+    MutableMapping,
+    Optional,
+    Tuple,
+    Union,
+)
 
 import numpy as np
 import pandas as pd
 
-from cmdstanpy import _TMPDIR, _CMDSTAN_WARMUP, _CMDSTAN_SAMPLING, _CMDSTAN_THIN
-from cmdstanpy.cmdstan_args import CmdStanArgs, Method
+try:
+    import xarray as xr
+
+    XARRAY_INSTALLED = True
+except ImportError:
+    XARRAY_INSTALLED = False
+
+from cmdstanpy import _CMDSTAN_SAMPLING, _CMDSTAN_THIN, _CMDSTAN_WARMUP, _TMPDIR
+from cmdstanpy.cmdstan_args import (
+    CmdStanArgs,
+    Method,
+    OptimizeArgs,
+    SamplerArgs,
+    VariationalArgs,
+)
 from cmdstanpy.utils import (
     EXTENSION,
     check_sampler_csv,
@@ -194,9 +213,11 @@ 

Source code for cmdstanpy.stanfit

     cmdstan_version_at,
     create_named_text_file,
     do_command,
+    flatten_chains,
     get_logger,
-    parse_sampler_vars,
+    parse_method_vars,
     parse_stan_vars,
+    scan_config,
     scan_generated_quantities_csv,
     scan_optimize_csv,
     scan_variational_csv,
@@ -206,7 +227,7 @@ 

Source code for cmdstanpy.stanfit

 
[docs]class RunSet: """ Encapsulates the configuration and results of a call to any CmdStan - inference method. Records the sampler return code and locations of + inference method. Records the method return code and locations of all console, error, and output files. """ @@ -214,23 +235,27 @@

Source code for cmdstanpy.stanfit

         self,
         args: CmdStanArgs,
         chains: int = 4,
-        chain_ids: List[int] = None,
-        logger: logging.Logger = None,
+        chain_ids: Optional[List[int]] = None,
+        logger: Optional[logging.Logger] = None,
     ) -> None:
         """Initialize object."""
         self._args = args
         self._chains = chains
-        self._logger = logger or get_logger()
+        if logger is not None:
+            get_logger().warning(
+                "Parameter 'logger' is deprecated."
+                " Control logging behavior via logging.getLogger('cmdstanpy)'"
+            )
         if chains < 1:
             raise ValueError(
-                'chains must be positive integer value, '
+                'Chains must be positive integer value, '
                 'found {}'.format(chains)
             )
         if chain_ids is None:
             chain_ids = [x + 1 for x in range(chains)]
         elif len(chain_ids) != chains:
             raise ValueError(
-                'mismatch between number of chains and chain_ids, '
+                'Mismatch between number of chains and chain_ids, '
                 'found {} chains, but {} chain_ids'.format(
                     chains, len(chain_ids)
                 )
@@ -248,11 +273,11 @@ 

Source code for cmdstanpy.stanfit

             output_dir = args.output_dir
         else:
             output_dir = _TMPDIR
-        self._csv_files = [None for _ in range(chains)]
-        self._diagnostic_files = [None for _ in range(chains)]
-        self._profile_files = [None for _ in range(chains)]
-        self._stdout_files = [None for _ in range(chains)]
-        self._stderr_files = [None for _ in range(chains)]
+        self._csv_files = ['' for _ in range(chains)]
+        self._diagnostic_files = ['' for _ in range(chains)]
+        self._profile_files = ['' for _ in range(chains)]
+        self._stdout_files = ['' for _ in range(chains)]
+        self._stderr_files = ['' for _ in range(chains)]
         self._cmds = []
         for i in range(chains):
             if args.output_dir is None:
@@ -387,7 +412,7 @@ 

Source code for cmdstanpy.stanfit

         return self._chain_ids
 
     @property
-    def cmds(self) -> List[str]:
+    def cmds(self) -> List[List[str]]:
         """List of call(s) to CmdStan, one call per-chain."""
         return self._cmds
 
@@ -431,7 +456,7 @@ 

Source code for cmdstanpy.stanfit

         """Set retcode for chain[idx] to val."""
         self._retcodes[idx] = val
 
-
[docs] def get_err_msgs(self) -> List[str]: +
[docs] def get_err_msgs(self) -> str: """Checks console messages for each chain.""" msgs = [] for i in range(self._chains): @@ -464,11 +489,15 @@

Source code for cmdstanpy.stanfit

                     )
         return '\n'.join(msgs)
-
[docs] def save_csvfiles(self, dir: str = None) -> None: +
[docs] def save_csvfiles(self, dir: Optional[str] = None) -> None: """ Moves csvfiles to specified directory. :param dir: directory path + + See Also + -------- + cmdstanpy.from_csv """ if dir is None: dir = os.path.realpath('.') @@ -479,12 +508,12 @@

Source code for cmdstanpy.stanfit

                 pass
             os.remove(test_path)  # cleanup
         except (IOError, OSError, PermissionError) as exc:
-            raise Exception('cannot save to path: {}'.format(dir)) from exc
+            raise Exception('Cannot save to path: {}'.format(dir)) from exc
 
         for i in range(self.chains):
             if not os.path.exists(self._csv_files[i]):
                 raise ValueError(
-                    'cannot access csv file {}'.format(self._csv_files[i])
+                    'Cannot access csv file {}'.format(self._csv_files[i])
                 )
 
             path, filename = os.path.split(self._csv_files[i])
@@ -497,33 +526,31 @@ 

Source code for cmdstanpy.stanfit

             to_path = os.path.join(dir, filename)
             if os.path.exists(to_path):
                 raise ValueError(
-                    'file exists, not overwriting: {}'.format(to_path)
+                    'File exists, not overwriting: {}'.format(to_path)
                 )
             try:
-                self._logger.debug(
+                get_logger().debug(
                     'saving tmpfile: "%s" as: "%s"', self._csv_files[i], to_path
                 )
                 shutil.move(self._csv_files[i], to_path)
                 self._csv_files[i] = to_path
             except (IOError, OSError, PermissionError) as e:
                 raise ValueError(
-                    'cannot save to file: {}'.format(to_path)
+                    'Cannot save to file: {}'.format(to_path)
                 ) from e
-class InferenceMetadata: +
[docs]class InferenceMetadata: """ CmdStan configuration and contents of output file parsed out of the Stan CSV file header comments and column headers. - Assumes valid CSV files. Uses deepcopy for immutability. + Assumes valid CSV files. """ - def __init__(self, config: Dict) -> None: + def __init__(self, config: Dict[str, Any]) -> None: """Initialize object from CSV headers""" self._cmdstan_config = config - self._sampler_vars_cols = parse_sampler_vars( - names=config['column_names'] - ) + self._method_vars_cols = parse_method_vars(names=config['column_names']) stan_vars_dims, stan_vars_cols = parse_stan_vars( names=config['column_names'] ) @@ -534,20 +561,45 @@

Source code for cmdstanpy.stanfit

         return 'Metadata:\n{}\n'.format(self._cmdstan_config)
 
     @property
-    def cmdstan_config(self) -> Dict:
+    def cmdstan_config(self) -> Dict[str, Any]:
+        """
+        Returns a dictionary containing a set of name, value pairs
+        parsed out of the Stan CSV file header.  These include the
+        command configuration and the CSV file header row information.
+        Uses deepcopy for immutability.
+        """
         return copy.deepcopy(self._cmdstan_config)
 
     @property
-    def sampler_vars_cols(self) -> Dict:
-        return copy.deepcopy(self._sampler_vars_cols)
+    def method_vars_cols(self) -> Dict[str, Tuple[int, ...]]:
+        """
+        Returns a map from a Stan inference method variable to
+        a tuple of column indices in inference engine's output array.
+        Method variable names always end in `__`, e.g. `lp__`.
+        Uses deepcopy for immutability.
+        """
+        return copy.deepcopy(self._method_vars_cols)
 
     @property
-    def stan_vars_dims(self) -> Dict:
-        return copy.deepcopy(self._stan_vars_dims)
+    def stan_vars_cols(self) -> Dict[str, Tuple[int, ...]]:
+        """
+        Returns a map from a Stan program variable name to a
+        tuple of the column indices in the vector or matrix of
+        estimates produced by a CmdStan inference method.
+        Uses deepcopy for immutability.
+        """
+        return copy.deepcopy(self._stan_vars_cols)
 
     @property
-    def stan_vars_cols(self) -> Dict:
-        return copy.deepcopy(self._stan_vars_cols)
+    def stan_vars_dims(self) -> Dict[str, Tuple[int, ...]]:
+        """
+        Returns map from Stan program variable names to variable dimensions.
+        Scalar types are mapped to the empty tuple, e.g.,
+        program variable ``int foo`` has dimension ``()`` and
+        program variable ``vector[10] bar`` has single dimension ``(10)``.
+        Uses deepcopy for immutability.
+        """
+        return copy.deepcopy(self._stan_vars_dims)
[docs]class CmdStanMCMC: @@ -555,20 +607,18 @@

Source code for cmdstanpy.stanfit

     Container for outputs from CmdStan sampler run.
     Provides methods to summarize and diagnose the model fit
     and accessor methods to access the entire sample or
-    individual items.
+    individual items. Created by :meth:`CmdStanModel.sample`
 
     The sample is lazily instantiated on first access of either
     the resulting sample or the HMC tuning parameters, i.e., the
-    step size and metric.  The sample can treated either as a 2D or
-    3D array; the former flattens all chains into a single dimension.
+    step size and metric.
     """
 
     # pylint: disable=too-many-public-methods
     def __init__(
         self,
         runset: RunSet,
-        validate_csv: bool = True,
-        logger: logging.Logger = None,
+        logger: Optional[logging.Logger] = None,
     ) -> None:
         """Initialize object."""
         if not runset.method == Method.SAMPLE:
@@ -577,31 +627,41 @@ 

Source code for cmdstanpy.stanfit

                 'found method {}'.format(runset.method)
             )
         self.runset = runset
-        self._logger = logger or get_logger()
-        # copy info from runset
-        self._iter_sampling = runset._args.method_args.iter_sampling
-        if self._iter_sampling is None:
+        if logger is not None:
+            get_logger().warning(
+                "Parameter 'logger' is deprecated."
+                " Control logging behavior via logging.getLogger('cmdstanpy')"
+            )
+        # info from runset to be exposed
+        sampler_args = self.runset._args.method_args
+        assert isinstance(
+            sampler_args, SamplerArgs
+        )  # make the typechecker happy
+        iter_sampling = sampler_args.iter_sampling
+        if iter_sampling is None:
             self._iter_sampling = _CMDSTAN_SAMPLING
-        self._iter_warmup = runset._args.method_args.iter_warmup
-        if self._iter_warmup is None:
+        else:
+            self._iter_sampling = iter_sampling
+        iter_warmup = sampler_args.iter_warmup
+        if iter_warmup is None:
             self._iter_warmup = _CMDSTAN_WARMUP
-        self._thin = runset._args.method_args.thin
-        if self._thin is None:
-            self._thin = _CMDSTAN_THIN
-        self._is_fixed_param = runset._args.method_args.fixed_param
-        self._save_warmup = runset._args.method_args.save_warmup
+        else:
+            self._iter_warmup = iter_warmup
+        thin = sampler_args.thin
+        if thin is None:
+            self._thin: int = _CMDSTAN_THIN
+        else:
+            self._thin = thin
+        self._is_fixed_param = sampler_args.fixed_param
+        self._save_warmup = sampler_args.save_warmup
         self._sig_figs = runset._args.sig_figs
-        # metadata from Stan CSV files
-        self._metadata = None
-        # HMC tuning params
-        self._metric = None
-        self._step_size = None
-        # inference
-        self._draws = None
-        self._draws_pd = None
-        self._validate_csv = validate_csv
-        if validate_csv:
-            self.validate_csv_files()
+        # info from CSV values, instantiated lazily
+        self._metric = np.array(())
+        self._step_size = np.array(())
+        self._draws = np.array(())
+        # info from CSV initial comments and header
+        config = self._validate_csv_files()
+        self._metadata: InferenceMetadata = InferenceMetadata(config)
 
     def __repr__(self) -> str:
         repr = 'CmdStanMCMC: model={} chains={}{}'.format(
@@ -640,6 +700,48 @@ 

Source code for cmdstanpy.stanfit

         """
         return int(math.ceil((self._iter_sampling) / self._thin))
 
+    @property
+    def metadata(self) -> InferenceMetadata:
+        """
+        Returns object which contains CmdStan configuration as well as
+        information about the names and structure of the inference method
+        and model output variables.
+        """
+        return self._metadata
+
+    @property
+    def sampler_vars_cols(self) -> Dict[str, Tuple[int, ...]]:
+        """
+        Deprecated - use "metadata.method_vars_cols" instead
+        """
+        get_logger().warning(
+            'Property "sampler_vars_cols" has been deprecated, '
+            'use "metadata.method_vars_cols" instead.'
+        )
+        return self.metadata.method_vars_cols
+
+    @property
+    def stan_vars_cols(self) -> Dict[str, Tuple[int, ...]]:
+        """
+        Deprecated - use "metadata.stan_vars_cols" instead
+        """
+        get_logger().warning(
+            'Property "stan_vars_cols" has been deprecated, '
+            'use "metadata.stan_vars_cols" instead.'
+        )
+        return self.metadata.stan_vars_cols
+
+    @property
+    def stan_vars_dims(self) -> Dict[str, Tuple[int, ...]]:
+        """
+        Deprecated - use "metadata.stan_vars_dims" instead
+        """
+        get_logger().warning(
+            'Property "stan_vars_dims" has been deprecated, '
+            'use "metadata.stan_vars_dims" instead.'
+        )
+        return self.metadata.stan_vars_dims
+
     @property
     def column_names(self) -> Tuple[str, ...]:
         """
@@ -648,13 +750,7 @@ 

Source code for cmdstanpy.stanfit

         and quantities of interest. Corresponds to Stan CSV file header row,
         with names munged to array notation, e.g. `beta[1]` not `beta.1`.
         """
-        if not self._validate_csv and self._metadata is None:
-            self._logger.warning(
-                'csv files not yet validated, run method validate_csv_files()'
-                ' in order to retrieve sample metadata.'
-            )
-            return None
-        return self._metadata.cmdstan_config['column_names']
+        return self._metadata.cmdstan_config['column_names']  # type: ignore
 
     @property
     def num_unconstrained_params(self) -> int:
@@ -672,110 +768,44 @@ 

Source code for cmdstanpy.stanfit

         however a model with variables ``real alpha`` and ``simplex[3] beta``
         has 4 constrained and 3 unconstrained parameters.
         """
-        if not self._validate_csv and self._metadata is None:
-            self._logger.warning(
-                'csv files not yet validated, run method validate_csv_files()'
-                ' in order to retrieve sample metadata.'
-            )
-            return None
-        return self._metadata.cmdstan_config['num_unconstrained_params']
-
-    @property
-    def sampler_config(self) -> Dict:
-        """Returns dict of CmdStan configuration arguments."""
-        return self._metadata.cmdstan_config
-
-    @property
-    def sampler_vars_cols(self) -> Dict:
-        """
-        Returns map from sampler variable names to column indices.
-        """
-        if not self._validate_csv and self._metadata is None:
-            self._logger.warning(
-                'csv files not yet validated, run method validate_csv_files()'
-                ' in order to retrieve sample metadata.'
-            )
-            return None
-        return self._metadata.sampler_vars_cols
-
-    @property
-    def stan_vars_dims(self) -> Dict:
-        """
-        Returns map from Stan program variable names to variable dimensions.
-        Scalar types are mapped to the empty tuple, e.g.,
-        program variable ``int foo`` has dimesion ``()`` and
-        program variable ``vector[10] bar`` has dimension ``(10,)``.
-        """
-        if not self._validate_csv and self._metadata is None:
-            self._logger.warning(
-                'csv files not yet validated, run method validate_csv_files()'
-                ' in order to retrieve sample metadata.'
-            )
-            return None
-        return self._metadata.stan_vars_dims
-
-    @property
-    def stan_vars_cols(self) -> Dict:
-        """
-        Returns map from Stan program variable names to column indices.
-        """
-        if not self._validate_csv and self._metadata is None:
-            self._logger.warning(
-                'csv files not yet validated, run method validate_csv_files()'
-                ' in order to retrieve sample metadata.'
-            )
-            return None
-        return self._metadata.stan_vars_cols
+        if self._is_fixed_param:
+            return 0
+        return self._metadata.cmdstan_config[  # type: ignore
+            'num_unconstrained_params'
+        ]
 
     @property
-    def metric_type(self) -> str:
+    def metric_type(self) -> Optional[str]:
         """
         Metric type used for adaptation, either 'diag_e' or 'dense_e'.
         When sampler algorithm 'fixed_param' is specified, metric_type is None.
         """
         if self._is_fixed_param:
             return None
-        if not self._validate_csv and self._metadata is None:
-            self._logger.warning(
-                'csv files not yet validated, run method validate_csv_files()'
-                ' in order to retrieve sample metadata.'
-            )
-            return None
-        return self._metadata.cmdstan_config['metric']  # cmdstan arg name
+        # cmdstan arg name
+        return self._metadata.cmdstan_config['metric']  # type: ignore
 
     @property
-    def metric(self) -> np.ndarray:
+    def metric(self) -> Optional[np.ndarray]:
         """
         Metric used by sampler for each chain.
         When sampler algorithm 'fixed_param' is specified, metric is None.
         """
         if self._is_fixed_param:
             return None
-        if not self._validate_csv and self._metric is None:
-            self._logger.warning(
-                'csv files not yet validated, run method validate_csv_files()'
-                ' in order to retrieve sample metadata.'
-            )
-            return None
-        if self._draws is None:
+        if self._metric.shape == (0,):
             self._assemble_draws()
         return self._metric
 
     @property
-    def step_size(self) -> np.ndarray:
+    def step_size(self) -> Optional[np.ndarray]:
         """
         Step size used by sampler for each chain.
         When sampler algorithm 'fixed_param' is specified, step size is None.
         """
         if self._is_fixed_param:
             return None
-        if not self._validate_csv and self._step_size is None:
-            self._logger.warning(
-                'csv files not yet validated, run method validate_csv_files()'
-                ' in order to retrieve sample metadata.'
-            )
-            return None
-        if self._draws is None:
+        if self._step_size.shape == (0,):
             self._assemble_draws()
         return self._step_size
 
@@ -784,7 +814,7 @@ 

Source code for cmdstanpy.stanfit

         """
         Period between recorded iterations.  (Default is 1).
         """
-        return self._metadata.cmdstan_config['thin']
+        return self._thin
 
 
[docs] def draws( self, *, inc_warmup: bool = False, concat_chains: bool = False @@ -795,9 +825,9 @@

Source code for cmdstanpy.stanfit

         in memory, likewise all draws from a chain are contiguous.
         By default, returns a 3D array arranged (draws, chains, columns);
         parameter ``concat_chains=True`` will return a 2D array where all
-        chains are flattened into a single column, although underlyingly,
-        given M chains of N draws, the first N draws are from chain 1, up
-        through the last N draws from chain M.
+        chains are flattened into a single column, preserving chain order,
+        so that given M chains of N draws, the first N draws are from chain 1,
+        up through the last N draws from chain M.
 
         :param inc_warmup: When ``True`` and the warmup draws are present in
             the output, i.e., the sampler was run with ``save_warmup=True``,
@@ -805,39 +835,37 @@ 

Source code for cmdstanpy.stanfit

 
         :param concat_chains: When ``True`` return a 2D array flattening all
             all draws from all chains.  Default value is ``False``.
-        """
-        if not self._validate_csv and self._draws is None:
-            self.validate_csv_files()
 
-        if self._draws is None:
+        See Also
+        --------
+        CmdStanMCMC.draws_pd
+        CmdStanMCMC.draws_xr
+        CmdStanGQ.draws
+        """
+        if self._draws.size == 0:
             self._assemble_draws()
 
         if inc_warmup and not self._save_warmup:
-            self._logger.warning(
-                'draws from warmup iterations not available,'
-                ' must run sampler with "save_warmup=True".'
+            get_logger().warning(
+                "Sample doesn't contain draws from warmup iterations,"
+                ' rerun sampler with "save_warmup=True".'
             )
 
-        num_rows = self._draws.shape[0]
         start_idx = 0
         if not inc_warmup and self._save_warmup:
             start_idx = self.num_draws_warmup
-            num_rows -= start_idx
 
         if concat_chains:
-            num_rows *= self.chains
-            return self._draws[start_idx:, :, :].reshape(
-                (num_rows, len(self.column_names)), order='F'
-            )
-        return self._draws[start_idx:, :, :]
+ return flatten_chains(self._draws[start_idx:, :, :]) + return self._draws[start_idx:, :, :] # type: ignore
@property def sample(self) -> np.ndarray: """ Deprecated - use method "draws()" instead. """ - self._logger.warning( - 'method "sample" will be deprecated, use method "draws" instead.' + get_logger().warning( + 'Method "sample" has been deprecated, use method "draws" instead.' ) return self.draws() @@ -846,17 +874,18 @@

Source code for cmdstanpy.stanfit

         """
         Deprecated - use "draws(inc_warmup=True)"
         """
-        self._logger.warning(
-            'method "warmup" has been deprecated, instead use method'
+        get_logger().warning(
+            'Method "warmup" has been deprecated, instead use method'
             ' "draws(inc_warmup=True)", returning draws from both'
             ' warmup and sampling iterations.'
         )
         return self.draws(inc_warmup=True)
 
-
[docs] def validate_csv_files(self) -> None: + def _validate_csv_files(self) -> Dict[str, Any]: """ - Checks that csv output files for all chains are consistent. - Populates attributes for metadata, draws, metric, step size. + Checks that Stan CSV output files for all chains are consistent + and returns dict containing config and column names. + Raises exception when inconsistencies detected. """ dzero = {} @@ -879,6 +908,7 @@

Source code for cmdstanpy.stanfit

                     save_warmup=self._save_warmup,
                     thin=self._thin,
                 )
+                # pylint: disable=consider-using-dict-items
                 for key in dzero:
                     if (
                         key
@@ -895,22 +925,22 @@ 

Source code for cmdstanpy.stanfit

                         and dzero[key] != drest[key]
                     ):
                         raise ValueError(
-                            'csv file header mismatch, '
-                            'file {}, key {} is {}, expected {}'.format(
+                            'CmdStan config mismatch in Stan CSV file {}: '
+                            'arg {} is {}, expected {}'.format(
                                 self.runset.csv_files[i],
                                 key,
                                 dzero[key],
                                 drest[key],
                             )
                         )
-        self._metadata = InferenceMetadata(dzero)
+ return dzero def _assemble_draws(self) -> None: """ Allocates and populates the step size, metric, and sample arrays by parsing the validated stan_csv files. """ - if self._draws is not None: + if self._draws.shape != (0,): return num_draws = self.num_draws_sampling @@ -975,9 +1005,12 @@

Source code for cmdstanpy.stanfit

                     line = fd.readline().strip()
                     xs = line.split(',')
                     self._draws[i, chain, :] = [float(x) for x in xs]
+        assert self._draws is not None
 
 
[docs] def summary( - self, percentiles: List[int] = None, sig_figs: int = None + self, + percentiles: Optional[List[int]] = None, + sig_figs: Optional[int] = None, ) -> pd.DataFrame: """ Run cmdstan/bin/stansummary over all output csv files, assemble @@ -1003,14 +1036,14 @@

Source code for cmdstanpy.stanfit

         if percentiles is not None:
             if len(percentiles) == 0:
                 raise ValueError(
-                    'invalid percentiles argument, must be ordered'
+                    'Invalid percentiles argument, must be ordered'
                     ' non-empty list from (1, 99), inclusive.'
                 )
             cur_pct = 0
             for pct in percentiles:
                 if pct > 99 or not pct > cur_pct:
                     raise ValueError(
-                        'invalid percentiles spec, must be ordered'
+                        'Invalid percentiles spec, must be ordered'
                         ' non-empty list from (1, 99), inclusive.'
                     )
                 cur_pct = pct
@@ -1021,12 +1054,12 @@ 

Source code for cmdstanpy.stanfit

         if sig_figs is not None:
             if not isinstance(sig_figs, int) or sig_figs < 1 or sig_figs > 18:
                 raise ValueError(
-                    'sig_figs must be an integer between 1 and 18,'
+                    'Keyword "sig_figs" must be an integer between 1 and 18,'
                     ' found {}'.format(sig_figs)
                 )
             csv_sig_figs = self._sig_figs or 6
             if sig_figs > csv_sig_figs:
-                self._logger.warning(
+                get_logger().warning(
                     'Requesting %d significant digits of output, but CSV files'
                     ' only have %d digits of precision.',
                     sig_figs,
@@ -1049,7 +1082,7 @@ 

Source code for cmdstanpy.stanfit

             sig_figs_str,
             csv_str,
         ] + self.runset.csv_files
-        do_command(cmd, logger=self.runset._logger)
+        do_command(cmd)
         with open(tmp_csv_path, 'rb') as fd:
             summary_data = pd.read_csv(
                 fd,
@@ -1062,7 +1095,7 @@ 

Source code for cmdstanpy.stanfit

         mask = [x == 'lp__' or not x.endswith('__') for x in summary_data.index]
         return summary_data[mask]
-
[docs] def diagnose(self) -> str: +
[docs] def diagnose(self) -> Optional[str]: """ Run cmdstan/bin/diagnose over all output csv files. Returns output of diagnose (stdout/stderr). @@ -1078,58 +1111,154 @@

Source code for cmdstanpy.stanfit

         """
         cmd_path = os.path.join(cmdstan_path(), 'bin', 'diagnose' + EXTENSION)
         cmd = [cmd_path] + self.runset.csv_files
-        result = do_command(cmd=cmd, logger=self.runset._logger)
+        result = do_command(cmd=cmd)
         if result:
-            self.runset._logger.info(result)
+            get_logger().info(result)
         return result
[docs] def draws_pd( - self, params: List[str] = None, inc_warmup: bool = False + self, + vars: Union[List[str], str, None] = None, + inc_warmup: bool = False, + *, + params: Union[List[str], str, None] = None, ) -> pd.DataFrame: """ - Returns the sampler draws as a pandas DataFrame. Flattens all - chains into single column. + Returns the sample draws as a pandas DataFrame. + Flattens all chains into single column. Container variables + (array, vector, matrix) will span multiple columns, one column + per element. E.g. variable 'matrix[2,2] foo' spans 4 columns: + 'foo[1,1], ... foo[2,2]'. - :param params: optional list of variable names. + :param vars: optional list of variable names. :param inc_warmup: When ``True`` and the warmup draws are present in the output, i.e., the sampler was run with ``save_warmup=True``, then the warmup draws are included. Default value is ``False``. + + See Also + -------- + CmdStanMCMC.draws + CmdStanMCMC.draws_xr + CmdStanGQ.draws_pd """ + if params is not None: + if vars is not None: + raise ValueError("Cannot use both vars and (deprecated) params") + get_logger().warning( + 'Keyword "params" is deprecated, use "vars" instead.' + ) + vars = params + if vars is not None: + if isinstance(vars, str): + vars_list = [vars] + else: + vars_list = vars + if inc_warmup and not self._save_warmup: - self._logger.warning( - 'draws from warmup iterations not available,' + get_logger().warning( + 'Draws from warmup iterations not available,' ' must run sampler with "save_warmup=True".' ) + self._assemble_draws() - mask = [] - if params is not None: - for param in set(params): + cols = [] + if vars is not None: + for var in set(vars_list): if ( - param not in self.sampler_vars_cols - and param not in self.stan_vars_cols + var not in self.metadata.method_vars_cols + and var not in self.metadata.stan_vars_cols ): - raise ValueError('unknown parameter: {}'.format(param)) - if param in self.sampler_vars_cols: - mask.append(param) + raise ValueError('Unknown variable: {}'.format(var)) + if var in self.metadata.method_vars_cols: + cols.append(var) else: - for idx in self.stan_vars_cols[param]: - mask.append(self.column_names[idx]) + for idx in self.metadata.stan_vars_cols[var]: + cols.append(self.column_names[idx]) + else: + cols = list(self.column_names) + + return pd.DataFrame( + data=flatten_chains(self.draws(inc_warmup=inc_warmup)), + columns=self.column_names, + )[cols]
+ +
[docs] def draws_xr( + self, vars: Union[str, List[str], None] = None, inc_warmup: bool = False + ) -> "xr.Dataset": + """ + Returns the sampler draws as a xarray Dataset. + + :param vars: optional list of variable names. + + :param inc_warmup: When ``True`` and the warmup draws are present in + the output, i.e., the sampler was run with ``save_warmup=True``, + then the warmup draws are included. Default value is ``False``. + + See Also + -------- + CmdStanMCMC.draws + CmdStanMCMC.draws_pd + CmdStanGQ.draws_xr + """ + if not XARRAY_INSTALLED: + raise RuntimeError( + 'Package "xarray" is not installed, cannot produce draws array.' + ) + if inc_warmup and not self._save_warmup: + get_logger().warning( + "Draws from warmup iterations not available," + ' must run sampler with "save_warmup=True".' + ) + if vars is None: + vars_list = list(self.metadata.stan_vars_cols.keys()) + elif isinstance(vars, str): + vars_list = [vars] + else: + vars_list = vars + + self._assemble_draws() + num_draws = self.num_draws_sampling + meta = self._metadata.cmdstan_config + attrs: MutableMapping[Hashable, Any] = { + "stan_version": f"{meta['stan_version_major']}." + f"{meta['stan_version_minor']}.{meta['stan_version_patch']}", + "model": meta["model"], + "num_unconstrained_params": self.num_unconstrained_params, + "num_draws_sampling": num_draws, + } if inc_warmup and self._save_warmup: num_draws += self.num_draws_warmup - num_rows = num_draws * self.chains - if self._draws_pd is None or self._draws_pd.shape[0] != num_rows: - # pylint: disable=redundant-keyword-arg - data = self.draws(inc_warmup=inc_warmup).reshape( - (num_rows, len(self.column_names)), order='F' + attrs["num_draws_warmup"] = self.num_draws_warmup + + data: MutableMapping[Hashable, Any] = {} + coordinates: MutableMapping[Hashable, Any] = { + "chain": self.chain_ids, + "draw": np.arange(num_draws), + } + + for var in vars_list: + build_xarray_data( + data, + var, + self._metadata.stan_vars_dims[var], + self._metadata.stan_vars_cols[var], + 0, + self.draws(inc_warmup=inc_warmup), ) - self._draws_pd = pd.DataFrame(data=data, columns=self.column_names) - if params is None: - return self._draws_pd - return self._draws_pd[mask]
-
[docs] def stan_variable(self, name: str, inc_warmup: bool = False) -> np.ndarray: + return xr.Dataset(data, coords=coordinates, attrs=attrs).transpose( + 'chain', 'draw', ... + )
+ +
[docs] def stan_variable( + self, + var: Optional[str] = None, + inc_warmup: bool = False, + *, + name: Optional[str] = None, + ) -> np.ndarray: """ Return a numpy.ndarray which contains the set of draws for the named Stan program variable. Flattens the chains, @@ -1155,16 +1284,32 @@

Source code for cmdstanpy.stanfit

         and the sample consists of 4 chains with 1000 post-warmup draws,
         this function will return a numpy.ndarray with shape (4000,3,3).
 
-        :param name: variable name
+        :param var: variable name
 
         :param inc_warmup: When ``True`` and the warmup draws are present in
             the output, i.e., the sampler was run with ``save_warmup=True``,
             then the warmup draws are included.  Default value is ``False``.
+
+        See Also
+        --------
+        CmdStanMCMC.stan_variables
+        CmdStanMLE.stan_variable
+        CmdStanVB.stan_variable
+        CmdStanGQ.stan_variable
         """
-        if self._draws is None:
-            self._assemble_draws()
-        if name not in self.stan_vars_dims:
-            raise ValueError('unknown name: {}'.format(name))
+        if name is not None:
+            if var is not None:
+                raise ValueError(
+                    'Cannot use both "var" and (deprecated) "name"'
+                )
+            get_logger().warning(
+                'Keyword "name" is deprecated, use "var" instead.'
+            )
+            var = name
+        if var is None:
+            raise ValueError('No variable name specified.')
+        if var not in self._metadata.stan_vars_dims:
+            raise ValueError('Unknown variable name: {}'.format(var))
         self._assemble_draws()
         draw1 = 0
         if not inc_warmup and self._save_warmup:
@@ -1173,22 +1318,32 @@ 

Source code for cmdstanpy.stanfit

         if inc_warmup and self._save_warmup:
             num_draws += self.num_draws_warmup
         dims = [num_draws * self.chains]
-        col_idxs = self._metadata.stan_vars_cols[name]
+        col_idxs = self._metadata.stan_vars_cols[var]
         if len(col_idxs) > 0:
-            dims.extend(self._metadata.stan_vars_dims[name])
+            dims.extend(self._metadata.stan_vars_dims[var])
         # pylint: disable=redundant-keyword-arg
-        return self._draws[draw1:, :, col_idxs].reshape(dims, order='F')
+ return self._draws[draw1:, :, col_idxs].reshape( # type: ignore + dims, order='F' + )
-
[docs] def stan_variables(self) -> Dict: +
[docs] def stan_variables(self) -> Dict[str, np.ndarray]: """ - Return a dictionary of all Stan program variables. + Return a dictionary mapping Stan program variables names + to the corresponding numpy.ndarray containing the inferred values. + + See Also + -------- + CmdStanMCMC.stan_variable + CmdStanMLE.stan_variables + CmdStanVB.stan_variables + CmdStanGQ.stan_variables """ result = {} - for name in self.stan_vars_dims.keys(): + for name in self._metadata.stan_vars_dims.keys(): result[name] = self.stan_variable(name) return result
-
[docs] def sampler_variables(self) -> Dict: +
[docs] def method_variables(self) -> Dict[str, np.ndarray]: """ Returns a dictionary of all sampler variables, i.e., all output column names ending in `__`. Assumes that all variables @@ -1198,19 +1353,32 @@

Source code for cmdstanpy.stanfit

         """
         result = {}
         self._assemble_draws()
-        for idxs in self.sampler_vars_cols.values():
+        for idxs in self.metadata.method_vars_cols.values():
             for idx in idxs:
                 result[self.column_names[idx]] = self._draws[:, :, idx]
         return result
- def sampler_diagnostics(self) -> Dict: - self._logger.warning( - 'method "sampler_diagnostics" will be deprecated, ' - 'use method "sampler_variables" instead.' +
[docs] def sampler_variables(self) -> Dict[str, np.ndarray]: + """ + Deprecated, use "method_variables" instead + """ + get_logger().warning( + 'Method "sampler_variables" has been deprecated, ' + 'use method "method_variables" instead.' + ) + return self.method_variables()
+ +
[docs] def sampler_diagnostics(self) -> Dict[str, np.ndarray]: + """ + Deprecated, use "method_variables" instead + """ + get_logger().warning( + 'Method "sampler_diagnostics" has been deprecated, ' + 'use method "method_variables" instead.' ) - return self.sampler_variables() + return self.method_variables()
-
[docs] def save_csvfiles(self, dir: str = None) -> None: +
[docs] def save_csvfiles(self, dir: Optional[str] = None) -> None: """ Move output csvfiles to specified directory. If files were written to the temporary session directory, clean filename. @@ -1218,6 +1386,11 @@

Source code for cmdstanpy.stanfit

         'bernoulli-201912081451-1.csv'.
 
         :param dir: directory path
+
+        See Also
+        --------
+        stanfit.RunSet.save_csvfiles
+        cmdstanpy.from_csv
         """
         self.runset.save_csvfiles(dir)
@@ -1225,6 +1398,7 @@

Source code for cmdstanpy.stanfit

 
[docs]class CmdStanMLE: """ Container for outputs from CmdStan optimization. + Created by :meth:`CmdStanModel.optimize`. """ def __init__(self, runset: RunSet) -> None: @@ -1235,8 +1409,6 @@

Source code for cmdstanpy.stanfit

                 'found method {}'.format(runset.method)
             )
         self.runset = runset
-        self._column_names = ()
-        self._mle = {}
         self._set_mle_attrs(runset.csv_files[0])
 
     def __repr__(self) -> str:
@@ -1253,19 +1425,29 @@ 

Source code for cmdstanpy.stanfit

 
     def _set_mle_attrs(self, sample_csv_0: str) -> None:
         meta = scan_optimize_csv(sample_csv_0)
-        self._column_names = meta['column_names']
-        self._mle = meta['mle']
+        self._metadata = InferenceMetadata(meta)
+        self._column_names: Tuple[str, ...] = meta['column_names']
+        self._mle: List[float] = meta['mle']
 
     @property
     def column_names(self) -> Tuple[str, ...]:
         """
         Names of estimated quantities, includes joint log probability,
-        and all parameters, transformed parameters, and generated quantitites.
+        and all parameters, transformed parameters, and generated quantities.
         """
         return self._column_names
 
     @property
-    def optimized_params_np(self) -> np.array:
+    def metadata(self) -> InferenceMetadata:
+        """
+        Returns object which contains CmdStan configuration as well as
+        information about the names and structure of the inference method
+        and model output variables.
+        """
+        return self._metadata
+
+    @property
+    def optimized_params_np(self) -> np.ndarray:
         """Returns optimized params as numpy array."""
         return np.asarray(self._mle)
 
@@ -1275,11 +1457,66 @@ 

Source code for cmdstanpy.stanfit

         return pd.DataFrame([self._mle], columns=self.column_names)
 
     @property
-    def optimized_params_dict(self) -> OrderedDict:
+    def optimized_params_dict(self) -> Dict[str, float]:
         """Returns optimized params as Dict."""
         return OrderedDict(zip(self.column_names, self._mle))
 
-
[docs] def save_csvfiles(self, dir: str = None) -> None: +
[docs] def stan_variable( + self, var: Optional[str] = None, *, name: Optional[str] = None + ) -> np.ndarray: + """ + Return a numpy.ndarray which contains the estimates for the + for the named Stan program variable where the dimensions of the + numpy.ndarray match the shape of the Stan program variable. + + :param var: variable name + + See Also + -------- + CmdStanMLE.stan_variables + CmdStanMCMC.stan_variable + CmdStanVB.stan_variable + CmdStanGQ.stan_variable + """ + if name is not None: + if var is not None: + raise ValueError( + 'Cannot use both "var" and (deprecated) "name".' + ) + get_logger().warning( + 'Keyword "name" is deprecated, use "var" instead.' + ) + var = name + if var is None: + raise ValueError('no variable name specified.') + if var not in self._metadata.stan_vars_dims: + raise ValueError('unknown variable name: {}'.format(var)) + col_idxs = list(self._metadata.stan_vars_cols[var]) + vals = list(self._mle) + xs = [vals[x] for x in col_idxs] + shape: Tuple[int, ...] = () + if len(col_idxs) > 0: + shape = self._metadata.stan_vars_dims[var] + return np.array(xs).reshape(shape)
+ +
[docs] def stan_variables(self) -> Dict[str, np.ndarray]: + """ + Return a dictionary mapping Stan program variables names + to the corresponding numpy.ndarray containing the inferred values. + + See Also + -------- + CmdStanMLE.stan_variable + CmdStanMCMC.stan_variables + CmdStanVB.stan_variables + CmdStanGQ.stan_variables + """ + result = {} + for name in self._metadata.stan_vars_dims.keys(): + result[name] = self.stan_variable(name) + return result
+ +
[docs] def save_csvfiles(self, dir: Optional[str] = None) -> None: """ Move output csvfiles to specified directory. If files were written to the temporary session directory, clean filename. @@ -1287,6 +1524,11 @@

Source code for cmdstanpy.stanfit

         'bernoulli-201912081451-1.csv'.
 
         :param dir: directory path
+
+        See Also
+        --------
+        stanfit.RunSet.save_csvfiles
+        cmdstanpy.from_csv
         """
         self.runset.save_csvfiles(dir)
@@ -1294,9 +1536,14 @@

Source code for cmdstanpy.stanfit

 
[docs]class CmdStanGQ: """ Container for outputs from CmdStan generate_quantities run. + Created by :meth:`CmdStanModel.generate_quantities`. """ - def __init__(self, runset: RunSet, mcmc_sample: pd.DataFrame) -> None: + def __init__( + self, + runset: RunSet, + mcmc_sample: CmdStanMCMC, + ) -> None: """Initialize object.""" if not runset.method == Method.GENERATE_QUANTITIES: raise ValueError( @@ -1305,10 +1552,9 @@

Source code for cmdstanpy.stanfit

             )
         self.runset = runset
         self.mcmc_sample = mcmc_sample
-        self._generated_quantities = None
-        self._column_names = scan_generated_quantities_csv(
-            self.runset.csv_files[0]
-        )['column_names']
+        self._draws = np.array(())
+        config = self._validate_csv_files()
+        self._metadata = InferenceMetadata(config)
 
     def __repr__(self) -> str:
         repr = 'CmdStanGQ: model={} chains={}{}'.format(
@@ -1323,89 +1569,524 @@ 

Source code for cmdstanpy.stanfit

         )
         return repr
 
+    def _validate_csv_files(self) -> dict:
+        """
+        Checks that Stan CSV output files for all chains are consistent
+        and returns dict containing config and column names.
+
+        Raises exception when inconsistencies detected.
+        """
+        dzero = {}
+        for i in range(self.chains):
+            if i == 0:
+                dzero = scan_generated_quantities_csv(
+                    path=self.runset.csv_files[i],
+                )
+            else:
+                drest = scan_generated_quantities_csv(
+                    path=self.runset.csv_files[i],
+                )
+                # pylint: disable=consider-using-dict-items
+                for key in dzero:
+                    if (
+                        key
+                        not in [
+                            'id',
+                            'fitted_params',
+                            'diagnostic_file',
+                            'metric_file',
+                            'profile_file',
+                            'init',
+                            'seed',
+                            'start_datetime',
+                        ]
+                        and dzero[key] != drest[key]
+                    ):
+                        raise ValueError(
+                            'CmdStan config mismatch in Stan CSV file {}: '
+                            'arg {} is {}, expected {}'.format(
+                                self.runset.csv_files[i],
+                                key,
+                                dzero[key],
+                                drest[key],
+                            )
+                        )
+        return dzero
+
     @property
     def chains(self) -> int:
         """Number of chains."""
         return self.runset.chains
 
+    @property
+    def chain_ids(self) -> List[int]:
+        """Chain ids."""
+        return self.runset.chain_ids
+
     @property
     def column_names(self) -> Tuple[str, ...]:
         """
         Names of generated quantities of interest.
         """
-        return self._column_names
+        return self._metadata.cmdstan_config['column_names']  # type: ignore
+
+    @property
+    def metadata(self) -> InferenceMetadata:
+        """
+        Returns object which contains CmdStan configuration as well as
+        information about the names and structure of the inference method
+        and model output variables.
+        """
+        return self._metadata
 
     @property
     def generated_quantities(self) -> np.ndarray:
         """
-        A 2D numpy ndarray which contains generated quantities draws
-        for all chains where the columns correspond to the generated quantities
-        block variables and the rows correspond to the draws from all chains,
-        where first M draws are the first M draws of chain 1 and the
-        last M draws are the last M draws of chain N, i.e.,
-        flattened chain, draw ordering.
+        Deprecated - use method ``draws`` instead.
         """
-        if not self.runset.method == Method.GENERATE_QUANTITIES:
-            raise ValueError('Bad runset method {}.'.format(self.runset.method))
-        if self._generated_quantities is None:
+        get_logger().warning(
+            'Property "generated_quantities" has been deprecated, '
+            'use method "draws" instead.'
+        )
+        if self._draws.size == 0:
             self._assemble_generated_quantities()
-        return self._generated_quantities
+        return flatten_chains(self._draws)
 
     @property
     def generated_quantities_pd(self) -> pd.DataFrame:
         """
-        Returns the generated quantities as a pandas DataFrame consisting of
-        one column per quantity of interest and one row per draw.
+        Deprecated - use method ``draws_pd`` instead.
         """
-        if not self.runset.method == Method.GENERATE_QUANTITIES:
-            raise ValueError('Bad runset method {}.'.format(self.runset.method))
-        if self._generated_quantities is None:
+        get_logger().warning(
+            'Property "generated_quantities_pd" has been deprecated, '
+            'use method "draws_pd" instead.'
+        )
+        if self._draws.size == 0:
             self._assemble_generated_quantities()
         return pd.DataFrame(
-            data=self._generated_quantities, columns=self.column_names
+            data=flatten_chains(self._draws),
+            columns=self.column_names,
         )
 
     @property
     def sample_plus_quantities(self) -> pd.DataFrame:
         """
-        Returns the column-wise concatenation of the input drawset
-        with generated quantities drawset.  If there are duplicate
-        columns in both the input and the generated quantities,
-        the input column is dropped in favor of the recomputed
-        values in the generate quantities drawset.
+        Deprecated - use method "draws_pd(inc_sample=True)" instead.
+        """
+        get_logger().warning(
+            'Property "sample_plus_quantities" has been deprecated, '
+            'use method "draws_pd(inc_sample=True)" instead.'
+        )
+        return self.draws_pd(inc_sample=True)
+
+
[docs] def draws( + self, + *, + inc_warmup: bool = False, + concat_chains: bool = False, + inc_sample: bool = False, + ) -> np.ndarray: + """ + Returns a numpy.ndarray over the generated quantities draws from + all chains which is stored column major so that the values + for a parameter are contiguous in memory, likewise all draws from + a chain are contiguous. By default, returns a 3D array arranged + (draws, chains, columns); parameter ``concat_chains=True`` will + return a 2D array where all chains are flattened into a single column, + preserving chain order, so that given M chains of N draws, + the first N draws are from chain 1, ..., and the the last N draws + are from chain M. + + :param inc_warmup: When ``True`` and the warmup draws are present in + the output, i.e., the sampler was run with ``save_warmup=True``, + then the warmup draws are included. Default value is ``False``. + + :param concat_chains: When ``True`` return a 2D array flattening all + all draws from all chains. Default value is ``False``. + + :param inc_sample: When ``True`` include all columns in the mcmc_sample + draws array as well, excepting columns for variables already present + in the generated quantities drawset. Default value is ``False``. + + See Also + -------- + CmdStanGQ.draws_pd + CmdStanGQ.draws_xr + CmdStanMCMC.draws """ - if not self.runset.method == Method.GENERATE_QUANTITIES: - raise ValueError('Bad runset method {}.'.format(self.runset.method)) - if self._generated_quantities is None: + if self._draws.size == 0: self._assemble_generated_quantities() + if ( + inc_warmup + and not self.mcmc_sample.metadata.cmdstan_config['save_warmup'] + ): + get_logger().warning( + "Sample doesn't contain draws from warmup iterations," + ' rerun sampler with "save_warmup=True".' + ) + if inc_sample: + cols_1 = self.mcmc_sample.column_names + cols_2 = self.column_names + dups = [ + item + for item, count in Counter(cols_1 + cols_2).items() + if count > 1 + ] + drop_cols: List[int] = [] + for dup in dups: + drop_cols.extend(self.mcmc_sample.metadata.stan_vars_cols[dup]) - cols_1 = self.mcmc_sample.columns.tolist() - cols_2 = self.generated_quantities_pd.columns.tolist() + start_idx = 0 + if ( + not inc_warmup + and self.mcmc_sample.metadata.cmdstan_config['save_warmup'] + ): + start_idx = self.mcmc_sample.num_draws_warmup - dups = [ - item - for item, count in Counter(cols_1 + cols_2).items() - if count > 1 - ] - return pd.concat( - [self.mcmc_sample.drop(columns=dups), self.generated_quantities_pd], - axis=1, - ) + if concat_chains and inc_sample: + return flatten_chains( + np.dstack( + ( + np.delete(self.mcmc_sample.draws(), drop_cols, axis=1), + self._draws, + ) + )[start_idx:, :, :] + ) + if concat_chains: + return flatten_chains(self._draws[start_idx:, :, :]) + if inc_sample: + return np.dstack( # type: ignore + ( + np.delete(self.mcmc_sample.draws(), drop_cols, axis=1), + self._draws, + ) + )[start_idx:, :, :] + return self._draws[start_idx:, :, :] # type: ignore
+ +
[docs] def draws_pd( + self, + vars: Union[List[str], str, None] = None, + inc_warmup: bool = False, + inc_sample: bool = False, + ) -> pd.DataFrame: + """ + Returns the generated quantities draws as a pandas DataFrame. + Flattens all chains into single column. Container variables + (array, vector, matrix) will span multiple columns, one column + per element. E.g. variable 'matrix[2,2] foo' spans 4 columns: + 'foo[1,1], ... foo[2,2]'. + + :param vars: optional list of variable names. + + :param inc_warmup: When ``True`` and the warmup draws are present in + the output, i.e., the sampler was run with ``save_warmup=True``, + then the warmup draws are included. Default value is ``False``. + + See Also + -------- + CmdStanGQ.draws + CmdStanGQ.draws_xr + CmdStanMCMC.draws_pd + """ + if vars is not None: + if isinstance(vars, str): + vars_list = [vars] + else: + vars_list = vars + if ( + inc_warmup + and not self.mcmc_sample.metadata.cmdstan_config['save_warmup'] + ): + get_logger().warning( + 'Draws from warmup iterations not available,' + ' must run sampler with "save_warmup=True".' + ) + self._assemble_generated_quantities() + + gq_cols = [] + mcmc_vars = [] + if vars is not None: + for var in set(vars_list): + if var in self.metadata.stan_vars_cols: + for idx in self.metadata.stan_vars_cols[var]: + gq_cols.append(self.column_names[idx]) + elif ( + inc_sample + and var in self.mcmc_sample.metadata.stan_vars_cols + ): + mcmc_vars.append(var) + else: + raise ValueError('Unknown variable: {}'.format(var)) + else: + gq_cols = list(self.column_names) + + if inc_sample and mcmc_vars: + if gq_cols: + return pd.concat( + [ + self.mcmc_sample.draws_pd( + vars=mcmc_vars, inc_warmup=inc_warmup + ).reset_index(drop=True), + pd.DataFrame( + data=flatten_chains( + self.draws(inc_warmup=inc_warmup) + ), + columns=self.column_names, + )[gq_cols], + ], + axis='columns', + ) + else: + return self.mcmc_sample.draws_pd( + vars=mcmc_vars, inc_warmup=inc_warmup + ) + elif inc_sample and vars is None: + cols_1 = self.mcmc_sample.column_names + cols_2 = self.column_names + dups = [ + item + for item, count in Counter(cols_1 + cols_2).items() + if count > 1 + ] + return pd.concat( + [ + self.mcmc_sample.draws_pd(inc_warmup=inc_warmup) + .drop(columns=dups) + .reset_index(drop=True), + pd.DataFrame( + data=flatten_chains(self.draws(inc_warmup=inc_warmup)), + columns=self.column_names, + ), + ], + axis='columns', + ignore_index=True, + ) + elif gq_cols: + return pd.DataFrame( + data=flatten_chains(self.draws(inc_warmup=inc_warmup)), + columns=self.column_names, + )[gq_cols] + + return pd.DataFrame( + data=flatten_chains(self.draws(inc_warmup=inc_warmup)), + columns=self.column_names, + )
+ +
[docs] def draws_xr( + self, + vars: Union[str, List[str], None] = None, + inc_warmup: bool = False, + inc_sample: bool = False, + ) -> "xr.Dataset": + """ + Returns the generated quantities draws as a xarray Dataset. + + :param vars: optional list of variable names. + + :param inc_warmup: When ``True`` and the warmup draws are present in + the MCMC sample, then the warmup draws are included. + Default value is ``False``. + + See Also + -------- + CmdStanGQ.draws + CmdStanGQ.draws_pd + CmdStanMCMC.draws_xr + """ + if not XARRAY_INSTALLED: + raise RuntimeError( + 'Package "xarray" is not installed, cannot produce draws array.' + ) + mcmc_vars_list = [] + dup_vars = [] + if vars is not None: + if isinstance(vars, str): + vars_list = [vars] + else: + vars_list = vars + for var in vars_list: + if var not in self.metadata.stan_vars_cols: + if inc_sample and var in self.mcmc_sample.stan_vars_cols: + mcmc_vars_list.append(var) + dup_vars.append(var) + else: + raise ValueError('Unknown variable: {}'.format(var)) + else: + vars_list = list(self.metadata.stan_vars_cols.keys()) + if inc_sample: + for var in self.mcmc_sample.metadata.stan_vars_cols.keys(): + if var not in vars_list and var not in mcmc_vars_list: + mcmc_vars_list.append(var) + for var in dup_vars: + vars_list.remove(var) + + self._assemble_generated_quantities() + + num_draws = self.mcmc_sample.num_draws_sampling + sample_config = self.mcmc_sample.metadata.cmdstan_config + attrs: MutableMapping[Hashable, Any] = { + "stan_version": f"{sample_config['stan_version_major']}." + f"{sample_config['stan_version_minor']}." + f"{sample_config['stan_version_patch']}", + "model": sample_config["model"], + "num_unconstrained_params": ( + self.mcmc_sample.num_unconstrained_params + ), + "num_draws_sampling": num_draws, + } + if inc_warmup and sample_config['save_warmup']: + num_draws += self.mcmc_sample.num_draws_warmup + attrs["num_draws_warmup"] = self.mcmc_sample.num_draws_warmup + + data: MutableMapping[Hashable, Any] = {} + coordinates: MutableMapping[Hashable, Any] = { + "chain": self.chain_ids, + "draw": np.arange(num_draws), + } + + for var in vars_list: + build_xarray_data( + data, + var, + self._metadata.stan_vars_dims[var], + self._metadata.stan_vars_cols[var], + 0, + self.draws(inc_warmup=inc_warmup), + ) + if inc_sample: + for var in mcmc_vars_list: + build_xarray_data( + data, + var, + self.mcmc_sample.metadata.stan_vars_dims[var], + self.mcmc_sample.metadata.stan_vars_cols[var], + 0, + self.mcmc_sample.draws(inc_warmup=inc_warmup), + ) + + return xr.Dataset(data, coords=coordinates, attrs=attrs).transpose( + 'chain', 'draw', ... + )
+ +
[docs] def stan_variable( + self, + var: Optional[str] = None, + inc_warmup: bool = False, + *, + name: Optional[str] = None, + ) -> np.ndarray: + """ + Return a numpy.ndarray which contains the set of draws + for the named Stan program variable. Flattens the chains, + leaving the draws in chain order. The first array dimension, + corresponds to number of draws in the sample. + The remaining dimensions correspond to + the shape of the Stan program variable. + + Underlyingly draws are in chain order, i.e., for a sample with + N chains of M draws each, the first M array elements are from chain 1, + the next M are from chain 2, and the last M elements are from chain N. + + * If the variable is a scalar variable, the return array has shape + ( draws X chains, 1). + * If the variable is a vector, the return array has shape + ( draws X chains, len(vector)) + * If the variable is a matrix, the return array has shape + ( draws X chains, size(dim 1) X size(dim 2) ) + * If the variable is an array with N dimensions, the return array + has shape ( draws X chains, size(dim 1) X ... X size(dim N)) + + For example, if the Stan program variable ``theta`` is a 3x3 matrix, + and the sample consists of 4 chains with 1000 post-warmup draws, + this function will return a numpy.ndarray with shape (4000,3,3). + + :param var: variable name + + :param inc_warmup: When ``True`` and the warmup draws are present in + the MCMC sample, then the warmup draws are included. + Default value is ``False``. + + See Also + -------- + CmdStanGQ.stan_variables + CmdStanMCMC.stan_variable + CmdStanMLE.stan_variable + CmdStanVB.stan_variable + """ + if name is not None: + if var is not None: + raise ValueError( + 'Cannot use both "var" and (deprecated) "name"' + ) + get_logger().warning( + 'Keyword "name" is deprecated, use "var" instead.' + ) + var = name + if var is None: + raise ValueError('No variable name specified.') + model_var_names = self.mcmc_sample.metadata.stan_vars_cols.keys() + gq_var_names = self.metadata.stan_vars_cols.keys() + if not (var in model_var_names or var in gq_var_names): + raise ValueError('Unknown variable name: {}'.format(var)) + if var not in gq_var_names: + return self.mcmc_sample.stan_variable(var, inc_warmup=inc_warmup) + else: # is gq variable + self._assemble_generated_quantities() + col_idxs = self._metadata.stan_vars_cols[var] + if ( + not inc_warmup + and self.mcmc_sample.metadata.cmdstan_config['save_warmup'] + ): + draw1 = self.mcmc_sample.num_draws_warmup * self.chains + return flatten_chains(self._draws)[ # type: ignore + draw1:, col_idxs + ] + return flatten_chains(self._draws)[:, col_idxs] # type: ignore
+ +
[docs] def stan_variables(self, inc_warmup: bool = False) -> Dict[str, np.ndarray]: + """ + Return a dictionary mapping Stan program variables names + to the corresponding numpy.ndarray containing the inferred values. + + :param inc_warmup: When ``True`` and the warmup draws are present in + the MCMC sample, then the warmup draws are included. + Default value is ``False`` + + See Also + -------- + CmdStanGQ.stan_variable + CmdStanMCMC.stan_variables + CmdStanMLE.stan_variables + CmdStanVB.stan_variables + """ + result = {} + sample_var_names = self.mcmc_sample.metadata.stan_vars_cols.keys() + gq_var_names = self.metadata.stan_vars_cols.keys() + for name in gq_var_names: + result[name] = self.stan_variable(name, inc_warmup) + for name in sample_var_names: + if name not in gq_var_names: + result[name] = self.stan_variable(name, inc_warmup) + return result
def _assemble_generated_quantities(self) -> None: - drawset_list = [] + # use numpy genfromtext + warmup = self.mcmc_sample.metadata.cmdstan_config['save_warmup'] + num_draws = self.mcmc_sample.draws(inc_warmup=warmup).shape[0] + gq_sample = np.empty( + (num_draws, self.chains, len(self.column_names)), + dtype=float, + order='F', + ) for chain in range(self.chains): - drawset_list.append( - pd.read_csv( - self.runset.csv_files[chain], - comment='#', - float_precision='high', - dtype=float, + with open(self.runset.csv_files[chain], 'r') as fd: + lines = (line for line in fd if not line.startswith('#')) + gq_sample[:, chain, :] = np.loadtxt( + lines, dtype=np.ndarray, ndmin=2, skiprows=1, delimiter=',' ) - ) - self._generated_quantities = pd.concat(drawset_list).values + self._draws = gq_sample -
[docs] def save_csvfiles(self, dir: str = None) -> None: +
[docs] def save_csvfiles(self, dir: Optional[str] = None) -> None: """ Move output csvfiles to specified directory. If files were written to the temporary session directory, clean filename. @@ -1413,6 +2094,11 @@

Source code for cmdstanpy.stanfit

         'bernoulli-201912081451-1.csv'.
 
         :param dir: directory path
+
+        See Also
+        --------
+        stanfit.RunSet.save_csvfiles
+        cmdstanpy.from_csv
         """
         self.runset.save_csvfiles(dir)
@@ -1420,6 +2106,7 @@

Source code for cmdstanpy.stanfit

 
[docs]class CmdStanVB: """ Container for outputs from CmdStan variational run. + Created by :meth:`CmdStanModel.variational`. """ def __init__(self, runset: RunSet) -> None: @@ -1430,9 +2117,6 @@

Source code for cmdstanpy.stanfit

                 'found method {}'.format(runset.method)
             )
         self.runset = runset
-        self._column_names = ()
-        self._variational_mean = {}
-        self._variational_sample = None
         self._set_variational_attrs(runset.csv_files[0])
 
     def __repr__(self) -> str:
@@ -1449,9 +2133,11 @@ 

Source code for cmdstanpy.stanfit

 
     def _set_variational_attrs(self, sample_csv_0: str) -> None:
         meta = scan_variational_csv(sample_csv_0)
-        self._column_names = meta['column_names']
-        self._variational_mean = meta['variational_mean']
-        self._variational_sample = meta['variational_sample']
+        self._metadata = InferenceMetadata(meta)
+        # these three assignments don't grant type information
+        self._column_names: Tuple[str, ...] = meta['column_names']
+        self._variational_mean: np.ndarray = meta['variational_mean']
+        self._variational_sample: np.ndarray = meta['variational_sample']
 
     @property
     def columns(self) -> int:
@@ -1472,26 +2158,94 @@ 

Source code for cmdstanpy.stanfit

         return self._column_names
 
     @property
-    def variational_params_np(self) -> np.array:
-        """Returns inferred parameter means as numpy array."""
+    def variational_params_np(self) -> np.ndarray:
+        """
+        Returns inferred parameter means as numpy array.
+        """
         return self._variational_mean
 
     @property
     def variational_params_pd(self) -> pd.DataFrame:
-        """Returns inferred parameter means as pandas DataFrame."""
+        """
+        Returns inferred parameter means as pandas DataFrame.
+        """
         return pd.DataFrame([self._variational_mean], columns=self.column_names)
 
     @property
-    def variational_params_dict(self) -> OrderedDict:
+    def variational_params_dict(self) -> Dict[str, np.ndarray]:
         """Returns inferred parameter means as Dict."""
         return OrderedDict(zip(self.column_names, self._variational_mean))
 
     @property
-    def variational_sample(self) -> np.array:
+    def metadata(self) -> InferenceMetadata:
+        """
+        Returns object which contains CmdStan configuration as well as
+        information about the names and structure of the inference method
+        and model output variables.
+        """
+        return self._metadata
+
+
[docs] def stan_variable( + self, var: Optional[str] = None, *, name: Optional[str] = None + ) -> np.ndarray: + """ + Return a numpy.ndarray which contains the estimates for the + for the named Stan program variable where the dimensions of the + numpy.ndarray match the shape of the Stan program variable. + + :param var: variable name + + See Also + -------- + CmdStanVB.stan_variables + CmdStanMCMC.stan_variable + CmdStanMLE.stan_variable + CmdStanGQ.stan_variable + """ + if name is not None: + if var is not None: + raise ValueError( + 'Cannot use both "var" and (deprecated) "name"' + ) + get_logger().warning( + 'Keyword "name" is deprecated, use "var" instead.' + ) + var = name + if var is None: + raise ValueError('No variable name specified.') + if var not in self._metadata.stan_vars_dims: + raise ValueError('Unknown variable name: {}'.format(var)) + col_idxs = list(self._metadata.stan_vars_cols[var]) + vals = list(self._variational_mean) + xs = [vals[x] for x in col_idxs] + shape: Tuple[int, ...] = () + if len(col_idxs) > 0: + shape = self._metadata.stan_vars_dims[var] + return np.array(xs).reshape(shape)
+ +
[docs] def stan_variables(self) -> Dict[str, np.ndarray]: + """ + Return a dictionary mapping Stan program variables names + to the corresponding numpy.ndarray containing the inferred values. + + See Also + -------- + CmdStanVB.stan_variable + CmdStanMCMC.stan_variables + CmdStanMLE.stan_variables + CmdStanGQ.stan_variables + """ + result = {} + for name in self._metadata.stan_vars_dims.keys(): + result[name] = self.stan_variable(name) + return result
+ + @property + def variational_sample(self) -> np.ndarray: """Returns the set of approximate posterior output draws.""" return self._variational_sample -
[docs] def save_csvfiles(self, dir: str = None) -> None: +
[docs] def save_csvfiles(self, dir: Optional[str] = None) -> None: """ Move output csvfiles to specified directory. If files were written to the temporary session directory, clean filename. @@ -1499,51 +2253,260 @@

Source code for cmdstanpy.stanfit

         'bernoulli-201912081451-1.csv'.
 
         :param dir: directory path
+
+        See Also
+        --------
+        stanfit.RunSet.save_csvfiles
+        cmdstanpy.from_csv
         """
         self.runset.save_csvfiles(dir)
-
-
- -
-
-
+
[docs]def from_csv( + path: Union[str, List[str], None] = None, method: Optional[str] = None +) -> Union[CmdStanMCMC, CmdStanMLE, CmdStanVB, None]: + """ + Instantiate a CmdStan object from a the Stan CSV files from a CmdStan run. + CSV files are specified from either a list of Stan CSV files or a single + filepath which can be either a directory name, a Stan CSV filename, or + a pathname pattern (i.e., a Python glob). The optional argument 'method' + checks that the CSV files were produced by that method. + Stan CSV files from CmdStan methods 'sample', 'optimize', and 'variational' + result in objects of class CmdStanMCMC, CmdStanMLE, and CmdStanVB, + respectively. + + :param path: directory path + :param method: method name (optional) + + :return: either a CmdStanMCMC, CmdStanMLE, or CmdStanVB object + """ + if path is None: + raise ValueError('Must specify path to Stan CSV files.') + if method is not None and method not in [ + 'sample', + 'optimize', + 'variational', + ]: + raise ValueError( + 'Bad method argument {}, must be one of: ' + '"sample", "optimize", "variational"'.format(method) + ) -
-

- © Copyright 2021, Stan Development Team. + csvfiles = [] + if isinstance(path, list): + csvfiles = path + elif isinstance(path, str): + if '*' in path: + splits = os.path.split(path) + if splits[0] is not None: + if not (os.path.exists(splits[0]) and os.path.isdir(splits[0])): + raise ValueError( + 'Invalid path specification, {} ' + ' unknown directory: {}'.format(path, splits[0]) + ) + csvfiles = glob.glob(path) + elif os.path.exists(path) and os.path.isdir(path): + for file in os.listdir(path): + if file.endswith(".csv"): + csvfiles.append(os.path.join(path, file)) + elif os.path.exists(path): + csvfiles.append(path) + else: + raise ValueError('Invalid path specification: {}'.format(path)) + else: + raise ValueError('Invalid path specification: {}'.format(path)) + + if len(csvfiles) == 0: + raise ValueError('No CSV files found in directory {}'.format(path)) + for file in csvfiles: + if not (os.path.exists(file) and file.endswith('.csv')): + raise ValueError( + 'Bad CSV file path spec,' + ' includes non-csv file: {}'.format(file) + ) -

-
- - - - Built with Sphinx using a - - theme - - provided by Read the Docs. + config_dict: Dict[str, Any] = {} + try: + with open(csvfiles[0], 'r') as fd: + scan_config(fd, config_dict, 0) + except (IOError, OSError, PermissionError) as e: + raise ValueError('Cannot read CSV file: {}'.format(csvfiles[0])) from e + if 'model' not in config_dict or 'method' not in config_dict: + raise ValueError("File {} is not a Stan CSV file.".format(csvfiles[0])) + if method is not None and method != config_dict['method']: + raise ValueError( + 'Expecting Stan CSV output files from method {}, ' + ' found outputs from method {}'.format( + method, config_dict['method'] + ) + ) + try: + if config_dict['method'] == 'sample': + chains = len(csvfiles) + sampler_args = SamplerArgs( + iter_sampling=config_dict['num_samples'], + iter_warmup=config_dict['num_warmup'], + thin=config_dict['thin'], + save_warmup=config_dict['save_warmup'], + ) + # bugfix 425, check for fixed_params output + try: + check_sampler_csv( + csvfiles[0], + iter_sampling=config_dict['num_samples'], + iter_warmup=config_dict['num_warmup'], + thin=config_dict['thin'], + save_warmup=config_dict['save_warmup'], + ) + except ValueError: + try: + check_sampler_csv( + csvfiles[0], + is_fixed_param=True, + iter_sampling=config_dict['num_samples'], + iter_warmup=config_dict['num_warmup'], + thin=config_dict['thin'], + save_warmup=config_dict['save_warmup'], + ) + sampler_args = SamplerArgs( + iter_sampling=config_dict['num_samples'], + iter_warmup=config_dict['num_warmup'], + thin=config_dict['thin'], + save_warmup=config_dict['save_warmup'], + fixed_param=True, + ) + except (ValueError) as e: + raise ValueError( + 'Invalid or corrupt Stan CSV output file, ' + ) from e + + cmdstan_args = CmdStanArgs( + model_name=config_dict['model'], + model_exe=config_dict['model'], + chain_ids=[x + 1 for x in range(chains)], + method_args=sampler_args, + ) + runset = RunSet(args=cmdstan_args, chains=chains) + runset._csv_files = csvfiles + for i in range(len(runset._retcodes)): + runset._set_retcode(i, 0) + fit = CmdStanMCMC(runset) + fit.draws() + return fit + elif config_dict['method'] == 'optimize': + if 'algorithm' not in config_dict: + raise ValueError( + "Cannot find optimization algorithm" + " in file {}.".format(csvfiles[0]) + ) + optimize_args = OptimizeArgs( + algorithm=config_dict['algorithm'], + ) + cmdstan_args = CmdStanArgs( + model_name=config_dict['model'], + model_exe=config_dict['model'], + chain_ids=None, + method_args=optimize_args, + ) + runset = RunSet(args=cmdstan_args) + runset._csv_files = csvfiles + for i in range(len(runset._retcodes)): + runset._set_retcode(i, 0) + return CmdStanMLE(runset) + elif config_dict['method'] == 'variational': + if 'algorithm' not in config_dict: + raise ValueError( + "Cannot find variational algorithm" + " in file {}.".format(csvfiles[0]) + ) + variational_args = VariationalArgs( + algorithm=config_dict['algorithm'], + iter=config_dict['iter'], + grad_samples=config_dict['grad_samples'], + elbo_samples=config_dict['elbo_samples'], + eta=config_dict['eta'], + tol_rel_obj=config_dict['tol_rel_obj'], + eval_elbo=config_dict['eval_elbo'], + output_samples=config_dict['output_samples'], + ) + cmdstan_args = CmdStanArgs( + model_name=config_dict['model'], + model_exe=config_dict['model'], + chain_ids=None, + method_args=variational_args, + ) + runset = RunSet(args=cmdstan_args) + runset._csv_files = csvfiles + for i in range(len(runset._retcodes)): + runset._set_retcode(i, 0) + return CmdStanVB(runset) + else: + get_logger().info( + 'Unable to process CSV output files from method %s.', + (config_dict['method']), + ) + return None + except (IOError, OSError, PermissionError) as e: + raise ValueError( + 'An error occured processing the CSV files:\n\t{}'.format(str(e)) + ) from e
+ + +def build_xarray_data( + data: MutableMapping[Hashable, Tuple[Tuple[str, ...], np.ndarray]], + var_name: str, + dims: Tuple[int, ...], + col_idxs: Tuple[int, ...], + start_row: int, + drawset: np.ndarray, +) -> None: + """ + Adds Stan variable name, labels, and values to a dictionary + that will be used to construct an xarray DataSet. + """ + var_dims: Tuple[str, ...] = ('draw', 'chain') + if dims: + var_dims += tuple(f"{var_name}_dim_{i}" for i in range(len(dims))) + data[var_name] = (var_dims, drawset[start_row:, :, col_idxs]) + else: + data[var_name] = ( + var_dims, + np.squeeze(drawset[start_row:, :, col_idxs], axis=2), + ) +
- -
-
+
+ + +
+ -
+
+ + + - + + + - - - - + + \ No newline at end of file diff --git a/docs/_modules/cmdstanpy/utils.html b/docs/_modules/cmdstanpy/utils.html index 8721ed5a..fbef4123 100644 --- a/docs/_modules/cmdstanpy/utils.html +++ b/docs/_modules/cmdstanpy/utils.html @@ -1,177 +1,175 @@ - - - - - - - - cmdstanpy.utils — CmdStanPy 0.9.76 documentation - - - - - - - - - + + + + + cmdstanpy.utils — CmdStanPy 0.9.77 documentation + + + - - + + + + - + + - - - - - - - - + + + - + + + + + + + + + + + + + - - - + - + + + + - -
- -
- - - - - -
- -
- - - - - - - - - - - - - - - - - - -
- -
    - -
  • »
  • - -
  • Module code »
  • - -
  • cmdstanpy.utils
  • - - -
  • - -
  • - -
- - -
-
-
-
+ + +
+ +
+

Source code for cmdstanpy.utils

 """
 Utility functions
 """
+import contextlib
+import functools
 import logging
 import math
 import os
@@ -182,9 +180,20 @@ 

Source code for cmdstanpy.utils

 import sys
 import tempfile
 from collections import OrderedDict
-from collections.abc import Sequence
-from numbers import Integral, Real
-from typing import Dict, List, TextIO, Tuple, Union
+from collections.abc import Collection
+from typing import (
+    Any,
+    Callable,
+    Dict,
+    Iterator,
+    List,
+    Mapping,
+    MutableMapping,
+    Optional,
+    TextIO,
+    Tuple,
+    Union,
+)
 
 import numpy as np
 import pandas as pd
@@ -202,7 +211,8 @@ 

Source code for cmdstanpy.utils

 EXTENSION = '.exe' if platform.system() == 'Windows' else ''
 
 
-def get_logger():
+@functools.lru_cache(maxsize=None)
+def get_logger() -> logging.Logger:
     """cmdstanpy logger"""
     logger = logging.getLogger('cmdstanpy')
     if len(logger.handlers) == 0:
@@ -210,7 +220,7 @@ 

Source code for cmdstanpy.utils

     return logger
 
 
-def validate_dir(install_dir: str):
+def validate_dir(install_dir: str) -> None:
     """Check that specified install directory exists, can write."""
     if not os.path.exists(install_dir):
         try:
@@ -234,7 +244,7 @@ 

Source code for cmdstanpy.utils

             ) from e
 
 
-def get_latest_cmdstan(cmdstan_dir: str) -> str:
+def get_latest_cmdstan(cmdstan_dir: str) -> Optional[str]:
     """
     Given a valid directory path, find all installed CmdStan versions
     and return highest (i.e., latest) version number.
@@ -317,6 +327,11 @@ 

Source code for cmdstanpy.utils

                     'no CmdStan installation found, '
                     'run command line script "install_cmdstan"'
                 )
+            get_logger().warning(
+                "Using ~/.cmdstanpy is deprecated and"
+                " will not be automatically detected in version 1.0!\n"
+                " Please rename to ~/.cmdstan"
+            )
         latest_cmdstan = get_latest_cmdstan(cmdstan_dir)
         if latest_cmdstan is None:
             raise ValueError(
@@ -374,7 +389,9 @@ 

Source code for cmdstanpy.utils

     return False
 
 
-def cxx_toolchain_path(version: str = None) -> Tuple[str]:
+def cxx_toolchain_path(
+    version: Optional[str] = None, install_dir: Optional[str] = None
+) -> Tuple[str, ...]:
     """
     Validate, then activate C++ toolchain directory path.
     """
@@ -402,14 +419,14 @@ 

Source code for cmdstanpy.utils

                         'Found invalid installion for RTools40 on %s',
                         toolchain_root,
                     )
-                    toolchain_root = None
+                    toolchain_root = ''
             else:
                 compiler_path = ''
                 logger.warning(
                     'Found invalid installion for RTools40 on %s',
                     toolchain_root,
                 )
-                toolchain_root = None
+                toolchain_root = ''
 
         elif os.path.exists(os.path.join(toolchain_root, 'mingw_64')):
             compiler_path = os.path.join(
@@ -426,32 +443,43 @@ 

Source code for cmdstanpy.utils

                         'Found invalid installion for RTools35 on %s',
                         toolchain_root,
                     )
-                    toolchain_root = None
+                    toolchain_root = ''
             else:
                 compiler_path = ''
                 logger.warning(
                     'Found invalid installion for RTools35 on %s',
                     toolchain_root,
                 )
-                toolchain_root = None
+                toolchain_root = ''
     else:
         rtools40_home = os.environ.get('RTOOLS40_HOME')
         cmdstan_dir = os.path.expanduser(os.path.join('~', _DOT_CMDSTAN))
         cmdstan_dir_old = os.path.expanduser(os.path.join('~', _DOT_CMDSTANPY))
         for toolchain_root in (
-            [rtools40_home] if rtools40_home is not None else []
-        ) + [
-            os.path.join(cmdstan_dir, 'RTools40'),
-            os.path.join(cmdstan_dir_old, 'RTools40'),
-            os.path.join(os.path.abspath("/"), "RTools40"),
-            os.path.join(cmdstan_dir, 'RTools35'),
-            os.path.join(cmdstan_dir_old, 'RTools35'),
-            os.path.join(os.path.abspath("/"), "RTools35"),
-            os.path.join(cmdstan_dir, 'RTools'),
-            os.path.join(cmdstan_dir_old, 'RTools'),
-            os.path.join(os.path.abspath("/"), "RTools"),
-            os.path.join(os.path.abspath("/"), "RBuildTools"),
-        ]:
+            ([rtools40_home] if rtools40_home is not None else [])
+            + (
+                [
+                    os.path.join(install_dir, 'RTools40'),
+                    os.path.join(install_dir, 'RTools35'),
+                    os.path.join(install_dir, 'RTools30'),
+                    os.path.join(install_dir, 'RTools'),
+                ]
+                if install_dir is not None
+                else []
+            )
+            + [
+                os.path.join(cmdstan_dir, 'RTools40'),
+                os.path.join(cmdstan_dir_old, 'RTools40'),
+                os.path.join(os.path.abspath("/"), "RTools40"),
+                os.path.join(cmdstan_dir, 'RTools35'),
+                os.path.join(cmdstan_dir_old, 'RTools35'),
+                os.path.join(os.path.abspath("/"), "RTools35"),
+                os.path.join(cmdstan_dir, 'RTools'),
+                os.path.join(cmdstan_dir_old, 'RTools'),
+                os.path.join(os.path.abspath("/"), "RTools"),
+                os.path.join(os.path.abspath("/"), "RBuildTools"),
+            ]
+        ):
             compiler_path = ''
             tool_path = ''
 
@@ -471,7 +499,7 @@ 

Source code for cmdstanpy.utils

                                 'Found invalid installation for RTools40 on %s',
                                 toolchain_root,
                             )
-                            toolchain_root = None
+                            toolchain_root = ''
                         else:
                             break
                     else:
@@ -480,7 +508,7 @@ 

Source code for cmdstanpy.utils

                             'Found invalid installation for RTools40 on %s',
                             toolchain_root,
                         )
-                        toolchain_root = None
+                        toolchain_root = ''
                 else:
                     compiler_path = os.path.join(
                         toolchain_root,
@@ -496,7 +524,7 @@ 

Source code for cmdstanpy.utils

                                 'Found invalid installation for RTools35 on %s',
                                 toolchain_root,
                             )
-                            toolchain_root = None
+                            toolchain_root = ''
                         else:
                             break
                     else:
@@ -505,9 +533,9 @@ 

Source code for cmdstanpy.utils

                             'Found invalid installation for RTools35 on %s',
                             toolchain_root,
                         )
-                        toolchain_root = None
+                        toolchain_root = ''
             else:
-                toolchain_root = None
+                toolchain_root = ''
 
     if not toolchain_root:
         raise ValueError(
@@ -526,40 +554,65 @@ 

Source code for cmdstanpy.utils

     return compiler_path, tool_path
 
 
-def _rdump_array(key: str, val: np.ndarray) -> str:
-    """Flatten numpy ndarray, format as Rdump variable declaration."""
-    c = 'c(' + ', '.join(map(str, val.T.flat)) + ')'
-    if (val.size,) == val.shape:
-        return '{key} <- {c}'.format(key=key, c=c)
-    else:
-        dim = '.Dim = c{}'.format(val.shape)
-        struct = '{key} <- structure({c}, {dim})'.format(key=key, c=c, dim=dim)
-        return struct
+
[docs]def write_stan_json(path: str, data: Mapping[str, Any]) -> None: + """ + Dump a mapping of strings to data to a JSON file. + Values can be any numeric type, a boolean (converted to int), + or any collection compatible with :func:`numpy.asarray`, e.g a + :class:`pandas.Series`. -def jsondump(path: str, data: Dict) -> None: - """Dump a dict of data to a JSON file.""" - data = data.copy() + Produces a file compatible with the + `Json Format for Cmdstan + <https://mc-stan.org/docs/2_27/cmdstan-guide/json.html>`__ + + :param path: File path for the created json. Will be overwritten if + already in existence. + + :param data: A mapping from strings to values. This can be a dictionary + or something more exotic like an :class:`xarray.Dataset`. This will be + copied before type conversion, not modified + """ + data_out = {} for key, val in data.items(): - if type(val).__module__ == 'numpy': - val = val.tolist() - data[key] = val - with open(path, 'w') as fd: - json.dump(data, fd) + if val is not None: + if isinstance(val, (str, bytes)) or ( + type(val).__module__ != 'numpy' + and not isinstance(val, (Collection, bool, int, float)) + ): + raise TypeError( + f"Invalid type '{type(val)}' provided to " + + f"write_stan_json for key '{key}'" + ) + try: + if not np.all(np.isfinite(val)): + raise ValueError( + "Input to write_stan_json has nan or infinite " + + f"values for key '{key}'" + ) + except TypeError: + # handles cases like val == ['hello'] + # pylint: disable=raise-missing-from + raise ValueError( + "Invalid type provided to " + + f"write_stan_json for key '{key}' " + + f"as part of collection {type(val)}" + ) + if type(val).__module__ == 'numpy': + data_out[key] = val.tolist() + elif isinstance(val, Collection): + data_out[key] = np.asarray(val).tolist() + elif isinstance(val, bool): + data_out[key] = int(val) + else: + data_out[key] = val -def rdump(path: str, data: Dict) -> None: - """Dump a dict of data to a R dump format file.""" with open(path, 'w') as fd: - for key, val in data.items(): - if isinstance(val, (np.ndarray, Sequence)): - line = _rdump_array(key, np.asarray(val)) - else: - line = '{} <- {}'.format(key, val) - print(line, file=fd) + json.dump(data_out, fd)
-def rload(fname: str) -> dict: +def rload(fname: str) -> Optional[Dict[str, Union[int, float, np.ndarray]]]: """Parse data and parameter variable values from an R dump format file. This parser only supports the subset of R dump data as described in the "Dump Data Format" section of the CmdStan manual, i.e., @@ -592,7 +645,7 @@

Source code for cmdstanpy.utils

     return data_dict
 
 
-def parse_rdump_value(rhs: str) -> Union[int, float, np.array]:
+def parse_rdump_value(rhs: str) -> Union[int, float, np.ndarray]:
     """Process right hand side of Rdump variable assignment statement.
     Value is either scalar, vector, or multi-dim structure.
     Use regex to capture structure values, dimensions.
@@ -601,7 +654,7 @@ 

Source code for cmdstanpy.utils

         r'structure\(\s*c\((?P<vals>[^)]*)\)'
         r'(,\s*\.Dim\s*=\s*c\s*\((?P<dims>[^)]*)\s*\))?\)'
     )
-    val = None
+    val: Union[int, float, np.ndarray]
     try:
         if rhs.startswith('structure'):
             parse = pat.match(rhs)
@@ -626,11 +679,11 @@ 

Source code for cmdstanpy.utils

 def check_sampler_csv(
     path: str,
     is_fixed_param: bool = False,
-    iter_sampling: int = None,
-    iter_warmup: int = None,
+    iter_sampling: Optional[int] = None,
+    iter_warmup: Optional[int] = None,
     save_warmup: bool = False,
-    thin: int = None,
-) -> Dict:
+    thin: Optional[int] = None,
+) -> Dict[str, Any]:
     """Capture essential config, shape from stan_csv file."""
     meta = scan_sampler_csv(path, is_fixed_param)
     if thin is None:
@@ -638,12 +691,12 @@ 

Source code for cmdstanpy.utils

     elif thin > _CMDSTAN_THIN:
         if 'thin' not in meta:
             raise ValueError(
-                'bad csv file {}, '
+                'bad Stan CSV file {}, '
                 'config error, expected thin = {}'.format(path, thin)
             )
         if meta['thin'] != thin:
             raise ValueError(
-                'bad csv file {}, '
+                'bad Stan CSV file {}, '
                 'config error, expected thin = {}, found {}'.format(
                     path, thin, meta['thin']
                 )
@@ -658,19 +711,19 @@ 

Source code for cmdstanpy.utils

     draws_sampling = int(math.ceil(draws_sampling / thin))
     if meta['draws_sampling'] != draws_sampling:
         raise ValueError(
-            'bad csv file {}, expected {} draws, found {}'.format(
+            'bad Stan CSV file {}, expected {} draws, found {}'.format(
                 path, draws_sampling, meta['draws_sampling']
             )
         )
     if save_warmup:
         if not ('save_warmup' in meta and meta['save_warmup'] == 1):
             raise ValueError(
-                'bad csv file {}, '
+                'bad Stan CSV file {}, '
                 'config error, expected save_warmup = 1'.format(path)
             )
         if meta['draws_warmup'] != draws_warmup:
             raise ValueError(
-                'bad csv file {}, '
+                'bad Stan CSV file {}, '
                 'expected {} warmup draws, found {}'.format(
                     path, draws_warmup, meta['draws_warmup']
                 )
@@ -678,9 +731,9 @@ 

Source code for cmdstanpy.utils

     return meta
 
 
-def scan_sampler_csv(path: str, is_fixed_param: bool = False) -> Dict:
+def scan_sampler_csv(path: str, is_fixed_param: bool = False) -> Dict[str, Any]:
     """Process sampler stan_csv output file line by line."""
-    dict = {}
+    dict: Dict[str, Any] = {}
     lineno = 0
     with open(path, 'r') as fd:
         lineno = scan_config(fd, dict, lineno)
@@ -692,9 +745,9 @@ 

Source code for cmdstanpy.utils

     return dict
 
 
-def scan_optimize_csv(path: str) -> Dict:
+def scan_optimize_csv(path: str) -> Dict[str, Any]:
     """Process optimizer stan_csv output file line by line."""
-    dict = {}
+    dict: Dict[str, Any] = {}
     lineno = 0
     with open(path, 'r') as fd:
         lineno = scan_config(fd, dict, lineno)
@@ -705,11 +758,11 @@ 

Source code for cmdstanpy.utils

     return dict
 
 
-def scan_generated_quantities_csv(path: str) -> Dict:
+def scan_generated_quantities_csv(path: str) -> Dict[str, Any]:
     """
     Process standalone generated quantities stan_csv output file line by line.
     """
-    dict = {}
+    dict: Dict[str, Any] = {}
     lineno = 0
     with open(path, 'r') as fd:
         lineno = scan_config(fd, dict, lineno)
@@ -717,9 +770,9 @@ 

Source code for cmdstanpy.utils

     return dict
 
 
-def scan_variational_csv(path: str) -> Dict:
+def scan_variational_csv(path: str) -> Dict[str, Any]:
     """Process advi stan_csv output file line by line."""
-    dict = {}
+    dict: Dict[str, Any] = {}
     lineno = 0
     with open(path, 'r') as fd:
         lineno = scan_config(fd, dict, lineno)
@@ -750,7 +803,7 @@ 

Source code for cmdstanpy.utils

     return dict
 
 
-def scan_config(fd: TextIO, config_dict: Dict, lineno: int) -> int:
+def scan_config(fd: TextIO, config_dict: Dict[str, Any], lineno: int) -> int:
     """
     Scan initial stan_csv file comments lines and
     save non-default configuration information to config_dict.
@@ -768,6 +821,7 @@ 

Source code for cmdstanpy.utils

                 config_dict['data_file'] = key_val[1].strip()
             elif key_val[0].strip() != 'file':
                 raw_val = key_val[1].strip()
+                val: Union[int, float, str]
                 try:
                     val = int(raw_val)
                 except ValueError:
@@ -782,7 +836,9 @@ 

Source code for cmdstanpy.utils

     return lineno
 
 
-def scan_warmup_iters(fd: TextIO, config_dict: Dict, lineno: int) -> int:
+def scan_warmup_iters(
+    fd: TextIO, config_dict: Dict[str, Any], lineno: int
+) -> int:
     """
     Check warmup iterations, if any.
     """
@@ -801,7 +857,9 @@ 

Source code for cmdstanpy.utils

     return lineno
 
 
-def scan_column_names(fd: TextIO, config_dict: Dict, lineno: int) -> int:
+def scan_column_names(
+    fd: TextIO, config_dict: MutableMapping[str, Any], lineno: int
+) -> int:
     """
     Process columns header, add to config_dict as 'column_names'
     """
@@ -813,7 +871,7 @@ 

Source code for cmdstanpy.utils

     return lineno
 
 
-def munge_varnames(names: List) -> List:
+def munge_varnames(names: List[str]) -> List[str]:
     """
     Change formatting for indices of container var elements
     from use of dot separator to array-like notation, e.g.,
@@ -827,20 +885,23 @@ 

Source code for cmdstanpy.utils

     ]
 
 
-def parse_sampler_vars(names: Tuple[str, ...]) -> Dict:
+def parse_method_vars(names: Tuple[str, ...]) -> Dict[str, Tuple[int, ...]]:
     """
     Parses out names ending in `__` from list of CSV file column names.
     Return a dict mapping sampler variable name to Stan CSV file column, using
     zero-based column indexing.
+    Currently, (Stan 2.X) all CmdStan inference method vars are scalar,
+    the map entries are tuples of int to allow for structured variables.
     """
     if names is None:
         raise ValueError('missing argument "names"')
-    # note: value as tuple allows structured sampler vars
-    # currently, all sampler vars a scalar, not checking for structure
+    # note: method vars are currently all scalar so not checking for structure
     return {v: tuple([k]) for (k, v) in enumerate(names) if v.endswith('__')}
 
 
-def parse_stan_vars(names: Tuple[str, ...]) -> (Dict, Dict):
+def parse_stan_vars(
+    names: Tuple[str, ...]
+) -> Tuple[Dict[str, Tuple[int, ...]], Dict[str, Tuple[int, ...]]]:
     """
     Parses out Stan variable names (i.e., names not ending in `__`)
     from list of CSV file column names.
@@ -851,9 +912,10 @@ 

Source code for cmdstanpy.utils

     """
     if names is None:
         raise ValueError('missing argument "names"')
-    dims_map = {}
-    cols_map = {}
+    dims_map: Dict[str, Tuple[int, ...]] = {}
+    cols_map: Dict[str, Tuple[int, ...]] = {}
     idxs = []
+    dims: Union[List[str], List[int]]
     for (idx, name) in enumerate(names):
         idxs.append(idx)
         var, *dims = name.split('[')
@@ -873,7 +935,7 @@ 

Source code for cmdstanpy.utils

     return (dims_map, cols_map)
 
 
-def scan_metric(fd: TextIO, config_dict: Dict, lineno: int) -> int:
+def scan_metric(fd: TextIO, config_dict: Dict[str, Any], lineno: int) -> int:
     """
     Scan step size, metric from  stan_csv file comment lines,
     set config_dict entries 'metric' and 'num_unconstrained_params'
@@ -934,7 +996,9 @@ 

Source code for cmdstanpy.utils

         return lineno
 
 
-def scan_sampling_iters(fd: TextIO, config_dict: Dict, lineno: int) -> int:
+def scan_sampling_iters(
+    fd: TextIO, config_dict: Dict[str, Any], lineno: int
+) -> int:
     """
     Parse sampling iteration, save number of iterations to config_dict.
     """
@@ -968,8 +1032,8 @@ 

Source code for cmdstanpy.utils

         with open(path, 'r') as fd:
             metric_dict = json.load(fd)
         if 'inv_metric' in metric_dict:
-            dims = np.asarray(metric_dict['inv_metric'])
-            return list(dims.shape)
+            dims_np = np.asarray(metric_dict['inv_metric'])
+            return list(dims_np.shape)
         else:
             raise ValueError(
                 'metric file {}, bad or missing'
@@ -990,7 +1054,7 @@ 

Source code for cmdstanpy.utils

     Find dimensions of variable named 'inv_metric' in Rdump data file.
     """
     metric_dict = rload(path)
-    if not (
+    if metric_dict is None or not (
         'inv_metric' in metric_dict
         and isinstance(metric_dict['inv_metric'], np.ndarray)
     ):
@@ -1000,13 +1064,15 @@ 

Source code for cmdstanpy.utils

     return list(metric_dict['inv_metric'].shape)
 
 
-def do_command(cmd: str, cwd: str = None, logger: logging.Logger = None) -> str:
+def do_command(
+    cmd: List[str],
+    cwd: Optional[str] = None,
+) -> Optional[str]:
     """
     Spawn process, print stdout/stderr to console.
     Throws RuntimeError on non-zero returncode.
     """
-    if logger:
-        logger.debug('cmd: %s', cmd)
+    get_logger().debug('cmd: %s', cmd)
     try:
         proc = subprocess.Popen(
             cmd,
@@ -1048,7 +1114,7 @@ 

Source code for cmdstanpy.utils

                 )
             return msg
     except OSError as e:
-        msg = 'Command: {}\nfailed with error {}\n'.format(msg, str(e))
+        msg = 'Command: {}\nfailed with error {}\n'.format(cmd, str(e))
         raise RuntimeError(msg) from e
     return None  # success
 
@@ -1082,7 +1148,10 @@ 

Source code for cmdstanpy.utils

     from ctypes import wintypes
 
     # pylint: disable=invalid-name
-    _GetShortPathNameW = ctypes.windll.kernel32.GetShortPathNameW
+    _GetShortPathNameW = (
+        ctypes.windll.kernel32.GetShortPathNameW  # type: ignore
+    )
+
     _GetShortPathNameW.argtypes = [
         wintypes.LPCWSTR,
         wintypes.LPWSTR,
@@ -1126,10 +1195,11 @@ 

Source code for cmdstanpy.utils

 
 
 
[docs]def install_cmdstan( - version: str = None, - dir: str = None, + version: Optional[str] = None, + dir: Optional[str] = None, overwrite: bool = False, verbose: bool = False, + compiler: bool = False, ) -> bool: """ Download and install a CmdStan release from GitHub by running @@ -1142,8 +1212,8 @@

Source code for cmdstanpy.utils

         Defaults to latest CmdStan release.
 
     :param dir: Path to install directory.  Defaults to hidden directory
-        ``$HOME/.cmdstan`` or ``$HOME/.cmdstanpy``, if the latter exists.
-        If no directory is specified and neither of the above directories
+        ``$HOME/.cmdstan``.
+        If no directory is specified and the above directory does not
         exist, directory ``$HOME/.cmdstan`` will be created and populated.
 
     :param overwrite:  Boolean value; when ``True``, will overwrite and
@@ -1152,6 +1222,10 @@ 

Source code for cmdstanpy.utils

     :param verbose:  Boolean value; when ``True``, output from CmdStan build
         processes will be streamed to the console.  Default is ``False``.
 
+    :param compiler: Boolean value; when ``True`` on WINDOWS ONLY, use the
+        C++ compiler from the ``install_cxx_toolchain`` command or install
+        one if none is found.
+
     :return: Boolean value; ``True`` for success.
     """
     logger = get_logger()
@@ -1164,9 +1238,11 @@ 

Source code for cmdstanpy.utils

     if dir is not None:
         cmd.extend(['--dir', dir])
     if overwrite:
-        cmd.extend(['--overwrite', 'TRUE'])
+        cmd.append('--overwrite')
     if verbose:
-        cmd.extend(['--verbose', 'TRUE'])
+        cmd.append('--verbose')
+    if compiler:
+        cmd.append('--compiler')
     proc = subprocess.Popen(
         cmd,
         stdin=subprocess.DEVNULL,
@@ -1174,7 +1250,7 @@ 

Source code for cmdstanpy.utils

         stderr=subprocess.PIPE,
         env=os.environ,
     )
-    while proc.poll() is None:
+    while proc.poll() is None and proc.stdout:
         print(proc.stdout.readline().decode('utf-8').strip())
 
     _, stderr = proc.communicate()
@@ -1183,33 +1259,89 @@ 

Source code for cmdstanpy.utils

         if stderr:
             logger.warning(stderr.decode('utf-8').strip())
         return False
+    if dir is not None:
+        if version is not None:
+            set_cmdstan_path(os.path.join(dir, 'cmdstan-' + version))
+        else:
+            set_cmdstan_path(
+                os.path.join(dir, get_latest_cmdstan(dir))  # type: ignore
+            )
     return True
+def flatten_chains(draws_array: np.ndarray) -> np.ndarray: + """ + Flatten a 3D array of draws X chains X variable into 2D array + where all chains are concatenated into a single column. + + :param draws_array: 3D array of draws + """ + if len(draws_array.shape) != 3: + raise ValueError( + 'Expecting 3D array, found array with {} dims'.format( + len(draws_array.shape) + ) + ) + + num_rows = draws_array.shape[0] * draws_array.shape[1] + num_cols = draws_array.shape[2] + return draws_array.reshape((num_rows, num_cols), order='F') + + +@contextlib.contextmanager +def pushd(new_dir: str) -> Iterator[None]: + """Acts like pushd/popd.""" + previous_dir = os.getcwd() + os.chdir(new_dir) + yield + os.chdir(previous_dir) + + +def wrap_progress_hook() -> Optional[Callable[[int, int, int], None]]: + try: + from tqdm import tqdm + + pbar = tqdm( + unit='B', + unit_scale=True, + unit_divisor=1024, + ) + + def download_progress_hook( + count: int, block_size: int, total_size: int + ) -> None: + if pbar.total is None: + pbar.total = total_size + pbar.reset() + downloaded_size = count * block_size + pbar.update(downloaded_size - pbar.n) + if pbar.n >= total_size: + pbar.close() + + except (ImportError, ModuleNotFoundError): + print("tqdm was not downloaded, progressbar not shown") + return None + + return download_progress_hook + + class MaybeDictToFilePath: """Context manager for json files.""" def __init__( - self, *objs: Union[str, dict, list], logger: logging.Logger = None + self, + *objs: Union[str, Mapping[str, Any], List[Any], int, float, None], ): self._unlink = [False] * len(objs) - self._paths = [''] * len(objs) - self._logger = logger or get_logger() + self._paths: List[Any] = [''] * len(objs) i = 0 for obj in objs: - if isinstance(obj, dict): + if isinstance(obj, Mapping): data_file = create_named_text_file( dir=_TMPDIR, prefix='', suffix='.json' ) - self._logger.debug('input tempfile: %s', data_file) - if any( - not item - for item in obj - if isinstance(item, (Sequence, np.ndarray)) - ): - rdump(data_file, obj) - else: - jsondump(data_file, obj) + get_logger().debug('input tempfile: %s', data_file) + write_stan_json(data_file, obj) self._paths[i] = data_file self._unlink[i] = True elif isinstance(obj, str): @@ -1238,16 +1370,16 @@

Source code for cmdstanpy.utils

                 self._paths[i] = obj
             elif obj is None:
                 self._paths[i] = None
-            elif i == 1 and isinstance(obj, (Integral, Real)):
+            elif i == 1 and isinstance(obj, (int, float)):
                 self._paths[i] = obj
             else:
                 raise ValueError('data must be string or dict')
             i += 1
 
-    def __enter__(self):
+    def __enter__(self) -> List[str]:
         return self._paths
 
-    def __exit__(self, exc_type, exc_val, exc_tb):
+    def __exit__(self, exc_type, exc_val, exc_tb) -> None:  # type: ignore
         for can_unlink, path in zip(self._unlink, self._paths):
             if can_unlink and path:
                 try:
@@ -1260,7 +1392,6 @@ 

Source code for cmdstanpy.utils

     """Context manager for tmpfiles, handles spaces in filepath."""
 
     def __init__(self, file_path: str):
-        self._path = None
         self._tmpdir = None
         if ' ' in os.path.abspath(file_path) and platform.system() == 'Windows':
             base_path, file_name = os.path.split(os.path.abspath(file_path))
@@ -1288,55 +1419,46 @@ 

Source code for cmdstanpy.utils

         else:
             self._path = file_path
 
-    def __enter__(self):
+    def __enter__(self) -> Tuple[str, bool]:
         return self._path, self._tmpdir is not None
 
-    def __exit__(self, exc_type, exc_val, exc_tb):
+    def __exit__(self, exc_type, exc_val, exc_tb) -> None:  # type: ignore
         if self._tmpdir:
             shutil.rmtree(self._tmpdir, ignore_errors=True)
 
-
- -
-
+
+ + +
+ -
+
+ +
+ -
-

- © Copyright 2021, Stan Development Team. +

+
+ + -

-
+ -
-
- -
-
- - - - - - - - - - + + \ No newline at end of file diff --git a/docs/_modules/index.html b/docs/_modules/index.html index b16c39e2..e938afc3 100644 --- a/docs/_modules/index.html +++ b/docs/_modules/index.html @@ -1,218 +1,207 @@ - - - - - - - - Overview: module code — CmdStanPy 0.9.76 documentation - - - - - - - - - + + + + + Overview: module code — CmdStanPy 0.9.77 documentation + + + - - + + + + - + + - - - - - - - - + + + - + + + + + + + + + + + + + - - - + - + + + + - -
- -
- - - - - -
- -
- - - - - - - - - - - - - - - - - - -
- -
    - -
  • »
  • - -
  • Overview: module code
  • - - -
  • - -
  • - -
- - -
-
-
-
+ + +
+ +
+

All modules for which code is available

-
- -
-
+
+ + +
+ -
+
+ + + -
-

- © Copyright 2021, Stan Development Team. +

+
+ + -

-
- + -
- - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/docs/_sources/api.rst.txt b/docs/_sources/api.rst.txt index 2ad477e5..bf3f8d0d 100644 --- a/docs/_sources/api.rst.txt +++ b/docs/_sources/api.rst.txt @@ -1,3 +1,5 @@ +.. py:currentmodule:: cmdstanpy + ############# API Reference ############# @@ -6,62 +8,57 @@ API Reference Classes ******* -.. _class_cmdstanmodel: - CmdStanModel ============ A CmdStanModel object encapsulates the Stan program. It manages program compilation and provides the following inference methods: -sample +:meth:`~CmdStanModel.sample` runs the HMC-NUTS sampler to produce a set of draws from the posterior distribution. -optimize +:meth:`~CmdStanModel.optimize` produce a penalized maximum likelihood estimate (point estimate) of the model parameters. -variational +:meth:`~CmdStanModel.variational` run CmdStan’s variational inference algorithm to approximate the posterior distribution. -generate_quantities +:meth:`~CmdStanModel.generate_quantities` runs CmdStan’s generate_quantities method to produce additional quantities of interest based on draws from an existing sample. .. autoclass:: cmdstanpy.CmdStanModel :members: -.. _class_cmdstanmcmc: - CmdStanMCMC =========== .. autoclass:: cmdstanpy.CmdStanMCMC :members: -.. _class_cmdstanmle: - CmdStanMLE ========== .. autoclass:: cmdstanpy.CmdStanMLE :members: -.. _class_cmdstanqq: - CmdStanGQ ========= .. autoclass:: cmdstanpy.CmdStanGQ :members: -.. _class_cmdstanvb: - CmdStanVB ========= .. autoclass:: cmdstanpy.CmdStanVB :members: -.. _class_runset: + +InferenceMetadata +================= + +.. autoclass:: cmdstanpy.InferenceMetadata + :members: RunSet ====== @@ -73,30 +70,32 @@ RunSet Functions ********* -.. _function_cmdstan_path: - cmdstan_path ============ .. autofunction:: cmdstanpy.cmdstan_path -.. _function_install_cmdstan: - -install_cmstan -============== +install_cmdstan +=============== .. autofunction:: cmdstanpy.install_cmdstan -.. _function_set_cmdstan_path: - set_cmdstan_path ================ .. autofunction:: cmdstanpy.set_cmdstan_path -.. _function_set_make_env: - set_make_env ============ .. autofunction:: cmdstanpy.set_make_env + +from_csv +======== + +.. autofunction:: cmdstanpy.from_csv + +write_stan_json +=============== + +.. autofunction:: cmdstanpy.write_stan_json diff --git a/docs/_sources/hello_world.rst.txt b/docs/_sources/hello_world.rst.txt index 371f5646..6565dd03 100644 --- a/docs/_sources/hello_world.rst.txt +++ b/docs/_sources/hello_world.rst.txt @@ -1,17 +1,29 @@ +.. py:currentmodule:: cmdstanpy + "Hello, World" -______________ +-------------- + +Fitting a Stan model using the NUTS-HMC sampler +*********************************************** -Bayesian estimation via Stan's HMC-NUTS sampler ------------------------------------------------- +In order to verify the installation and also to demonstrate +the CmdStanPy workflow, we use CmdStanPy to fit the +the example Stan model ``bernoulli.stan`` +to the dataset ``bernoulli.data.json``. +This model and data are included with the CmdStan distribution +in subdirectory ``examples/bernoulli``. +This example allows the user to verify that CmdStanPy, CmdStan, +the StanC compiler, and the C++ toolchain have all been properly installed. +For substantive example models and +guidance on coding statistical models in Stan, see +the `CmdStan User's Guide `_. -To exercise the essential functions of CmdStanPy we show how to run -Stan's HMC-NUTS sampler to estimate the posterior probability -of the model parameters conditioned on the data, -using the example Stan model ``bernoulli.stan`` -and corresponding dataset ``bernoulli.data.json`` which are -distributed with CmdStan. -This is a simple model for binary data: given a set of N observations of i.i.d. binary data +The Stan model +^^^^^^^^^^^^^^ + +The model ``bernoulli.stan`` is a simple model for binary data: +given a set of N observations of i.i.d. binary data `y[1] ... y[N]`, it calculates the Bernoulli chance-of-success `theta`. .. code:: @@ -28,24 +40,13 @@ This is a simple model for binary data: given a set of N observations of i.i.d. y ~ bernoulli(theta); } -The data file specifies the number of observations and their values. - -.. code:: - - { - "N" : 10, - "y" : [0,1,0,0,0,0,0,0,0,1] - } - - -Instantiate the Stan model, assemble the data -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The :ref:`class_cmdstanmodel` class manages the Stan program and its corresponding compiled executable. +The :class:`CmdStanModel` class manages the Stan program and its corresponding compiled executable. It provides properties and functions to inspect the model code and filepaths. -By default, the Stan program is compiled on instantiation. +CmdStanPy, manages the environment variable ``CMDSTAN`` which specifies the path to +the local CmdStan installation. +The function :func:`~cmdstan_path` returns the value of this environment variable. -.. code-block:: python +.. ipython:: python # import packages import os @@ -61,121 +62,127 @@ By default, the Stan program is compiled on instantiation. print(bernoulli_model) -Run the HMC-NUTS sampler -^^^^^^^^^^^^^^^^^^^^^^^^ - -The :ref:`class_cmdstanmodel` method ``sample`` is used to do Bayesian inference -over the model conditioned on data using using Hamiltonian Monte Carlo -(HMC) sampling. It runs Stan's HMC-NUTS sampler on the model and data and -returns a :ref:`class_cmdstanmcmc` object. The data can be specified -either as a filepath or a Python dict; in this example, we use the -example datafile `bernoulli.data.json`: - +Data inputs +^^^^^^^^^^^ -By default, the ``sample`` command runs 4 sampler chains. -This is a set of per-chain -`Stan CSV files `__ -The filenames follow the template '--' -plus the file suffix '.csv'. -There is also a correspondingly named file with suffix '.txt' -which contains all messages written to the console. -If the ``output_dir`` argument is omitted, the output files are written -to a temporary directory which is deleted when the current Python session is terminated. +CmdStanPy accepts input data either as a Python dictionary which maps data variable names +to values, or as the corresponding JSON file. -.. code-block:: python +The bernoulli model requires two inputs: the number of observations `N`, and +an N-length vector `y` of binary outcomes. +The data file `bernoulli.data.json` contains the following inputs: - # specify data file - bernoulli_data = os.path.join(cmdstan_path(), 'examples', 'bernoulli', 'bernoulli.data.json') +.. code:: - # fit the model - bern_fit = bernoulli_model.sample(data=bernoulli_data, output_dir='.') + { + "N" : 10, + "y" : [0,1,0,0,0,0,0,0,0,1] + } - # printing the object reports sampler commands, output files - print(bern_fit) -Access the sample +Fitting the model ^^^^^^^^^^^^^^^^^ -The :ref:`class_cmdstanmcmc` object -provides properties and methods to access, summarize, and manage the sample and its metadata. - -The sampler and model outputs from each chain are written out to Stan CSV files. -The CmdStanMCMC object assembles these outputs into a -numpy.ndarray which contains all across all chains arranged as (draws, chains, columns). -The ``draws`` method returns the draws array. -By default, it returns the underlying 3D array. -The optional boolean argument ``concat_chains``, when ``True``, -will flatten the chains resulting in a 2D array. - -.. code-block:: python +The :meth:`~CmdStanModel.sample` method is used to do Bayesian inference +over the model conditioned on data using using Hamiltonian Monte Carlo +(HMC) sampling. It runs Stan's HMC-NUTS sampler on the model and data and +returns a :class:`CmdStanMCMC` object. The data can be specified +either as a filepath or a Python dictionary; in this example, we use the +example datafile `bernoulli.data.json`: - bern_fit.draws().shape - bern_fit.draws(concat_chains=True).shape +By default, the :meth:`~CmdStanModel.sample` method runs 4 sampler chains. +The ``output_dir`` argument is an optional argument which specifies +the path to the output directory used by CmdStan. +If this argument is omitted, the output files are written +to a temporary directory which is deleted when the current Python session is terminated. -To work with the draws from all chains for a parameter or quantity of interest -in the model, use the ``stan_variable`` method to obtains -a numpy.ndarray which contains the set of draws in the sample for the named Stan program variable -by flattening the draws by chains into a single column: +.. ipython:: python -.. code-block:: python + # specify data file + bernoulli_data = os.path.join(cmdstan_path(), 'examples', 'bernoulli', 'bernoulli.data.json') - draws_theta = bern_fit.stan_variable(name='theta') - draws_theta.shape + # fit the model + bernoulli_fit = bernoulli_model.sample(data=bernoulli_data) + # printing the object reports sampler commands, output files + print(bernoulli_fit) -The draws array contains both the sampler variables and the model -variables. Sampler variables report the sampler state and end in `__`. -To see the names and output columns for all sampler and model -variables, we call accessor functions ``sampler_vars_cols`` and -``stan_vars_cols``: -.. code-block:: python +Accessing the sample +^^^^^^^^^^^^^^^^^^^^ - sampler_variables = bern_fit.sampler_vars_cols - stan_variables = bern_fit.stan_vars_cols - print('Sampler variables:\n{}'.format(sampler_variables)) - print('Stan variables:\n{}'.format(stan_variables)) +The :meth:`~CmdStanModel.sample` method outputs are a set of per-chain +`Stan CSV files `__. +The filenames follow the template '--' +plus the file suffix '.csv'. +The :class:`CmdStanMCMC` class provides methods to assemble the contents +of these files in memory as well as methods to manage the disk files. + +Underlyingly, the draws from all chains are stored as an +a numpy.ndarray with dimensions: draws, chains, columns. +CmdStanPy provides accessor methods which return the sample +either in terms of the CSV file columns or in terms of the +sampler and Stan program variables. +The :meth:`~CmdStanMCMC.draws` and :meth:`~CmdStanMCMC.draws_pd` methods return the sample contents +in columnar format. + +The :meth:`~CmdStanMCMC.stan_variable` method to returns a numpy.ndarray object +which contains the set of all draws in the sample for the named Stan program variable. +The draws from all chains are flattened into a single drawset. +The first ndarray dimension is the number of draws X number of chains. +The remaining ndarray dimensions correspond to the Stan program variable dimension. +The :meth:`~CmdStanMCMC.stan_variables` method returns a Python dict over all Stan model variables. + +.. ipython:: python + + bernoulli_fit.draws().shape + bernoulli_fit.draws(concat_chains=True).shape + + draws_theta = bernoulli_fit.stan_variable(name='theta') + draws_theta.shape -The NUTS-HMC sampler reports 7 variables. -The Bernoulli example model contains a single variable `theta`. -Summarize the results -^^^^^^^^^^^^^^^^^^^^^ +CmdStan utilities: `stansummary`, `diagnose` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ CmdStan is distributed with a posterior analysis utility `stansummary `__ that reads the outputs of all chains and computes summary statistics for all sampler and model parameters and quantities of interest. -The :ref:`class_cmdstanmcmc` method ``summary`` runs this utility and returns +The :class:`CmdStanMCMC` method :meth:`~CmdStanMCMC.summary` runs this utility and returns summaries of the total joint log-probability density **lp__** plus all model parameters and quantities of interest in a pandas.DataFrame: -.. code-block:: python +.. ipython:: python - bern_fit.summary() + bernoulli_fit.summary() CmdStan is distributed with a second posterior analysis utility `diagnose `__ which analyzes the per-draw sampler parameters across all chains looking for potential problems which indicate that the sample isn't a representative sample from the posterior. -The ``diagnose`` method runs this utility and prints the output to the console. +The :meth:`~CmdStanMCMC.diagnose` method runs this utility and prints the output to the console. -.. code-block:: python +.. ipython:: python - bern_fit.diagnose() + print(bernoulli_fit.diagnose()) -Save the Stan CSV files +Managing Stan CSV files ^^^^^^^^^^^^^^^^^^^^^^^ - -The ``save_csvfiles`` function moves the CmdStan CSV output files + +The :class:`CmdStanMCMC` object keeps track of all output files produced +by the sampler run. +The :meth:`~CmdStanMCMC.save_csvfiles` function moves the CSV files to a specified directory. -.. code-block:: python +.. ipython:: python + :verbatim: + + bernoulli_fit.save_csvfiles(dir='some/path') - bern_fit.save_csvfiles(dir='some/path') .. comment Progress bar @@ -186,14 +193,14 @@ to a specified directory. .. code-block:: python - bern_fit = bernoulli_model.sample(data=bernoulli_data, show_progress=True) + bernoulli_fit = bernoulli_model.sample(data=bernoulli_data, show_progress=True) On Jupyter Notebook environment user should use notebook version by using ``show_progress='notebook'``. .. code-block:: python - bern_fit = bernoulli_model.sample(data=bernoulli_data, show_progress='notebook') + bernoulli_fit = bernoulli_model.sample(data=bernoulli_data, show_progress='notebook') To enable javascript progress bar on Jupyter Lab Notebook user needs to install nodejs and ipywidgets. Following the instructions in @@ -216,3 +223,5 @@ to a specified directory. .. code-block:: bash jupyter labextension install @jupyter-widgets/jupyterlab-manager + + diff --git a/docs/_sources/index.rst.txt b/docs/_sources/index.rst.txt index 8900e791..87d549f5 100644 --- a/docs/_sources/index.rst.txt +++ b/docs/_sources/index.rst.txt @@ -12,6 +12,14 @@ .. moduleauthor:: Stan Developement Team +CmdStanPy is a lightweight interface to Stan for Python users which +provides the necessary objects and functions to do Bayesian inference +given a probability model and data. +It wraps the +`CmdStan `_ +command line interface in a small set of +Python classes which provide methods to do analysis and manage the resulting +set of model, data, and posterior estimates. .. toctree:: :maxdepth: 4 @@ -19,12 +27,8 @@ overview installation hello_world - stan_models - sample - generate_quantities - optimize - variational_bayes - under_the_hood + workflow + examples api :ref:`genindex` diff --git a/docs/_sources/installation.rst.txt b/docs/_sources/installation.rst.txt index f7381a3b..49979912 100644 --- a/docs/_sources/installation.rst.txt +++ b/docs/_sources/installation.rst.txt @@ -1,17 +1,48 @@ Installation ============ -Both CmdStanPy and CmdStan must be installed; -since the CmdStanPy package contains utility ``install_cmdstan``, -we recommend installing the CmdStanPy package first. +CmdStanPy is a pure-Python3 package, but it relies on CmdStan for all +of its functionality. There are several ways to install CmdStan and CmdStanPy, +which depend on the kind of user you are. -Install package CmdStanPy +Conda users (Recommended) ------------------------- -CmdStanPy is a pure-Python3 package. +If you use `conda `__, +installation of both can be done very simply. CmdStanPy +and CmdStan are both available via the +`conda-forge `__ repository. -It can be installed from PyPI via URL: https://pypi.org/project/cmdstanpy/ or from the +We recommend creating a new environment for CmdStan[Py]: + +.. code-block:: bash + + conda create -n cmdstan -c conda-forge cmdstanpy + +but installation is possible in an existing environment: + +.. code-block:: bash + + conda install -c conda-forge cmdstanpy + +These commands will install CmdStanPy, CmdStan, and the +required compilers for using CmdStan on your system inside +a conda environment. To use them, run ``conda activate cmdstan``, +or whichever name you used for your environment (following ``-n`` +above). + +Note that CmdStan is only available on conda for versions +2.27.0 and newer. If you require an older version, you must use +one of the following methods to install it. If you require a +version of CmdStan *newer* than 2.27.0, but not the latest, +you can install it in the standard conda way by specifying +``cmdstan==VERSION`` in the install command. + +Pip (non-Conda) users +------------------------- + +CmdStan can also be installed from PyPI via URL: https://pypi.org/project/cmdstanpy/ or from the command line using ``pip``: .. code-block:: bash @@ -20,7 +51,8 @@ command line using ``pip``: The optional packages are - * ``tqdm`` which allows for progress bar display during sampling +* ``tqdm`` which allows for progress bar display during sampling +* ``xarray``, an n-dimension labeled dataset package which can be used for outputs To install CmdStanPy with all the optional packages: @@ -32,15 +64,21 @@ To install the current develop branch from GitHub: .. code-block:: bash - pip install -e git+https://github.com/stan-dev/cmdstanpy@/develop + pip install -e git+https://github.com/stan-dev/cmdstanpy@/develop#egg=cmdstanpy + +If you install CmdStanPy from GitHub, +**you must install CmdStan**. The recommended way for Pip users +to do so is via the ``install_cmdstan`` function +:ref:`described below` -*Note for PyStan users:* PyStan and CmdStanPy should be installed in separate environments. +*Note for PyStan & RTools users:* PyStan and CmdStanPy should be installed in +separate environments if you are using the RTools toolchain (primarily Windows users). If you already have PyStan installed, you should take care to install CmdStanPy in its own virtual environment. -Install CmdStan ---------------- +Installing CmdStan +------------------ Prerequisites ^^^^^^^^^^^^^ @@ -54,17 +92,17 @@ consisting of a modern C++ compiler and the GNU-Make utility. + maxOS: install XCode and Xcode command line tools via command: `xcode-select --install`. +.. _install-cmdstan-fun: + Function ``install_cmdstan`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -CmdStanPy provides the function :ref:`function_install_cmdstan` which +CmdStanPy provides the function :func:`~cmdstanpy.install_cmdstan` which downloads CmdStan from GitHub and builds the CmdStan utilities. It can be can be called from within Python or from the command line. The default install location is a hidden directory in the user ``$HOME`` directory -named ``.cmdstan``. (In earlier versions, the hidden directory was named ``.cmdstanpy``, -and if directory ``$HOME/.cmdstanpy`` exists, it will continue to be used as the -default install dir.) This directory will be created by the install script. +named ``.cmdstan``. This directory will be created by the install script. + From Python @@ -105,18 +143,16 @@ Post Installation: Setting Environment Variables ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The default for the CmdStan installation location -is a directory named ``.cmdstan`` in your ``$HOME`` directory. -(In earlier versions, the hidden directory was named ``.cmdstanpy``, -and if directory ``$HOME/.cmdstanpy`` exists, it will continue to be used as the -default install dir.) - +is a directory named ``.cmdstan`` in your ``$HOME`` directory. [1]_ If you have installed CmdStan in a different directory, then you can set the environment variable ``CMDSTAN`` to this -location and it will be picked up by CmdStanPy: +location and it will be picked up by CmdStanPy. `Note:` This is done +for you if you installed via ``conda``, as cmdstan will be installed +in the ``bin/`` subfolder of the environment directory. .. code-block:: bash - export CMDSTAN='/path/to/cmdstan-2.24.0' + export CMDSTAN='/path/to/cmdstan-2.27.0' The CmdStanPy commands ``cmdstan_path`` and ``set_cmdstan_path`` @@ -136,3 +172,11 @@ To use custom ``make``-tool use ``set_make_env`` function. from cmdstanpy import set_make_env set_make_env("mingw32-make.exe") # On Windows with mingw32-make + + +.. rubric:: Footnotes + +.. [1] In earlier versions, the hidden directory was named ``.cmdstanpy``; + use of this directory has been deprecated. + + diff --git a/docs/_sources/overview.rst.txt b/docs/_sources/overview.rst.txt index 343950a0..ce7de3f7 100644 --- a/docs/_sources/overview.rst.txt +++ b/docs/_sources/overview.rst.txt @@ -12,23 +12,13 @@ set of model, data, and posterior estimates. CmdStanPy is a lightweight interface in that it is designed to use minimal memory beyond what is used by CmdStan itself to do inference given -and model and data. It manages the set of CmdStan input and output files. -It runs and records an analysis, but the user chooses +and model and data.It runs and records an analysis, but the user chooses whether or not to instantiate the results in memory, thus CmdStanPy has the potential to fit more complex models to larger datasets than might be possible in PyStan or RStan. - -The statistical modeling enterprise has two principal modalities: -development and production. -The focus of development is model building, comparison, and validation. -Many models are written and fitted to many kinds of data. -The focus of production is using a known model on real-world data in order -obtain estimates used for decision-making. -CmdStanPy is designed to support both of these modalities. -Because model development and testing may require many iterations, -the defaults favor development mode and therefore output files are -stored on a temporary filesystem. -Non-default options allow all aspects of a run to be specified -so that scripts can be used to distributed analysis jobs across -nodes and machines. +It manages the set of CmdStan input and output files and provides +methods and options which allow the user to save these files +to a specific filepath. +By default, CmdStan output files are written to a temporary directory +in order to avoid filling up the user's filesystem. diff --git a/docs/_static/basic.css b/docs/_static/basic.css index aa9df316..10301e15 100644 --- a/docs/_static/basic.css +++ b/docs/_static/basic.css @@ -55,7 +55,7 @@ div.sphinxsidebarwrapper { div.sphinxsidebar { float: left; - width: 230px; + width: 270px; margin-left: -100%; font-size: 90%; word-wrap: break-word; @@ -819,7 +819,7 @@ div.code-block-caption code { table.highlighttable td.linenos, span.linenos, -div.doctest > div.highlight span.gp { /* gp: Generic.Prompt */ +div.highlight span.gp { /* gp: Generic.Prompt */ user-select: none; -webkit-user-select: text; /* Safari fallback only */ -webkit-user-select: none; /* Chrome/Safari */ diff --git a/docs/_static/css/theme.css b/docs/_static/css/theme.css index 8cd4f101..3f6e79da 100644 --- a/docs/_static/css/theme.css +++ b/docs/_static/css/theme.css @@ -1,4 +1,117 @@ -html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a,.wy-menu-vertical li.current>a span.toctree-expand:before,.wy-menu-vertical li.on a,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li span.toctree-expand:before,.wy-nav-top a,.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! - * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome - * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li span.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p.caption .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a span.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a span.fa-pull-left.toctree-expand,.wy-menu-vertical li span.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p.caption .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a span.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a span.fa-pull-right.toctree-expand,.wy-menu-vertical li span.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p.caption .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a span.pull-left.toctree-expand,.wy-menu-vertical li.on a span.pull-left.toctree-expand,.wy-menu-vertical li span.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p.caption .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a span.pull-right.toctree-expand,.wy-menu-vertical li.on a span.pull-right.toctree-expand,.wy-menu-vertical li span.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li span.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li span.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li span.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li a span.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li span.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p.caption .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a span.toctree-expand,.btn .wy-menu-vertical li.on a span.toctree-expand,.btn .wy-menu-vertical li span.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p.caption .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a span.toctree-expand,.nav .wy-menu-vertical li.on a span.toctree-expand,.nav .wy-menu-vertical li span.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p.caption .btn .headerlink,.rst-content p.caption .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn span.toctree-expand,.wy-menu-vertical li.current>a .btn span.toctree-expand,.wy-menu-vertical li.current>a .nav span.toctree-expand,.wy-menu-vertical li .nav span.toctree-expand,.wy-menu-vertical li.on a .btn span.toctree-expand,.wy-menu-vertical li.on a .nav span.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p.caption .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li span.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p.caption .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li span.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p.caption .btn .fa-large.headerlink,.rst-content p.caption .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn span.fa-large.toctree-expand,.wy-menu-vertical li .nav span.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p.caption .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li span.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p.caption .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li span.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p.caption .btn .fa-spin.headerlink,.rst-content p.caption .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn span.fa-spin.toctree-expand,.wy-menu-vertical li .nav span.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p.caption .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li span.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p.caption .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li span.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p.caption .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li span.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p.caption .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini span.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol li,.rst-content ol.arabic li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content ol.arabic li p:last-child,.rst-content ol.arabic li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol li ul li,.rst-content ol.arabic li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs li{display:inline-block}.wy-breadcrumbs li.wy-breadcrumbs-aside{float:right}.wy-breadcrumbs li a{display:inline-block;padding:5px}.wy-breadcrumbs li a:first-child{padding-left:0}.rst-content .wy-breadcrumbs li tt,.wy-breadcrumbs li .rst-content tt,.wy-breadcrumbs li code{padding:5px;border:none;background:none}.rst-content .wy-breadcrumbs li tt.literal,.wy-breadcrumbs li .rst-content tt.literal,.wy-breadcrumbs li code.literal{color:#404040}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li span.toctree-expand{display:block;float:left;margin-left:-1.2em;font-size:.8em;line-height:1.6em;color:#4d4d4d}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover span.toctree-expand,.wy-menu-vertical li.on a:hover span.toctree-expand{color:grey}.wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand{display:block;font-size:.8em;line-height:1.6em;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover span.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 span.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 span.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover span.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active span.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p.caption .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p.caption .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version span.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content img{max-width:100%;height:auto}.rst-content div.figure{margin-bottom:24px}.rst-content div.figure p.caption{font-style:italic}.rst-content div.figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp{user-select:none;pointer-events:none}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink{visibility:hidden;font-size:14px}.rst-content .code-block-caption .headerlink:after,.rst-content .toctree-wrapper>p.caption .headerlink:after,.rst-content dl dt .headerlink:after,.rst-content h1 .headerlink:after,.rst-content h2 .headerlink:after,.rst-content h3 .headerlink:after,.rst-content h4 .headerlink:after,.rst-content h5 .headerlink:after,.rst-content h6 .headerlink:after,.rst-content p.caption .headerlink:after,.rst-content table>caption .headerlink:after{content:"\f0c1";font-family:FontAwesome}.rst-content .code-block-caption:hover .headerlink:after,.rst-content .toctree-wrapper>p.caption:hover .headerlink:after,.rst-content dl dt:hover .headerlink:after,.rst-content h1:hover .headerlink:after,.rst-content h2:hover .headerlink:after,.rst-content h3:hover .headerlink:after,.rst-content h4:hover .headerlink:after,.rst-content h5:hover .headerlink:after,.rst-content h6:hover .headerlink:after,.rst-content p.caption:hover .headerlink:after,.rst-content table>caption:hover .headerlink:after{visibility:visible}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .hlist{width:100%}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl dt span.classifier:before{content:" : "}html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.field-list>dt:after,html.writer-html5 .rst-content dl.footnote>dt:after{content:":"}html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.footnote>dt>span.brackets{margin-right:.5rem}html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{font-style:italic}html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.footnote>dd p,html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{font-size:inherit;line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.field-list)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dl:not(.field-list)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.field-list)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dl:not(.field-list)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code,html.writer-html4 .rst-content dl:not(.docutils) tt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel{border:1px solid #7fbbe3;background:#e7f2fa;font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file +:root { + /***************************************************************************** + * Theme config + **/ + --pst-header-height: 60px; + + /***************************************************************************** + * Font size + **/ + --pst-font-size-base: 15px; /* base font size - applied at body / html level */ + + /* heading font sizes */ + --pst-font-size-h1: 36px; + --pst-font-size-h2: 32px; + --pst-font-size-h3: 26px; + --pst-font-size-h4: 21px; + --pst-font-size-h5: 18px; + --pst-font-size-h6: 16px; + + /* smaller then heading font sizes*/ + --pst-font-size-milli: 12px; + + --pst-sidebar-font-size: .9em; + --pst-sidebar-caption-font-size: .9em; + + /***************************************************************************** + * Font family + **/ + /* These are adapted from https://systemfontstack.com/ */ + --pst-font-family-base-system: -apple-system, BlinkMacSystemFont, Segoe UI, "Helvetica Neue", + Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol; + --pst-font-family-monospace-system: "SFMono-Regular", Menlo, Consolas, Monaco, + Liberation Mono, Lucida Console, monospace; + + --pst-font-family-base: var(--pst-font-family-base-system); + --pst-font-family-heading: var(--pst-font-family-base); + --pst-font-family-monospace: var(--pst-font-family-monospace-system); + + /***************************************************************************** + * Color + * + * Colors are defined in rgb string way, "red, green, blue" + **/ + --pst-color-primary: 19, 6, 84; + --pst-color-success: 40, 167, 69; + --pst-color-info: 0, 123, 255; /*23, 162, 184;*/ + --pst-color-warning: 255, 193, 7; + --pst-color-danger: 220, 53, 69; + --pst-color-text-base: 51, 51, 51; + + --pst-color-h1: var(--pst-color-primary); + --pst-color-h2: var(--pst-color-primary); + --pst-color-h3: var(--pst-color-text-base); + --pst-color-h4: var(--pst-color-text-base); + --pst-color-h5: var(--pst-color-text-base); + --pst-color-h6: var(--pst-color-text-base); + --pst-color-paragraph: var(--pst-color-text-base); + --pst-color-link: 0, 91, 129; + --pst-color-link-hover: 227, 46, 0; + --pst-color-headerlink: 198, 15, 15; + --pst-color-headerlink-hover: 255, 255, 255; + --pst-color-preformatted-text: 34, 34, 34; + --pst-color-preformatted-background: 250, 250, 250; + --pst-color-inline-code: 232, 62, 140; + + --pst-color-active-navigation: 19, 6, 84; + --pst-color-navbar-link: 77, 77, 77; + --pst-color-navbar-link-hover: var(--pst-color-active-navigation); + --pst-color-navbar-link-active: var(--pst-color-active-navigation); + --pst-color-sidebar-link: 77, 77, 77; + --pst-color-sidebar-link-hover: var(--pst-color-active-navigation); + --pst-color-sidebar-link-active: var(--pst-color-active-navigation); + --pst-color-sidebar-expander-background-hover: 244, 244, 244; + --pst-color-sidebar-caption: 77, 77, 77; + --pst-color-toc-link: 119, 117, 122; + --pst-color-toc-link-hover: var(--pst-color-active-navigation); + --pst-color-toc-link-active: var(--pst-color-active-navigation); + + /***************************************************************************** + * Icon + **/ + + /* font awesome icons*/ + --pst-icon-check-circle: '\f058'; + --pst-icon-info-circle: '\f05a'; + --pst-icon-exclamation-triangle: '\f071'; + --pst-icon-exclamation-circle: '\f06a'; + --pst-icon-times-circle: '\f057'; + --pst-icon-lightbulb: '\f0eb'; + + /***************************************************************************** + * Admonitions + **/ + + --pst-color-admonition-default: var(--pst-color-info); + --pst-color-admonition-note: var(--pst-color-info); + --pst-color-admonition-attention: var(--pst-color-warning); + --pst-color-admonition-caution: var(--pst-color-warning); + --pst-color-admonition-warning: var(--pst-color-warning); + --pst-color-admonition-danger: var(--pst-color-danger); + --pst-color-admonition-error: var(--pst-color-danger); + --pst-color-admonition-hint: var(--pst-color-success); + --pst-color-admonition-tip: var(--pst-color-success); + --pst-color-admonition-important: var(--pst-color-success); + + --pst-icon-admonition-default: var(--pst-icon-info-circle); + --pst-icon-admonition-note: var(--pst-icon-info-circle); + --pst-icon-admonition-attention: var(--pst-icon-exclamation-circle); + --pst-icon-admonition-caution: var(--pst-icon-exclamation-triangle); + --pst-icon-admonition-warning: var(--pst-icon-exclamation-triangle); + --pst-icon-admonition-danger: var(--pst-icon-exclamation-triangle); + --pst-icon-admonition-error: var(--pst-icon-times-circle); + --pst-icon-admonition-hint: var(--pst-icon-lightbulb); + --pst-icon-admonition-tip: var(--pst-icon-lightbulb); + --pst-icon-admonition-important: var(--pst-icon-exclamation-circle); + +} diff --git a/docs/_static/doctools.js b/docs/_static/doctools.js index 61ac9d26..8cbf1b16 100644 --- a/docs/_static/doctools.js +++ b/docs/_static/doctools.js @@ -301,12 +301,14 @@ var Documentation = { window.location.href = prevHref; return false; } + break; case 39: // right var nextHref = $('link[rel="next"]').prop('href'); if (nextHref) { window.location.href = nextHref; return false; } + break; } } }); diff --git a/docs/_static/documentation_options.js b/docs/_static/documentation_options.js index f23810e7..cc949b07 100644 --- a/docs/_static/documentation_options.js +++ b/docs/_static/documentation_options.js @@ -1,6 +1,6 @@ var DOCUMENTATION_OPTIONS = { URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), - VERSION: '0.9.76', + VERSION: '0.9.77', LANGUAGE: 'None', COLLAPSE_INDEX: false, BUILDER: 'html', @@ -8,5 +8,5 @@ var DOCUMENTATION_OPTIONS = { LINK_SUFFIX: '.html', HAS_SOURCE: true, SOURCELINK_SUFFIX: '.txt', - NAVIGATION_WITH_KEYS: false + NAVIGATION_WITH_KEYS: true }; \ No newline at end of file diff --git a/docs/api.html b/docs/api.html index ca21f31a..97118249 100644 --- a/docs/api.html +++ b/docs/api.html @@ -1,209 +1,297 @@ - - - - - - - - API Reference — CmdStanPy 0.9.76 documentation - - - - - - - - - - - - - - + + + + + API Reference — CmdStanPy 0.9.77 documentation + + + - - - - - - - - + + + + - + + + + + + + + + + + + + + - - - - + - -
+ + - +
+
+ + +
+ + + +
+ + +
+ +
+ + + +
+ + -
+
+ + +
+ - - - -
-
-
-
+ +
+ +
+

API Reference

Classes

-

CmdStanModel

+

CmdStanModel

A CmdStanModel object encapsulates the Stan program. It manages program compilation and provides the following inference methods:

-
sample

runs the HMC-NUTS sampler to produce a set of draws from the posterior distribution.

+
sample()

runs the HMC-NUTS sampler to produce a set of draws from the posterior distribution.

-
optimize

produce a penalized maximum likelihood estimate (point estimate) of the model parameters.

+
optimize()

produce a penalized maximum likelihood estimate (point estimate) of the model parameters.

-
variational

run CmdStan’s variational inference algorithm to approximate the posterior distribution.

+
variational()

run CmdStan’s variational inference algorithm to approximate the posterior distribution.

-
generate_quantities

runs CmdStan’s generate_quantities method to produce additional quantities of interest based on draws from an existing sample.

+
generate_quantities()

runs CmdStan’s generate_quantities method to produce additional quantities of interest based on draws from an existing sample.

@@ -217,25 +305,25 @@

Classes
Parameters
    -
  • model_name (str) – Model name, used for output file names. +

  • model_name (Optional[str]) – Model name, used for output file names. Optional, default is the base filename of the Stan program file.

  • -
  • stan_file (str) – Path to Stan program file.

  • -
  • exe_file (str) – Path to compiled executable file. Optional, unless +

  • stan_file (Optional[str]) – Path to Stan program file.

  • +
  • exe_file (Optional[str]) – Path to compiled executable file. Optional, unless no Stan program file is specified. If both the program file and the compiled executable file are specified, the base filenames must match, (but different directory locations are allowed).

  • -
  • compile (bool) – Whether or not to compile the model. Default is True.

  • -
  • stanc_options (Dict) – Options for stanc compiler, specified as a Python +

  • compile (bool) – Whether or not to compile the model. Default is True.

  • +
  • stanc_options (Optional[Dict[str, Any]]) – Options for stanc compiler, specified as a Python dictionary containing Stanc3 compiler option name, value pairs. Optional.

  • -
  • cpp_options (Dict) – Options for C++ compiler, specified as a Python +

  • cpp_options (Optional[Dict[str, Any]]) – Options for C++ compiler, specified as a Python dictionary containing C++ compiler option name, value pairs. Optional.

  • -
  • logger (logging.Logger) –

  • +
  • logger (Optional[logging.Logger]) –

Return type
-

None

+

None

@@ -244,7 +332,7 @@

Classes
Return type
-

str

+

Optional[str]

@@ -260,18 +348,18 @@

Classes
Parameters
    -
  • force (bool) – When True, always compile, even if the executable file +

  • force (bool) – When True, always compile, even if the executable file is newer than the source file. Used for Stan models which have #include directives in order to force recompilation when changes are made to the included files.

  • -
  • stanc_options (Optional[Dict]) – Options for stanc compiler.

  • -
  • cpp_options (Optional[Dict]) – Options for C++ compiler.

  • -
  • override_options (bool) – When True, override existing option. +

  • stanc_options (Optional[Dict[str, Any]]) – Options for stanc compiler.

  • +
  • cpp_options (Optional[Dict[str, Any]]) – Options for C++ compiler.

  • +
  • override_options (bool) – When True, override existing option. When False, add/replace existing options. Default is False.

Return type
-

None

+

None

@@ -281,10 +369,10 @@

Classesgenerate_quantities(data=None, mcmc_sample=None, seed=None, gq_output_dir=None, sig_figs=None, refresh=None)[source]

Run CmdStan’s generate_quantities method which runs the generated quantities block of a model given an existing sample.

-

This function takes a CmdStanMCMC object and the dataset used to -generate that sample and calls to the CmdStan generate_quantities +

This function takes a CmdStanMCMC object and the dataset used +to generate that sample and calls to the CmdStan generate_quantities method to generate additional quantities of interest.

-

The CmdStanGQ object records the command, the return code, +

The CmdStanGQ object records the command, the return code, and the paths to the generate method output csv and console files. The output files are written either to a specified output directory or to a temporary directory which is deleted upon session exit.

@@ -298,28 +386,28 @@

Classes
Parameters
    -
  • data (Optional[Union[Dict, str]]) – Values for all data variables in the model, specified +

  • data (Optional[Union[Mapping[str, Any], str]]) – Values for all data variables in the model, specified either as a dictionary with entries matching the data variables, or as the path of a data file in JSON or Rdump format.

  • -
  • mcmc_sample (Optional[Union[cmdstanpy.stanfit.CmdStanMCMC, List[str]]]) – Can be either a CmdStanMCMC object returned by -the sample method or a list of stan-csv files generated +

  • mcmc_sample (Optional[Union[cmdstanpy.stanfit.CmdStanMCMC, List[str]]]) – Can be either a CmdStanMCMC object returned +by the sample() method or a list of stan-csv files generated by fitting the model to the data using any Stan interface.

  • -
  • seed (Optional[int]) – The seed for random number generator. Must be an integer +

  • seed (Optional[int]) – The seed for random number generator. Must be an integer between 0 and 2^32 - 1. If unspecified, -numpy.random.RandomState() +numpy.random.RandomState is used to generate a seed which will be used for all chains. NOTE: Specifying the seed will guarantee the same result for multiple invocations of this method with the same inputs. However this will not reproduce results from the sample method given the same inputs because the RNG will be in a different state.

  • -
  • gq_output_dir (Optional[str]) – Name of the directory in which the CmdStan output +

  • gq_output_dir (Optional[str]) – Name of the directory in which the CmdStan output files are saved. If unspecified, files will be written to a temporary directory which is deleted upon session exit.

  • -
  • sig_figs (Optional[int]) – Numerical precision used for output CSV and text files. +

  • sig_figs (Optional[int]) – Numerical precision used for output CSV and text files. Must be an integer between 1 and 18. If unspecified, the default precision for the system file I/O is used; the usual value is 6. Introduced in CmdStan-2.25.

  • -
  • refresh (Optional[int]) – Specify the number of iterations cmdstan will take +

  • refresh (Optional[int]) – Specify the number of iterations cmdstan will take between progress messages. Default value is 100.

@@ -334,7 +422,7 @@

Classes
-optimize(data=None, seed=None, inits=None, output_dir=None, sig_figs=None, save_profile=False, algorithm=None, init_alpha=None, iter=None, refresh=None)[source]
+optimize(data=None, seed=None, inits=None, output_dir=None, sig_figs=None, save_profile=False, algorithm=None, init_alpha=None, tol_obj=None, tol_rel_obj=None, tol_grad=None, tol_rel_grad=None, tol_param=None, history_size=None, iter=None, refresh=None)[source]

Run the specified CmdStan optimize algorithm to produce a penalized maximum likelihood estimate of the model parameters.

This function validates the specified configuration, composes a call to @@ -342,7 +430,7 @@

ClassesCmdStanMLE object records the command, the return code, +

The CmdStanMLE object records the command, the return code, and the paths to the optimize method output csv and console files. The output files are written either to a specified output directory or to a temporary directory which is deleted upon session exit.

@@ -356,13 +444,13 @@

Classes
Parameters
    -
  • data (Optional[Union[Dict, str]]) – Values for all data variables in the model, specified +

  • data (Optional[Union[Mapping[str, Any], str]]) – Values for all data variables in the model, specified either as a dictionary with entries matching the data variables, or as the path of a data file in JSON or Rdump format.

  • -
  • seed (Optional[int]) – The seed for random number generator. Must be an integer +

  • seed (Optional[int]) – The seed for random number generator. Must be an integer between 0 and 2^32 - 1. If unspecified, -numpy.random.RandomState() is used to generate a seed.

  • -
  • inits (Optional[Union[Dict, float, str]]) –

    Specifies how the sampler initializes parameter values. +numpy.random.RandomState is used to generate a seed.

  • +
  • inits (Optional[Union[Dict[str, float], float, str]]) –

    Specifies how the sampler initializes parameter values. Initialization is either uniform random on a range centered on 0, exactly 0, or a dictionary or file of initial values for some or all parameters in the model. The default initialization behavior @@ -377,45 +465,37 @@

    Classesstr]) – Name of the directory to which CmdStan output files are written. If unspecified, output files will be written to a temporary directory which is deleted upon session exit.

  • -
  • sig_figs (Optional[int]) – Numerical precision used for output CSV and text files. +

  • sig_figs (Optional[int]) – Numerical precision used for output CSV and text files. Must be an integer between 1 and 18. If unspecified, the default precision for the system file I/O is used; the usual value is 6. Introduced in CmdStan-2.25.

  • -
  • save_profile (bool) – Whether or not to profile auto-diff operations in +

  • save_profile (bool) – Whether or not to profile auto-diff operations in labelled blocks of code. If True, csv outputs are written to a file ‘<model_name>-<YYYYMMDDHHMM>-profile-<chain_id>’. Introduced in CmdStan-2.26.

  • -
  • algorithm (Optional[str]) – Algorithm to use. One of: ‘BFGS’, ‘LBFGS’, ‘Newton’

  • -
  • init_alpha (Optional[float]) – Line search step size for first iteration

  • -
  • iter (Optional[int]) – Total number of iterations

  • -
  • refresh (Optional[int]) – Specify the number of iterations cmdstan will take

  • +
  • algorithm (Optional[str]) – Algorithm to use. One of: ‘BFGS’, ‘LBFGS’, ‘Newton’

  • +
  • init_alpha (Optional[float]) – Line search step size for first iteration

  • +
  • tol_obj (Optional[float]) – Convergence tolerance on changes in objective +function value

  • +
  • tol_rel_obj (Optional[float]) – Convergence tolerance on relative changes +in objective function value

  • +
  • tol_grad (Optional[float]) – Convergence tolerance on the norm of the gradient

  • +
  • tol_rel_grad (Optional[float]) – Convergence tolerance on the relative +norm of the gradient

  • +
  • tol_param (Optional[float]) – Convergence tolerance on changes in parameter value

  • +
  • history_size (Optional[int]) – Size of the history for LBFGS Hessian +approximation. The value should be less than the dimensionality +of the parameter space. 5-10 usually sufficient

  • +
  • iter (Optional[int]) – Total number of iterations

  • +
  • refresh (Optional[int]) – Specify the number of iterations cmdstan will take +between progress messages. Default value is 100.

-
Return type
-

cmdstanpy.stanfit.CmdStanMLE

-
- -

between progress messages. Default value is 100.

-
-
Returns
-

CmdStanMLE object

-
-
Parameters
-
    -
  • data (Optional[Union[Dict, str]]) –

  • -
  • seed (Optional[int]) –

  • -
  • inits (Optional[Union[Dict, float, str]]) –

  • -
  • output_dir (Optional[str]) –

  • -
  • sig_figs (Optional[int]) –

  • -
  • save_profile (bool) –

  • -
  • algorithm (Optional[str]) –

  • -
  • init_alpha (Optional[float]) –

  • -
  • iter (Optional[int]) –

  • -
  • refresh (Optional[int]) –

  • -
+
Returns
+

CmdStanMLE object

Return type

cmdstanpy.stanfit.CmdStanMLE

@@ -425,15 +505,15 @@

Classes
-sample(data=None, chains=None, parallel_chains=None, threads_per_chain=None, seed=None, chain_ids=None, inits=None, iter_warmup=None, iter_sampling=None, save_warmup=False, thin=None, max_treedepth=None, metric=None, step_size=None, adapt_engaged=True, adapt_delta=None, adapt_init_phase=None, adapt_metric_window=None, adapt_step_size=None, fixed_param=False, output_dir=None, sig_figs=None, save_diagnostics=False, save_profile=False, show_progress=False, validate_csv=True, refresh=None)[source]
-

Run or more chains of the NUTS sampler to produce a set of draws +sample(data=None, chains=None, parallel_chains=None, threads_per_chain=None, seed=None, chain_ids=None, inits=None, iter_warmup=None, iter_sampling=None, save_warmup=False, thin=None, max_treedepth=None, metric=None, step_size=None, adapt_engaged=True, adapt_delta=None, adapt_init_phase=None, adapt_metric_window=None, adapt_step_size=None, fixed_param=False, output_dir=None, sig_figs=None, save_diagnostics=False, save_profile=False, show_progress=False, refresh=None)[source] +

Run or more chains of the NUTS-HMC sampler to produce a set of draws from the posterior distribution of a model conditioned on some data.

This function validates the specified configuration, composes a call to the CmdStan sample method and spawns one subprocess per chain to run the sampler and waits for all chains to run to completion. Unspecified arguments are not included in the call to CmdStan, i.e., those arguments will have CmdStan default values.

-

For each chain, the CmdStanMCMC object records the command, +

For each chain, the CmdStanMCMC object records the command, the return code, the sampler output file paths, and the corresponding console outputs, if any. The output files are written either to a specified output directory or to a temporary directory which is deleted @@ -448,27 +528,27 @@

Classes
Parameters
    -
  • data (Optional[Union[Dict, str]]) – Values for all data variables in the model, specified +

  • data (Optional[Union[Mapping[str, Any], str]]) – Values for all data variables in the model, specified either as a dictionary with entries matching the data variables, or as the path of a data file in JSON or Rdump format.

  • -
  • chains (Optional[int]) – Number of sampler chains, must be a positive integer.

  • -
  • parallel_chains (Optional[int]) – Number of processes to run in parallel. Must be -a positive integer. Defaults to multiprocessing.cpu_count().

  • -
  • threads_per_chain (Optional[int]) – The number of threads to use in parallelized +

  • chains (Optional[int]) – Number of sampler chains, must be a positive integer.

  • +
  • parallel_chains (Optional[int]) – Number of processes to run in parallel. Must be +a positive integer. Defaults to multiprocessing.cpu_count().

  • +
  • threads_per_chain (Optional[int]) – The number of threads to use in parallelized sections within an MCMC chain (e.g., when using the Stan functions reduce_sum() or map_rect()). This will only have an effect if the model was compiled with threading support. The total number of threads used will be parallel_chains * threads_per_chain.

  • -
  • seed (Optional[Union[int, List[int]]]) – The seed for random number generator. Must be an integer +

  • seed (Optional[Union[int, List[int]]]) – The seed for random number generator. Must be an integer between 0 and 2^32 - 1. If unspecified, -numpy.random.RandomState() +numpy.random.RandomState is used to generate a seed which will be used for all chains. When the same seed is used across all chains, the chain-id is used to advance the RNG to avoid dependent samples.

  • -
  • chain_ids (Optional[Union[int, List[int]]]) – The offset for the random number generator, either +

  • chain_ids (Optional[Union[int, List[int]]]) – The offset for the random number generator, either an integer or a list of unique per-chain offsets. If unspecified, chain ids are numbered sequentially starting from 1.

  • -
  • inits (Optional[Union[Dict, float, str, List[str]]]) –

    Specifies how the sampler initializes parameter values. +

  • inits (Optional[Union[Dict[str, float], float, str, List[str]]]) –

    Specifies how the sampler initializes parameter values. Initialization is either uniform random on a range centered on 0, exactly 0, or a dictionary or file of initial values for some or all parameters in the model. The default initialization behavior will @@ -484,16 +564,16 @@

    Classesint]) – Number of warmup iterations for each chain.

  • +
  • iter_sampling (Optional[int]) – Number of draws from the posterior for each chain.

  • -
  • save_warmup (bool) – When True, sampler saves warmup draws as part of +

  • save_warmup (bool) – When True, sampler saves warmup draws as part of the Stan csv output file.

  • -
  • thin (Optional[int]) – Period between recorded iterations. Default is 1, i.e., +

  • thin (Optional[int]) – Period between recorded iterations. Default is 1, i.e., all iterations are recorded.

  • -
  • max_treedepth (Optional[float]) – Maximum depth of trees evaluated by NUTS sampler +

  • max_treedepth (Optional[int]) – Maximum depth of trees evaluated by NUTS sampler per iteration.

  • -
  • metric (Optional[Union[str, List[str]]]) –

    Specification of the mass matrix, either as a +

  • metric (Optional[Union[str, List[str]]]) –

    Specification of the mass matrix, either as a vector consisting of the diagonal elements of the covariance matrix (‘diag’ or ‘diag_e’) or the full covariance matrix (‘dense’ or ‘dense_e’).

    @@ -506,28 +586,28 @@

    Classesfloat, List[float]]]) – Initial step size for HMC sampler. The value is either a single number or a list of numbers which will be used as the global or per-chain initial step size, respectively. The length of the list of step sizes must match the number of chains.

  • -
  • adapt_engaged (bool) – When True, adapt step size and metric.

  • -
  • adapt_delta (Optional[float]) – Adaptation target Metropolis acceptance rate. +

  • adapt_engaged (bool) – When True, adapt step size and metric.

  • +
  • adapt_delta (Optional[float]) – Adaptation target Metropolis acceptance rate. The default value is 0.8. Increasing this value, which must be strictly less than 1, causes adaptation to use smaller step sizes which improves the effective sample size, but may increase the time per iteration.

  • -
  • adapt_init_phase (Optional[int]) – Iterations for initial phase of adaptation +

  • adapt_init_phase (Optional[int]) – Iterations for initial phase of adaptation during which step size is adjusted so that the chain converges towards the typical set.

  • -
  • adapt_metric_window (Optional[int]) – The second phase of adaptation tunes +

  • adapt_metric_window (Optional[int]) – The second phase of adaptation tunes the metric and step size in a series of intervals. This parameter specifies the number of iterations used for the first tuning interval; window size increases for each subsequent interval.

  • -
  • adapt_step_size (Optional[int]) – Number of iterations given over to adjusting +

  • adapt_step_size (Optional[int]) – Number of iterations given over to adjusting the step size given the tuned metric during the final phase of adaptation.

  • -
  • fixed_param (bool) – When True, call CmdStan with argument +

  • fixed_param (bool) – When True, call CmdStan with argument algorithm=fixed_param which runs the sampler without updating the Markov Chain, thus the values of all parameters and transformed parameters are constant across all draws and @@ -536,71 +616,31 @@

    ClassesFalse.

  • -
  • output_dir (Optional[str]) – Name of the directory to which CmdStan output +

  • output_dir (Optional[str]) – Name of the directory to which CmdStan output files are written. If unspecified, output files will be written to a temporary directory which is deleted upon session exit.

  • -
  • sig_figs (Optional[int]) – Numerical precision used for output CSV and text files. +

  • sig_figs (Optional[int]) – Numerical precision used for output CSV and text files. Must be an integer between 1 and 18. If unspecified, the default precision for the system file I/O is used; the usual value is 6. Introduced in CmdStan-2.25.

  • -
  • save_diagnostics (bool) – Whether or not to output the position and +

  • save_diagnostics (bool) – Whether or not to output the position and momentum information for each parameter. If True, csv outputs are written to an output file using filename template ‘<model_name>-<YYYYMMDDHHMM>-diagnostic-<chain_id>’, e.g. ‘bernoulli-201912081451-diagnostic-1.csv’.

  • -
  • save_profile (bool) – Whether or not to profile auto-diff operations in +

  • save_profile (bool) – Whether or not to profile auto-diff operations in labelled blocks of code. If True, csv outputs are written to a file ‘<model_name>-<YYYYMMDDHHMM>-profile-<chain_id>’. Introduced in CmdStan-2.26.

  • -
  • show_progress (Union[bool, str]) – Use tqdm progress bar to show sampling progress. +

  • show_progress (Union[bool, str]) – Use tqdm progress bar to show sampling progress. If show_progress==’notebook’ use tqdm_notebook (needs nodejs for jupyter).

  • -
  • validate_csv (bool) – If False, skip scan of sample csv output file. -When sample is large or disk i/o is slow, will speed up processing. -Default is True - sample csv files are scanned for completeness -and consistency.

  • -
  • refresh (Optional[int]) – Specify the number of iterations cmdstan will take

  • +
  • refresh (Optional[int]) – Specify the number of iterations cmdstan will take +between progress messages. Default value is 100.

-
Return type
-

cmdstanpy.stanfit.CmdStanMCMC

-
-

-

between progress messages. Default value is 100.

-
-
Returns
-

CmdStanMCMC object

-
-
Parameters
-
    -
  • data (Optional[Union[Dict, str]]) –

  • -
  • chains (Optional[int]) –

  • -
  • parallel_chains (Optional[int]) –

  • -
  • threads_per_chain (Optional[int]) –

  • -
  • seed (Optional[Union[int, List[int]]]) –

  • -
  • chain_ids (Optional[Union[int, List[int]]]) –

  • -
  • inits (Optional[Union[Dict, float, str, List[str]]]) –

  • -
  • iter_warmup (Optional[int]) –

  • -
  • iter_sampling (Optional[int]) –

  • -
  • save_warmup (bool) –

  • -
  • thin (Optional[int]) –

  • -
  • max_treedepth (Optional[float]) –

  • -
  • metric (Optional[Union[str, List[str]]]) –

  • -
  • step_size (Optional[Union[float, List[float]]]) –

  • -
  • adapt_engaged (bool) –

  • -
  • adapt_delta (Optional[float]) –

  • -
  • adapt_init_phase (Optional[int]) –

  • -
  • adapt_metric_window (Optional[int]) –

  • -
  • adapt_step_size (Optional[int]) –

  • -
  • fixed_param (bool) –

  • -
  • output_dir (Optional[str]) –

  • -
  • sig_figs (Optional[int]) –

  • -
  • save_diagnostics (bool) –

  • -
  • save_profile (bool) –

  • -
  • show_progress (Union[bool, str]) –

  • -
  • validate_csv (bool) –

  • -
  • refresh (Optional[int]) –

  • -
+
Returns
+

CmdStanMCMC object

Return type

cmdstanpy.stanfit.CmdStanMCMC

@@ -618,7 +658,7 @@

ClassesCmdStanVB object records the command, the return code, +

The CmdStanVB object records the command, the return code, and the paths to the variational method output csv and console files. The output files are written either to a specified output directory or to a temporary directory which is deleted upon session exit.

@@ -632,46 +672,46 @@

Classes
Parameters
    -
  • data (Optional[Union[Dict, str]]) – Values for all data variables in the model, specified +

  • data (Optional[Union[Mapping[str, Any], str]]) – Values for all data variables in the model, specified either as a dictionary with entries matching the data variables, or as the path of a data file in JSON or Rdump format.

  • -
  • seed (Optional[int]) – The seed for random number generator. Must be an integer +

  • seed (Optional[int]) – The seed for random number generator. Must be an integer between 0 and 2^32 - 1. If unspecified, -numpy.random.RandomState() +numpy.random.RandomState is used to generate a seed which will be used for all chains.

  • -
  • inits (Optional[float]) – Specifies how the sampler initializes parameter values. +

  • inits (Optional[float]) – Specifies how the sampler initializes parameter values. Initialization is uniform random on a range centered on 0 with default range of 2. Specifying a single number n > 0 changes the initialization range to [-n, n].

  • -
  • output_dir (Optional[str]) – Name of the directory to which CmdStan output +

  • output_dir (Optional[str]) – Name of the directory to which CmdStan output files are written. If unspecified, output files will be written to a temporary directory which is deleted upon session exit.

  • -
  • sig_figs (Optional[int]) – Numerical precision used for output CSV and text files. +

  • sig_figs (Optional[int]) – Numerical precision used for output CSV and text files. Must be an integer between 1 and 18. If unspecified, the default precision for the system file I/O is used; the usual value is 6. Introduced in CmdStan-2.25.

  • -
  • save_diagnostics (bool) – Whether or not to save diagnostics. If True, +

  • save_diagnostics (bool) – Whether or not to save diagnostics. If True, csv outputs are written to an output file using filename template ‘<model_name>-<YYYYMMDDHHMM>-diagnostic-<chain_id>’, e.g. ‘bernoulli-201912081451-diagnostic-1.csv’.

  • -
  • save_profile (bool) – Whether or not to profile auto-diff operations in +

  • save_profile (bool) – Whether or not to profile auto-diff operations in labelled blocks of code. If True, csv outputs are written to a file ‘<model_name>-<YYYYMMDDHHMM>-profile-<chain_id>’. Introduced in CmdStan-2.26.

  • -
  • algorithm (Optional[str]) – Algorithm to use. One of: ‘meanfield’, ‘fullrank’.

  • -
  • iter (Optional[int]) – Maximum number of ADVI iterations.

  • -
  • grad_samples (Optional[int]) – Number of MC draws for computing the gradient.

  • -
  • elbo_samples (Optional[int]) – Number of MC draws for estimate of ELBO.

  • -
  • eta (Optional[numbers.Real]) – Step size scaling parameter.

  • -
  • adapt_engaged (bool) – Whether eta adaptation is engaged.

  • -
  • adapt_iter (Optional[int]) – Number of iterations for eta adaptation.

  • -
  • tol_rel_obj (Optional[numbers.Real]) – Relative tolerance parameter for convergence.

  • -
  • eval_elbo (Optional[int]) – Number of iterations between ELBO evaluations.

  • -
  • output_samples (Optional[int]) – Number of approximate posterior output draws +

  • algorithm (Optional[str]) – Algorithm to use. One of: ‘meanfield’, ‘fullrank’.

  • +
  • iter (Optional[int]) – Maximum number of ADVI iterations.

  • +
  • grad_samples (Optional[int]) – Number of MC draws for computing the gradient.

  • +
  • elbo_samples (Optional[int]) – Number of MC draws for estimate of ELBO.

  • +
  • eta (Optional[float]) – Step size scaling parameter.

  • +
  • adapt_engaged (bool) – Whether eta adaptation is engaged.

  • +
  • adapt_iter (Optional[int]) – Number of iterations for eta adaptation.

  • +
  • tol_rel_obj (Optional[float]) – Relative tolerance parameter for convergence.

  • +
  • eval_elbo (Optional[int]) – Number of iterations between ELBO evaluations.

  • +
  • output_samples (Optional[int]) – Number of approximate posterior output draws to save.

  • -
  • require_converged (bool) – Whether or not to raise an error if stan +

  • require_converged (bool) – Whether or not to raise an error if stan reports that “The algorithm may not have converged”.

  • -
  • refresh (Optional[int]) – Specify the number of iterations cmdstan will take +

  • refresh (Optional[int]) – Specify the number of iterations cmdstan will take between progress messages. Default value is 100.

@@ -686,13 +726,13 @@

Classes
-property cpp_options: Dict
+property cpp_options: Dict[str, Union[bool, int]]

Options to C++ compilers.

-property exe_file: str
+property exe_file: Optional[str]

Full path to Stan exe file.

@@ -706,13 +746,13 @@

Classes
-property stan_file: str
+property stan_file: Optional[str]

Full path to Stan program file.

-property stanc_options: Dict
+property stanc_options: Dict[str, Union[bool, int, str]]

Options to stanc compilers.

@@ -720,28 +760,26 @@

Classes -

CmdStanMCMC

+

CmdStanMCMC

-class cmdstanpy.CmdStanMCMC(runset, validate_csv=True, logger=None)[source]
+class cmdstanpy.CmdStanMCMC(runset, logger=None)[source]

Container for outputs from CmdStan sampler run. Provides methods to summarize and diagnose the model fit and accessor methods to access the entire sample or -individual items.

+individual items. Created by CmdStanModel.sample()

The sample is lazily instantiated on first access of either the resulting sample or the HMC tuning parameters, i.e., the -step size and metric. The sample can treated either as a 2D or -3D array; the former flattens all chains into a single dimension.

+step size and metric.

Parameters
Return type
-

None

+

None

@@ -760,7 +798,7 @@

Classes
Return type
-

str

+

Optional[str]

@@ -773,48 +811,83 @@

Classesconcat_chains=True will return a 2D array where all -chains are flattened into a single column, although underlyingly, -given M chains of N draws, the first N draws are from chain 1, up -through the last N draws from chain M.

+chains are flattened into a single column, preserving chain order, +so that given M chains of N draws, the first N draws are from chain 1, +up through the last N draws from chain M.

Parameters
Return type
-

numpy.ndarray

+

numpy.ndarray

+

-draws_pd(params=None, inc_warmup=False)[source]
-

Returns the sampler draws as a pandas DataFrame. Flattens all -chains into single column.

+draws_pd(vars=None, inc_warmup=False, *, params=None)[source] +

Returns the sample draws as a pandas DataFrame. +Flattens all chains into single column. Container variables +(array, vector, matrix) will span multiple columns, one column +per element. E.g. variable ‘matrix[2,2] foo’ spans 4 columns: +‘foo[1,1], … foo[2,2]’.

Parameters
    -
  • params (Optional[List[str]]) – optional list of variable names.

  • -
  • inc_warmup (bool) – When True and the warmup draws are present in +

  • vars (Optional[Union[str, List[str]]]) – optional list of variable names.

  • +
  • inc_warmup (bool) – When True and the warmup draws are present in the output, i.e., the sampler was run with save_warmup=True, then the warmup draws are included. Default value is False.

  • +
  • params (Optional[Union[str, List[str]]]) –

Return type

pandas.core.frame.DataFrame

+
-
-sampler_variables()[source]
+
+draws_xr(vars=None, inc_warmup=False)[source]
+

Returns the sampler draws as a xarray Dataset.

+
+
Parameters
+
    +
  • vars (Optional[Union[str, List[str]]]) – optional list of variable names.

  • +
  • inc_warmup (bool) – When True and the warmup draws are present in +the output, i.e., the sampler was run with save_warmup=True, +then the warmup draws are included. Default value is False.

  • +
+
+
Return type
+

xr.Dataset

+
+
+ +
+ +
+
+method_variables()[source]

Returns a dictionary of all sampler variables, i.e., all output column names ending in __. Assumes that all variables are scalar variables where column name is variable name. @@ -822,7 +895,29 @@

Classes
Return type
-

Dict

+

Dict[str, numpy.ndarray]

+
+

+

+ +
+
+sampler_diagnostics()[source]
+

Deprecated, use “method_variables” instead

+
+
Return type
+

Dict[str, numpy.ndarray]

+
+
+
+ +
+
+sampler_variables()[source]
+

Deprecated, use “method_variables” instead

+
+
Return type
+

Dict[str, numpy.ndarray]

@@ -836,17 +931,21 @@

Classes
Parameters
-

dir (Optional[str]) – directory path

+

dir (Optional[str]) – directory path

Return type
-

None

+

None

+
-stan_variable(name, inc_warmup=False)[source]
+stan_variable(var=None, inc_warmup=False, *, name=None)[source]

Return a numpy.ndarray which contains the set of draws for the named Stan program variable. Flattens the chains, leaving the draws in chain order. The first array dimension, @@ -872,25 +971,35 @@

Classes
Parameters
Return type
-

numpy.ndarray

+

numpy.ndarray

+
stan_variables()[source]
-

Return a dictionary of all Stan program variables.

+

Return a dictionary mapping Stan program variables names +to the corresponding numpy.ndarray containing the inferred values.

+
Return type
-

Dict

+

Dict[str, numpy.ndarray]

@@ -907,9 +1016,9 @@

Classes
Parameters
    -
  • percentiles (Optional[List[int]]) – Ordered non-empty list of percentiles to report. +

  • percentiles (Optional[List[int]]) – Ordered non-empty list of percentiles to report. Must be integers from (1, 99), inclusive.

  • -
  • sig_figs (Optional[int]) – Number of significant figures to report. +

  • sig_figs (Optional[int]) – Number of significant figures to report. Must be an integer between 1 and 18. If unspecified, the default precision for the system file I/O is used; the usual value is 6. If precision above 6 is requested, sample must have been produced @@ -926,19 +1035,6 @@

    Classes -
    -validate_csv_files()[source]
    -

    Checks that csv output files for all chains are consistent. -Populates attributes for metadata, draws, metric, step size. -Raises exception when inconsistencies detected.

    -
    -
    Return type
    -

    None

    -
    -
    -
    -
    property chain_ids: List[int]
    @@ -960,16 +1056,24 @@

    Classes +
    +property metadata: cmdstanpy.stanfit.InferenceMetadata
    +

    Returns object which contains CmdStan configuration as well as +information about the names and structure of the inference method +and model output variables.

    +

    +
    -property metric: numpy.ndarray
    +property metric: Optional[numpy.ndarray]

    Metric used by sampler for each chain. When sampler algorithm ‘fixed_param’ is specified, metric is None.

    -property metric_type: str
    +property metric_type: Optional[str]

    Metric type used for adaptation, either ‘diag_e’ or ‘dense_e’. When sampler algorithm ‘fixed_param’ is specified, metric_type is None.

    @@ -1009,36 +1113,27 @@

    Classes -
    -property sampler_config: Dict
    -

    Returns dict of CmdStan configuration arguments.

    -
    -
    -property sampler_vars_cols: Dict
    -

    Returns map from sampler variable names to column indices.

    +property sampler_vars_cols: Dict[str, Tuple[int, ...]] +

    Deprecated - use “metadata.method_vars_cols” instead

    -property stan_vars_cols: Dict
    -

    Returns map from Stan program variable names to column indices.

    +property stan_vars_cols: Dict[str, Tuple[int, ...]] +

    Deprecated - use “metadata.stan_vars_cols” instead

    -property stan_vars_dims: Dict
    -

    Returns map from Stan program variable names to variable dimensions. -Scalar types are mapped to the empty tuple, e.g., -program variable int foo has dimesion () and -program variable vector[10] bar has dimension (10,).

    +property stan_vars_dims: Dict[str, Tuple[int, ...]] +

    Deprecated - use “metadata.stan_vars_dims” instead

    -property step_size: numpy.ndarray
    +property step_size: Optional[numpy.ndarray]

    Step size used by sampler for each chain. When sampler algorithm ‘fixed_param’ is specified, step size is None.

    @@ -1059,17 +1154,18 @@

    Classes -

    CmdStanMLE

    +

    CmdStanMLE

    class cmdstanpy.CmdStanMLE(runset)[source]
    -

    Container for outputs from CmdStan optimization.

    +

    Container for outputs from CmdStan optimization. +Created by CmdStanModel.optimize().

    Parameters

    runset (cmdstanpy.stanfit.RunSet) –

    Return type
    -

    None

    +

    None

    @@ -1081,10 +1177,53 @@

    Classes
    Parameters
    -

    dir (Optional[str]) – directory path

    +

    dir (Optional[str]) – directory path

    Return type
    -

    None

    +

    None

    +
    +

    + +
    + +
    +
    +stan_variable(var=None, *, name=None)[source]
    +

    Return a numpy.ndarray which contains the estimates for the +for the named Stan program variable where the dimensions of the +numpy.ndarray match the shape of the Stan program variable.

    +
    +
    Parameters
    +
      +
    • var (Optional[str]) – variable name

    • +
    • name (Optional[str]) –

    • +
    +
    +
    Return type
    +

    numpy.ndarray

    +
    +
    + +
    + +
    +
    +stan_variables()[source]
    +

    Return a dictionary mapping Stan program variables names +to the corresponding numpy.ndarray containing the inferred values.

    + +
    +
    Return type
    +

    Dict[str, numpy.ndarray]

    @@ -1093,18 +1232,26 @@

    Classes property column_names: Tuple[str, ...]

    Names of estimated quantities, includes joint log probability, -and all parameters, transformed parameters, and generated quantitites.

    +and all parameters, transformed parameters, and generated quantities.

    +
    + +
    +
    +property metadata: cmdstanpy.stanfit.InferenceMetadata
    +

    Returns object which contains CmdStan configuration as well as +information about the names and structure of the inference method +and model output variables.

    -property optimized_params_dict: collections.OrderedDict
    +property optimized_params_dict: Dict[str, float]

    Returns optimized params as Dict.

    -property optimized_params_np: numpy.array
    +property optimized_params_np: numpy.ndarray

    Returns optimized params as numpy array.

    @@ -1118,22 +1265,110 @@

    Classes -

    CmdStanGQ

    +

    CmdStanGQ

    class cmdstanpy.CmdStanGQ(runset, mcmc_sample)[source]
    -

    Container for outputs from CmdStan generate_quantities run.

    +

    Container for outputs from CmdStan generate_quantities run. +Created by CmdStanModel.generate_quantities().

    Parameters
    +
    +
    Return type
    +

    None

    +
    +
    +
    +
    +draws(*, inc_warmup=False, concat_chains=False, inc_sample=False)[source]
    +

    Returns a numpy.ndarray over the generated quantities draws from +all chains which is stored column major so that the values +for a parameter are contiguous in memory, likewise all draws from +a chain are contiguous. By default, returns a 3D array arranged +(draws, chains, columns); parameter concat_chains=True will +return a 2D array where all chains are flattened into a single column, +preserving chain order, so that given M chains of N draws, +the first N draws are from chain 1, …, and the the last N draws +are from chain M.

    +
    +
    Parameters
    +
      +
    • inc_warmup (bool) – When True and the warmup draws are present in +the output, i.e., the sampler was run with save_warmup=True, +then the warmup draws are included. Default value is False.

    • +
    • concat_chains (bool) – When True return a 2D array flattening all +all draws from all chains. Default value is False.

    • +
    • inc_sample (bool) – When True include all columns in the mcmc_sample +draws array as well, excepting columns for variables already present +in the generated quantities drawset. Default value is False.

    • +
    +
    +
    Return type
    +

    numpy.ndarray

    +
    +
    + +
    + +
    +
    +draws_pd(vars=None, inc_warmup=False, inc_sample=False)[source]
    +

    Returns the generated quantities draws as a pandas DataFrame. +Flattens all chains into single column. Container variables +(array, vector, matrix) will span multiple columns, one column +per element. E.g. variable ‘matrix[2,2] foo’ spans 4 columns: +‘foo[1,1], … foo[2,2]’.

    +
    +
    Parameters
    +
      +
    • vars (Optional[Union[str, List[str]]]) – optional list of variable names.

    • +
    • inc_warmup (bool) – When True and the warmup draws are present in +the output, i.e., the sampler was run with save_warmup=True, +then the warmup draws are included. Default value is False.

    • +
    • inc_sample (bool) –

    Return type
    -

    None

    +

    pandas.core.frame.DataFrame

    + +
    + +
    +
    +draws_xr(vars=None, inc_warmup=False, inc_sample=False)[source]
    +

    Returns the generated quantities draws as a xarray Dataset.

    +
    +
    Parameters
    +
      +
    • vars (Optional[Union[str, List[str]]]) – optional list of variable names.

    • +
    • inc_warmup (bool) – When True and the warmup draws are present in +the MCMC sample, then the warmup draws are included. +Default value is False.

    • +
    • inc_sample (bool) –

    • +
    +
    +
    Return type
    +

    xr.Dataset

    +
    +
    + +
    +
    save_csvfiles(dir=None)[source]
    @@ -1143,12 +1378,88 @@

    Classes
    Parameters
    -

    dir (Optional[str]) – directory path

    +

    dir (Optional[str]) – directory path

    +
    +
    Return type
    +

    None

    +
    +

    + +
    + +
    +
    +stan_variable(var=None, inc_warmup=False, *, name=None)[source]
    +

    Return a numpy.ndarray which contains the set of draws +for the named Stan program variable. Flattens the chains, +leaving the draws in chain order. The first array dimension, +corresponds to number of draws in the sample. +The remaining dimensions correspond to +the shape of the Stan program variable.

    +

    Underlyingly draws are in chain order, i.e., for a sample with +N chains of M draws each, the first M array elements are from chain 1, +the next M are from chain 2, and the last M elements are from chain N.

    +
      +
    • If the variable is a scalar variable, the return array has shape +( draws X chains, 1).

    • +
    • If the variable is a vector, the return array has shape +( draws X chains, len(vector))

    • +
    • If the variable is a matrix, the return array has shape +( draws X chains, size(dim 1) X size(dim 2) )

    • +
    • If the variable is an array with N dimensions, the return array +has shape ( draws X chains, size(dim 1) X … X size(dim N))

    • +
    +

    For example, if the Stan program variable theta is a 3x3 matrix, +and the sample consists of 4 chains with 1000 post-warmup draws, +this function will return a numpy.ndarray with shape (4000,3,3).

    +
    +
    Parameters
    +
      +
    • var (Optional[str]) – variable name

    • +
    • inc_warmup (bool) – When True and the warmup draws are present in +the MCMC sample, then the warmup draws are included. +Default value is False.

    • +
    • name (Optional[str]) –

    • +
    Return type
    -

    None

    +

    numpy.ndarray

    + +
    + +
    +
    +stan_variables(inc_warmup=False)[source]
    +

    Return a dictionary mapping Stan program variables names +to the corresponding numpy.ndarray containing the inferred values.

    +
    +
    Parameters
    +

    inc_warmup (bool) – When True and the warmup draws are present in +the MCMC sample, then the warmup draws are included. +Default value is False

    +
    +
    Return type
    +

    Dict[str, numpy.ndarray]

    +
    +
    + +
    + +
    +
    +property chain_ids: List[int]
    +

    Chain ids.

    @@ -1166,46 +1477,45 @@

    Classes
    property generated_quantities: numpy.ndarray
    -

    A 2D numpy ndarray which contains generated quantities draws -for all chains where the columns correspond to the generated quantities -block variables and the rows correspond to the draws from all chains, -where first M draws are the first M draws of chain 1 and the -last M draws are the last M draws of chain N, i.e., -flattened chain, draw ordering.

    +

    Deprecated - use method draws instead.

    property generated_quantities_pd: pandas.core.frame.DataFrame
    -

    Returns the generated quantities as a pandas DataFrame consisting of -one column per quantity of interest and one row per draw.

    +

    Deprecated - use method draws_pd instead.

    +
    + +
    +
    +property metadata: cmdstanpy.stanfit.InferenceMetadata
    +

    Returns object which contains CmdStan configuration as well as +information about the names and structure of the inference method +and model output variables.

    property sample_plus_quantities: pandas.core.frame.DataFrame
    -

    Returns the column-wise concatenation of the input drawset -with generated quantities drawset. If there are duplicate -columns in both the input and the generated quantities, -the input column is dropped in favor of the recomputed -values in the generate quantities drawset.

    +

    Deprecated - use method “draws_pd(inc_sample=True)” instead.

-

CmdStanVB

+

CmdStanVB

class cmdstanpy.CmdStanVB(runset)[source]
-

Container for outputs from CmdStan variational run.

+

Container for outputs from CmdStan variational run. +Created by CmdStanModel.variational().

Parameters

runset (cmdstanpy.stanfit.RunSet) –

Return type
-

None

+

None

@@ -1217,10 +1527,53 @@

Classes
Parameters
-

dir (Optional[str]) – directory path

+

dir (Optional[str]) – directory path

+
+
Return type
+

None

+
+

+ +
+ +
+
+stan_variable(var=None, *, name=None)[source]
+

Return a numpy.ndarray which contains the estimates for the +for the named Stan program variable where the dimensions of the +numpy.ndarray match the shape of the Stan program variable.

+
+
Parameters
+
    +
  • var (Optional[str]) – variable name

  • +
  • name (Optional[str]) –

  • +
Return type
-

None

+

numpy.ndarray

+
+
+ +
+ +
+
+stan_variables()[source]
+

Return a dictionary mapping Stan program variables names +to the corresponding numpy.ndarray containing the inferred values.

+ +
+
Return type
+

Dict[str, numpy.ndarray]

@@ -1241,15 +1594,23 @@

Classes +
+property metadata: cmdstanpy.stanfit.InferenceMetadata
+

Returns object which contains CmdStan configuration as well as +information about the names and structure of the inference method +and model output variables.

+
+
-property variational_params_dict: collections.OrderedDict
+property variational_params_dict: Dict[str, numpy.ndarray]

Returns inferred parameter means as Dict.

-property variational_params_np: numpy.array
+property variational_params_np: numpy.ndarray

Returns inferred parameter means as numpy array.

@@ -1261,32 +1622,88 @@

Classes
-property variational_sample: numpy.array
+property variational_sample: numpy.ndarray

Returns the set of approximate posterior output draws.

+

+
+

InferenceMetadata

+
+
+class cmdstanpy.InferenceMetadata(config)[source]
+

CmdStan configuration and contents of output file parsed out of +the Stan CSV file header comments and column headers. +Assumes valid CSV files.

+
+
Parameters
+

config (Dict[str, Any]) –

+
+
Return type
+

None

+
+
+
+
+property cmdstan_config: Dict[str, Any]
+

Returns a dictionary containing a set of name, value pairs +parsed out of the Stan CSV file header. These include the +command configuration and the CSV file header row information. +Uses deepcopy for immutability.

+
+ +
+
+property method_vars_cols: Dict[str, Tuple[int, ...]]
+

Returns a map from a Stan inference method variable to +a tuple of column indices in inference engine’s output array. +Method variable names always end in __, e.g. lp__. +Uses deepcopy for immutability.

+
+ +
+
+property stan_vars_cols: Dict[str, Tuple[int, ...]]
+

Returns a map from a Stan program variable name to a +tuple of the column indices in the vector or matrix of +estimates produced by a CmdStan inference method. +Uses deepcopy for immutability.

+
+ +
+
+property stan_vars_dims: Dict[str, Tuple[int, ...]]
+

Returns map from Stan program variable names to variable dimensions. +Scalar types are mapped to the empty tuple, e.g., +program variable int foo has dimension () and +program variable vector[10] bar has single dimension (10). +Uses deepcopy for immutability.

+
+ +
+
-

RunSet

+

RunSet

class cmdstanpy.stanfit.RunSet(args, chains=4, chain_ids=None, logger=None)[source]

Encapsulates the configuration and results of a call to any CmdStan -inference method. Records the sampler return code and locations of +inference method. Records the method return code and locations of all console, error, and output files.

Parameters
  • args (cmdstanpy.cmdstan_args.CmdStanArgs) –

  • -
  • chains (int) –

  • -
  • chain_ids (List[int]) –

  • -
  • logger (logging.Logger) –

  • +
  • chains (int) –

  • +
  • chain_ids (Optional[List[int]]) –

  • +
  • logger (Optional[logging.Logger]) –

Return type
-

None

+

None

@@ -1295,7 +1712,7 @@

Classes
Return type
-

List[str]

+

str

@@ -1306,12 +1723,16 @@

Classes
Parameters
-

dir (Optional[str]) – directory path

+

dir (Optional[str]) – directory path

Return type
-

None

+

None

+
+

See also

+

cmdstanpy.from_csv

+
@@ -1328,7 +1749,7 @@

Classes
-property cmds: List[str]
+property cmds: List[List[str]]

List of call(s) to CmdStan, one call per-chain.

@@ -1381,24 +1802,24 @@

Classes

Functions

-

cmdstan_path

+

cmdstan_path

cmdstanpy.cmdstan_path()[source]

Validate, then return CmdStan directory path.

Return type
-

str

+

str

-
-

install_cmstan

+
+

install_cmdstan

-cmdstanpy.install_cmdstan(version=None, dir=None, overwrite=False, verbose=False)[source]
+cmdstanpy.install_cmdstan(version=None, dir=None, overwrite=False, verbose=False, compiler=False)[source]

Download and install a CmdStan release from GitHub by running script install_cmdstan as a subprocess. Downloads the release tar.gz file to temporary storage. Retries GitHub requests in order @@ -1407,57 +1828,118 @@

Functions
Parameters
    -
  • version (Optional[str]) – CmdStan version string, e.g. “2.24.1”. +

  • version (Optional[str]) – CmdStan version string, e.g. “2.24.1”. Defaults to latest CmdStan release.

  • -
  • dir (Optional[str]) – Path to install directory. Defaults to hidden directory -$HOME/.cmdstan or $HOME/.cmdstanpy, if the latter exists. -If no directory is specified and neither of the above directories +

  • dir (Optional[str]) – Path to install directory. Defaults to hidden directory +$HOME/.cmdstan. +If no directory is specified and the above directory does not exist, directory $HOME/.cmdstan will be created and populated.

  • -
  • overwrite (bool) – Boolean value; when True, will overwrite and +

  • overwrite (bool) – Boolean value; when True, will overwrite and rebuild an existing CmdStan installation. Default is False.

  • -
  • verbose (bool) – Boolean value; when True, output from CmdStan build +

  • verbose (bool) – Boolean value; when True, output from CmdStan build processes will be streamed to the console. Default is False.

  • +
  • compiler (bool) – Boolean value; when True on WINDOWS ONLY, use the +C++ compiler from the install_cxx_toolchain command or install +one if none is found.

Returns

Boolean value; True for success.

Return type
-

bool

+

bool

-

set_cmdstan_path

+

set_cmdstan_path

cmdstanpy.set_cmdstan_path(path)[source]

Validate, then set CmdStan directory path.

Parameters
-

path (str) –

+

path (str) –

Return type
-

None

+

None

-

set_make_env

+

set_make_env

cmdstanpy.set_make_env(make)[source]

set MAKE environmental variable.

Parameters
-

make (str) –

+

make (str) –

+
+
Return type
+

None

+
+
+
+ +
+
+

from_csv

+
+
+cmdstanpy.from_csv(path=None, method=None)[source]
+

Instantiate a CmdStan object from a the Stan CSV files from a CmdStan run. +CSV files are specified from either a list of Stan CSV files or a single +filepath which can be either a directory name, a Stan CSV filename, or +a pathname pattern (i.e., a Python glob). The optional argument ‘method’ +checks that the CSV files were produced by that method. +Stan CSV files from CmdStan methods ‘sample’, ‘optimize’, and ‘variational’ +result in objects of class CmdStanMCMC, CmdStanMLE, and CmdStanVB, +respectively.

+
+
Parameters
+
    +
  • path (Optional[Union[str, List[str]]]) – directory path

  • +
  • method (Optional[str]) – method name (optional)

  • +
+
+
Returns
+

either a CmdStanMCMC, CmdStanMLE, or CmdStanVB object

+
+
Return type
+

Optional[Union[cmdstanpy.stanfit.CmdStanMCMC, cmdstanpy.stanfit.CmdStanMLE, cmdstanpy.stanfit.CmdStanVB]]

+
+
+
+ +
+
+

write_stan_json

+
+
+cmdstanpy.write_stan_json(path, data)[source]
+

Dump a mapping of strings to data to a JSON file.

+

Values can be any numeric type, a boolean (converted to int), +or any collection compatible with numpy.asarray(), e.g a +pandas.Series.

+

Produces a file compatible with the +Json Format for Cmdstan

+
+
Parameters
+
    +
  • path (str) – File path for the created json. Will be overwritten if +already in existence.

  • +
  • data (Mapping[str, Any]) – A mapping from strings to values. This can be a dictionary +or something more exotic like an xarray.Dataset. This will be +copied before type conversion, not modified

  • +
Return type
-

None

+

None

@@ -1467,50 +1949,39 @@

Functions - -

+
+ + + + +

+ -
-

- © Copyright 2021, Stan Development Team. +

+
+ + -

-
- - +
+
- Built with Sphinx using a + - theme + - provided by Read the Docs. - -
-
-
- - -
- - - - - - - - - - + + \ No newline at end of file diff --git a/docs/genindex.html b/docs/genindex.html index 1d8adebd..319a6d1f 100644 --- a/docs/genindex.html +++ b/docs/genindex.html @@ -1,173 +1,169 @@ - - - - - - - - Index — CmdStanPy 0.9.76 documentation - - - - - - - - - - - - - - + + + + + Index — CmdStanPy 0.9.77 documentation + + + - - - - - - - - + + + + - + + + + + + + + + + + + + + - - - - + - -
+ + - + -
+ + +