From 1ca8d4fdf5835d78462ddd95eafd7564980ee6d2 Mon Sep 17 00:00:00 2001 From: Brady Planden Date: Fri, 27 Oct 2023 09:56:00 +0100 Subject: [PATCH 01/22] Add Initial Sphinx Docs --- docs/Makefile | 20 ++++++++++++++++++++ docs/make.bat | 35 +++++++++++++++++++++++++++++++++++ docs/source/conf.py | 28 ++++++++++++++++++++++++++++ docs/source/index.rst | 20 ++++++++++++++++++++ 4 files changed, 103 insertions(+) create mode 100644 docs/Makefile create mode 100644 docs/make.bat create mode 100644 docs/source/conf.py create mode 100644 docs/source/index.rst diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 00000000..d0c3cbf1 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 00000000..747ffb7b --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 00000000..b5be5c25 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,28 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = 'PyBOP' +copyright = '2023, Brady Planden, Nicola Courtier, David Howey' +author = 'Brady Planden, Nicola Courtier, David Howey' +release = '23.9' + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [] + +templates_path = ['_templates'] +exclude_patterns = [] + + + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = 'alabaster' +html_static_path = ['_static'] diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 00000000..d84fc8c6 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,20 @@ +.. PyBOP documentation master file, created by + sphinx-quickstart on Fri Oct 27 09:54:56 2023. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to PyBOP's documentation! +================================= + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` From 7f887af0fcb27ecebc8f9c4d10d0bb30ceaac751 Mon Sep 17 00:00:00 2001 From: Brady Planden Date: Fri, 8 Dec 2023 11:00:47 +0000 Subject: [PATCH 02/22] doc dependancies --- docs/Makefile | 4 +- docs/_extension/gallery_directive.py | 145 +++ docs/api/index.rst | 11 + docs/api/pybop/_problem/index.rst | 85 ++ docs/api/pybop/costs/error_costs/index.rst | 72 ++ docs/api/pybop/costs/index.rst | 14 + docs/api/pybop/costs/standalone/index.rst | 31 + .../api/pybop/datasets/base_dataset/index.rst | 30 + docs/api/pybop/datasets/index.rst | 13 + docs/api/pybop/index.rst | 868 ++++++++++++++++++ docs/api/pybop/models/base_model/index.rst | 83 ++ docs/api/pybop/models/index.rst | 22 + .../models/lithium_ion/base_echem/index.rst | 35 + docs/api/pybop/models/lithium_ion/index.rst | 44 + docs/api/pybop/optimisation/index.rst | 120 +++ .../pybop/optimisers/base_optimiser/index.rst | 39 + docs/api/pybop/optimisers/index.rst | 16 + .../pybop/optimisers/nlopt_optimize/index.rst | 46 + .../optimisers/pints_optimisers/index.rst | 86 ++ .../pybop/optimisers/scipy_minimize/index.rst | 46 + .../pybop/parameters/base_parameter/index.rst | 41 + .../parameters/base_parameter_set/index.rst | 23 + docs/api/pybop/parameters/index.rst | 15 + docs/api/pybop/parameters/priors/index.rst | 78 ++ docs/api/pybop/plotting/index.rst | 17 + .../pybop/plotting/plot_convergence/index.rst | 38 + docs/api/pybop/plotting/plot_cost2d/index.rst | 32 + .../pybop/plotting/plot_parameters/index.rst | 89 ++ .../pybop/plotting/plotly_manager/index.rst | 87 ++ docs/api/pybop/plotting/quick_plot/index.rst | 137 +++ docs/api/pybop/version/index.rst | 11 + docs/conf.py | 78 ++ docs/contributing.md | 2 + docs/index.md | 35 + docs/make.bat | 4 +- docs/source/conf.py | 28 - docs/source/index.rst | 20 - docs/source/modules.rst | 7 + docs/source/pybop.costs.rst | 29 + docs/source/pybop.datasets.rst | 21 + docs/source/pybop.optimisers.rst | 45 + docs/source/pybop.parameters.rst | 37 + docs/source/pybop.plotting.rst | 53 ++ docs/source/pybop.rst | 42 + pybop/plotting/plot_parameters.py | 16 +- pybop/plotting/plotly_manager.py | 12 +- 46 files changed, 2741 insertions(+), 66 deletions(-) create mode 100644 docs/_extension/gallery_directive.py create mode 100644 docs/api/index.rst create mode 100644 docs/api/pybop/_problem/index.rst create mode 100644 docs/api/pybop/costs/error_costs/index.rst create mode 100644 docs/api/pybop/costs/index.rst create mode 100644 docs/api/pybop/costs/standalone/index.rst create mode 100644 docs/api/pybop/datasets/base_dataset/index.rst create mode 100644 docs/api/pybop/datasets/index.rst create mode 100644 docs/api/pybop/index.rst create mode 100644 docs/api/pybop/models/base_model/index.rst create mode 100644 docs/api/pybop/models/index.rst create mode 100644 docs/api/pybop/models/lithium_ion/base_echem/index.rst create mode 100644 docs/api/pybop/models/lithium_ion/index.rst create mode 100644 docs/api/pybop/optimisation/index.rst create mode 100644 docs/api/pybop/optimisers/base_optimiser/index.rst create mode 100644 docs/api/pybop/optimisers/index.rst create mode 100644 docs/api/pybop/optimisers/nlopt_optimize/index.rst create mode 100644 docs/api/pybop/optimisers/pints_optimisers/index.rst create mode 100644 docs/api/pybop/optimisers/scipy_minimize/index.rst create mode 100644 docs/api/pybop/parameters/base_parameter/index.rst create mode 100644 docs/api/pybop/parameters/base_parameter_set/index.rst create mode 100644 docs/api/pybop/parameters/index.rst create mode 100644 docs/api/pybop/parameters/priors/index.rst create mode 100644 docs/api/pybop/plotting/index.rst create mode 100644 docs/api/pybop/plotting/plot_convergence/index.rst create mode 100644 docs/api/pybop/plotting/plot_cost2d/index.rst create mode 100644 docs/api/pybop/plotting/plot_parameters/index.rst create mode 100644 docs/api/pybop/plotting/plotly_manager/index.rst create mode 100644 docs/api/pybop/plotting/quick_plot/index.rst create mode 100644 docs/api/pybop/version/index.rst create mode 100644 docs/conf.py create mode 100644 docs/contributing.md create mode 100644 docs/index.md delete mode 100644 docs/source/conf.py delete mode 100644 docs/source/index.rst create mode 100644 docs/source/modules.rst create mode 100644 docs/source/pybop.costs.rst create mode 100644 docs/source/pybop.datasets.rst create mode 100644 docs/source/pybop.optimisers.rst create mode 100644 docs/source/pybop.parameters.rst create mode 100644 docs/source/pybop.plotting.rst create mode 100644 docs/source/pybop.rst diff --git a/docs/Makefile b/docs/Makefile index d0c3cbf1..d4bb2cbb 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -5,8 +5,8 @@ # from the environment for the first two. SPHINXOPTS ?= SPHINXBUILD ?= sphinx-build -SOURCEDIR = source -BUILDDIR = build +SOURCEDIR = . +BUILDDIR = _build # Put it first so that "make" without argument is like "make help". help: diff --git a/docs/_extension/gallery_directive.py b/docs/_extension/gallery_directive.py new file mode 100644 index 00000000..4dcc2c63 --- /dev/null +++ b/docs/_extension/gallery_directive.py @@ -0,0 +1,145 @@ +"""A directive to generate a gallery of images from structured data. + +Generating a gallery of images that are all the same size is a common +pattern in documentation, and this can be cumbersome if the gallery is +generated programmatically. This directive wraps this particular use-case +in a helper-directive to generate it with a single YAML configuration file. + +It currently exists for maintainers of the pydata-sphinx-theme, +but might be abstracted into a standalone package if it proves useful. + +Credit: PyData Sphinx Theme +""" +from pathlib import Path +from typing import Any, Dict, List + +from docutils import nodes +from docutils.parsers.rst import directives +from sphinx.application import Sphinx +from sphinx.util import logging +from sphinx.util.docutils import SphinxDirective +from yaml import safe_load + +logger = logging.getLogger(__name__) + + +TEMPLATE_GRID = """ +`````{{grid}} {columns} +{options} + +{content} + +````` +""" + +GRID_CARD = """ +````{{grid-item-card}} {title} +{options} + +{content} +```` +""" + + +class GalleryGridDirective(SphinxDirective): + """A directive to show a gallery of images and links in a Bootstrap grid. + + The grid can be generated from a YAML file that contains a list of items, or + from the content of the directive (also formatted in YAML). Use the parameter + "class-card" to add an additional CSS class to all cards. When specifying the grid + items, you can use all parameters from "grid-item-card" directive to customize + individual cards + ["image", "header", "content", "title"]. + + Danger: + This directive can only be used in the context of a Myst documentation page as + the templates use Markdown flavored formatting. + """ + + name = "gallery-grid" + has_content = True + required_arguments = 0 + optional_arguments = 1 + final_argument_whitespace = True + option_spec = { + # A class to be added to the resulting container + "grid-columns": directives.unchanged, + "class-container": directives.unchanged, + "class-card": directives.unchanged, + } + + def run(self) -> List[nodes.Node]: + """Create the gallery grid.""" + if self.arguments: + # If an argument is given, assume it's a path to a YAML file + # Parse it and load it into the directive content + path_data_rel = Path(self.arguments[0]) + path_doc, _ = self.get_source_info() + path_doc = Path(path_doc).parent + path_data = (path_doc / path_data_rel).resolve() + if not path_data.exists(): + logger.info(f"Could not find grid data at {path_data}.") + nodes.text("No grid data found at {path_data}.") + return + yaml_string = path_data.read_text() + else: + yaml_string = "\n".join(self.content) + + # Use all the element with an img-bottom key as sites to show + # and generate a card item for each of them + grid_items = [] + for item in safe_load(yaml_string): + # remove parameters that are not needed for the card options + title = item.pop("title", "") + + # build the content of the card using some extra parameters + header = f"{item.pop('header')} \n^^^ \n" if "header" in item else "" + image = f"![image]({item.pop('image')}) \n" if "image" in item else "" + content = f"{item.pop('content')} \n" if "content" in item else "" + + # optional parameter that influence all cards + if "class-card" in self.options: + item["class-card"] = self.options["class-card"] + + loc_options_str = "\n".join(f":{k}: {v}" for k, v in item.items()) + " \n" + + card = GRID_CARD.format( + options=loc_options_str, content=header + image + content, title=title + ) + grid_items.append(card) + + # Parse the template with Sphinx Design to create an output container + # Prep the options for the template grid + class_ = "gallery-directive" + f' {self.options.get("class-container", "")}' + options = {"gutter": 2, "class-container": class_} + options_str = "\n".join(f":{k}: {v}" for k, v in options.items()) + + # Create the directive string for the grid + grid_directive = TEMPLATE_GRID.format( + columns=self.options.get("grid-columns", "1 2 3 4"), + options=options_str, + content="\n".join(grid_items), + ) + + # Parse content as a directive so Sphinx Design processes it + container = nodes.container() + self.state.nested_parse([grid_directive], 0, container) + + # Sphinx Design outputs a container too, so just use that + return [container.children[0]] + + +def setup(app: Sphinx) -> Dict[str, Any]: + """Add custom configuration to sphinx app. + + Args: + app: the Sphinx application + + Returns: + the 2 parallel parameters set to ``True``. + """ + app.add_directive("gallery-grid", GalleryGridDirective) + + return { + "parallel_read_safe": True, + "parallel_write_safe": True, + } diff --git a/docs/api/index.rst b/docs/api/index.rst new file mode 100644 index 00000000..52c74ac8 --- /dev/null +++ b/docs/api/index.rst @@ -0,0 +1,11 @@ +API Reference +============= + +This page contains auto-generated API reference documentation [#f1]_. + +.. toctree:: + :titlesonly: + + /api/pybop/index + +.. [#f1] Created with `sphinx-autoapi `_ diff --git a/docs/api/pybop/_problem/index.rst b/docs/api/pybop/_problem/index.rst new file mode 100644 index 00000000..a51adad8 --- /dev/null +++ b/docs/api/pybop/_problem/index.rst @@ -0,0 +1,85 @@ +:py:mod:`pybop._problem` +======================== + +.. py:module:: pybop._problem + + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. autoapisummary:: + + pybop._problem.BaseProblem + pybop._problem.DesignProblem + pybop._problem.FittingProblem + + + + +.. py:class:: BaseProblem(parameters, model=None, check_model=True, init_soc=None, x0=None) + + + Defines the PyBOP base problem, following the PINTS interface. + + .. py:method:: evaluate(parameters) + :abstractmethod: + + Evaluate the model with the given parameters and return the signal. + + + .. py:method:: evaluateS1(parameters) + :abstractmethod: + + Evaluate the model with the given parameters and return the signal and + its derivatives. + + + +.. py:class:: DesignProblem(model, parameters, experiment, check_model=True, init_soc=None, x0=None) + + + Bases: :py:obj:`BaseProblem` + + Defines the problem class for a design optimiation problem. + + .. py:method:: evaluate(parameters) + + Evaluate the model with the given parameters and return the signal. + + + .. py:method:: evaluateS1(parameters) + + Evaluate the model with the given parameters and return the signal and + its derivatives. + + + .. py:method:: target() + + Returns the target dataset. + + + +.. py:class:: FittingProblem(model, parameters, dataset, signal='Terminal voltage [V]', check_model=True, init_soc=None, x0=None) + + + Bases: :py:obj:`BaseProblem` + + Defines the problem class for a fitting (parameter estimation) problem. + + .. py:method:: evaluate(parameters) + + Evaluate the model with the given parameters and return the signal. + + + .. py:method:: evaluateS1(parameters) + + Evaluate the model with the given parameters and return the signal and + its derivatives. + + + .. py:method:: target() + + Returns the target dataset. diff --git a/docs/api/pybop/costs/error_costs/index.rst b/docs/api/pybop/costs/error_costs/index.rst new file mode 100644 index 00000000..70f18e02 --- /dev/null +++ b/docs/api/pybop/costs/error_costs/index.rst @@ -0,0 +1,72 @@ +:py:mod:`pybop.costs.error_costs` +================================= + +.. py:module:: pybop.costs.error_costs + + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. autoapisummary:: + + pybop.costs.error_costs.BaseCost + pybop.costs.error_costs.RootMeanSquaredError + pybop.costs.error_costs.SumSquaredError + + + + +.. py:class:: BaseCost(problem) + + + Base class for defining cost functions. + This class computes a corresponding goodness-of-fit for a corresponding model prediction and dataset. + Lower cost values indicate a better fit. + + .. py:method:: __call__(x, grad=None) + :abstractmethod: + + Returns the cost function value and computes the cost. + + + +.. py:class:: RootMeanSquaredError(problem) + + + Bases: :py:obj:`BaseCost` + + Defines the root mean square error cost function. + + .. py:method:: __call__(x, grad=None) + + Computes the cost. + + + +.. py:class:: SumSquaredError(problem) + + + Bases: :py:obj:`BaseCost` + + Defines the sum squared error cost function. + + The initial fail gradient is set equal to one, but this can be + changed at any time with :meth:`set_fail_gradient()`. + + .. py:method:: __call__(x, grad=None) + + Computes the cost. + + + .. py:method:: evaluateS1(x) + + Compute the cost and corresponding + gradients with respect to the parameters. + + + .. py:method:: set_fail_gradient(de) + + Sets the fail gradient for this optimiser. diff --git a/docs/api/pybop/costs/index.rst b/docs/api/pybop/costs/index.rst new file mode 100644 index 00000000..837718ef --- /dev/null +++ b/docs/api/pybop/costs/index.rst @@ -0,0 +1,14 @@ +:py:mod:`pybop.costs` +===================== + +.. py:module:: pybop.costs + + +Submodules +---------- +.. toctree:: + :titlesonly: + :maxdepth: 1 + + error_costs/index.rst + standalone/index.rst diff --git a/docs/api/pybop/costs/standalone/index.rst b/docs/api/pybop/costs/standalone/index.rst new file mode 100644 index 00000000..3d0957b4 --- /dev/null +++ b/docs/api/pybop/costs/standalone/index.rst @@ -0,0 +1,31 @@ +:py:mod:`pybop.costs.standalone` +================================ + +.. py:module:: pybop.costs.standalone + + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. autoapisummary:: + + pybop.costs.standalone.StandaloneCost + + + + +.. py:class:: StandaloneCost(problem=None) + + + Bases: :py:obj:`pybop.BaseCost` + + Base class for defining cost functions. + This class computes a corresponding goodness-of-fit for a corresponding model prediction and dataset. + Lower cost values indicate a better fit. + + .. py:method:: __call__(x, grad=None) + + Returns the cost function value and computes the cost. diff --git a/docs/api/pybop/datasets/base_dataset/index.rst b/docs/api/pybop/datasets/base_dataset/index.rst new file mode 100644 index 00000000..9d6e1fe0 --- /dev/null +++ b/docs/api/pybop/datasets/base_dataset/index.rst @@ -0,0 +1,30 @@ +:py:mod:`pybop.datasets.base_dataset` +===================================== + +.. py:module:: pybop.datasets.base_dataset + + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. autoapisummary:: + + pybop.datasets.base_dataset.Dataset + + + + +.. py:class:: Dataset(name, data) + + + Class for experimental observations. + + .. py:method:: Interpolant() + + + .. py:method:: __repr__() + + Return repr(self). diff --git a/docs/api/pybop/datasets/index.rst b/docs/api/pybop/datasets/index.rst new file mode 100644 index 00000000..0d868a1c --- /dev/null +++ b/docs/api/pybop/datasets/index.rst @@ -0,0 +1,13 @@ +:py:mod:`pybop.datasets` +======================== + +.. py:module:: pybop.datasets + + +Submodules +---------- +.. toctree:: + :titlesonly: + :maxdepth: 1 + + base_dataset/index.rst diff --git a/docs/api/pybop/index.rst b/docs/api/pybop/index.rst new file mode 100644 index 00000000..7b0272b1 --- /dev/null +++ b/docs/api/pybop/index.rst @@ -0,0 +1,868 @@ +:py:mod:`pybop` +=============== + +.. py:module:: pybop + + +Subpackages +----------- +.. toctree:: + :titlesonly: + :maxdepth: 3 + + costs/index.rst + datasets/index.rst + models/index.rst + optimisers/index.rst + parameters/index.rst + plotting/index.rst + + +Submodules +---------- +.. toctree:: + :titlesonly: + :maxdepth: 1 + + _problem/index.rst + optimisation/index.rst + version/index.rst + + +Package Contents +---------------- + +Classes +~~~~~~~ + +.. autoapisummary:: + + pybop.Adam + pybop.BaseCost + pybop.BaseModel + pybop.BaseOptimiser + pybop.CMAES + pybop.Dataset + pybop.DesignProblem + pybop.Exponential + pybop.FittingProblem + pybop.Gaussian + pybop.GradientDescent + pybop.IRPropMin + pybop.NLoptOptimize + pybop.Optimisation + pybop.PSO + pybop.Parameter + pybop.ParameterSet + pybop.PlotlyManager + pybop.RootMeanSquaredError + pybop.SNES + pybop.SciPyMinimize + pybop.StandardPlot + pybop.SumSquaredError + pybop.Uniform + pybop.XNES + + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + pybop.plot_convergence + pybop.plot_cost2d + pybop.plot_parameters + pybop.quick_plot + + + +Attributes +~~~~~~~~~~ + +.. autoapisummary:: + + pybop.FLOAT_FORMAT + pybop.__version__ + pybop.script_path + + +.. py:class:: Adam(x0, sigma0=0.1, bounds=None) + + + Bases: :py:obj:`pints.Adam` + + Adam optimiser. Inherits from the PINTS Adam class. + https://github.com/pints-team/pints/blob/main/pints/_optimisers/_adam.py + + +.. py:class:: BaseCost(problem) + + + Base class for defining cost functions. + This class computes a corresponding goodness-of-fit for a corresponding model prediction and dataset. + Lower cost values indicate a better fit. + + .. py:method:: __call__(x, grad=None) + :abstractmethod: + + Returns the cost function value and computes the cost. + + + +.. py:class:: BaseModel(name='Base Model') + + + Base class for pybop models. + + .. py:property:: built_model + + + .. py:property:: geometry + + + .. py:property:: mesh + + + .. py:property:: model_with_set_params + + + .. py:property:: parameter_set + + + .. py:property:: solver + + + .. py:property:: spatial_methods + + + .. py:property:: submesh_types + + + .. py:property:: var_pts + + + .. py:method:: build(dataset=None, parameters=None, check_model=True, init_soc=None) + + Build the PyBOP model (if not built already). + For PyBaMM forward models, this method follows a + similar process to pybamm.Simulation.build(). + + + .. py:method:: predict(inputs=None, t_eval=None, parameter_set=None, experiment=None, init_soc=None) + + Create a PyBaMM simulation object, solve it, and return a solution object. + + + .. py:method:: set_init_soc(init_soc) + + Set the initial state of charge. + + + .. py:method:: set_params() + + Set the parameters in the model. + + + .. py:method:: simulate(inputs, t_eval) + + Run the forward model and return the result in Numpy array format + aligning with Pints' ForwardModel simulate method. + + + .. py:method:: simulateS1(inputs, t_eval) + + Run the forward model and return the function evaulation and it's gradient + aligning with Pints' ForwardModel simulateS1 method. + + + +.. py:class:: BaseOptimiser + + + Base class for the optimisation methods. + + + .. py:method:: _runoptimise(cost_function, x0=None, bounds=None) + + Run optimisation method, to be overloaded by child classes. + + + + .. py:method:: name() + + Returns the name of the optimiser. + + + .. py:method:: optimise(cost_function, x0=None, bounds=None) + + Optimisiation method to be overloaded by child classes. + + + + +.. py:class:: CMAES(x0, sigma0=0.1, bounds=None) + + + Bases: :py:obj:`pints.CMAES` + + Class for the PINTS optimisation. Extends the BaseOptimiser class. + https://github.com/pints-team/pints/blob/main/pints/_optimisers/_cmaes.py + + +.. py:class:: Dataset(name, data) + + + Class for experimental observations. + + .. py:method:: Interpolant() + + + .. py:method:: __repr__() + + Return repr(self). + + + +.. py:class:: DesignProblem(model, parameters, experiment, check_model=True, init_soc=None, x0=None) + + + Bases: :py:obj:`BaseProblem` + + Defines the problem class for a design optimiation problem. + + .. py:method:: evaluate(parameters) + + Evaluate the model with the given parameters and return the signal. + + + .. py:method:: evaluateS1(parameters) + + Evaluate the model with the given parameters and return the signal and + its derivatives. + + + .. py:method:: target() + + Returns the target dataset. + + + +.. py:class:: Exponential(scale) + + + Exponential prior class. + + .. py:method:: __repr__() + + Return repr(self). + + + .. py:method:: logpdf(x) + + + .. py:method:: pdf(x) + + + .. py:method:: rvs(size) + + + +.. py:class:: FittingProblem(model, parameters, dataset, signal='Terminal voltage [V]', check_model=True, init_soc=None, x0=None) + + + Bases: :py:obj:`BaseProblem` + + Defines the problem class for a fitting (parameter estimation) problem. + + .. py:method:: evaluate(parameters) + + Evaluate the model with the given parameters and return the signal. + + + .. py:method:: evaluateS1(parameters) + + Evaluate the model with the given parameters and return the signal and + its derivatives. + + + .. py:method:: target() + + Returns the target dataset. + + + +.. py:class:: Gaussian(mean, sigma) + + + Gaussian prior class. + + .. py:method:: __repr__() + + Return repr(self). + + + .. py:method:: logpdf(x) + + + .. py:method:: pdf(x) + + + .. py:method:: rvs(size) + + + +.. py:class:: GradientDescent(x0, sigma0=0.1, bounds=None) + + + Bases: :py:obj:`pints.GradientDescent` + + Gradient descent optimiser. Inherits from the PINTS gradient descent class. + https://github.com/pints-team/pints/blob/main/pints/_optimisers/_gradient_descent.py + + +.. py:class:: IRPropMin(x0, sigma0=0.1, bounds=None) + + + Bases: :py:obj:`pints.IRPropMin` + + IRProp- optimiser. Inherits from the PINTS IRPropMinus class. + https://github.com/pints-team/pints/blob/main/pints/_optimisers/_irpropmin.py + + +.. py:class:: NLoptOptimize(n_param, xtol=None, method=None) + + + Bases: :py:obj:`pybop.optimisers.base_optimiser.BaseOptimiser` + + Wrapper class for the NLOpt optimiser class. Extends the BaseOptimiser class. + + .. py:method:: _runoptimise(cost_function, x0, bounds) + + Run the NLOpt optimisation method. + + Inputs + ---------- + cost_function: function for optimising + method: optimisation algorithm + x0: initialisation array + bounds: bounds array + + + .. py:method:: name() + + Returns the name of the optimiser. + + + .. py:method:: needs_sensitivities() + + Returns True if the optimiser needs sensitivities. + + + +.. py:class:: Optimisation(cost, optimiser=None, sigma0=None, verbose=False) + + + Optimisation class for PyBOP. + This class provides functionality for PyBOP optimisers and Pints optimisers. + :param cost: PyBOP cost function + :param optimiser: A PyBOP or Pints optimiser + :param sigma0: initial step size + :param verbose: print optimisation progress + + .. py:method:: _run_pints() + + Run method for PINTS optimisers. + This method is heavily based on the run method in the PINTS.OptimisationController class. + :returns: best parameters + final_cost: final cost + :rtype: x + + + .. py:method:: _run_pybop() + + Run method for PyBOP based optimisers. + :returns: best parameters + final_cost: final cost + :rtype: x + + + .. py:method:: f_guessed_tracking() + + Returns ``True`` if f_guessed instead of f_best is being tracked, + ``False`` otherwise. See also :meth:`set_f_guessed_tracking`. + + Credit: PINTS + + + .. py:method:: run() + + Run the optimisation algorithm. + Selects between PyBOP backend or Pints backend. + :returns: best parameters + final_cost: final cost + :rtype: x + + + .. py:method:: set_f_guessed_tracking(use_f_guessed=False) + + Sets the method used to track the optimiser progress to + :meth:`pints.Optimiser.f_guessed()` or + :meth:`pints.Optimiser.f_best()` (default). + + The tracked ``f`` value is used to evaluate stopping criteria. + + Credit: PINTS + + + .. py:method:: set_max_evaluations(evaluations=None) + + Adds a stopping criterion, allowing the routine to halt after the + given number of ``evaluations``. + + This criterion is disabled by default. To enable, pass in any positive + integer. To disable again, use ``set_max_evaluations(None)``. + + Credit: PINTS + + + .. py:method:: set_max_iterations(iterations=1000) + + Adds a stopping criterion, allowing the routine to halt after the + given number of ``iterations``. + + This criterion is enabled by default. To disable it, use + ``set_max_iterations(None)``. + + Credit: PINTS + + + .. py:method:: set_max_unchanged_iterations(iterations=25, threshold=1e-05) + + Adds a stopping criterion, allowing the routine to halt if the + objective function doesn't change by more than ``threshold`` for the + given number of ``iterations``. + + This criterion is enabled by default. To disable it, use + ``set_max_unchanged_iterations(None)``. + + Credit: PINTS + + + .. py:method:: set_parallel(parallel=False) + + Enables/disables parallel evaluation. + + If ``parallel=True``, the method will run using a number of worker + processes equal to the detected cpu core count. The number of workers + can be set explicitly by setting ``parallel`` to an integer greater + than 0. + Parallelisation can be disabled by setting ``parallel`` to ``0`` or + ``False``. + + Credit: PINTS + + + +.. py:class:: PSO(x0, sigma0=0.1, bounds=None) + + + Bases: :py:obj:`pints.PSO` + + Particle swarm optimiser. Inherits from the PINTS PSO class. + https://github.com/pints-team/pints/blob/main/pints/_optimisers/_pso.py + + +.. py:class:: Parameter(name, value=None, prior=None, bounds=None) + + + "" + Class for creating parameters in PyBOP. + + .. py:method:: __repr__() + + Return repr(self). + + + .. py:method:: rvs(n_samples) + + Returns a random value sample from the prior distribution. + + + .. py:method:: set_margin(margin) + + Sets the margin for the parameter. + + + .. py:method:: update(value) + + + +.. py:class:: ParameterSet + + + Class for creating parameter sets in PyBOP. + + +.. py:class:: PlotlyManager + + + Manages the installation and configuration of Plotly for generating visualisations. + + This class checks if Plotly is installed and, if not, prompts the user to install it. + It also ensures that the Plotly renderer and browser settings are properly configured + to display plots. + + .. method:: ``ensure_plotly_installed`` + + Verifies if Plotly is installed and installs it if necessary. + + .. method:: ``prompt_for_plotly_installation`` + + Prompts the user for permission to install Plotly. + + .. method:: ``install_plotly_package`` + + Installs the Plotly package using pip. + + .. method:: ``post_install_setup`` + + Sets up Plotly default renderer after installation. + + .. method:: ``check_renderer_settings`` + + Verifies that the Plotly renderer is correctly set. + + .. method:: ``check_browser_availability`` + + Checks if a web browser is available for rendering plots. + + + Usage: + Instantiate the PlotlyManager class to automatically ensure Plotly is installed + and configured correctly when creating an instance. + Example: + plotly_manager = PlotlyManager() + + .. py:method:: check_browser_availability() + + Ensures a web browser is available for rendering plots with the 'browser' renderer and provides guidance if not. + + + .. py:method:: check_renderer_settings() + + Checks if the Plotly renderer is set and provides information on how to set it if empty. + + + .. py:method:: ensure_plotly_installed() + + Verifies if Plotly is installed, importing necessary modules and prompting for installation if missing. + + + .. py:method:: install_plotly() + + Attempts to install the Plotly package using pip and exits if installation fails. + + + .. py:method:: post_install_setup() + + After successful installation, imports Plotly and sets the default renderer if necessary. + + + .. py:method:: prompt_for_plotly_installation() + + Prompts the user for permission to install Plotly and proceeds with installation if consented. + + + +.. py:class:: RootMeanSquaredError(problem) + + + Bases: :py:obj:`BaseCost` + + Defines the root mean square error cost function. + + .. py:method:: __call__(x, grad=None) + + Computes the cost. + + + +.. py:class:: SNES(x0, sigma0=0.1, bounds=None) + + + Bases: :py:obj:`pints.SNES` + + Stochastic natural evolution strategy optimiser. Inherits from the PINTS SNES class. + https://github.com/pints-team/pints/blob/main/pints/_optimisers/_snes.py + + +.. py:class:: SciPyMinimize(method=None, bounds=None) + + + Bases: :py:obj:`pybop.optimisers.base_optimiser.BaseOptimiser` + + Wrapper class for the SciPy optimisation class. Extends the BaseOptimiser class. + + .. py:method:: _runoptimise(cost_function, x0, bounds) + + Run the SciPy optimisation method. + + Inputs + ---------- + cost_function: function for optimising + method: optimisation algorithm + x0: initialisation array + bounds: bounds array + + + .. py:method:: name() + + Returns the name of the optimiser. + + + .. py:method:: needs_sensitivities() + + Returns True if the optimiser needs sensitivities. + + + +.. py:class:: StandardPlot(x, y, cost, y2=None, title=None, xaxis_title=None, yaxis_title=None, trace_name=None, width=1024, height=576) + + + A class for creating and displaying a plotly figure that compares a target dataset against a simulated model output. + + This class provides an interface for generating interactive plots using Plotly, with the ability to include an + optional secondary dataset and visualize uncertainty if provided. + + Attributes: + ----------- + x : list + The x-axis data points. + y : list or np.ndarray + The primary y-axis data points representing the simulated model output. + y2 : list or np.ndarray, optional + An optional secondary y-axis data points representing the target dataset against which the model output is compared. + cost : float + The cost associated with the model output. + title : str, optional + The title of the plot. + xaxis_title : str, optional + The title for the x-axis. + yaxis_title : str, optional + The title for the y-axis. + trace_name : str, optional + The name of the primary trace representing the model output. Defaults to "Simulated". + width : int, optional + The width of the figure in pixels. Defaults to 720. + height : int, optional + The height of the figure in pixels. Defaults to 540. + + Methods: + -------- + wrap_text(text, width) + A static method that wraps text to a specified width, inserting HTML line breaks for use in plot labels. + + create_layout() + Creates the layout for the plot, including titles and axis labels. + + create_traces() + Creates the traces for the plot, including the primary dataset, optional secondary dataset, and an optional uncertainty visualization. + + __call__() + Generates the plotly figure when the class instance is called as a function. + + Example: + -------- + >>> x_data = [1, 2, 3, 4] + >>> y_simulated = [10, 15, 13, 17] + >>> y_target = [11, 14, 12, 16] + >>> plot = pybop.StandardPlot(x_data, y_simulated, cost=0.05, y2=y_target, + title="Model vs. Target", xaxis_title="X Axis", yaxis_title="Y Axis") + >>> fig = plot() # Generate the figure + >>> fig.show() # Display the figure in a browser + + .. py:method:: __call__() + + Generate the plotly figure. + + + .. py:method:: create_layout() + + Create the layout for the plot. + + + .. py:method:: create_traces() + + Create the traces for the plot. + + + .. py:method:: wrap_text(text, width) + :staticmethod: + + Wrap text to a specified width. + + Parameters: + ----------- + text: str + Text to be wrapped. + width: int + Width to wrap text to. + + Returns: + -------- + str + Wrapped text with HTML line breaks. + + + +.. py:class:: SumSquaredError(problem) + + + Bases: :py:obj:`BaseCost` + + Defines the sum squared error cost function. + + The initial fail gradient is set equal to one, but this can be + changed at any time with :meth:`set_fail_gradient()`. + + .. py:method:: __call__(x, grad=None) + + Computes the cost. + + + .. py:method:: evaluateS1(x) + + Compute the cost and corresponding + gradients with respect to the parameters. + + + .. py:method:: set_fail_gradient(de) + + Sets the fail gradient for this optimiser. + + + +.. py:class:: Uniform(lower, upper) + + + Uniform prior class. + + .. py:method:: __repr__() + + Return repr(self). + + + .. py:method:: logpdf(x) + + + .. py:method:: pdf(x) + + + .. py:method:: rvs(size) + + + +.. py:class:: XNES(x0, sigma0=0.1, bounds=None) + + + Bases: :py:obj:`pints.XNES` + + Exponential natural evolution strategy optimiser. Inherits from the PINTS XNES class. + https://github.com/pints-team/pints/blob/main/pints/_optimisers/_xnes.py + + +.. py:function:: plot_convergence(optim, xaxis_title='Iteration', yaxis_title='Cost', title='Convergence') + + Plot the convergence of the optimisation algorithm. + + Parameters: + ---------- + optim : optimisation object + Optimisation object containing the cost function and optimiser. + xaxis_title : str, optional + Title for the x-axis (default is "Iteration"). + yaxis_title : str, optional + Title for the y-axis (default is "Cost"). + title : str, optional + Title of the plot (default is "Convergence"). + + Returns: + ------- + fig : plotly.graph_objs.Figure + The Plotly figure object for the convergence plot. + + +.. py:function:: plot_cost2d(cost, bounds=None, optim=None, steps=10) + + Query the cost landscape for a given parameter space and plot using plotly. + + +.. py:function:: plot_parameters(optim, xaxis_titles='Iteration', yaxis_titles=None, title='Convergence') + + Plot the evolution of the parameters during the optimisation process. + + Parameters: + ---------- + optim : optimisation object + An object representing the optimisation process, which should contain + information about the cost function, optimiser, and the history of the + parameter values throughout the iterations. + xaxis_title : str, optional + Title for the x-axis, representing the iteration number or a similar + discrete time step in the optimisation process (default is "Iteration"). + yaxis_title : str, optional + Title for the y-axis, which typically represents the metric being + optimised, such as cost or loss (default is "Cost"). + title : str, optional + Title of the plot, which provides an overall description of what the + plot represents (default is "Convergence"). + + Returns: + ------- + fig : plotly.graph_objs.Figure + The Plotly figure object for the plot depicting how the parameters of + the optimisation algorithm evolve over its course. This can be useful + for diagnosing the behaviour of the optimisation algorithm. + + Notes: + ----- + The function assumes that the 'optim' object has a 'cost.problem.parameters' + attribute containing the parameters of the optimisation algorithm and a 'log' + attribute containing a history of the iterations. + + +.. py:function:: quick_plot(params, cost, title='Scatter Plot', width=1024, height=576) + + Plot the target dataset against the minimised model output. + + Parameters: + ---------- + params : array-like + Optimised parameters. + cost : cost object + Cost object containing the problem, dataset, and signal. + title : str, optional + Title of the plot (default is "Scatter Plot"). + width : int, optional + Width of the figure in pixels (default is 720). + height : int, optional + Height of the figure in pixels (default is 540). + + Returns: + ------- + fig : plotly.graph_objs.Figure + The Plotly figure object for the scatter plot. + + +.. py:data:: FLOAT_FORMAT + :value: '{: .17e}' + + + +.. py:data:: __version__ + :value: '23.11' + + + +.. py:data:: script_path diff --git a/docs/api/pybop/models/base_model/index.rst b/docs/api/pybop/models/base_model/index.rst new file mode 100644 index 00000000..2eee2080 --- /dev/null +++ b/docs/api/pybop/models/base_model/index.rst @@ -0,0 +1,83 @@ +:py:mod:`pybop.models.base_model` +================================= + +.. py:module:: pybop.models.base_model + + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. autoapisummary:: + + pybop.models.base_model.BaseModel + + + + +.. py:class:: BaseModel(name='Base Model') + + + Base class for pybop models. + + .. py:property:: built_model + + + .. py:property:: geometry + + + .. py:property:: mesh + + + .. py:property:: model_with_set_params + + + .. py:property:: parameter_set + + + .. py:property:: solver + + + .. py:property:: spatial_methods + + + .. py:property:: submesh_types + + + .. py:property:: var_pts + + + .. py:method:: build(dataset=None, parameters=None, check_model=True, init_soc=None) + + Build the PyBOP model (if not built already). + For PyBaMM forward models, this method follows a + similar process to pybamm.Simulation.build(). + + + .. py:method:: predict(inputs=None, t_eval=None, parameter_set=None, experiment=None, init_soc=None) + + Create a PyBaMM simulation object, solve it, and return a solution object. + + + .. py:method:: set_init_soc(init_soc) + + Set the initial state of charge. + + + .. py:method:: set_params() + + Set the parameters in the model. + + + .. py:method:: simulate(inputs, t_eval) + + Run the forward model and return the result in Numpy array format + aligning with Pints' ForwardModel simulate method. + + + .. py:method:: simulateS1(inputs, t_eval) + + Run the forward model and return the function evaulation and it's gradient + aligning with Pints' ForwardModel simulateS1 method. diff --git a/docs/api/pybop/models/index.rst b/docs/api/pybop/models/index.rst new file mode 100644 index 00000000..6b06a221 --- /dev/null +++ b/docs/api/pybop/models/index.rst @@ -0,0 +1,22 @@ +:py:mod:`pybop.models` +====================== + +.. py:module:: pybop.models + + +Subpackages +----------- +.. toctree:: + :titlesonly: + :maxdepth: 3 + + lithium_ion/index.rst + + +Submodules +---------- +.. toctree:: + :titlesonly: + :maxdepth: 1 + + base_model/index.rst diff --git a/docs/api/pybop/models/lithium_ion/base_echem/index.rst b/docs/api/pybop/models/lithium_ion/base_echem/index.rst new file mode 100644 index 00000000..7348059d --- /dev/null +++ b/docs/api/pybop/models/lithium_ion/base_echem/index.rst @@ -0,0 +1,35 @@ +:py:mod:`pybop.models.lithium_ion.base_echem` +============================================= + +.. py:module:: pybop.models.lithium_ion.base_echem + + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. autoapisummary:: + + pybop.models.lithium_ion.base_echem.SPM + pybop.models.lithium_ion.base_echem.SPMe + + + + +.. py:class:: SPM(name='Single Particle Model', parameter_set=None, geometry=None, submesh_types=None, var_pts=None, spatial_methods=None, solver=None, options=None) + + + Bases: :py:obj:`pybop.models.base_model.BaseModel` + + Composition of the PyBaMM Single Particle Model class. + + + +.. py:class:: SPMe(name='Single Particle Model with Electrolyte', parameter_set=None, geometry=None, submesh_types=None, var_pts=None, spatial_methods=None, solver=None, options=None) + + + Bases: :py:obj:`pybop.models.base_model.BaseModel` + + Composition of the PyBaMM Single Particle Model with Electrolyte class. diff --git a/docs/api/pybop/models/lithium_ion/index.rst b/docs/api/pybop/models/lithium_ion/index.rst new file mode 100644 index 00000000..dfc4c95b --- /dev/null +++ b/docs/api/pybop/models/lithium_ion/index.rst @@ -0,0 +1,44 @@ +:py:mod:`pybop.models.lithium_ion` +================================== + +.. py:module:: pybop.models.lithium_ion + + +Submodules +---------- +.. toctree:: + :titlesonly: + :maxdepth: 1 + + base_echem/index.rst + + +Package Contents +---------------- + +Classes +~~~~~~~ + +.. autoapisummary:: + + pybop.models.lithium_ion.SPM + pybop.models.lithium_ion.SPMe + + + + +.. py:class:: SPM(name='Single Particle Model', parameter_set=None, geometry=None, submesh_types=None, var_pts=None, spatial_methods=None, solver=None, options=None) + + + Bases: :py:obj:`pybop.models.base_model.BaseModel` + + Composition of the PyBaMM Single Particle Model class. + + + +.. py:class:: SPMe(name='Single Particle Model with Electrolyte', parameter_set=None, geometry=None, submesh_types=None, var_pts=None, spatial_methods=None, solver=None, options=None) + + + Bases: :py:obj:`pybop.models.base_model.BaseModel` + + Composition of the PyBaMM Single Particle Model with Electrolyte class. diff --git a/docs/api/pybop/optimisation/index.rst b/docs/api/pybop/optimisation/index.rst new file mode 100644 index 00000000..9fca5c5a --- /dev/null +++ b/docs/api/pybop/optimisation/index.rst @@ -0,0 +1,120 @@ +:py:mod:`pybop.optimisation` +============================ + +.. py:module:: pybop.optimisation + + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. autoapisummary:: + + pybop.optimisation.Optimisation + + + + +.. py:class:: Optimisation(cost, optimiser=None, sigma0=None, verbose=False) + + + Optimisation class for PyBOP. + This class provides functionality for PyBOP optimisers and Pints optimisers. + :param cost: PyBOP cost function + :param optimiser: A PyBOP or Pints optimiser + :param sigma0: initial step size + :param verbose: print optimisation progress + + .. py:method:: _run_pints() + + Run method for PINTS optimisers. + This method is heavily based on the run method in the PINTS.OptimisationController class. + :returns: best parameters + final_cost: final cost + :rtype: x + + + .. py:method:: _run_pybop() + + Run method for PyBOP based optimisers. + :returns: best parameters + final_cost: final cost + :rtype: x + + + .. py:method:: f_guessed_tracking() + + Returns ``True`` if f_guessed instead of f_best is being tracked, + ``False`` otherwise. See also :meth:`set_f_guessed_tracking`. + + Credit: PINTS + + + .. py:method:: run() + + Run the optimisation algorithm. + Selects between PyBOP backend or Pints backend. + :returns: best parameters + final_cost: final cost + :rtype: x + + + .. py:method:: set_f_guessed_tracking(use_f_guessed=False) + + Sets the method used to track the optimiser progress to + :meth:`pints.Optimiser.f_guessed()` or + :meth:`pints.Optimiser.f_best()` (default). + + The tracked ``f`` value is used to evaluate stopping criteria. + + Credit: PINTS + + + .. py:method:: set_max_evaluations(evaluations=None) + + Adds a stopping criterion, allowing the routine to halt after the + given number of ``evaluations``. + + This criterion is disabled by default. To enable, pass in any positive + integer. To disable again, use ``set_max_evaluations(None)``. + + Credit: PINTS + + + .. py:method:: set_max_iterations(iterations=1000) + + Adds a stopping criterion, allowing the routine to halt after the + given number of ``iterations``. + + This criterion is enabled by default. To disable it, use + ``set_max_iterations(None)``. + + Credit: PINTS + + + .. py:method:: set_max_unchanged_iterations(iterations=25, threshold=1e-05) + + Adds a stopping criterion, allowing the routine to halt if the + objective function doesn't change by more than ``threshold`` for the + given number of ``iterations``. + + This criterion is enabled by default. To disable it, use + ``set_max_unchanged_iterations(None)``. + + Credit: PINTS + + + .. py:method:: set_parallel(parallel=False) + + Enables/disables parallel evaluation. + + If ``parallel=True``, the method will run using a number of worker + processes equal to the detected cpu core count. The number of workers + can be set explicitly by setting ``parallel`` to an integer greater + than 0. + Parallelisation can be disabled by setting ``parallel`` to ``0`` or + ``False``. + + Credit: PINTS diff --git a/docs/api/pybop/optimisers/base_optimiser/index.rst b/docs/api/pybop/optimisers/base_optimiser/index.rst new file mode 100644 index 00000000..932d64b5 --- /dev/null +++ b/docs/api/pybop/optimisers/base_optimiser/index.rst @@ -0,0 +1,39 @@ +:py:mod:`pybop.optimisers.base_optimiser` +========================================= + +.. py:module:: pybop.optimisers.base_optimiser + + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. autoapisummary:: + + pybop.optimisers.base_optimiser.BaseOptimiser + + + + +.. py:class:: BaseOptimiser + + + Base class for the optimisation methods. + + + .. py:method:: _runoptimise(cost_function, x0=None, bounds=None) + + Run optimisation method, to be overloaded by child classes. + + + + .. py:method:: name() + + Returns the name of the optimiser. + + + .. py:method:: optimise(cost_function, x0=None, bounds=None) + + Optimisiation method to be overloaded by child classes. diff --git a/docs/api/pybop/optimisers/index.rst b/docs/api/pybop/optimisers/index.rst new file mode 100644 index 00000000..1524300b --- /dev/null +++ b/docs/api/pybop/optimisers/index.rst @@ -0,0 +1,16 @@ +:py:mod:`pybop.optimisers` +========================== + +.. py:module:: pybop.optimisers + + +Submodules +---------- +.. toctree:: + :titlesonly: + :maxdepth: 1 + + base_optimiser/index.rst + nlopt_optimize/index.rst + pints_optimisers/index.rst + scipy_minimize/index.rst diff --git a/docs/api/pybop/optimisers/nlopt_optimize/index.rst b/docs/api/pybop/optimisers/nlopt_optimize/index.rst new file mode 100644 index 00000000..b210161f --- /dev/null +++ b/docs/api/pybop/optimisers/nlopt_optimize/index.rst @@ -0,0 +1,46 @@ +:py:mod:`pybop.optimisers.nlopt_optimize` +========================================= + +.. py:module:: pybop.optimisers.nlopt_optimize + + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. autoapisummary:: + + pybop.optimisers.nlopt_optimize.NLoptOptimize + + + + +.. py:class:: NLoptOptimize(n_param, xtol=None, method=None) + + + Bases: :py:obj:`pybop.optimisers.base_optimiser.BaseOptimiser` + + Wrapper class for the NLOpt optimiser class. Extends the BaseOptimiser class. + + .. py:method:: _runoptimise(cost_function, x0, bounds) + + Run the NLOpt optimisation method. + + Inputs + ---------- + cost_function: function for optimising + method: optimisation algorithm + x0: initialisation array + bounds: bounds array + + + .. py:method:: name() + + Returns the name of the optimiser. + + + .. py:method:: needs_sensitivities() + + Returns True if the optimiser needs sensitivities. diff --git a/docs/api/pybop/optimisers/pints_optimisers/index.rst b/docs/api/pybop/optimisers/pints_optimisers/index.rst new file mode 100644 index 00000000..68226d79 --- /dev/null +++ b/docs/api/pybop/optimisers/pints_optimisers/index.rst @@ -0,0 +1,86 @@ +:py:mod:`pybop.optimisers.pints_optimisers` +=========================================== + +.. py:module:: pybop.optimisers.pints_optimisers + + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. autoapisummary:: + + pybop.optimisers.pints_optimisers.Adam + pybop.optimisers.pints_optimisers.CMAES + pybop.optimisers.pints_optimisers.GradientDescent + pybop.optimisers.pints_optimisers.IRPropMin + pybop.optimisers.pints_optimisers.PSO + pybop.optimisers.pints_optimisers.SNES + pybop.optimisers.pints_optimisers.XNES + + + + +.. py:class:: Adam(x0, sigma0=0.1, bounds=None) + + + Bases: :py:obj:`pints.Adam` + + Adam optimiser. Inherits from the PINTS Adam class. + https://github.com/pints-team/pints/blob/main/pints/_optimisers/_adam.py + + +.. py:class:: CMAES(x0, sigma0=0.1, bounds=None) + + + Bases: :py:obj:`pints.CMAES` + + Class for the PINTS optimisation. Extends the BaseOptimiser class. + https://github.com/pints-team/pints/blob/main/pints/_optimisers/_cmaes.py + + +.. py:class:: GradientDescent(x0, sigma0=0.1, bounds=None) + + + Bases: :py:obj:`pints.GradientDescent` + + Gradient descent optimiser. Inherits from the PINTS gradient descent class. + https://github.com/pints-team/pints/blob/main/pints/_optimisers/_gradient_descent.py + + +.. py:class:: IRPropMin(x0, sigma0=0.1, bounds=None) + + + Bases: :py:obj:`pints.IRPropMin` + + IRProp- optimiser. Inherits from the PINTS IRPropMinus class. + https://github.com/pints-team/pints/blob/main/pints/_optimisers/_irpropmin.py + + +.. py:class:: PSO(x0, sigma0=0.1, bounds=None) + + + Bases: :py:obj:`pints.PSO` + + Particle swarm optimiser. Inherits from the PINTS PSO class. + https://github.com/pints-team/pints/blob/main/pints/_optimisers/_pso.py + + +.. py:class:: SNES(x0, sigma0=0.1, bounds=None) + + + Bases: :py:obj:`pints.SNES` + + Stochastic natural evolution strategy optimiser. Inherits from the PINTS SNES class. + https://github.com/pints-team/pints/blob/main/pints/_optimisers/_snes.py + + +.. py:class:: XNES(x0, sigma0=0.1, bounds=None) + + + Bases: :py:obj:`pints.XNES` + + Exponential natural evolution strategy optimiser. Inherits from the PINTS XNES class. + https://github.com/pints-team/pints/blob/main/pints/_optimisers/_xnes.py diff --git a/docs/api/pybop/optimisers/scipy_minimize/index.rst b/docs/api/pybop/optimisers/scipy_minimize/index.rst new file mode 100644 index 00000000..4d8c9233 --- /dev/null +++ b/docs/api/pybop/optimisers/scipy_minimize/index.rst @@ -0,0 +1,46 @@ +:py:mod:`pybop.optimisers.scipy_minimize` +========================================= + +.. py:module:: pybop.optimisers.scipy_minimize + + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. autoapisummary:: + + pybop.optimisers.scipy_minimize.SciPyMinimize + + + + +.. py:class:: SciPyMinimize(method=None, bounds=None) + + + Bases: :py:obj:`pybop.optimisers.base_optimiser.BaseOptimiser` + + Wrapper class for the SciPy optimisation class. Extends the BaseOptimiser class. + + .. py:method:: _runoptimise(cost_function, x0, bounds) + + Run the SciPy optimisation method. + + Inputs + ---------- + cost_function: function for optimising + method: optimisation algorithm + x0: initialisation array + bounds: bounds array + + + .. py:method:: name() + + Returns the name of the optimiser. + + + .. py:method:: needs_sensitivities() + + Returns True if the optimiser needs sensitivities. diff --git a/docs/api/pybop/parameters/base_parameter/index.rst b/docs/api/pybop/parameters/base_parameter/index.rst new file mode 100644 index 00000000..5bad5034 --- /dev/null +++ b/docs/api/pybop/parameters/base_parameter/index.rst @@ -0,0 +1,41 @@ +:py:mod:`pybop.parameters.base_parameter` +========================================= + +.. py:module:: pybop.parameters.base_parameter + + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. autoapisummary:: + + pybop.parameters.base_parameter.Parameter + + + + +.. py:class:: Parameter(name, value=None, prior=None, bounds=None) + + + "" + Class for creating parameters in PyBOP. + + .. py:method:: __repr__() + + Return repr(self). + + + .. py:method:: rvs(n_samples) + + Returns a random value sample from the prior distribution. + + + .. py:method:: set_margin(margin) + + Sets the margin for the parameter. + + + .. py:method:: update(value) diff --git a/docs/api/pybop/parameters/base_parameter_set/index.rst b/docs/api/pybop/parameters/base_parameter_set/index.rst new file mode 100644 index 00000000..d63a2ef0 --- /dev/null +++ b/docs/api/pybop/parameters/base_parameter_set/index.rst @@ -0,0 +1,23 @@ +:py:mod:`pybop.parameters.base_parameter_set` +============================================= + +.. py:module:: pybop.parameters.base_parameter_set + + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. autoapisummary:: + + pybop.parameters.base_parameter_set.ParameterSet + + + + +.. py:class:: ParameterSet + + + Class for creating parameter sets in PyBOP. diff --git a/docs/api/pybop/parameters/index.rst b/docs/api/pybop/parameters/index.rst new file mode 100644 index 00000000..43843f7f --- /dev/null +++ b/docs/api/pybop/parameters/index.rst @@ -0,0 +1,15 @@ +:py:mod:`pybop.parameters` +========================== + +.. py:module:: pybop.parameters + + +Submodules +---------- +.. toctree:: + :titlesonly: + :maxdepth: 1 + + base_parameter/index.rst + base_parameter_set/index.rst + priors/index.rst diff --git a/docs/api/pybop/parameters/priors/index.rst b/docs/api/pybop/parameters/priors/index.rst new file mode 100644 index 00000000..05f5b79e --- /dev/null +++ b/docs/api/pybop/parameters/priors/index.rst @@ -0,0 +1,78 @@ +:py:mod:`pybop.parameters.priors` +================================= + +.. py:module:: pybop.parameters.priors + + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. autoapisummary:: + + pybop.parameters.priors.Exponential + pybop.parameters.priors.Gaussian + pybop.parameters.priors.Uniform + + + + +.. py:class:: Exponential(scale) + + + Exponential prior class. + + .. py:method:: __repr__() + + Return repr(self). + + + .. py:method:: logpdf(x) + + + .. py:method:: pdf(x) + + + .. py:method:: rvs(size) + + + +.. py:class:: Gaussian(mean, sigma) + + + Gaussian prior class. + + .. py:method:: __repr__() + + Return repr(self). + + + .. py:method:: logpdf(x) + + + .. py:method:: pdf(x) + + + .. py:method:: rvs(size) + + + +.. py:class:: Uniform(lower, upper) + + + Uniform prior class. + + .. py:method:: __repr__() + + Return repr(self). + + + .. py:method:: logpdf(x) + + + .. py:method:: pdf(x) + + + .. py:method:: rvs(size) diff --git a/docs/api/pybop/plotting/index.rst b/docs/api/pybop/plotting/index.rst new file mode 100644 index 00000000..3bbad489 --- /dev/null +++ b/docs/api/pybop/plotting/index.rst @@ -0,0 +1,17 @@ +:py:mod:`pybop.plotting` +======================== + +.. py:module:: pybop.plotting + + +Submodules +---------- +.. toctree:: + :titlesonly: + :maxdepth: 1 + + plot_convergence/index.rst + plot_cost2d/index.rst + plot_parameters/index.rst + plotly_manager/index.rst + quick_plot/index.rst diff --git a/docs/api/pybop/plotting/plot_convergence/index.rst b/docs/api/pybop/plotting/plot_convergence/index.rst new file mode 100644 index 00000000..52e9e8c3 --- /dev/null +++ b/docs/api/pybop/plotting/plot_convergence/index.rst @@ -0,0 +1,38 @@ +:py:mod:`pybop.plotting.plot_convergence` +========================================= + +.. py:module:: pybop.plotting.plot_convergence + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + pybop.plotting.plot_convergence.plot_convergence + + + +.. py:function:: plot_convergence(optim, xaxis_title='Iteration', yaxis_title='Cost', title='Convergence') + + Plot the convergence of the optimisation algorithm. + + Parameters: + ---------- + optim : optimisation object + Optimisation object containing the cost function and optimiser. + xaxis_title : str, optional + Title for the x-axis (default is "Iteration"). + yaxis_title : str, optional + Title for the y-axis (default is "Cost"). + title : str, optional + Title of the plot (default is "Convergence"). + + Returns: + ------- + fig : plotly.graph_objs.Figure + The Plotly figure object for the convergence plot. diff --git a/docs/api/pybop/plotting/plot_cost2d/index.rst b/docs/api/pybop/plotting/plot_cost2d/index.rst new file mode 100644 index 00000000..31ee744b --- /dev/null +++ b/docs/api/pybop/plotting/plot_cost2d/index.rst @@ -0,0 +1,32 @@ +:py:mod:`pybop.plotting.plot_cost2d` +==================================== + +.. py:module:: pybop.plotting.plot_cost2d + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + pybop.plotting.plot_cost2d.create_figure + pybop.plotting.plot_cost2d.get_param_bounds + pybop.plotting.plot_cost2d.plot_cost2d + + + +.. py:function:: create_figure(x, y, z, bounds, params, optim) + + +.. py:function:: get_param_bounds(cost) + + Use parameters bounds for range of cost landscape + + +.. py:function:: plot_cost2d(cost, bounds=None, optim=None, steps=10) + + Query the cost landscape for a given parameter space and plot using plotly. diff --git a/docs/api/pybop/plotting/plot_parameters/index.rst b/docs/api/pybop/plotting/plot_parameters/index.rst new file mode 100644 index 00000000..07b660ca --- /dev/null +++ b/docs/api/pybop/plotting/plot_parameters/index.rst @@ -0,0 +1,89 @@ +:py:mod:`pybop.plotting.plot_parameters` +======================================== + +.. py:module:: pybop.plotting.plot_parameters + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + pybop.plotting.plot_parameters.create_subplots_with_traces + pybop.plotting.plot_parameters.create_traces + pybop.plotting.plot_parameters.plot_parameters + + + +.. py:function:: create_subplots_with_traces(traces, plot_size=(1024, 576), title='Parameter Convergence', axis_titles=None, **layout_kwargs) + + Creates a subplot figure with the given traces. + + :param traces: List of plotly.graph_objs traces that will be added to the subplots. + :param plot_size: Tuple (width, height) representing the desired size of the plot. + :param title: The main title of the subplot figure. + :param axis_titles: List of tuples for axis titles in the form [(x_title, y_title), ...] for each subplot. + :param layout_kwargs: Additional keyword arguments to be passed to fig.update_layout for custom layout. + :return: A plotly figure object with the subplots. + + +.. py:function:: create_traces(params, trace_data, x_values=None) + + Generate a list of Plotly Scatter trace objects from provided trace data. + + This function assumes that each column in the ``trace_data`` represents a separate trace to be plotted, + and that the ``params`` list contains objects with a ``name`` attribute used for trace names. + Text wrapping for trace names is performed by ``pybop.StandardPlot.wrap_text``. + + Parameters: + - params (list): A list of objects, where each object has a ``name`` attribute used as the trace name. + The list should have the same length as the number of traces in ``trace_data``. + - trace_data (list of lists): A 2D list where each inner list represents y-values for a trace. + - x_values (list, optional): A list of x-values to be used for all traces. If not provided, a + range of integers starting from 0 will be used. + + Returns: + - list: A list of Plotly ``go.Scatter`` objects, each representing a trace to be plotted. + + Notes: + - The function depends on ``pybop.StandardPlot.wrap_text`` for text wrapping, which needs to be available + in the execution context. + - The function assumes that ``go`` from ``plotly.graph_objs`` is already imported as ``go``. + + +.. py:function:: plot_parameters(optim, xaxis_titles='Iteration', yaxis_titles=None, title='Convergence') + + Plot the evolution of the parameters during the optimisation process. + + Parameters: + ---------- + optim : optimisation object + An object representing the optimisation process, which should contain + information about the cost function, optimiser, and the history of the + parameter values throughout the iterations. + xaxis_title : str, optional + Title for the x-axis, representing the iteration number or a similar + discrete time step in the optimisation process (default is "Iteration"). + yaxis_title : str, optional + Title for the y-axis, which typically represents the metric being + optimised, such as cost or loss (default is "Cost"). + title : str, optional + Title of the plot, which provides an overall description of what the + plot represents (default is "Convergence"). + + Returns: + ------- + fig : plotly.graph_objs.Figure + The Plotly figure object for the plot depicting how the parameters of + the optimisation algorithm evolve over its course. This can be useful + for diagnosing the behaviour of the optimisation algorithm. + + Notes: + ----- + The function assumes that the 'optim' object has a 'cost.problem.parameters' + attribute containing the parameters of the optimisation algorithm and a 'log' + attribute containing a history of the iterations. diff --git a/docs/api/pybop/plotting/plotly_manager/index.rst b/docs/api/pybop/plotting/plotly_manager/index.rst new file mode 100644 index 00000000..076d6541 --- /dev/null +++ b/docs/api/pybop/plotting/plotly_manager/index.rst @@ -0,0 +1,87 @@ +:py:mod:`pybop.plotting.plotly_manager` +======================================= + +.. py:module:: pybop.plotting.plotly_manager + + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. autoapisummary:: + + pybop.plotting.plotly_manager.PlotlyManager + + + + +.. py:class:: PlotlyManager + + + Manages the installation and configuration of Plotly for generating visualisations. + + This class checks if Plotly is installed and, if not, prompts the user to install it. + It also ensures that the Plotly renderer and browser settings are properly configured + to display plots. + + .. method:: ``ensure_plotly_installed`` + + Verifies if Plotly is installed and installs it if necessary. + + .. method:: ``prompt_for_plotly_installation`` + + Prompts the user for permission to install Plotly. + + .. method:: ``install_plotly_package`` + + Installs the Plotly package using pip. + + .. method:: ``post_install_setup`` + + Sets up Plotly default renderer after installation. + + .. method:: ``check_renderer_settings`` + + Verifies that the Plotly renderer is correctly set. + + .. method:: ``check_browser_availability`` + + Checks if a web browser is available for rendering plots. + + + Usage: + Instantiate the PlotlyManager class to automatically ensure Plotly is installed + and configured correctly when creating an instance. + Example: + plotly_manager = PlotlyManager() + + .. py:method:: check_browser_availability() + + Ensures a web browser is available for rendering plots with the 'browser' renderer and provides guidance if not. + + + .. py:method:: check_renderer_settings() + + Checks if the Plotly renderer is set and provides information on how to set it if empty. + + + .. py:method:: ensure_plotly_installed() + + Verifies if Plotly is installed, importing necessary modules and prompting for installation if missing. + + + .. py:method:: install_plotly() + + Attempts to install the Plotly package using pip and exits if installation fails. + + + .. py:method:: post_install_setup() + + After successful installation, imports Plotly and sets the default renderer if necessary. + + + .. py:method:: prompt_for_plotly_installation() + + Prompts the user for permission to install Plotly and proceeds with installation if consented. diff --git a/docs/api/pybop/plotting/quick_plot/index.rst b/docs/api/pybop/plotting/quick_plot/index.rst new file mode 100644 index 00000000..08165d30 --- /dev/null +++ b/docs/api/pybop/plotting/quick_plot/index.rst @@ -0,0 +1,137 @@ +:py:mod:`pybop.plotting.quick_plot` +=================================== + +.. py:module:: pybop.plotting.quick_plot + + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. autoapisummary:: + + pybop.plotting.quick_plot.StandardPlot + + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + pybop.plotting.quick_plot.quick_plot + + + +.. py:class:: StandardPlot(x, y, cost, y2=None, title=None, xaxis_title=None, yaxis_title=None, trace_name=None, width=1024, height=576) + + + A class for creating and displaying a plotly figure that compares a target dataset against a simulated model output. + + This class provides an interface for generating interactive plots using Plotly, with the ability to include an + optional secondary dataset and visualize uncertainty if provided. + + Attributes: + ----------- + x : list + The x-axis data points. + y : list or np.ndarray + The primary y-axis data points representing the simulated model output. + y2 : list or np.ndarray, optional + An optional secondary y-axis data points representing the target dataset against which the model output is compared. + cost : float + The cost associated with the model output. + title : str, optional + The title of the plot. + xaxis_title : str, optional + The title for the x-axis. + yaxis_title : str, optional + The title for the y-axis. + trace_name : str, optional + The name of the primary trace representing the model output. Defaults to "Simulated". + width : int, optional + The width of the figure in pixels. Defaults to 720. + height : int, optional + The height of the figure in pixels. Defaults to 540. + + Methods: + -------- + wrap_text(text, width) + A static method that wraps text to a specified width, inserting HTML line breaks for use in plot labels. + + create_layout() + Creates the layout for the plot, including titles and axis labels. + + create_traces() + Creates the traces for the plot, including the primary dataset, optional secondary dataset, and an optional uncertainty visualization. + + __call__() + Generates the plotly figure when the class instance is called as a function. + + Example: + -------- + >>> x_data = [1, 2, 3, 4] + >>> y_simulated = [10, 15, 13, 17] + >>> y_target = [11, 14, 12, 16] + >>> plot = pybop.StandardPlot(x_data, y_simulated, cost=0.05, y2=y_target, + title="Model vs. Target", xaxis_title="X Axis", yaxis_title="Y Axis") + >>> fig = plot() # Generate the figure + >>> fig.show() # Display the figure in a browser + + .. py:method:: __call__() + + Generate the plotly figure. + + + .. py:method:: create_layout() + + Create the layout for the plot. + + + .. py:method:: create_traces() + + Create the traces for the plot. + + + .. py:method:: wrap_text(text, width) + :staticmethod: + + Wrap text to a specified width. + + Parameters: + ----------- + text: str + Text to be wrapped. + width: int + Width to wrap text to. + + Returns: + -------- + str + Wrapped text with HTML line breaks. + + + +.. py:function:: quick_plot(params, cost, title='Scatter Plot', width=1024, height=576) + + Plot the target dataset against the minimised model output. + + Parameters: + ---------- + params : array-like + Optimised parameters. + cost : cost object + Cost object containing the problem, dataset, and signal. + title : str, optional + Title of the plot (default is "Scatter Plot"). + width : int, optional + Width of the figure in pixels (default is 720). + height : int, optional + Height of the figure in pixels (default is 540). + + Returns: + ------- + fig : plotly.graph_objs.Figure + The Plotly figure object for the scatter plot. diff --git a/docs/api/pybop/version/index.rst b/docs/api/pybop/version/index.rst new file mode 100644 index 00000000..bf5679ef --- /dev/null +++ b/docs/api/pybop/version/index.rst @@ -0,0 +1,11 @@ +:py:mod:`pybop.version` +======================= + +.. py:module:: pybop.version + + +Module Contents +--------------- + +.. py:data:: __version__ + :value: '23.11' diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 00000000..c1145409 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,78 @@ +# Configuration file for the Sphinx documentation builder. + + +# -- Path setup -------------------------------------------------------------- +import sys +from pathlib import Path + +sys.path.append(str(Path(".").resolve())) + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = "PyBOP" +copyright = "2023, The PyBOP Team" +author = "The PyBOP Team" +release = "v23.11" + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [ + "sphinx.ext.napoleon", + "sphinx.ext.autodoc", + "sphinx.ext.autosummary", + "sphinx.ext.todo", + "sphinx.ext.viewcode", + "sphinxext.rediraffe", + "sphinx_design", + "sphinx_copybutton", + "autoapi.extension", + # custom extentions + "_extension.gallery_directive", + # "_extension.component_directive", + # For extension examples and demos + "myst_parser", + # "ablog", + # "jupyter_sphinx", + # "sphinxcontrib.youtube", + # "nbsphinx", + # "numpydoc", + # "sphinx_togglebutton", + # "jupyterlite_sphinx", + # "sphinx_favicon", +] + +templates_path = ["_templates"] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] + +# -- Options for autoapi ------------------------------------------------------- +autoapi_type = "python" +autoapi_dirs = ["../pybop"] +autoapi_keep_files = True +autoapi_root = "api" +autoapi_member_order = "groupwise" + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +# Set html_theme +html_theme = "pydata_sphinx_theme" +html_show_sourcelink = False +html_title = "PyBOP Documentation" + +# html_theme options +html_theme_options = { + "icon_links": [ + { + "name": "GitHub", + "url": "https://github.com/pybop-team/pybop", + "icon": "fab fa-github-square", + }, + # other icon links + ], + "search_bar_text": "Search the docs...", + # other options +} + +html_static_path = ["_static"] diff --git a/docs/contributing.md b/docs/contributing.md new file mode 100644 index 00000000..78caf34e --- /dev/null +++ b/docs/contributing.md @@ -0,0 +1,2 @@ +```{include} ../CONTRIBUTING.md +``` diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 00000000..fd8a0ddc --- /dev/null +++ b/docs/index.md @@ -0,0 +1,35 @@ +--- +myst: + html_meta: + "description lang=en": | + High-level documentation for PyBOP, and corresponding links to the site. +html_theme.sidebar_secondary.remove: true +--- + +# The PyBOP Package + +A Python package for battery model optimisation and parameterisation. + +Version: v23.11 + +```{gallery-grid} +:grid-columns: 1 2 2 2 + +- header: "{fab}`bootstrap;pst-color-primary` API Documentation" + content: "Get detailed information on functions, classes, and modules that allow you to fully leverage the power of PyBOP in your own projects." + link: "api/index.html" +- header: "{fas}`bolt;pst-color-primary` Installation" + content: "Setting up PyBOP is straightforward. Follow our step-by-step guide to install PyBOP on your system." +- header: "{fas}`circle-half-stroke;pst-color-primary` Usage" + content: "Discover how to use PyBOP effectively with our usage examples. From basic tasks to advanced features, learn how to solve real-world problems with PyBOP." +- header: "{fab}`python;pst-color-primary` Contributing" + content: "Contribute to the PyBOP project and become a part of our growing community." + link: "contributing.html" +``` + +```{toctree} +:maxdepth: 2 +:hidden: + +contributing +``` diff --git a/docs/make.bat b/docs/make.bat index 747ffb7b..32bb2452 100644 --- a/docs/make.bat +++ b/docs/make.bat @@ -7,8 +7,8 @@ REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) -set SOURCEDIR=source -set BUILDDIR=build +set SOURCEDIR=. +set BUILDDIR=_build %SPHINXBUILD% >NUL 2>NUL if errorlevel 9009 ( diff --git a/docs/source/conf.py b/docs/source/conf.py deleted file mode 100644 index b5be5c25..00000000 --- a/docs/source/conf.py +++ /dev/null @@ -1,28 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# For the full list of built-in configuration values, see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Project information ----------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information - -project = 'PyBOP' -copyright = '2023, Brady Planden, Nicola Courtier, David Howey' -author = 'Brady Planden, Nicola Courtier, David Howey' -release = '23.9' - -# -- General configuration --------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration - -extensions = [] - -templates_path = ['_templates'] -exclude_patterns = [] - - - -# -- Options for HTML output ------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output - -html_theme = 'alabaster' -html_static_path = ['_static'] diff --git a/docs/source/index.rst b/docs/source/index.rst deleted file mode 100644 index d84fc8c6..00000000 --- a/docs/source/index.rst +++ /dev/null @@ -1,20 +0,0 @@ -.. PyBOP documentation master file, created by - sphinx-quickstart on Fri Oct 27 09:54:56 2023. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to PyBOP's documentation! -================================= - -.. toctree:: - :maxdepth: 2 - :caption: Contents: - - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` diff --git a/docs/source/modules.rst b/docs/source/modules.rst new file mode 100644 index 00000000..dfe70a82 --- /dev/null +++ b/docs/source/modules.rst @@ -0,0 +1,7 @@ +pybop +===== + +.. toctree:: + :maxdepth: 4 + + pybop diff --git a/docs/source/pybop.costs.rst b/docs/source/pybop.costs.rst new file mode 100644 index 00000000..ea854a29 --- /dev/null +++ b/docs/source/pybop.costs.rst @@ -0,0 +1,29 @@ +Costs +=================== + +Submodules +---------- + +pybop.costs.error\_costs module +------------------------------- + +.. automodule:: pybop.costs.error_costs + :members: + :undoc-members: + :show-inheritance: + +pybop.costs.standalone module +----------------------------- + +.. automodule:: pybop.costs.standalone + :members: + :undoc-members: + :show-inheritance: + +Module contents +--------------- + +.. automodule:: pybop.costs + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/pybop.datasets.rst b/docs/source/pybop.datasets.rst new file mode 100644 index 00000000..27399b6e --- /dev/null +++ b/docs/source/pybop.datasets.rst @@ -0,0 +1,21 @@ +pybop.datasets package +====================== + +Submodules +---------- + +pybop.datasets.base\_dataset module +----------------------------------- + +.. automodule:: pybop.datasets.base_dataset + :members: + :undoc-members: + :show-inheritance: + +Module contents +--------------- + +.. automodule:: pybop.datasets + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/pybop.optimisers.rst b/docs/source/pybop.optimisers.rst new file mode 100644 index 00000000..f134f257 --- /dev/null +++ b/docs/source/pybop.optimisers.rst @@ -0,0 +1,45 @@ +pybop.optimisers package +======================== + +Submodules +---------- + +pybop.optimisers.base\_optimiser module +--------------------------------------- + +.. automodule:: pybop.optimisers.base_optimiser + :members: + :undoc-members: + :show-inheritance: + +pybop.optimisers.nlopt\_optimize module +--------------------------------------- + +.. automodule:: pybop.optimisers.nlopt_optimize + :members: + :undoc-members: + :show-inheritance: + +pybop.optimisers.pints\_optimisers module +----------------------------------------- + +.. automodule:: pybop.optimisers.pints_optimisers + :members: + :undoc-members: + :show-inheritance: + +pybop.optimisers.scipy\_minimize module +--------------------------------------- + +.. automodule:: pybop.optimisers.scipy_minimize + :members: + :undoc-members: + :show-inheritance: + +Module contents +--------------- + +.. automodule:: pybop.optimisers + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/pybop.parameters.rst b/docs/source/pybop.parameters.rst new file mode 100644 index 00000000..278ad82f --- /dev/null +++ b/docs/source/pybop.parameters.rst @@ -0,0 +1,37 @@ +pybop.parameters package +======================== + +Submodules +---------- + +pybop.parameters.base\_parameter module +--------------------------------------- + +.. automodule:: pybop.parameters.base_parameter + :members: + :undoc-members: + :show-inheritance: + +pybop.parameters.base\_parameter\_set module +-------------------------------------------- + +.. automodule:: pybop.parameters.base_parameter_set + :members: + :undoc-members: + :show-inheritance: + +pybop.parameters.priors module +------------------------------ + +.. automodule:: pybop.parameters.priors + :members: + :undoc-members: + :show-inheritance: + +Module contents +--------------- + +.. automodule:: pybop.parameters + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/pybop.plotting.rst b/docs/source/pybop.plotting.rst new file mode 100644 index 00000000..21064bb0 --- /dev/null +++ b/docs/source/pybop.plotting.rst @@ -0,0 +1,53 @@ +pybop.plotting package +====================== + +Submodules +---------- + +pybop.plotting.plot\_convergence module +--------------------------------------- + +.. automodule:: pybop.plotting.plot_convergence + :members: + :undoc-members: + :show-inheritance: + +pybop.plotting.plot\_cost2d module +---------------------------------- + +.. automodule:: pybop.plotting.plot_cost2d + :members: + :undoc-members: + :show-inheritance: + +pybop.plotting.plot\_parameters module +-------------------------------------- + +.. automodule:: pybop.plotting.plot_parameters + :members: + :undoc-members: + :show-inheritance: + +pybop.plotting.plotly\_manager module +------------------------------------- + +.. automodule:: pybop.plotting.plotly_manager + :members: + :undoc-members: + :show-inheritance: + +pybop.plotting.quick\_plot module +--------------------------------- + +.. automodule:: pybop.plotting.quick_plot + :members: + :undoc-members: + :show-inheritance: + +Module contents +--------------- + +.. automodule:: pybop.plotting + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/pybop.rst b/docs/source/pybop.rst new file mode 100644 index 00000000..d2ef17f3 --- /dev/null +++ b/docs/source/pybop.rst @@ -0,0 +1,42 @@ +pybop package +============= + +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + pybop.costs + pybop.datasets + pybop.models + pybop.optimisers + pybop.parameters + pybop.plotting + +Submodules +---------- + +pybop.optimisation module +------------------------- + +.. automodule:: pybop.optimisation + :members: + :undoc-members: + :show-inheritance: + +.. pybop.version module +.. -------------------- + +.. .. automodule:: pybop.version +.. :members: +.. :undoc-members: +.. :show-inheritance: + +.. Module contents +.. --------------- + +.. .. automodule:: pybop +.. :members: +.. :undoc-members: +.. :show-inheritance: diff --git a/pybop/plotting/plot_parameters.py b/pybop/plotting/plot_parameters.py index 9f4bbc02..e94902bc 100644 --- a/pybop/plotting/plot_parameters.py +++ b/pybop/plotting/plot_parameters.py @@ -66,24 +66,24 @@ def create_traces(params, trace_data, x_values=None): """ Generate a list of Plotly Scatter trace objects from provided trace data. - This function assumes that each column in the `trace_data` represents a separate trace to be plotted, - and that the `params` list contains objects with a `name` attribute used for trace names. - Text wrapping for trace names is performed by `pybop.StandardPlot.wrap_text`. + This function assumes that each column in the ``trace_data`` represents a separate trace to be plotted, + and that the ``params`` list contains objects with a ``name`` attribute used for trace names. + Text wrapping for trace names is performed by ``pybop.StandardPlot.wrap_text``. Parameters: - - params (list): A list of objects, where each object has a `name` attribute used as the trace name. - The list should have the same length as the number of traces in `trace_data`. + - params (list): A list of objects, where each object has a ``name`` attribute used as the trace name. + The list should have the same length as the number of traces in ``trace_data``. - trace_data (list of lists): A 2D list where each inner list represents y-values for a trace. - x_values (list, optional): A list of x-values to be used for all traces. If not provided, a range of integers starting from 0 will be used. Returns: - - list: A list of Plotly `go.Scatter` objects, each representing a trace to be plotted. + - list: A list of Plotly ``go.Scatter`` objects, each representing a trace to be plotted. Notes: - - The function depends on `pybop.StandardPlot.wrap_text` for text wrapping, which needs to be available + - The function depends on ``pybop.StandardPlot.wrap_text`` for text wrapping, which needs to be available in the execution context. - - The function assumes that `go` from `plotly.graph_objs` is already imported as `go`. + - The function assumes that ``go`` from ``plotly.graph_objs`` is already imported as ``go``. """ # Attempt to import plotly when an instance is created diff --git a/pybop/plotting/plotly_manager.py b/pybop/plotting/plotly_manager.py index 2384f299..692b44bc 100644 --- a/pybop/plotting/plotly_manager.py +++ b/pybop/plotting/plotly_manager.py @@ -12,12 +12,12 @@ class PlotlyManager: to display plots. Methods: - `ensure_plotly_installed`: Verifies if Plotly is installed and installs it if necessary. - `prompt_for_plotly_installation`: Prompts the user for permission to install Plotly. - `install_plotly_package`: Installs the Plotly package using pip. - `post_install_setup`: Sets up Plotly default renderer after installation. - `check_renderer_settings`: Verifies that the Plotly renderer is correctly set. - `check_browser_availability`: Checks if a web browser is available for rendering plots. + ``ensure_plotly_installed``: Verifies if Plotly is installed and installs it if necessary. + ``prompt_for_plotly_installation``: Prompts the user for permission to install Plotly. + ``install_plotly_package``: Installs the Plotly package using pip. + ``post_install_setup``: Sets up Plotly default renderer after installation. + ``check_renderer_settings``: Verifies that the Plotly renderer is correctly set. + ``check_browser_availability``: Checks if a web browser is available for rendering plots. Usage: Instantiate the PlotlyManager class to automatically ensure Plotly is installed From 3134b3deb4bc647a4a9e31a3c896e1773498bb69 Mon Sep 17 00:00:00 2001 From: Brady Planden Date: Fri, 8 Dec 2023 14:10:46 +0000 Subject: [PATCH 03/22] Adds User Guide, Installation, and Quick Start --- docs/api/pybop/index.rst | 93 +++++++++---------- .../pybop/plotting/plot_convergence/index.rst | 2 +- docs/api/pybop/plotting/plot_cost2d/index.rst | 24 ++++- .../pybop/plotting/plot_parameters/index.rst | 6 +- .../pybop/plotting/plotly_manager/index.rst | 39 +++----- docs/api/pybop/plotting/quick_plot/index.rst | 22 +---- docs/conf.py | 13 +-- docs/index.md | 9 +- docs/user_guide/index.md | 22 +++++ docs/user_guide/installation.rst | 67 +++++++++++++ docs/user_guide/usage.rst | 61 ++++++++++++ pybop/plotting/plot_convergence.py | 2 +- pybop/plotting/plot_cost2d.py | 24 ++++- pybop/plotting/plot_parameters.py | 6 +- pybop/plotting/plotly_manager.py | 20 ++-- pybop/plotting/quick_plot.py | 22 +---- 16 files changed, 284 insertions(+), 148 deletions(-) create mode 100644 docs/user_guide/index.md create mode 100644 docs/user_guide/installation.rst create mode 100644 docs/user_guide/usage.rst diff --git a/docs/api/pybop/index.rst b/docs/api/pybop/index.rst index 7b0272b1..075983ac 100644 --- a/docs/api/pybop/index.rst +++ b/docs/api/pybop/index.rst @@ -513,36 +513,19 @@ Attributes It also ensures that the Plotly renderer and browser settings are properly configured to display plots. - .. method:: ``ensure_plotly_installed`` - - Verifies if Plotly is installed and installs it if necessary. - - .. method:: ``prompt_for_plotly_installation`` - - Prompts the user for permission to install Plotly. - - .. method:: ``install_plotly_package`` - - Installs the Plotly package using pip. - - .. method:: ``post_install_setup`` - - Sets up Plotly default renderer after installation. - - .. method:: ``check_renderer_settings`` - - Verifies that the Plotly renderer is correctly set. - - .. method:: ``check_browser_availability`` - - Checks if a web browser is available for rendering plots. - + Methods: + ``ensure_plotly_installed``: Verifies if Plotly is installed and installs it if necessary. + ``prompt_for_plotly_installation``: Prompts the user for permission to install Plotly. + ``install_plotly_package``: Installs the Plotly package using pip. + ``post_install_setup``: Sets up Plotly default renderer after installation. + ``check_renderer_settings``: Verifies that the Plotly renderer is correctly set. + ``check_browser_availability``: Checks if a web browser is available for rendering plots. Usage: - Instantiate the PlotlyManager class to automatically ensure Plotly is installed - and configured correctly when creating an instance. - Example: - plotly_manager = PlotlyManager() + Instantiate the PlotlyManager class to automatically ensure Plotly is installed + and configured correctly when creating an instance. + Example: + plotly_manager = PlotlyManager() .. py:method:: check_browser_availability() @@ -658,22 +641,8 @@ Attributes height : int, optional The height of the figure in pixels. Defaults to 540. - Methods: - -------- - wrap_text(text, width) - A static method that wraps text to a specified width, inserting HTML line breaks for use in plot labels. - - create_layout() - Creates the layout for the plot, including titles and axis labels. - - create_traces() - Creates the traces for the plot, including the primary dataset, optional secondary dataset, and an optional uncertainty visualization. - - __call__() - Generates the plotly figure when the class instance is called as a function. - Example: - -------- + ---------- >>> x_data = [1, 2, 3, 4] >>> y_simulated = [10, 15, 13, 17] >>> y_target = [11, 14, 12, 16] @@ -710,7 +679,7 @@ Attributes Width to wrap text to. Returns: - -------- + ---------- str Wrapped text with HTML line breaks. @@ -788,14 +757,36 @@ Attributes Title of the plot (default is "Convergence"). Returns: - ------- + ---------- fig : plotly.graph_objs.Figure The Plotly figure object for the convergence plot. .. py:function:: plot_cost2d(cost, bounds=None, optim=None, steps=10) - Query the cost landscape for a given parameter space and plot using plotly. + Query the cost landscape for a given parameter space and plot it using Plotly. + + This function creates a 2D plot that visualizes the cost landscape over a grid + of points within specified parameter bounds. If no bounds are provided, it determines + them from the bounds on the parameter class. + + :param cost: A callable representing the cost function to be queried. It should + take a list of parameters and return a cost value. + :type cost: callable + :param bounds: The bounds for the parameter space as a 2x2 array, with each + sub-array representing the min and max bounds for a parameter. + If None, bounds will be determined by `get_param_bounds`. + :type bounds: numpy.ndarray, optional + :param optim: An optional optimizer instance. If provided, it will be used to + overlay optimizer-specific information on the plot. + :type optim: object, optional + :param steps: The number of steps to divide the parameter space grid. More steps + result in finer resolution but increase computational cost. + :type steps: int, optional + :return: A Plotly figure object representing the cost landscape plot. + :rtype: plotly.graph_objs.Figure + + :raises ValueError: If the cost function does not behave as expected. .. py:function:: plot_parameters(optim, xaxis_titles='Iteration', yaxis_titles=None, title='Convergence') @@ -803,7 +794,7 @@ Attributes Plot the evolution of the parameters during the optimisation process. Parameters: - ---------- + ------------ optim : optimisation object An object representing the optimisation process, which should contain information about the cost function, optimiser, and the history of the @@ -819,14 +810,14 @@ Attributes plot represents (default is "Convergence"). Returns: - ------- + ---------- fig : plotly.graph_objs.Figure The Plotly figure object for the plot depicting how the parameters of the optimisation algorithm evolve over its course. This can be useful for diagnosing the behaviour of the optimisation algorithm. Notes: - ----- + ---------- The function assumes that the 'optim' object has a 'cost.problem.parameters' attribute containing the parameters of the optimisation algorithm and a 'log' attribute containing a history of the iterations. @@ -837,7 +828,7 @@ Attributes Plot the target dataset against the minimised model output. Parameters: - ---------- + ----------- params : array-like Optimised parameters. cost : cost object @@ -850,7 +841,7 @@ Attributes Height of the figure in pixels (default is 540). Returns: - ------- + ---------- fig : plotly.graph_objs.Figure The Plotly figure object for the scatter plot. diff --git a/docs/api/pybop/plotting/plot_convergence/index.rst b/docs/api/pybop/plotting/plot_convergence/index.rst index 52e9e8c3..79d2080c 100644 --- a/docs/api/pybop/plotting/plot_convergence/index.rst +++ b/docs/api/pybop/plotting/plot_convergence/index.rst @@ -33,6 +33,6 @@ Functions Title of the plot (default is "Convergence"). Returns: - ------- + ---------- fig : plotly.graph_objs.Figure The Plotly figure object for the convergence plot. diff --git a/docs/api/pybop/plotting/plot_cost2d/index.rst b/docs/api/pybop/plotting/plot_cost2d/index.rst index 31ee744b..83023b5d 100644 --- a/docs/api/pybop/plotting/plot_cost2d/index.rst +++ b/docs/api/pybop/plotting/plot_cost2d/index.rst @@ -29,4 +29,26 @@ Functions .. py:function:: plot_cost2d(cost, bounds=None, optim=None, steps=10) - Query the cost landscape for a given parameter space and plot using plotly. + Query the cost landscape for a given parameter space and plot it using Plotly. + + This function creates a 2D plot that visualizes the cost landscape over a grid + of points within specified parameter bounds. If no bounds are provided, it determines + them from the bounds on the parameter class. + + :param cost: A callable representing the cost function to be queried. It should + take a list of parameters and return a cost value. + :type cost: callable + :param bounds: The bounds for the parameter space as a 2x2 array, with each + sub-array representing the min and max bounds for a parameter. + If None, bounds will be determined by `get_param_bounds`. + :type bounds: numpy.ndarray, optional + :param optim: An optional optimizer instance. If provided, it will be used to + overlay optimizer-specific information on the plot. + :type optim: object, optional + :param steps: The number of steps to divide the parameter space grid. More steps + result in finer resolution but increase computational cost. + :type steps: int, optional + :return: A Plotly figure object representing the cost landscape plot. + :rtype: plotly.graph_objs.Figure + + :raises ValueError: If the cost function does not behave as expected. diff --git a/docs/api/pybop/plotting/plot_parameters/index.rst b/docs/api/pybop/plotting/plot_parameters/index.rst index 07b660ca..56416c1e 100644 --- a/docs/api/pybop/plotting/plot_parameters/index.rst +++ b/docs/api/pybop/plotting/plot_parameters/index.rst @@ -60,7 +60,7 @@ Functions Plot the evolution of the parameters during the optimisation process. Parameters: - ---------- + ------------ optim : optimisation object An object representing the optimisation process, which should contain information about the cost function, optimiser, and the history of the @@ -76,14 +76,14 @@ Functions plot represents (default is "Convergence"). Returns: - ------- + ---------- fig : plotly.graph_objs.Figure The Plotly figure object for the plot depicting how the parameters of the optimisation algorithm evolve over its course. This can be useful for diagnosing the behaviour of the optimisation algorithm. Notes: - ----- + ---------- The function assumes that the 'optim' object has a 'cost.problem.parameters' attribute containing the parameters of the optimisation algorithm and a 'log' attribute containing a history of the iterations. diff --git a/docs/api/pybop/plotting/plotly_manager/index.rst b/docs/api/pybop/plotting/plotly_manager/index.rst index 076d6541..d0606b3c 100644 --- a/docs/api/pybop/plotting/plotly_manager/index.rst +++ b/docs/api/pybop/plotting/plotly_manager/index.rst @@ -26,36 +26,19 @@ Classes It also ensures that the Plotly renderer and browser settings are properly configured to display plots. - .. method:: ``ensure_plotly_installed`` - - Verifies if Plotly is installed and installs it if necessary. - - .. method:: ``prompt_for_plotly_installation`` - - Prompts the user for permission to install Plotly. - - .. method:: ``install_plotly_package`` - - Installs the Plotly package using pip. - - .. method:: ``post_install_setup`` - - Sets up Plotly default renderer after installation. - - .. method:: ``check_renderer_settings`` - - Verifies that the Plotly renderer is correctly set. - - .. method:: ``check_browser_availability`` - - Checks if a web browser is available for rendering plots. - + Methods: + ``ensure_plotly_installed``: Verifies if Plotly is installed and installs it if necessary. + ``prompt_for_plotly_installation``: Prompts the user for permission to install Plotly. + ``install_plotly_package``: Installs the Plotly package using pip. + ``post_install_setup``: Sets up Plotly default renderer after installation. + ``check_renderer_settings``: Verifies that the Plotly renderer is correctly set. + ``check_browser_availability``: Checks if a web browser is available for rendering plots. Usage: - Instantiate the PlotlyManager class to automatically ensure Plotly is installed - and configured correctly when creating an instance. - Example: - plotly_manager = PlotlyManager() + Instantiate the PlotlyManager class to automatically ensure Plotly is installed + and configured correctly when creating an instance. + Example: + plotly_manager = PlotlyManager() .. py:method:: check_browser_availability() diff --git a/docs/api/pybop/plotting/quick_plot/index.rst b/docs/api/pybop/plotting/quick_plot/index.rst index 08165d30..87d9db9c 100644 --- a/docs/api/pybop/plotting/quick_plot/index.rst +++ b/docs/api/pybop/plotting/quick_plot/index.rst @@ -56,22 +56,8 @@ Functions height : int, optional The height of the figure in pixels. Defaults to 540. - Methods: - -------- - wrap_text(text, width) - A static method that wraps text to a specified width, inserting HTML line breaks for use in plot labels. - - create_layout() - Creates the layout for the plot, including titles and axis labels. - - create_traces() - Creates the traces for the plot, including the primary dataset, optional secondary dataset, and an optional uncertainty visualization. - - __call__() - Generates the plotly figure when the class instance is called as a function. - Example: - -------- + ---------- >>> x_data = [1, 2, 3, 4] >>> y_simulated = [10, 15, 13, 17] >>> y_target = [11, 14, 12, 16] @@ -108,7 +94,7 @@ Functions Width to wrap text to. Returns: - -------- + ---------- str Wrapped text with HTML line breaks. @@ -119,7 +105,7 @@ Functions Plot the target dataset against the minimised model output. Parameters: - ---------- + ----------- params : array-like Optimised parameters. cost : cost object @@ -132,6 +118,6 @@ Functions Height of the figure in pixels (default is 540). Returns: - ------- + ---------- fig : plotly.graph_objs.Figure The Plotly figure object for the scatter plot. diff --git a/docs/conf.py b/docs/conf.py index c1145409..a6073c39 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -8,23 +8,19 @@ sys.path.append(str(Path(".").resolve())) # -- Project information ----------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information - project = "PyBOP" copyright = "2023, The PyBOP Team" author = "The PyBOP Team" release = "v23.11" # -- General configuration --------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration - extensions = [ "sphinx.ext.napoleon", "sphinx.ext.autodoc", "sphinx.ext.autosummary", "sphinx.ext.todo", "sphinx.ext.viewcode", - "sphinxext.rediraffe", + # "sphinxext.rediraffe", "sphinx_design", "sphinx_copybutton", "autoapi.extension", @@ -54,9 +50,6 @@ autoapi_member_order = "groupwise" # -- Options for HTML output ------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output - -# Set html_theme html_theme = "pydata_sphinx_theme" html_show_sourcelink = False html_title = "PyBOP Documentation" @@ -69,10 +62,10 @@ "url": "https://github.com/pybop-team/pybop", "icon": "fab fa-github-square", }, - # other icon links + # add other icon links as needed ], "search_bar_text": "Search the docs...", - # other options + "show_prev_next": False, } html_static_path = ["_static"] diff --git a/docs/index.md b/docs/index.md index fd8a0ddc..cea4f85c 100644 --- a/docs/index.md +++ b/docs/index.md @@ -6,11 +6,11 @@ myst: html_theme.sidebar_secondary.remove: true --- -# The PyBOP Package +

Parameterise and Optimise Battery Models with PyBOP

-A Python package for battery model optimisation and parameterisation. +Welcome to PyBOP, an advanced Python package dedicated to the optimization and parameterization of battery models. PyBOP is designed to streamline your workflow, whether you are conducting academic research, working in industry, or simply interested in battery technology and modelling. -Version: v23.11 +**Version: v23.11** ```{gallery-grid} :grid-columns: 1 2 2 2 @@ -20,8 +20,10 @@ Version: v23.11 link: "api/index.html" - header: "{fas}`bolt;pst-color-primary` Installation" content: "Setting up PyBOP is straightforward. Follow our step-by-step guide to install PyBOP on your system." + link: "user_guide/installation.html" - header: "{fas}`circle-half-stroke;pst-color-primary` Usage" content: "Discover how to use PyBOP effectively with our usage examples. From basic tasks to advanced features, learn how to solve real-world problems with PyBOP." + link: "user_guide/index.html" - header: "{fab}`python;pst-color-primary` Contributing" content: "Contribute to the PyBOP project and become a part of our growing community." link: "contributing.html" @@ -32,4 +34,5 @@ Version: v23.11 :hidden: contributing +user_guide/index ``` diff --git a/docs/user_guide/index.md b/docs/user_guide/index.md new file mode 100644 index 00000000..76fd9cb2 --- /dev/null +++ b/docs/user_guide/index.md @@ -0,0 +1,22 @@ +--- +myst: + html_meta: + "description lang=en": | + Documentation for PyBOP users. +--- + +# User Guide + +```{toctree} +:caption: Installation + +installation + +``` + +```{toctree} +:caption: Usage + +usage + +```{toctree} diff --git a/docs/user_guide/installation.rst b/docs/user_guide/installation.rst new file mode 100644 index 00000000..1482edc4 --- /dev/null +++ b/docs/user_guide/installation.rst @@ -0,0 +1,67 @@ +Installation Guide for PyBOP +***************************** + +PyBOP is a versatile Python package designed for optimization and parameterization of battery models. Follow the instructions below to install PyBOP and set up your environment to begin utilizing its capabilities. + +Installing PyBOP with pip +------------------------- + +The simplest method to install PyBOP is using pip. Run the following command in your terminal: + +.. code-block:: console + + $ pip install pybop + +This command will download and install the latest stable version of PyBOP. If you want to install a specific version, you can specify the version number using the following command: + +.. code-block:: console + + $ pip install pybop==23.11 + +Installing the Development Version +---------------------------------- + +If you're interested in the cutting-edge features and want to try out the latest enhancements, you can install the development version directly from the ``develop`` branch on GitHub: + +.. code-block:: console + + $ pip install git+https://github.com/pybop-team/PyBOP.git@develop + +Please note that the development version may be less stable than the official releases. + +Local Installation from Source +------------------------------ + +For those who prefer to install PyBOP from a local clone of the repository or wish to modify the source code, you can use pip to install the package in "editable" mode. Replace "path/to/pybop" with the actual path to your local PyBOP directory: + +.. code-block:: console + + $ pip install -e "path/to/pybop" + +In editable mode, changes you make to the source code will immediately affect the PyBOP installation without the need for reinstallation. + +Verifying Installation +---------------------- + +To verify that PyBOP has been installed successfully, try running one of the provided example scripts included in the documentation or repository. If the example executes without any errors, PyBOP is ready to use. + +For Developers +-------------- + +If you are installing PyBOP for development purposes, such as contributing to the project, please ensure that you follow the guidelines outlined in the contributing guide. It includes additional steps that might be necessary for setting up a development environment, including the installation of dependencies and setup of pre-commit hooks. + +`Contributing Guide `_ + +Further Assistance +------------------ + +If you encounter any issues during the installation process or have any questions regarding the use of PyBOP, feel free to reach out to the community via the `PyBOP GitHub Discussions `_. + +Next Steps +---------- + +After installing PyBOP, you might want to: + +* Explore the `Quick Start Guide `_ to begin using PyBOP. +* Read through the `User Manual `_ for in-depth documentation on PyBOP's features. +* Check out the `API Reference <../api/index.html>`_ for detailed information on PyBOP's programming interface. diff --git a/docs/user_guide/usage.rst b/docs/user_guide/usage.rst new file mode 100644 index 00000000..4e2b2418 --- /dev/null +++ b/docs/user_guide/usage.rst @@ -0,0 +1,61 @@ +Quick Start Guide for PyBOP +**************************** + +Welcome to the Quick Start Guide for PyBOP. This guide will help you get up and running with PyBOP. If you're new to PyBOP, we recommend you start here to learn the basics and get a feel for the package. + +Getting Started with PyBOP +-------------------------- + +PyBOP is equipped with a series of robust tools that can help you optimize various parameters within your battery models to better match empirical data or to explore the effects of different parameters on battery behavior. + +To begin using PyBOP: + +1. Install the package using pip: + + .. code-block:: console + + $ pip install pybop + + For detailed installation instructions, including how to install specific versions or from source, see the :ref:`installation` section. + +2. Once PyBOP is installed, you can import it in your Python scripts or Jupyter notebooks: + + .. code-block:: python + + import pybop + + Now you're ready to utilize PyBOP's functionality in your projects! + +Exploring Examples +------------------ + +To help you get acquainted with PyBOP's capabilities, we provide a collection of examples that demonstrate common use cases and features of the package: + +- **Jupyter Notebooks**: Interactive notebooks that include detailed explanations alongside the live code, visualizations, and results. These are an excellent resource for learning and can be easily modified and executed to suit your needs. + +- **Python Scripts**: For those who prefer working in a text editor, IDE, or for integrating into larger projects, we provide equivalent examples in plain Python script format. + +You can find these resources in the ``examples`` folder of the PyBOP repository. To access the examples, navigate to the following path after cloning or downloading the repository: + +.. code-block:: console + + path/to/pybop/examples + +These examples are also available on our `GitHub repository `_. + +Next Steps +---------- + +Once you're comfortable with the basics demonstrated in the examples, you can dive deeper into the functionality of PyBOP by: + +- Exploring the :ref:`user-guide` for a comprehensive overview of features. +- Delving into the :ref:`api-reference` for detailed API documentation. +- Checking out the :ref:`advanced-topics` for in-depth discussions on specific PyBOP features and how to customize them for complex scenarios. + +Support and Contributions +------------------------- + +If you encounter any issues or have questions as you start using PyBOP, don't hesitate to reach out to our community: + +- **Support**: Visit our :ref:`support` page for FAQs and contact information. +- **Contributions**: Interested in contributing to PyBOP? Check out our :ref:`contributing-guide` for guidelines on how to contribute. diff --git a/pybop/plotting/plot_convergence.py b/pybop/plotting/plot_convergence.py index 94ffdf90..315a3871 100644 --- a/pybop/plotting/plot_convergence.py +++ b/pybop/plotting/plot_convergence.py @@ -19,7 +19,7 @@ def plot_convergence( Title of the plot (default is "Convergence"). Returns: - ------- + ---------- fig : plotly.graph_objs.Figure The Plotly figure object for the convergence plot. """ diff --git a/pybop/plotting/plot_cost2d.py b/pybop/plotting/plot_cost2d.py index aa7b2e3b..2475506c 100644 --- a/pybop/plotting/plot_cost2d.py +++ b/pybop/plotting/plot_cost2d.py @@ -3,7 +3,29 @@ def plot_cost2d(cost, bounds=None, optim=None, steps=10): """ - Query the cost landscape for a given parameter space and plot using plotly. + Query the cost landscape for a given parameter space and plot it using Plotly. + + This function creates a 2D plot that visualizes the cost landscape over a grid + of points within specified parameter bounds. If no bounds are provided, it determines + them from the bounds on the parameter class. + + :param cost: A callable representing the cost function to be queried. It should + take a list of parameters and return a cost value. + :type cost: callable + :param bounds: The bounds for the parameter space as a 2x2 array, with each + sub-array representing the min and max bounds for a parameter. + If None, bounds will be determined by `get_param_bounds`. + :type bounds: numpy.ndarray, optional + :param optim: An optional optimizer instance. If provided, it will be used to + overlay optimizer-specific information on the plot. + :type optim: object, optional + :param steps: The number of steps to divide the parameter space grid. More steps + result in finer resolution but increase computational cost. + :type steps: int, optional + :return: A Plotly figure object representing the cost landscape plot. + :rtype: plotly.graph_objs.Figure + + :raises ValueError: If the cost function does not behave as expected. """ if bounds is None: diff --git a/pybop/plotting/plot_parameters.py b/pybop/plotting/plot_parameters.py index e94902bc..2dcf582d 100644 --- a/pybop/plotting/plot_parameters.py +++ b/pybop/plotting/plot_parameters.py @@ -9,7 +9,7 @@ def plot_parameters( Plot the evolution of the parameters during the optimisation process. Parameters: - ---------- + ------------ optim : optimisation object An object representing the optimisation process, which should contain information about the cost function, optimiser, and the history of the @@ -25,14 +25,14 @@ def plot_parameters( plot represents (default is "Convergence"). Returns: - ------- + ---------- fig : plotly.graph_objs.Figure The Plotly figure object for the plot depicting how the parameters of the optimisation algorithm evolve over its course. This can be useful for diagnosing the behaviour of the optimisation algorithm. Notes: - ----- + ---------- The function assumes that the 'optim' object has a 'cost.problem.parameters' attribute containing the parameters of the optimisation algorithm and a 'log' attribute containing a history of the iterations. diff --git a/pybop/plotting/plotly_manager.py b/pybop/plotting/plotly_manager.py index 692b44bc..c8b80dc9 100644 --- a/pybop/plotting/plotly_manager.py +++ b/pybop/plotting/plotly_manager.py @@ -12,18 +12,18 @@ class PlotlyManager: to display plots. Methods: - ``ensure_plotly_installed``: Verifies if Plotly is installed and installs it if necessary. - ``prompt_for_plotly_installation``: Prompts the user for permission to install Plotly. - ``install_plotly_package``: Installs the Plotly package using pip. - ``post_install_setup``: Sets up Plotly default renderer after installation. - ``check_renderer_settings``: Verifies that the Plotly renderer is correctly set. - ``check_browser_availability``: Checks if a web browser is available for rendering plots. + ``ensure_plotly_installed``: Verifies if Plotly is installed and installs it if necessary. + ``prompt_for_plotly_installation``: Prompts the user for permission to install Plotly. + ``install_plotly_package``: Installs the Plotly package using pip. + ``post_install_setup``: Sets up Plotly default renderer after installation. + ``check_renderer_settings``: Verifies that the Plotly renderer is correctly set. + ``check_browser_availability``: Checks if a web browser is available for rendering plots. Usage: - Instantiate the PlotlyManager class to automatically ensure Plotly is installed - and configured correctly when creating an instance. - Example: - plotly_manager = PlotlyManager() + Instantiate the PlotlyManager class to automatically ensure Plotly is installed + and configured correctly when creating an instance. + Example: + plotly_manager = PlotlyManager() """ def __init__(self): diff --git a/pybop/plotting/quick_plot.py b/pybop/plotting/quick_plot.py index d6628760..8d9ef02b 100644 --- a/pybop/plotting/quick_plot.py +++ b/pybop/plotting/quick_plot.py @@ -33,22 +33,8 @@ class StandardPlot: height : int, optional The height of the figure in pixels. Defaults to 540. - Methods: - -------- - wrap_text(text, width) - A static method that wraps text to a specified width, inserting HTML line breaks for use in plot labels. - - create_layout() - Creates the layout for the plot, including titles and axis labels. - - create_traces() - Creates the traces for the plot, including the primary dataset, optional secondary dataset, and an optional uncertainty visualization. - - __call__() - Generates the plotly figure when the class instance is called as a function. - Example: - -------- + ---------- >>> x_data = [1, 2, 3, 4] >>> y_simulated = [10, 15, 13, 17] >>> y_target = [11, 14, 12, 16] @@ -103,7 +89,7 @@ def wrap_text(text, width): Width to wrap text to. Returns: - -------- + ---------- str Wrapped text with HTML line breaks. """ @@ -176,7 +162,7 @@ def quick_plot(params, cost, title="Scatter Plot", width=1024, height=576): Plot the target dataset against the minimised model output. Parameters: - ---------- + ----------- params : array-like Optimised parameters. cost : cost object @@ -189,7 +175,7 @@ def quick_plot(params, cost, title="Scatter Plot", width=1024, height=576): Height of the figure in pixels (default is 540). Returns: - ------- + ---------- fig : plotly.graph_objs.Figure The Plotly figure object for the scatter plot. """ From ddae28828ef12e2c3b2eb3eea74c3e6c59543589 Mon Sep 17 00:00:00 2001 From: Brady Planden Date: Fri, 8 Dec 2023 15:24:40 +0000 Subject: [PATCH 04/22] Add nox session for docs, add pip install option for docs --- noxfile.py | 35 +++++++++++++++++++++++++++++++++++ setup.py | 9 +++++++++ 2 files changed, 44 insertions(+) diff --git a/noxfile.py b/noxfile.py index e1759a3d..dddabfa7 100644 --- a/noxfile.py +++ b/noxfile.py @@ -32,3 +32,38 @@ def notebooks(session): session.run_always("pip", "install", "-e", ".[all]") session.install("pytest", "nbmake") session.run("pytest", "--nbmake", "examples/", external=True) + + +@nox.session +def build_docs(session): + """ + Build the documentation and load it in a browser tab, rebuilding on changes. + Credit: PyBaMM Team + """ + envbindir = session.bin + session.install("-e", ".[all,docs]") + session.chdir("docs") + # Local development + if session.interactive: + session.run( + "sphinx-autobuild", + "-j", + "auto", + "--open-browser", + "-qT", + ".", + f"{envbindir}/../tmp/html", + ) + # Runs in CI only, treating warnings as errors + else: + session.run( + "sphinx-build", + "-j", + "auto", + "-b", + "html", + "-W", + "--keep-going", + ".", + f"{envbindir}/../tmp/html", + ) diff --git a/setup.py b/setup.py index 4591c384..78b54e53 100644 --- a/setup.py +++ b/setup.py @@ -35,6 +35,15 @@ extras_require={ "plot": ["plotly>=5.0"], "all": ["pybop[plot]"], + "docs": [ + "sphinx>=6", + "pydata-sphinx-theme", + "sphinx-autobuild", + "sphinx-autoapi", + "sphinx_copybutton", + "sphinx_design", + "myst-parser", + ], }, # https://pypi.org/classifiers/ classifiers=[], From f98355a281e87b2d3aaacfa064af3dc5adb53469 Mon Sep 17 00:00:00 2001 From: Brady Planden Date: Sun, 10 Dec 2023 11:40:17 +0000 Subject: [PATCH 05/22] Updt cost, dataset structure, improve docstrings, iterate on docs site --- docs/api/pybop/_costs/index.rst | 153 ++++++++++++ docs/api/pybop/_dataset/index.rst | 50 ++++ docs/api/pybop/costs/error_costs/index.rst | 72 ------ docs/api/pybop/costs/index.rst | 14 -- docs/api/pybop/costs/standalone/index.rst | 31 --- .../api/pybop/datasets/base_dataset/index.rst | 30 --- docs/api/pybop/datasets/index.rst | 13 - docs/api/pybop/index.rst | 133 ++++++++-- docs/conf.py | 5 +- docs/index.md | 4 +- docs/source/modules.rst | 7 - docs/source/pybop.costs.rst | 29 --- docs/source/pybop.datasets.rst | 21 -- docs/source/pybop.optimisers.rst | 45 ---- docs/source/pybop.parameters.rst | 37 --- docs/source/pybop.plotting.rst | 53 ---- docs/source/pybop.rst | 42 ---- docs/user_guide/index.md | 2 +- examples/costs/standalone.py | 72 ++++++ .../parameters/fit_ecm_parameters.json | 24 ++ noxfile.py | 2 +- pybop/__init__.py | 4 +- pybop/_costs.py | 229 ++++++++++++++++++ pybop/_dataset.py | 64 +++++ pybop/costs/__init__.py | 0 pybop/costs/error_costs.py | 114 --------- pybop/costs/standalone.py | 18 -- pybop/datasets/__init__.py | 0 pybop/datasets/base_dataset.py | 20 -- setup.py | 1 + tests/unit/test_optimisation.py | 2 +- 31 files changed, 718 insertions(+), 573 deletions(-) create mode 100644 docs/api/pybop/_costs/index.rst create mode 100644 docs/api/pybop/_dataset/index.rst delete mode 100644 docs/api/pybop/costs/error_costs/index.rst delete mode 100644 docs/api/pybop/costs/index.rst delete mode 100644 docs/api/pybop/costs/standalone/index.rst delete mode 100644 docs/api/pybop/datasets/base_dataset/index.rst delete mode 100644 docs/api/pybop/datasets/index.rst delete mode 100644 docs/source/modules.rst delete mode 100644 docs/source/pybop.costs.rst delete mode 100644 docs/source/pybop.datasets.rst delete mode 100644 docs/source/pybop.optimisers.rst delete mode 100644 docs/source/pybop.parameters.rst delete mode 100644 docs/source/pybop.plotting.rst delete mode 100644 docs/source/pybop.rst create mode 100644 examples/costs/standalone.py create mode 100644 examples/scripts/parameters/fit_ecm_parameters.json create mode 100644 pybop/_costs.py create mode 100644 pybop/_dataset.py delete mode 100644 pybop/costs/__init__.py delete mode 100644 pybop/costs/error_costs.py delete mode 100644 pybop/costs/standalone.py delete mode 100644 pybop/datasets/__init__.py delete mode 100644 pybop/datasets/base_dataset.py diff --git a/docs/api/pybop/_costs/index.rst b/docs/api/pybop/_costs/index.rst new file mode 100644 index 00000000..36d8cab8 --- /dev/null +++ b/docs/api/pybop/_costs/index.rst @@ -0,0 +1,153 @@ +:py:mod:`pybop._costs` +====================== + +.. py:module:: pybop._costs + + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. autoapisummary:: + + pybop._costs.BaseCost + pybop._costs.RootMeanSquaredError + pybop._costs.SumSquaredError + + + + +.. py:class:: BaseCost(problem) + + + Base class for defining cost functions. + + This class is intended to be subclassed to create specific cost functions + for evaluating model predictions against a set of data. The cost function + quantifies the goodness-of-fit between the model predictions and the + observed data, with a lower cost value indicating a better fit. + + :param problem: A problem instance containing the data and functions necessary for + evaluating the cost function. + :type problem: object + :param _target: An array containing the target data to fit. + :type _target: array-like + :param x0: The initial guess for the model parameters. + :type x0: array-like + :param bounds: The bounds for the model parameters. + :type bounds: tuple + :param n_parameters: The number of parameters in the model. + :type n_parameters: int + + .. py:method:: __call__(x, grad=None) + :abstractmethod: + + Calculate the cost function value for a given set of parameters. + + This method must be implemented by subclasses. + + :param x: The parameters for which to evaluate the cost. + :type x: array-like + :param grad: An array to store the gradient of the cost function with respect + to the parameters. + :type grad: array-like, optional + + :returns: The calculated cost function value. + :rtype: float + + :raises NotImplementedError: If the method has not been implemented by the subclass. + + + +.. py:class:: RootMeanSquaredError(problem) + + + Bases: :py:obj:`BaseCost` + + Root mean square error cost function. + + Computes the root mean square error between model predictions and the target + data, providing a measure of the differences between predicted values and + observed values. + + Inherits all parameters and attributes from ``BaseCost``. + + + .. py:method:: __call__(x, grad=None) + + Calculate the root mean square error for a given set of parameters. + + :param x: The parameters for which to evaluate the cost. + :type x: array-like + :param grad: An array to store the gradient of the cost function with respect + to the parameters. + :type grad: array-like, optional + + :returns: The root mean square error. + :rtype: float + + :raises ValueError: If an error occurs during the calculation of the cost. + + + +.. py:class:: SumSquaredError(problem) + + + Bases: :py:obj:`BaseCost` + + Sum of squared errors cost function. + + Computes the sum of the squares of the differences between model predictions + and target data, which serves as a measure of the total error between the + predicted and observed values. + + Inherits all parameters and attributes from ``BaseCost``. + + Additional Attributes + --------------------- + _de : float + The gradient of the cost function to use if an error occurs during + evaluation. Defaults to 1.0. + + + .. py:method:: __call__(x, grad=None) + + Calculate the sum of squared errors for a given set of parameters. + + :param x: The parameters for which to evaluate the cost. + :type x: array-like + :param grad: An array to store the gradient of the cost function with respect + to the parameters. + :type grad: array-like, optional + + :returns: The sum of squared errors. + :rtype: float + + :raises ValueError: If an error occurs during the calculation of the cost. + + + .. py:method:: evaluateS1(x) + + Compute the cost and its gradient with respect to the parameters. + + :param x: The parameters for which to compute the cost and gradient. + :type x: array-like + + :returns: A tuple containing the cost and the gradient. The cost is a float, + and the gradient is an array-like of the same length as `x`. + :rtype: tuple + + :raises ValueError: If an error occurs during the calculation of the cost or gradient. + + + .. py:method:: set_fail_gradient(de) + + Set the fail gradient to a specified value. + + The fail gradient is used if an error occurs during the calculation + of the gradient. This method allows updating the default gradient value. + + :param de: The new fail gradient value to be used. + :type de: float diff --git a/docs/api/pybop/_dataset/index.rst b/docs/api/pybop/_dataset/index.rst new file mode 100644 index 00000000..53913bed --- /dev/null +++ b/docs/api/pybop/_dataset/index.rst @@ -0,0 +1,50 @@ +:py:mod:`pybop._dataset` +======================== + +.. py:module:: pybop._dataset + + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. autoapisummary:: + + pybop._dataset.Dataset + + + + +.. py:class:: Dataset(name, data) + + + Represents a collection of experimental observations. + + This class provides a structured way to store and work with experimental data, + which may include applying operations such as interpolation. + + :param name: The name of the dataset, providing a label for identification. + :type name: str + :param data: The actual experimental data, typically in a structured form such as + a NumPy array or a pandas DataFrame. + :type data: array-like + + .. py:method:: Interpolant() + + Create an interpolation function of the dataset based on the independent variable. + + Currently, only time-based interpolation is supported. This method modifies + the instance's Interpolant attribute to be an interpolation function that + can be evaluated at different points in time. + + :raises NotImplementedError: If the independent variable for interpolation is not supported. + + + .. py:method:: __repr__() + + Return a string representation of the Dataset instance. + + :returns: A string that includes the name and data of the dataset. + :rtype: str diff --git a/docs/api/pybop/costs/error_costs/index.rst b/docs/api/pybop/costs/error_costs/index.rst deleted file mode 100644 index 70f18e02..00000000 --- a/docs/api/pybop/costs/error_costs/index.rst +++ /dev/null @@ -1,72 +0,0 @@ -:py:mod:`pybop.costs.error_costs` -================================= - -.. py:module:: pybop.costs.error_costs - - -Module Contents ---------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - pybop.costs.error_costs.BaseCost - pybop.costs.error_costs.RootMeanSquaredError - pybop.costs.error_costs.SumSquaredError - - - - -.. py:class:: BaseCost(problem) - - - Base class for defining cost functions. - This class computes a corresponding goodness-of-fit for a corresponding model prediction and dataset. - Lower cost values indicate a better fit. - - .. py:method:: __call__(x, grad=None) - :abstractmethod: - - Returns the cost function value and computes the cost. - - - -.. py:class:: RootMeanSquaredError(problem) - - - Bases: :py:obj:`BaseCost` - - Defines the root mean square error cost function. - - .. py:method:: __call__(x, grad=None) - - Computes the cost. - - - -.. py:class:: SumSquaredError(problem) - - - Bases: :py:obj:`BaseCost` - - Defines the sum squared error cost function. - - The initial fail gradient is set equal to one, but this can be - changed at any time with :meth:`set_fail_gradient()`. - - .. py:method:: __call__(x, grad=None) - - Computes the cost. - - - .. py:method:: evaluateS1(x) - - Compute the cost and corresponding - gradients with respect to the parameters. - - - .. py:method:: set_fail_gradient(de) - - Sets the fail gradient for this optimiser. diff --git a/docs/api/pybop/costs/index.rst b/docs/api/pybop/costs/index.rst deleted file mode 100644 index 837718ef..00000000 --- a/docs/api/pybop/costs/index.rst +++ /dev/null @@ -1,14 +0,0 @@ -:py:mod:`pybop.costs` -===================== - -.. py:module:: pybop.costs - - -Submodules ----------- -.. toctree:: - :titlesonly: - :maxdepth: 1 - - error_costs/index.rst - standalone/index.rst diff --git a/docs/api/pybop/costs/standalone/index.rst b/docs/api/pybop/costs/standalone/index.rst deleted file mode 100644 index 3d0957b4..00000000 --- a/docs/api/pybop/costs/standalone/index.rst +++ /dev/null @@ -1,31 +0,0 @@ -:py:mod:`pybop.costs.standalone` -================================ - -.. py:module:: pybop.costs.standalone - - -Module Contents ---------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - pybop.costs.standalone.StandaloneCost - - - - -.. py:class:: StandaloneCost(problem=None) - - - Bases: :py:obj:`pybop.BaseCost` - - Base class for defining cost functions. - This class computes a corresponding goodness-of-fit for a corresponding model prediction and dataset. - Lower cost values indicate a better fit. - - .. py:method:: __call__(x, grad=None) - - Returns the cost function value and computes the cost. diff --git a/docs/api/pybop/datasets/base_dataset/index.rst b/docs/api/pybop/datasets/base_dataset/index.rst deleted file mode 100644 index 9d6e1fe0..00000000 --- a/docs/api/pybop/datasets/base_dataset/index.rst +++ /dev/null @@ -1,30 +0,0 @@ -:py:mod:`pybop.datasets.base_dataset` -===================================== - -.. py:module:: pybop.datasets.base_dataset - - -Module Contents ---------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - pybop.datasets.base_dataset.Dataset - - - - -.. py:class:: Dataset(name, data) - - - Class for experimental observations. - - .. py:method:: Interpolant() - - - .. py:method:: __repr__() - - Return repr(self). diff --git a/docs/api/pybop/datasets/index.rst b/docs/api/pybop/datasets/index.rst deleted file mode 100644 index 0d868a1c..00000000 --- a/docs/api/pybop/datasets/index.rst +++ /dev/null @@ -1,13 +0,0 @@ -:py:mod:`pybop.datasets` -======================== - -.. py:module:: pybop.datasets - - -Submodules ----------- -.. toctree:: - :titlesonly: - :maxdepth: 1 - - base_dataset/index.rst diff --git a/docs/api/pybop/index.rst b/docs/api/pybop/index.rst index 075983ac..6ac0d00d 100644 --- a/docs/api/pybop/index.rst +++ b/docs/api/pybop/index.rst @@ -10,8 +10,6 @@ Subpackages :titlesonly: :maxdepth: 3 - costs/index.rst - datasets/index.rst models/index.rst optimisers/index.rst parameters/index.rst @@ -24,6 +22,8 @@ Submodules :titlesonly: :maxdepth: 1 + _costs/index.rst + _dataset/index.rst _problem/index.rst optimisation/index.rst version/index.rst @@ -100,13 +100,41 @@ Attributes Base class for defining cost functions. - This class computes a corresponding goodness-of-fit for a corresponding model prediction and dataset. - Lower cost values indicate a better fit. + + This class is intended to be subclassed to create specific cost functions + for evaluating model predictions against a set of data. The cost function + quantifies the goodness-of-fit between the model predictions and the + observed data, with a lower cost value indicating a better fit. + + :param problem: A problem instance containing the data and functions necessary for + evaluating the cost function. + :type problem: object + :param _target: An array containing the target data to fit. + :type _target: array-like + :param x0: The initial guess for the model parameters. + :type x0: array-like + :param bounds: The bounds for the model parameters. + :type bounds: tuple + :param n_parameters: The number of parameters in the model. + :type n_parameters: int .. py:method:: __call__(x, grad=None) :abstractmethod: - Returns the cost function value and computes the cost. + Calculate the cost function value for a given set of parameters. + + This method must be implemented by subclasses. + + :param x: The parameters for which to evaluate the cost. + :type x: array-like + :param grad: An array to store the gradient of the cost function with respect + to the parameters. + :type grad: array-like, optional + + :returns: The calculated cost function value. + :rtype: float + + :raises NotImplementedError: If the method has not been implemented by the subclass. @@ -213,14 +241,34 @@ Attributes .. py:class:: Dataset(name, data) - Class for experimental observations. + Represents a collection of experimental observations. + + This class provides a structured way to store and work with experimental data, + which may include applying operations such as interpolation. + + :param name: The name of the dataset, providing a label for identification. + :type name: str + :param data: The actual experimental data, typically in a structured form such as + a NumPy array or a pandas DataFrame. + :type data: array-like .. py:method:: Interpolant() + Create an interpolation function of the dataset based on the independent variable. + + Currently, only time-based interpolation is supported. This method modifies + the instance's Interpolant attribute to be an interpolation function that + can be evaluated at different points in time. + + :raises NotImplementedError: If the independent variable for interpolation is not supported. + .. py:method:: __repr__() - Return repr(self). + Return a string representation of the Dataset instance. + + :returns: A string that includes the name and data of the dataset. + :rtype: str @@ -563,11 +611,29 @@ Attributes Bases: :py:obj:`BaseCost` - Defines the root mean square error cost function. + Root mean square error cost function. + + Computes the root mean square error between model predictions and the target + data, providing a measure of the differences between predicted values and + observed values. + + Inherits all parameters and attributes from ``BaseCost``. + .. py:method:: __call__(x, grad=None) - Computes the cost. + Calculate the root mean square error for a given set of parameters. + + :param x: The parameters for which to evaluate the cost. + :type x: array-like + :param grad: An array to store the gradient of the cost function with respect + to the parameters. + :type grad: array-like, optional + + :returns: The root mean square error. + :rtype: float + + :raises ValueError: If an error occurs during the calculation of the cost. @@ -690,25 +756,60 @@ Attributes Bases: :py:obj:`BaseCost` - Defines the sum squared error cost function. + Sum of squared errors cost function. + + Computes the sum of the squares of the differences between model predictions + and target data, which serves as a measure of the total error between the + predicted and observed values. + + Inherits all parameters and attributes from ``BaseCost``. + + Additional Attributes + --------------------- + _de : float + The gradient of the cost function to use if an error occurs during + evaluation. Defaults to 1.0. - The initial fail gradient is set equal to one, but this can be - changed at any time with :meth:`set_fail_gradient()`. .. py:method:: __call__(x, grad=None) - Computes the cost. + Calculate the sum of squared errors for a given set of parameters. + + :param x: The parameters for which to evaluate the cost. + :type x: array-like + :param grad: An array to store the gradient of the cost function with respect + to the parameters. + :type grad: array-like, optional + + :returns: The sum of squared errors. + :rtype: float + + :raises ValueError: If an error occurs during the calculation of the cost. .. py:method:: evaluateS1(x) - Compute the cost and corresponding - gradients with respect to the parameters. + Compute the cost and its gradient with respect to the parameters. + + :param x: The parameters for which to compute the cost and gradient. + :type x: array-like + + :returns: A tuple containing the cost and the gradient. The cost is a float, + and the gradient is an array-like of the same length as `x`. + :rtype: tuple + + :raises ValueError: If an error occurs during the calculation of the cost or gradient. .. py:method:: set_fail_gradient(de) - Sets the fail gradient for this optimiser. + Set the fail gradient to a specified value. + + The fail gradient is used if an error occurs during the calculation + of the gradient. This method allows updating the default gradient value. + + :param de: The new fail gradient value to be used. + :type de: float diff --git a/docs/conf.py b/docs/conf.py index a6073c39..84364515 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -20,23 +20,20 @@ "sphinx.ext.autosummary", "sphinx.ext.todo", "sphinx.ext.viewcode", - # "sphinxext.rediraffe", "sphinx_design", "sphinx_copybutton", "autoapi.extension", # custom extentions "_extension.gallery_directive", - # "_extension.component_directive", # For extension examples and demos "myst_parser", # "ablog", # "jupyter_sphinx", - # "sphinxcontrib.youtube", # "nbsphinx", # "numpydoc", # "sphinx_togglebutton", # "jupyterlite_sphinx", - # "sphinx_favicon", + "sphinx_favicon", ] templates_path = ["_templates"] diff --git a/docs/index.md b/docs/index.md index cea4f85c..94d276fe 100644 --- a/docs/index.md +++ b/docs/index.md @@ -8,7 +8,7 @@ html_theme.sidebar_secondary.remove: true

Parameterise and Optimise Battery Models with PyBOP

-Welcome to PyBOP, an advanced Python package dedicated to the optimization and parameterization of battery models. PyBOP is designed to streamline your workflow, whether you are conducting academic research, working in industry, or simply interested in battery technology and modelling. +Welcome to PyBOP, a Python package dedicated to the optimization and parameterization of battery models. PyBOP is designed to streamline your workflow, whether you are conducting academic research, working in industry, or simply interested in battery technology and modelling. **Version: v23.11** @@ -33,6 +33,6 @@ Welcome to PyBOP, an advanced Python package dedicated to the optimization and p :maxdepth: 2 :hidden: -contributing user_guide/index +contributing ``` diff --git a/docs/source/modules.rst b/docs/source/modules.rst deleted file mode 100644 index dfe70a82..00000000 --- a/docs/source/modules.rst +++ /dev/null @@ -1,7 +0,0 @@ -pybop -===== - -.. toctree:: - :maxdepth: 4 - - pybop diff --git a/docs/source/pybop.costs.rst b/docs/source/pybop.costs.rst deleted file mode 100644 index ea854a29..00000000 --- a/docs/source/pybop.costs.rst +++ /dev/null @@ -1,29 +0,0 @@ -Costs -=================== - -Submodules ----------- - -pybop.costs.error\_costs module -------------------------------- - -.. automodule:: pybop.costs.error_costs - :members: - :undoc-members: - :show-inheritance: - -pybop.costs.standalone module ------------------------------ - -.. automodule:: pybop.costs.standalone - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: pybop.costs - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pybop.datasets.rst b/docs/source/pybop.datasets.rst deleted file mode 100644 index 27399b6e..00000000 --- a/docs/source/pybop.datasets.rst +++ /dev/null @@ -1,21 +0,0 @@ -pybop.datasets package -====================== - -Submodules ----------- - -pybop.datasets.base\_dataset module ------------------------------------ - -.. automodule:: pybop.datasets.base_dataset - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: pybop.datasets - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pybop.optimisers.rst b/docs/source/pybop.optimisers.rst deleted file mode 100644 index f134f257..00000000 --- a/docs/source/pybop.optimisers.rst +++ /dev/null @@ -1,45 +0,0 @@ -pybop.optimisers package -======================== - -Submodules ----------- - -pybop.optimisers.base\_optimiser module ---------------------------------------- - -.. automodule:: pybop.optimisers.base_optimiser - :members: - :undoc-members: - :show-inheritance: - -pybop.optimisers.nlopt\_optimize module ---------------------------------------- - -.. automodule:: pybop.optimisers.nlopt_optimize - :members: - :undoc-members: - :show-inheritance: - -pybop.optimisers.pints\_optimisers module ------------------------------------------ - -.. automodule:: pybop.optimisers.pints_optimisers - :members: - :undoc-members: - :show-inheritance: - -pybop.optimisers.scipy\_minimize module ---------------------------------------- - -.. automodule:: pybop.optimisers.scipy_minimize - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: pybop.optimisers - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pybop.parameters.rst b/docs/source/pybop.parameters.rst deleted file mode 100644 index 278ad82f..00000000 --- a/docs/source/pybop.parameters.rst +++ /dev/null @@ -1,37 +0,0 @@ -pybop.parameters package -======================== - -Submodules ----------- - -pybop.parameters.base\_parameter module ---------------------------------------- - -.. automodule:: pybop.parameters.base_parameter - :members: - :undoc-members: - :show-inheritance: - -pybop.parameters.base\_parameter\_set module --------------------------------------------- - -.. automodule:: pybop.parameters.base_parameter_set - :members: - :undoc-members: - :show-inheritance: - -pybop.parameters.priors module ------------------------------- - -.. automodule:: pybop.parameters.priors - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: pybop.parameters - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pybop.plotting.rst b/docs/source/pybop.plotting.rst deleted file mode 100644 index 21064bb0..00000000 --- a/docs/source/pybop.plotting.rst +++ /dev/null @@ -1,53 +0,0 @@ -pybop.plotting package -====================== - -Submodules ----------- - -pybop.plotting.plot\_convergence module ---------------------------------------- - -.. automodule:: pybop.plotting.plot_convergence - :members: - :undoc-members: - :show-inheritance: - -pybop.plotting.plot\_cost2d module ----------------------------------- - -.. automodule:: pybop.plotting.plot_cost2d - :members: - :undoc-members: - :show-inheritance: - -pybop.plotting.plot\_parameters module --------------------------------------- - -.. automodule:: pybop.plotting.plot_parameters - :members: - :undoc-members: - :show-inheritance: - -pybop.plotting.plotly\_manager module -------------------------------------- - -.. automodule:: pybop.plotting.plotly_manager - :members: - :undoc-members: - :show-inheritance: - -pybop.plotting.quick\_plot module ---------------------------------- - -.. automodule:: pybop.plotting.quick_plot - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: pybop.plotting - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pybop.rst b/docs/source/pybop.rst deleted file mode 100644 index d2ef17f3..00000000 --- a/docs/source/pybop.rst +++ /dev/null @@ -1,42 +0,0 @@ -pybop package -============= - -Subpackages ------------ - -.. toctree:: - :maxdepth: 4 - - pybop.costs - pybop.datasets - pybop.models - pybop.optimisers - pybop.parameters - pybop.plotting - -Submodules ----------- - -pybop.optimisation module -------------------------- - -.. automodule:: pybop.optimisation - :members: - :undoc-members: - :show-inheritance: - -.. pybop.version module -.. -------------------- - -.. .. automodule:: pybop.version -.. :members: -.. :undoc-members: -.. :show-inheritance: - -.. Module contents -.. --------------- - -.. .. automodule:: pybop -.. :members: -.. :undoc-members: -.. :show-inheritance: diff --git a/docs/user_guide/index.md b/docs/user_guide/index.md index 76fd9cb2..0a5496f4 100644 --- a/docs/user_guide/index.md +++ b/docs/user_guide/index.md @@ -19,4 +19,4 @@ installation usage -```{toctree} +``` diff --git a/examples/costs/standalone.py b/examples/costs/standalone.py new file mode 100644 index 00000000..f4fa74f9 --- /dev/null +++ b/examples/costs/standalone.py @@ -0,0 +1,72 @@ +import pybop +import numpy as np + + +class StandaloneCost(pybop.BaseCost): + """ + A standalone cost function example that inherits from pybop.BaseCost. + + This class represents a simple cost function without a problem obkect, used for demonstration purposes. + It is a quadratic function of one variable with a constant term, defined by + the formula: cost(x) = x^2 + 42. + + Parameters + ---------- + problem : object, optional + A dummy problem instance used to initialize the superclass. This is not + used in the current class but is accepted for compatibility with the + BaseCost interface. + x0 : array-like + The initial guess for the optimization problem, set to [4.2]. + n_parameters : int + The number of parameters in the model, which is 1 in this case. + bounds : dict + A dictionary containing the lower and upper bounds for the parameter, + set to [-1] and [10], respectively. + + Methods + ------- + __call__(x, grad=None) + Calculate the cost for a given parameter value. + """ + + def __init__(self, problem=None): + """ + Initialize the StandaloneCost class with optional problem instance. + + The problem parameter is not utilized in this subclass. The initial guess, + number of parameters, and bounds are predefined for the standalone cost function. + """ + super().__init__(problem) + + self.x0 = np.array([4.2]) + self.n_parameters = len(self.x0) + + self.bounds = dict( + lower=[-1], + upper=[10], + ) + + def __call__(self, x, grad=None): + """ + Calculate the cost for a given parameter value. + + The cost function is defined as cost(x) = x^2 + 42, where x is the + parameter value. + + Parameters + ---------- + x : array-like + A one-element array containing the parameter value for which to + evaluate the cost. + grad : array-like, optional + Unused parameter, present for compatibility with gradient-based + optimizers. + + Returns + ------- + float + The calculated cost value for the given parameter. + """ + + return x[0] ** 2 + 42 diff --git a/examples/scripts/parameters/fit_ecm_parameters.json b/examples/scripts/parameters/fit_ecm_parameters.json new file mode 100644 index 00000000..63377470 --- /dev/null +++ b/examples/scripts/parameters/fit_ecm_parameters.json @@ -0,0 +1,24 @@ +{ + "chemistry": "ecm", + "Initial SoC": 0.5, + "Initial temperature [K]": 298.15, + "Cell capacity [A.h]": 5, + "Nominal cell capacity [A.h]": 5, + "Ambient temperature [K]": 298.15, + "Current function [A]": 5, + "Upper voltage cut-off [V]": 4.2, + "Lower voltage cut-off [V]": 3.0, + "Cell thermal mass [J/K]": 1000, + "Cell-jig heat transfer coefficient [W/K]": 10, + "Jig thermal mass [J/K]": 500, + "Jig-air heat transfer coefficient [W/K]": 10, + "Open-circuit voltage [V]": "Unable to write value to JSON file", + "R0 [Ohm]": 0.000944987987318333, + "Element-1 initial overpotential [V]": 0, + "Element-2 initial overpotential [V]": 0, + "R1 [Ohm]": 0.0002590935163068119, + "R2 [Ohm]": 0.0003, + "C1 [F]": 10000, + "C2 [F]": 5000, + "Entropic change [V/K]": 0.0004 +} diff --git a/noxfile.py b/noxfile.py index dddabfa7..739f86e0 100644 --- a/noxfile.py +++ b/noxfile.py @@ -35,7 +35,7 @@ def notebooks(session): @nox.session -def build_docs(session): +def docs(session): """ Build the documentation and load it in a browser tab, rebuilding on changes. Credit: PyBaMM Team diff --git a/pybop/__init__.py b/pybop/__init__.py index 48a24b2d..7b1fad9e 100644 --- a/pybop/__init__.py +++ b/pybop/__init__.py @@ -26,12 +26,12 @@ # # Cost function class # -from .costs.error_costs import BaseCost, RootMeanSquaredError, SumSquaredError +from ._costs import BaseCost, RootMeanSquaredError, SumSquaredError # # Dataset class # -from .datasets.base_dataset import Dataset +from ._dataset import Dataset # # Model classes diff --git a/pybop/_costs.py b/pybop/_costs.py new file mode 100644 index 00000000..71ae6c98 --- /dev/null +++ b/pybop/_costs.py @@ -0,0 +1,229 @@ +import numpy as np + + +class BaseCost: + """ + Base class for defining cost functions. + + This class is intended to be subclassed to create specific cost functions + for evaluating model predictions against a set of data. The cost function + quantifies the goodness-of-fit between the model predictions and the + observed data, with a lower cost value indicating a better fit. + + Parameters + ---------- + problem : object + A problem instance containing the data and functions necessary for + evaluating the cost function. + _target : array-like + An array containing the target data to fit. + x0 : array-like + The initial guess for the model parameters. + bounds : tuple + The bounds for the model parameters. + n_parameters : int + The number of parameters in the model. + """ + + def __init__(self, problem): + self.problem = problem + if problem is not None: + self._target = problem._target + self.x0 = problem.x0 + self.bounds = problem.bounds + self.n_parameters = problem.n_parameters + + def __call__(self, x, grad=None): + """ + Calculate the cost function value for a given set of parameters. + + This method must be implemented by subclasses. + + Parameters + ---------- + x : array-like + The parameters for which to evaluate the cost. + grad : array-like, optional + An array to store the gradient of the cost function with respect + to the parameters. + + Returns + ------- + float + The calculated cost function value. + + Raises + ------ + NotImplementedError + If the method has not been implemented by the subclass. + """ + + raise NotImplementedError + + +class RootMeanSquaredError(BaseCost): + """ + Root mean square error cost function. + + Computes the root mean square error between model predictions and the target + data, providing a measure of the differences between predicted values and + observed values. + + Inherits all parameters and attributes from ``BaseCost``. + + """ + + def __init__(self, problem): + super(RootMeanSquaredError, self).__init__(problem) + + def __call__(self, x, grad=None): + """ + Calculate the root mean square error for a given set of parameters. + + Parameters + ---------- + x : array-like + The parameters for which to evaluate the cost. + grad : array-like, optional + An array to store the gradient of the cost function with respect + to the parameters. + + Returns + ------- + float + The root mean square error. + + Raises + ------ + ValueError + If an error occurs during the calculation of the cost. + """ + + try: + prediction = self.problem.evaluate(x) + + if len(prediction) < len(self._target): + return np.float64(np.inf) # simulation stopped early + else: + return np.sqrt(np.mean((prediction - self._target) ** 2)) + + except Exception as e: + raise ValueError(f"Error in cost calculation: {e}") + + +class SumSquaredError(BaseCost): + """ + Sum of squared errors cost function. + + Computes the sum of the squares of the differences between model predictions + and target data, which serves as a measure of the total error between the + predicted and observed values. + + Inherits all parameters and attributes from ``BaseCost``. + + Additional Attributes + --------------------- + _de : float + The gradient of the cost function to use if an error occurs during + evaluation. Defaults to 1.0. + + """ + + def __init__(self, problem): + super(SumSquaredError, self).__init__(problem) + + # Default fail gradient + self._de = 1.0 + + def __call__(self, x, grad=None): + """ + Calculate the sum of squared errors for a given set of parameters. + + Parameters + ---------- + x : array-like + The parameters for which to evaluate the cost. + grad : array-like, optional + An array to store the gradient of the cost function with respect + to the parameters. + + Returns + ------- + float + The sum of squared errors. + + Raises + ------ + ValueError + If an error occurs during the calculation of the cost. + """ + try: + prediction = self.problem.evaluate(x) + + if len(prediction) < len(self._target): + return np.float64(np.inf) # simulation stopped early + else: + return np.sum( + (np.sum(((prediction - self._target) ** 2), axis=0)), + axis=0, + ) + + except Exception as e: + raise ValueError(f"Error in cost calculation: {e}") + + def evaluateS1(self, x): + """ + Compute the cost and its gradient with respect to the parameters. + + Parameters + ---------- + x : array-like + The parameters for which to compute the cost and gradient. + + Returns + ------- + tuple + A tuple containing the cost and the gradient. The cost is a float, + and the gradient is an array-like of the same length as `x`. + + Raises + ------ + ValueError + If an error occurs during the calculation of the cost or gradient. + """ + try: + y, dy = self.problem.evaluateS1(x) + if len(y) < len(self._target): + e = np.float64(np.inf) + de = self._de * np.ones(self.problem.n_parameters) + else: + dy = dy.reshape( + ( + self.problem.n_time_data, + self.problem.n_outputs, + self.problem.n_parameters, + ) + ) + r = y - self._target + e = np.sum(np.sum(r**2, axis=0), axis=0) + de = 2 * np.sum(np.sum((r.T * dy.T), axis=2), axis=1) + + return e, de + + except Exception as e: + raise ValueError(f"Error in cost calculation: {e}") + + def set_fail_gradient(self, de): + """ + Set the fail gradient to a specified value. + + The fail gradient is used if an error occurs during the calculation + of the gradient. This method allows updating the default gradient value. + + Parameters + ---------- + de : float + The new fail gradient value to be used. + """ + de = float(de) + self._de = de diff --git a/pybop/_dataset.py b/pybop/_dataset.py new file mode 100644 index 00000000..9a5f6650 --- /dev/null +++ b/pybop/_dataset.py @@ -0,0 +1,64 @@ +import pybamm + + +class Dataset: + """ + Represents a collection of experimental observations. + + This class provides a structured way to store and work with experimental data, + which may include applying operations such as interpolation. + + Parameters + ---------- + name : str + The name of the dataset, providing a label for identification. + data : array-like + The actual experimental data, typically in a structured form such as + a NumPy array or a pandas DataFrame. + + """ + + def __init__(self, name, data): + """ + Initialize a Dataset instance with a name and data. + + Parameters + ---------- + name : str + The name for the dataset. + data : array-like + The experimental data to store within the dataset. + """ + + self.name = name + self.data = data + + def __repr__(self): + """ + Return a string representation of the Dataset instance. + + Returns + ------- + str + A string that includes the name and data of the dataset. + """ + return f"Dataset: {self.name} \n Data: {self.data}" + + def Interpolant(self): + """ + Create an interpolation function of the dataset based on the independent variable. + + Currently, only time-based interpolation is supported. This method modifies + the instance's Interpolant attribute to be an interpolation function that + can be evaluated at different points in time. + + Raises + ------ + NotImplementedError + If the independent variable for interpolation is not supported. + """ + + if self.variable == "time": + self.Interpolant = pybamm.Interpolant(self.x, self.y, pybamm.t) + else: + NotImplementedError("Only time interpolation is supported") diff --git a/pybop/costs/__init__.py b/pybop/costs/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/pybop/costs/error_costs.py b/pybop/costs/error_costs.py deleted file mode 100644 index 2c497d45..00000000 --- a/pybop/costs/error_costs.py +++ /dev/null @@ -1,114 +0,0 @@ -import numpy as np - - -class BaseCost: - """ - Base class for defining cost functions. - This class computes a corresponding goodness-of-fit for a corresponding model prediction and dataset. - Lower cost values indicate a better fit. - """ - - def __init__(self, problem): - self.problem = problem - if problem is not None: - self._target = problem._target - self.x0 = problem.x0 - self.bounds = problem.bounds - self.n_parameters = problem.n_parameters - - def __call__(self, x, grad=None): - """ - Returns the cost function value and computes the cost. - """ - raise NotImplementedError - - -class RootMeanSquaredError(BaseCost): - """ - Defines the root mean square error cost function. - """ - - def __init__(self, problem): - super(RootMeanSquaredError, self).__init__(problem) - - def __call__(self, x, grad=None): - """ - Computes the cost. - """ - try: - prediction = self.problem.evaluate(x) - - if len(prediction) < len(self._target): - return np.float64(np.inf) # simulation stopped early - else: - return np.sqrt(np.mean((prediction - self._target) ** 2)) - - except Exception as e: - raise ValueError(f"Error in cost calculation: {e}") - - -class SumSquaredError(BaseCost): - """ - Defines the sum squared error cost function. - - The initial fail gradient is set equal to one, but this can be - changed at any time with :meth:`set_fail_gradient()`. - """ - - def __init__(self, problem): - super(SumSquaredError, self).__init__(problem) - - # Default fail gradient - self._de = 1.0 - - def __call__(self, x, grad=None): - """ - Computes the cost. - """ - try: - prediction = self.problem.evaluate(x) - - if len(prediction) < len(self._target): - return np.float64(np.inf) # simulation stopped early - else: - return np.sum( - (np.sum(((prediction - self._target) ** 2), axis=0)), - axis=0, - ) - - except Exception as e: - raise ValueError(f"Error in cost calculation: {e}") - - def evaluateS1(self, x): - """ - Compute the cost and corresponding - gradients with respect to the parameters. - """ - try: - y, dy = self.problem.evaluateS1(x) - if len(y) < len(self._target): - e = np.float64(np.inf) - de = self._de * np.ones(self.problem.n_parameters) - else: - dy = dy.reshape( - ( - self.problem.n_time_data, - self.problem.n_outputs, - self.problem.n_parameters, - ) - ) - r = y - self._target - e = np.sum(np.sum(r**2, axis=0), axis=0) - de = 2 * np.sum(np.sum((r.T * dy.T), axis=2), axis=1) - - return e, de - - except Exception as e: - raise ValueError(f"Error in cost calculation: {e}") - - def set_fail_gradient(self, de): - """ - Sets the fail gradient for this optimiser. - """ - de = float(de) - self._de = de diff --git a/pybop/costs/standalone.py b/pybop/costs/standalone.py deleted file mode 100644 index 197dcca5..00000000 --- a/pybop/costs/standalone.py +++ /dev/null @@ -1,18 +0,0 @@ -import pybop -import numpy as np - - -class StandaloneCost(pybop.BaseCost): - def __init__(self, problem=None): - super().__init__(problem) - - self.x0 = np.array([4.2]) - self.n_parameters = len(self.x0) - - self.bounds = dict( - lower=[-1], - upper=[10], - ) - - def __call__(self, x, grad=None): - return x[0] ** 2 + 42 diff --git a/pybop/datasets/__init__.py b/pybop/datasets/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/pybop/datasets/base_dataset.py b/pybop/datasets/base_dataset.py deleted file mode 100644 index ed194ae4..00000000 --- a/pybop/datasets/base_dataset.py +++ /dev/null @@ -1,20 +0,0 @@ -import pybamm - - -class Dataset: - """ - Class for experimental observations. - """ - - def __init__(self, name, data): - self.name = name - self.data = data - - def __repr__(self): - return f"Dataset: {self.name} \n Data: {self.data}" - - def Interpolant(self): - if self.variable == "time": - self.Interpolant = pybamm.Interpolant(self.x, self.y, pybamm.t) - else: - NotImplementedError("Only time interpolation is supported") diff --git a/setup.py b/setup.py index 78b54e53..2437425a 100644 --- a/setup.py +++ b/setup.py @@ -41,6 +41,7 @@ "sphinx-autobuild", "sphinx-autoapi", "sphinx_copybutton", + "sphinx_favicon", "sphinx_design", "myst-parser", ], diff --git a/tests/unit/test_optimisation.py b/tests/unit/test_optimisation.py index 22822753..b6adbbdf 100644 --- a/tests/unit/test_optimisation.py +++ b/tests/unit/test_optimisation.py @@ -1,7 +1,7 @@ import pybop import numpy as np import pytest -from pybop.costs.standalone import StandaloneCost +from examples.costs.standalone import StandaloneCost class TestOptimisation: From dafa7509d61da417fe9bbe384af8004504ed58a1 Mon Sep 17 00:00:00 2001 From: Brady Planden Date: Sun, 10 Dec 2023 16:54:00 +0000 Subject: [PATCH 06/22] Updts docstrings across package, remove redundant base naming convention for certain filenames --- docs/_templates/autoapi/index.rst | 16 + docs/api/index.rst | 1 + docs/api/pybop/_problem/index.rst | 14 +- docs/api/pybop/index.rst | 717 ++++++++++++++++-- docs/api/pybop/models/base_model/index.rst | 117 ++- docs/api/pybop/models/empirical/ecm/index.rst | 47 ++ docs/api/pybop/models/empirical/index.rst | 56 ++ docs/api/pybop/models/index.rst | 1 + .../models/lithium_ion/base_echem/index.rst | 35 - .../pybop/models/lithium_ion/echem/index.rst | 76 ++ docs/api/pybop/models/lithium_ion/index.rst | 49 +- docs/api/pybop/optimisation/index.rst | 5 + .../pybop/optimisers/base_optimiser/index.rst | 52 +- docs/api/pybop/optimisers/index.rst | 2 +- .../pybop/optimisers/nlopt_optimize/index.rst | 57 +- .../optimisers/pints_optimisers/index.rst | 131 +++- .../pybop/optimisers/scipy_minimize/index.rst | 46 -- .../optimisers/scipy_optimisers/index.rst | 115 +++ .../pybop/parameters/base_parameter/index.rst | 41 - .../parameters/base_parameter_set/index.rst | 23 - docs/api/pybop/parameters/index.rst | 4 +- docs/api/pybop/parameters/parameter/index.rst | 95 +++ .../pybop/parameters/parameter_set/index.rst | 95 +++ docs/api/pybop/parameters/priors/index.rst | 112 ++- docs/conf.py | 1 + pybop/models/base_model.py | 141 +++- pybop/models/empirical/__init__.py | 2 +- .../models/empirical/{base_ecm.py => ecm.py} | 26 +- pybop/models/lithium_ion/__init__.py | 2 +- pybop/models/lithium_ion/base_echem.py | 88 --- pybop/models/lithium_ion/echem.py | 138 ++++ pybop/optimisers/base_optimiser.py | 59 +- pybop/optimisers/nlopt_optimize.py | 59 +- pybop/optimisers/pints_optimisers.py | 138 +++- pybop/optimisers/scipy_optimisers.py | 98 ++- pybop/parameters/parameter.py | 84 +- pybop/parameters/parameter_set.py | 83 +- pybop/parameters/priors.py | 175 ++++- 38 files changed, 2559 insertions(+), 442 deletions(-) create mode 100644 docs/_templates/autoapi/index.rst create mode 100644 docs/api/pybop/models/empirical/ecm/index.rst create mode 100644 docs/api/pybop/models/empirical/index.rst delete mode 100644 docs/api/pybop/models/lithium_ion/base_echem/index.rst create mode 100644 docs/api/pybop/models/lithium_ion/echem/index.rst delete mode 100644 docs/api/pybop/optimisers/scipy_minimize/index.rst create mode 100644 docs/api/pybop/optimisers/scipy_optimisers/index.rst delete mode 100644 docs/api/pybop/parameters/base_parameter/index.rst delete mode 100644 docs/api/pybop/parameters/base_parameter_set/index.rst create mode 100644 docs/api/pybop/parameters/parameter/index.rst create mode 100644 docs/api/pybop/parameters/parameter_set/index.rst rename pybop/models/empirical/{base_ecm.py => ecm.py} (51%) delete mode 100644 pybop/models/lithium_ion/base_echem.py create mode 100644 pybop/models/lithium_ion/echem.py diff --git a/docs/_templates/autoapi/index.rst b/docs/_templates/autoapi/index.rst new file mode 100644 index 00000000..8cb56d2e --- /dev/null +++ b/docs/_templates/autoapi/index.rst @@ -0,0 +1,16 @@ +API Reference +============= + +This page contains auto-generated API reference documentation [#f1]_. + +.. toctree:: + :titlesonly: + :maxdepth: 2 + + {% for page in pages %} + {% if page.top_level_object and page.display %} + {{ page.include_path }} + {% endif %} + {% endfor %} + +.. [#f1] Created with `sphinx-autoapi `_ diff --git a/docs/api/index.rst b/docs/api/index.rst index 52c74ac8..a248a75b 100644 --- a/docs/api/index.rst +++ b/docs/api/index.rst @@ -5,6 +5,7 @@ This page contains auto-generated API reference documentation [#f1]_. .. toctree:: :titlesonly: + :maxdepth: 2 /api/pybop/index diff --git a/docs/api/pybop/_problem/index.rst b/docs/api/pybop/_problem/index.rst index a51adad8..58091c11 100644 --- a/docs/api/pybop/_problem/index.rst +++ b/docs/api/pybop/_problem/index.rst @@ -24,13 +24,13 @@ Classes Defines the PyBOP base problem, following the PINTS interface. - .. py:method:: evaluate(parameters) + .. py:method:: evaluate(x) :abstractmethod: Evaluate the model with the given parameters and return the signal. - .. py:method:: evaluateS1(parameters) + .. py:method:: evaluateS1(x) :abstractmethod: Evaluate the model with the given parameters and return the signal and @@ -45,12 +45,12 @@ Classes Defines the problem class for a design optimiation problem. - .. py:method:: evaluate(parameters) + .. py:method:: evaluate(x) Evaluate the model with the given parameters and return the signal. - .. py:method:: evaluateS1(parameters) + .. py:method:: evaluateS1(x) Evaluate the model with the given parameters and return the signal and its derivatives. @@ -62,19 +62,19 @@ Classes -.. py:class:: FittingProblem(model, parameters, dataset, signal='Terminal voltage [V]', check_model=True, init_soc=None, x0=None) +.. py:class:: FittingProblem(model, parameters, dataset, signal='Voltage [V]', check_model=True, init_soc=None, x0=None) Bases: :py:obj:`BaseProblem` Defines the problem class for a fitting (parameter estimation) problem. - .. py:method:: evaluate(parameters) + .. py:method:: evaluate(x) Evaluate the model with the given parameters and return the signal. - .. py:method:: evaluateS1(parameters) + .. py:method:: evaluateS1(x) Evaluate the model with the given parameters and return the signal and its derivatives. diff --git a/docs/api/pybop/index.rst b/docs/api/pybop/index.rst index 6ac0d00d..a3132137 100644 --- a/docs/api/pybop/index.rst +++ b/docs/api/pybop/index.rst @@ -57,6 +57,7 @@ Classes pybop.PlotlyManager pybop.RootMeanSquaredError pybop.SNES + pybop.SciPyDifferentialEvolution pybop.SciPyMinimize pybop.StandardPlot pybop.SumSquaredError @@ -92,8 +93,23 @@ Attributes Bases: :py:obj:`pints.Adam` - Adam optimiser. Inherits from the PINTS Adam class. - https://github.com/pints-team/pints/blob/main/pints/_optimisers/_adam.py + Implements the Adam optimization algorithm. + + This class extends the Adam optimizer from the PINTS library, which combines + ideas from RMSProp and Stochastic Gradient Descent with momentum. Note that + this optimizer does not support boundary constraints. + + :param x0: Initial position from which optimization will start. + :type x0: array_like + :param sigma0: Initial step size (default is 0.1). + :type sigma0: float, optional + :param bounds: Ignored by this optimizer, provided for API consistency. + :type bounds: sequence or ``Bounds``, optional + + .. seealso:: + + :obj:`pints.Adam` + The PINTS implementation this class is based on. .. py:class:: BaseCost(problem) @@ -141,7 +157,37 @@ Attributes .. py:class:: BaseModel(name='Base Model') - Base class for pybop models. + A base class for constructing and simulating models using PyBaMM. + + This class serves as a foundation for building specific models in PyBaMM. + It provides methods to set up the model, define parameters, and perform + simulations. The class is designed to be subclassed for creating models + with custom behavior. + + .. method:: build(dataset=None, parameters=None, check_model=True, init_soc=None) + + Construct the PyBaMM model if not already built. + + .. method:: set_init_soc(init_soc) + + Set the initial state of charge for the battery model. + + .. method:: set_params() + + Assign the parameters to the model. + + .. method:: simulate(inputs, t_eval) + + Execute the forward model simulation and return the result. + + .. method:: simulateS1(inputs, t_eval) + + Perform the forward model simulation with sensitivities. + + .. method:: predict(inputs=None, t_eval=None, parameter_set=None, experiment=None, init_soc=None) + + Solve the model using PyBaMM's simulation framework and return the solution. + .. py:property:: built_model @@ -172,60 +218,168 @@ Attributes .. py:method:: build(dataset=None, parameters=None, check_model=True, init_soc=None) - Build the PyBOP model (if not built already). - For PyBaMM forward models, this method follows a - similar process to pybamm.Simulation.build(). + Construct the PyBaMM model if not already built, and set parameters. + + This method initializes the model components, applies the given parameters, + sets up the mesh and discretization if needed, and prepares the model + for simulations. + + :param dataset: The dataset to be used in the model construction. + :type dataset: pybamm.Dataset, optional + :param parameters: A dictionary containing parameter values to apply to the model. + :type parameters: dict, optional + :param check_model: If True, the model will be checked for correctness after construction. + :type check_model: bool, optional + :param init_soc: The initial state of charge to be used in simulations. + :type init_soc: float, optional .. py:method:: predict(inputs=None, t_eval=None, parameter_set=None, experiment=None, init_soc=None) - Create a PyBaMM simulation object, solve it, and return a solution object. + Solve the model using PyBaMM's simulation framework and return the solution. + + This method sets up a PyBaMM simulation by configuring the model, parameters, experiment + (if any), and initial state of charge (if provided). It then solves the simulation and + returns the resulting solution object. + + :param inputs: Input parameters for the simulation. If the input is array-like, it is converted + to a dictionary using the model's fitting keys. Defaults to None, indicating + that the default parameters should be used. + :type inputs: dict or array-like, optional + :param t_eval: An array of time points at which to evaluate the solution. Defaults to None, + which means the time points need to be specified within experiment or elsewhere. + :type t_eval: array-like, optional + :param parameter_set: A PyBaMM ParameterValues object or a dictionary containing the parameter values + to use for the simulation. Defaults to the model's current ParameterValues if None. + :type parameter_set: pybamm.ParameterValues, optional + :param experiment: A PyBaMM Experiment object specifying the experimental conditions under which + the simulation should be run. Defaults to None, indicating no experiment. + :type experiment: pybamm.Experiment, optional + :param init_soc: The initial state of charge for the simulation, as a fraction (between 0 and 1). + Defaults to None. + :type init_soc: float, optional + + :returns: The solution object returned after solving the simulation. + :rtype: pybamm.Solution + + :raises ValueError: If the model has not been configured properly before calling this method or + if PyBaMM models are not supported by the current simulation method. .. py:method:: set_init_soc(init_soc) - Set the initial state of charge. + Set the initial state of charge for the battery model. + + :param init_soc: The initial state of charge to be used in the model. + :type init_soc: float .. py:method:: set_params() - Set the parameters in the model. + Assign the parameters to the model. + + This method processes the model with the given parameters, sets up + the geometry, and updates the model instance. .. py:method:: simulate(inputs, t_eval) - Run the forward model and return the result in Numpy array format - aligning with Pints' ForwardModel simulate method. + Execute the forward model simulation and return the result. + + :param inputs: The input parameters for the simulation. If array-like, it will be + converted to a dictionary using the model's fit keys. + :type inputs: dict or array-like + :param t_eval: An array of time points at which to evaluate the solution. + :type t_eval: array-like + + :returns: The simulation result corresponding to the specified signal. + :rtype: array-like + + :raises ValueError: If the model has not been built before simulation. .. py:method:: simulateS1(inputs, t_eval) - Run the forward model and return the function evaulation and it's gradient - aligning with Pints' ForwardModel simulateS1 method. + Perform the forward model simulation with sensitivities. + + :param inputs: The input parameters for the simulation. If array-like, it will be + converted to a dictionary using the model's fit keys. + :type inputs: dict or array-like + :param t_eval: An array of time points at which to evaluate the solution and its + sensitivities. + :type t_eval: array-like + + :returns: A tuple containing the simulation result and the sensitivities. + :rtype: tuple + + :raises ValueError: If the model has not been built before simulation. .. py:class:: BaseOptimiser - Base class for the optimisation methods. + A base class for defining optimisation methods. + + This class serves as a template for creating optimisers. It provides a basic structure for + an optimisation algorithm, including the initial setup and a method stub for performing + the optimisation process. Child classes should override the optimise and _runoptimise + methods with specific algorithms. + + .. method:: optimise(cost_function, x0=None, bounds=None, maxiter=None) + + Initiates the optimisation process. This is a stub and should be implemented in child classes. + + .. method:: _runoptimise(cost_function, x0=None, bounds=None) + + Contains the logic for the optimisation algorithm. This is a stub and should be implemented in child classes. + + .. method:: name() + + Returns the name of the optimiser. .. py:method:: _runoptimise(cost_function, x0=None, bounds=None) - Run optimisation method, to be overloaded by child classes. + Contains the logic for the optimisation algorithm. + + This method should be implemented by child classes to perform the actual optimisation. + :param cost_function: The cost function to be minimised by the optimiser. + :type cost_function: callable + :param x0: Initial guess for the parameters. Default is None. + :type x0: ndarray, optional + :param bounds: Bounds on the parameters. Default is None. + :type bounds: sequence or Bounds, optional + + :returns: * *This method is expected to return the result of the optimisation, the format of which* + * *will be determined by the child class implementation.* .. py:method:: name() Returns the name of the optimiser. + :returns: The name of the optimiser, which is "BaseOptimiser" for this base class. + :rtype: str + + + .. py:method:: optimise(cost_function, x0=None, bounds=None, maxiter=None) - .. py:method:: optimise(cost_function, x0=None, bounds=None) + Initiates the optimisation process. - Optimisiation method to be overloaded by child classes. + This method should be overridden by child classes with the specific optimisation algorithm. + :param cost_function: The cost function to be minimised by the optimiser. + :type cost_function: callable + :param x0: Initial guess for the parameters. Default is None. + :type x0: ndarray, optional + :param bounds: Bounds on the parameters. Default is None. + :type bounds: sequence or Bounds, optional + :param maxiter: Maximum number of iterations to perform. Default is None. + :type maxiter: int, optional + + :rtype: The result of the optimisation process. The specific type of this result will depend on the child implementation. @@ -234,8 +388,23 @@ Attributes Bases: :py:obj:`pints.CMAES` - Class for the PINTS optimisation. Extends the BaseOptimiser class. - https://github.com/pints-team/pints/blob/main/pints/_optimisers/_cmaes.py + Adapter for the Covariance Matrix Adaptation Evolution Strategy (CMA-ES) optimizer in PINTS. + + CMA-ES is an evolutionary algorithm for difficult non-linear non-convex optimization problems. + It adapts the covariance matrix of a multivariate normal distribution to capture the shape of the cost landscape. + + :param x0: The initial parameter vector to optimize. + :type x0: array_like + :param sigma0: Initial standard deviation of the sampling distribution, defaults to 0.1. + :type sigma0: float, optional + :param bounds: A dictionary with 'lower' and 'upper' keys containing arrays for lower and upper bounds on the parameters. + If ``None``, no bounds are enforced. + :type bounds: dict, optional + + .. seealso:: + + :obj:`pints.CMAES` + PINTS implementation of CMA-ES algorithm. .. py:class:: Dataset(name, data) @@ -279,12 +448,12 @@ Attributes Defines the problem class for a design optimiation problem. - .. py:method:: evaluate(parameters) + .. py:method:: evaluate(x) Evaluate the model with the given parameters and return the signal. - .. py:method:: evaluateS1(parameters) + .. py:method:: evaluateS1(x) Evaluate the model with the given parameters and return the signal and its derivatives. @@ -299,36 +468,68 @@ Attributes .. py:class:: Exponential(scale) - Exponential prior class. + Represents an exponential distribution with a specified scale parameter. + + This class provides methods to calculate the pdf, the log pdf, and to generate random + variates from the distribution. + + :param scale: The scale parameter (lambda) of the exponential distribution. + :type scale: float .. py:method:: __repr__() - Return repr(self). + Returns a string representation of the Uniform object. .. py:method:: logpdf(x) + Calculates the logarithm of the pdf of the exponential distribution at x. + + :param x: The point at which to evaluate the log pdf. + :type x: float + + :returns: The log of the probability density function value at x. + :rtype: float + .. py:method:: pdf(x) + Calculates the probability density function of the exponential distribution at x. + + :param x: The point at which to evaluate the pdf. + :type x: float + + :returns: The probability density function value at x. + :rtype: float + .. py:method:: rvs(size) + Generates random variates from the exponential distribution. + :param size: The number of random variates to generate. + :type size: int -.. py:class:: FittingProblem(model, parameters, dataset, signal='Terminal voltage [V]', check_model=True, init_soc=None, x0=None) + :returns: An array of random variates from the exponential distribution. + :rtype: array_like + + :raises ValueError: If the size parameter is not positive. + + + +.. py:class:: FittingProblem(model, parameters, dataset, signal='Voltage [V]', check_model=True, init_soc=None, x0=None) Bases: :py:obj:`BaseProblem` Defines the problem class for a fitting (parameter estimation) problem. - .. py:method:: evaluate(parameters) + .. py:method:: evaluate(x) Evaluate the model with the given parameters and return the signal. - .. py:method:: evaluateS1(parameters) + .. py:method:: evaluateS1(x) Evaluate the model with the given parameters and return the signal and its derivatives. @@ -343,21 +544,55 @@ Attributes .. py:class:: Gaussian(mean, sigma) - Gaussian prior class. + Represents a Gaussian (normal) distribution with a given mean and standard deviation. + + This class provides methods to calculate the probability density function (pdf), + the logarithm of the pdf, and to generate random variates (rvs) from the distribution. + + :param mean: The mean (mu) of the Gaussian distribution. + :type mean: float + :param sigma: The standard deviation (sigma) of the Gaussian distribution. + :type sigma: float .. py:method:: __repr__() - Return repr(self). + Returns a string representation of the Gaussian object. .. py:method:: logpdf(x) + Calculates the logarithm of the probability density function of the Gaussian distribution at x. + + :param x: The point at which to evaluate the log pdf. + :type x: float + + :returns: The logarithm of the probability density function value at x. + :rtype: float + .. py:method:: pdf(x) + Calculates the probability density function of the Gaussian distribution at x. + + :param x: The point at which to evaluate the pdf. + :type x: float + + :returns: The probability density function value at x. + :rtype: float + .. py:method:: rvs(size) + Generates random variates from the Gaussian distribution. + + :param size: The number of random variates to generate. + :type size: int + + :returns: An array of random variates from the Gaussian distribution. + :rtype: array_like + + :raises ValueError: If the size parameter is not positive. + .. py:class:: GradientDescent(x0, sigma0=0.1, bounds=None) @@ -365,8 +600,23 @@ Attributes Bases: :py:obj:`pints.GradientDescent` - Gradient descent optimiser. Inherits from the PINTS gradient descent class. - https://github.com/pints-team/pints/blob/main/pints/_optimisers/_gradient_descent.py + Implements a simple gradient descent optimization algorithm. + + This class extends the gradient descent optimizer from the PINTS library, designed + to minimize a scalar function of one or more variables. Note that this optimizer + does not support boundary constraints. + + :param x0: Initial position from which optimization will start. + :type x0: array_like + :param sigma0: Initial step size (default is 0.1). + :type sigma0: float, optional + :param bounds: Ignored by this optimizer, provided for API consistency. + :type bounds: sequence or ``Bounds``, optional + + .. seealso:: + + :obj:`pints.GradientDescent` + The PINTS implementation this class is based on. .. py:class:: IRPropMin(x0, sigma0=0.1, bounds=None) @@ -374,37 +624,87 @@ Attributes Bases: :py:obj:`pints.IRPropMin` - IRProp- optimiser. Inherits from the PINTS IRPropMinus class. - https://github.com/pints-team/pints/blob/main/pints/_optimisers/_irpropmin.py + Implements the iRpropMin optimization algorithm. + + This class inherits from the PINTS IRPropMin class, which is an optimizer that + uses resilient backpropagation with weight-backtracking. It is designed to handle + problems with large plateaus, noisy gradients, and local minima. + + :param x0: Initial position from which optimization will start. + :type x0: array_like + :param sigma0: Initial step size (default is 0.1). + :type sigma0: float, optional + :param bounds: Lower and upper bounds for each optimization parameter. + :type bounds: dict, optional + .. seealso:: -.. py:class:: NLoptOptimize(n_param, xtol=None, method=None) + :obj:`pints.IRPropMin` + The PINTS implementation this class is based on. + + +.. py:class:: NLoptOptimize(n_param, xtol=None, method=None, maxiter=None) Bases: :py:obj:`pybop.optimisers.base_optimiser.BaseOptimiser` - Wrapper class for the NLOpt optimiser class. Extends the BaseOptimiser class. + Extends BaseOptimiser to utilize the NLopt library for nonlinear optimization. + + This class serves as an interface to the NLopt optimization algorithms. It allows the user to + define an optimization problem with bounds, initial guesses, and to select an optimization method + provided by NLopt. + + :param n_param: Number of parameters to optimize. + :type n_param: int + :param xtol: The relative tolerance for optimization (stopping criteria). If not provided, a default of 1e-5 is used. + :type xtol: float, optional + :param method: The NLopt algorithm to use for optimization. If not provided, LN_BOBYQA is used by default. + :type method: nlopt.algorithm, optional + :param maxiter: The maximum number of iterations to perform during optimization. If not provided, NLopt's default is used. + :type maxiter: int, optional + + .. method:: _runoptimise(cost_function, x0, bounds) + + Performs the optimization using the NLopt library. + + .. method:: needs_sensitivities() + + Indicates whether the optimizer requires gradient information. + + .. method:: name() + + Returns the name of the optimizer. + .. py:method:: _runoptimise(cost_function, x0, bounds) - Run the NLOpt optimisation method. + Runs the optimization process using the NLopt library. - Inputs - ---------- - cost_function: function for optimising - method: optimisation algorithm - x0: initialisation array - bounds: bounds array + :param cost_function: The objective function to minimize. It should take an array of parameter values and return the scalar cost. + :type cost_function: callable + :param x0: The initial guess for the parameters. + :type x0: array_like + :param bounds: A dictionary containing the 'lower' and 'upper' bounds arrays for the parameters. + :type bounds: dict + + :returns: A tuple containing the optimized parameter values and the final cost. + :rtype: tuple .. py:method:: name() - Returns the name of the optimiser. + Returns the name of this optimizer instance. + + :returns: The name 'NLoptOptimize' representing this NLopt optimization class. + :rtype: str .. py:method:: needs_sensitivities() - Returns True if the optimiser needs sensitivities. + Indicates if the optimizer requires gradient information for the cost function. + + :returns: False, as the default NLopt algorithms do not require gradient information. + :rtype: bool @@ -511,45 +811,192 @@ Attributes Credit: PINTS + .. py:method:: store_optimised_parameters(x) + + Store the optimised parameters in the PyBOP parameter class. + + .. py:class:: PSO(x0, sigma0=0.1, bounds=None) Bases: :py:obj:`pints.PSO` - Particle swarm optimiser. Inherits from the PINTS PSO class. - https://github.com/pints-team/pints/blob/main/pints/_optimisers/_pso.py + Implements a particle swarm optimization (PSO) algorithm. + + This class extends the PSO optimizer from the PINTS library. PSO is a + metaheuristic optimization method inspired by the social behavior of birds + flocking or fish schooling, suitable for global optimization problems. + + :param x0: Initial positions of particles, which the optimization will use. + :type x0: array_like + :param sigma0: Spread of the initial particle positions (default is 0.1). + :type sigma0: float, optional + :param bounds: Lower and upper bounds for each optimization parameter. + :type bounds: dict, optional + .. seealso:: -.. py:class:: Parameter(name, value=None, prior=None, bounds=None) + :obj:`pints.PSO` + The PINTS implementation this class is based on. - "" - Class for creating parameters in PyBOP. +.. py:class:: Parameter(name, initial_value=None, prior=None, bounds=None) + + + Represents a parameter within the PyBOP framework. + + This class encapsulates the definition of a parameter, including its name, prior + distribution, initial value, bounds, and a margin to ensure the parameter stays + within feasible limits during optimization or sampling. + + :param name: The name of the parameter. + :type name: str + :param initial_value: The initial value to be assigned to the parameter. Defaults to None. + :type initial_value: float, optional + :param prior: The prior distribution from which parameter values are drawn. Defaults to None. + :type prior: scipy.stats distribution, optional + :param bounds: A tuple defining the lower and upper bounds for the parameter. + Defaults to None. + :type bounds: tuple, optional + + .. method:: rvs(n_samples) + + Draw random samples from the parameter's prior distribution. + + .. method:: update(value) + + Update the parameter's current value. + + .. method:: set_margin(margin) + + Set the margin to a specified positive value less than 1. + + + :raises ValueError: If the lower bound is not strictly less than the upper bound, or if + the margin is set outside the interval (0, 1). .. py:method:: __repr__() - Return repr(self). + Return a string representation of the Parameter instance. + + :returns: A string including the parameter's name, prior, bounds, and current value. + :rtype: str .. py:method:: rvs(n_samples) - Returns a random value sample from the prior distribution. + Draw random samples from the parameter's prior distribution. + + The samples are constrained to be within the parameter's bounds, excluding + a predefined margin at the boundaries. + + :param n_samples: The number of samples to draw. + :type n_samples: int + + :returns: An array of samples drawn from the prior distribution within the parameter's bounds. + :rtype: array-like .. py:method:: set_margin(margin) - Sets the margin for the parameter. + Set the margin to a specified positive value less than 1. + + The margin is used to ensure parameter samples are not drawn exactly at the bounds, + which may be problematic in some optimization or sampling algorithms. + + :param margin: The new margin value to be used, which must be in the interval (0, 1). + :type margin: float + + :raises ValueError: If the margin is not between 0 and 1. .. py:method:: update(value) + Update the parameter's current value. + + :param value: The new value to be assigned to the parameter. + :type value: float + + + +.. py:class:: ParameterSet(json_path=None, params_dict=None) + + + Handles the import and export of parameter sets for battery models. + + This class provides methods to load parameters from a JSON file and to export them + back to a JSON file. It also includes custom logic to handle special cases, such + as parameter values that require specific initialization. + :param json_path: Path to a JSON file containing parameter data. If provided, parameters will be imported from this file during initialization. + :type json_path: str, optional + :param params_dict: A dictionary of parameters to initialize the ParameterSet with. If not provided, an empty dictionary is used. + :type params_dict: dict, optional -.. py:class:: ParameterSet + .. py:method:: _handle_special_cases() + Processes special cases for parameter values that require custom handling. + + For example, if the open-circuit voltage is specified as 'default', it will + fetch the default value from the PyBaMM empirical Thevenin model. + + + .. py:method:: export_parameters(output_json_path, fit_params=None) + + Exports parameters to a JSON file specified by `output_json_path`. + + The current state of the `params` attribute is written to the file. If `fit_params` + is provided, these parameters are updated before export. Non-serializable values + are handled and noted in the output JSON. + + :param output_json_path: The file path where the JSON output will be saved. + :type output_json_path: str + :param fit_params: Parameters that have been fitted and need to be included in the export. + :type fit_params: list of fitted parameter objects, optional + + :raises ValueError: If there are no parameters to export. + + + .. py:method:: import_parameters(json_path=None) + + Imports parameters from a JSON file specified by the `json_path` attribute. + + If a `json_path` is provided at initialization or as an argument, that JSON file + is loaded and the parameters are stored in the `params` attribute. Special cases + are handled appropriately. + + :param json_path: Path to the JSON file from which to import parameters. If provided, it overrides the instance's `json_path`. + :type json_path: str, optional + + :returns: The dictionary containing the imported parameters. + :rtype: dict + + :raises FileNotFoundError: If the specified JSON file cannot be found. + + + .. py:method:: is_json_serializable(value) + + Determines if the given `value` can be serialized to JSON format. + + :param value: The value to check for JSON serializability. + :type value: any + + :returns: True if the value is JSON serializable, False otherwise. + :rtype: bool + + + .. py:method:: pybamm(name) + :classmethod: + + Retrieves a PyBaMM parameter set by name. + + :param name: The name of the PyBaMM parameter set to retrieve. + :type name: str + + :returns: A PyBaMM parameter set corresponding to the provided name. + :rtype: pybamm.ParameterValues - Class for creating parameter sets in PyBOP. .. py:class:: PlotlyManager @@ -642,37 +1089,120 @@ Attributes Bases: :py:obj:`pints.SNES` - Stochastic natural evolution strategy optimiser. Inherits from the PINTS SNES class. - https://github.com/pints-team/pints/blob/main/pints/_optimisers/_snes.py + Implements the stochastic natural evolution strategy (SNES) optimization algorithm. + + Inheriting from the PINTS SNES class, this optimizer is an evolutionary algorithm + that evolves a probability distribution on the parameter space, guiding the search + for the optimum based on the natural gradient of expected fitness. + + :param x0: Initial position from which optimization will start. + :type x0: array_like + :param sigma0: Initial step size (default is 0.1). + :type sigma0: float, optional + :param bounds: Lower and upper bounds for each optimization parameter. + :type bounds: dict, optional + + .. seealso:: + :obj:`pints.SNES` + The PINTS implementation this class is based on. -.. py:class:: SciPyMinimize(method=None, bounds=None) + +.. py:class:: SciPyDifferentialEvolution(bounds=None, strategy='best1bin', maxiter=1000, popsize=15) + + + Bases: :py:obj:`pybop.optimisers.base_optimiser.BaseOptimiser` + + Adapts SciPy's differential_evolution function for global optimization. + + This class provides a global optimization strategy based on differential evolution, useful for problems involving continuous parameters and potentially multiple local minima. + + :param bounds: Bounds for variables. Must be provided as it is essential for differential evolution. + :type bounds: sequence or ``Bounds`` + :param strategy: The differential evolution strategy to use. Defaults to 'best1bin'. + :type strategy: str, optional + :param maxiter: Maximum number of iterations to perform. Defaults to 1000. + :type maxiter: int, optional + :param popsize: The number of individuals in the population. Defaults to 15. + :type popsize: int, optional + + .. py:method:: _runoptimise(cost_function, x0=None, bounds=None) + + Executes the optimization process using SciPy's differential_evolution function. + + :param cost_function: The objective function to minimize. + :type cost_function: callable + :param x0: Ignored parameter, provided for API consistency. + :type x0: array_like, optional + :param bounds: Bounds for the variables, required for differential evolution. + :type bounds: sequence or ``Bounds`` + + :returns: A tuple (x, final_cost) containing the optimized parameters and the value of ``cost_function`` at the optimum. + :rtype: tuple + + + .. py:method:: name() + + Provides the name of the optimization strategy. + + :returns: The name 'SciPyDifferentialEvolution'. + :rtype: str + + + .. py:method:: needs_sensitivities() + + Determines if the optimization algorithm requires gradient information. + + :returns: False, indicating that gradient information is not required for differential evolution. + :rtype: bool + + + +.. py:class:: SciPyMinimize(method=None, bounds=None, maxiter=None) Bases: :py:obj:`pybop.optimisers.base_optimiser.BaseOptimiser` - Wrapper class for the SciPy optimisation class. Extends the BaseOptimiser class. + Adapts SciPy's minimize function for use as an optimization strategy. + + This class provides an interface to various scalar minimization algorithms implemented in SciPy, allowing fine-tuning of the optimization process through method selection and option configuration. + + :param method: The type of solver to use. If not specified, defaults to 'COBYLA'. + :type method: str, optional + :param bounds: Bounds for variables as supported by the selected method. + :type bounds: sequence or ``Bounds``, optional + :param maxiter: Maximum number of iterations to perform. + :type maxiter: int, optional .. py:method:: _runoptimise(cost_function, x0, bounds) - Run the SciPy optimisation method. + Executes the optimization process using SciPy's minimize function. - Inputs - ---------- - cost_function: function for optimising - method: optimisation algorithm - x0: initialisation array - bounds: bounds array + :param cost_function: The objective function to minimize. + :type cost_function: callable + :param x0: Initial guess for the parameters. + :type x0: array_like + :param bounds: Bounds for the variables. + :type bounds: sequence or `Bounds` + + :returns: A tuple (x, final_cost) containing the optimized parameters and the value of `cost_function` at the optimum. + :rtype: tuple .. py:method:: name() - Returns the name of the optimiser. + Provides the name of the optimization strategy. + + :returns: The name 'SciPyMinimize'. + :rtype: str .. py:method:: needs_sensitivities() - Returns True if the optimiser needs sensitivities. + Determines if the optimization algorithm requires gradient information. + + :returns: False, indicating that gradient information is not required. + :rtype: bool @@ -816,21 +1346,55 @@ Attributes .. py:class:: Uniform(lower, upper) - Uniform prior class. + Represents a uniform distribution over a specified interval. + + This class provides methods to calculate the pdf, the log pdf, and to generate + random variates from the distribution. + + :param lower: The lower bound of the distribution. + :type lower: float + :param upper: The upper bound of the distribution. + :type upper: float .. py:method:: __repr__() - Return repr(self). + Returns a string representation of the Uniform object. .. py:method:: logpdf(x) + Calculates the logarithm of the pdf of the uniform distribution at x. + + :param x: The point at which to evaluate the log pdf. + :type x: float + + :returns: The log of the probability density function value at x. + :rtype: float + .. py:method:: pdf(x) + Calculates the probability density function of the uniform distribution at x. + + :param x: The point at which to evaluate the pdf. + :type x: float + + :returns: The probability density function value at x. + :rtype: float + .. py:method:: rvs(size) + Generates random variates from the uniform distribution. + + :param size: The number of random variates to generate. + :type size: int + + :returns: An array of random variates from the uniform distribution. + :rtype: array_like + + :raises ValueError: If the size parameter is not positive. + .. py:class:: XNES(x0, sigma0=0.1, bounds=None) @@ -838,8 +1402,21 @@ Attributes Bases: :py:obj:`pints.XNES` - Exponential natural evolution strategy optimiser. Inherits from the PINTS XNES class. - https://github.com/pints-team/pints/blob/main/pints/_optimisers/_xnes.py + Implements the Exponential Natural Evolution Strategy (XNES) optimizer from PINTS. + + XNES is an evolutionary algorithm that samples from a multivariate normal distribution, which is updated iteratively to fit the distribution of successful solutions. + + :param x0: The initial parameter vector to optimize. + :type x0: array_like + :param sigma0: Initial standard deviation of the sampling distribution, defaults to 0.1. + :type sigma0: float, optional + :param bounds: A dictionary with 'lower' and 'upper' keys containing arrays for lower and upper bounds on the parameters. If ``None``, no bounds are enforced. + :type bounds: dict, optional + + .. seealso:: + + :obj:`pints.XNES` + PINTS implementation of XNES algorithm. .. py:function:: plot_convergence(optim, xaxis_title='Iteration', yaxis_title='Cost', title='Convergence') diff --git a/docs/api/pybop/models/base_model/index.rst b/docs/api/pybop/models/base_model/index.rst index 2eee2080..ab17a5db 100644 --- a/docs/api/pybop/models/base_model/index.rst +++ b/docs/api/pybop/models/base_model/index.rst @@ -20,7 +20,37 @@ Classes .. py:class:: BaseModel(name='Base Model') - Base class for pybop models. + A base class for constructing and simulating models using PyBaMM. + + This class serves as a foundation for building specific models in PyBaMM. + It provides methods to set up the model, define parameters, and perform + simulations. The class is designed to be subclassed for creating models + with custom behavior. + + .. method:: build(dataset=None, parameters=None, check_model=True, init_soc=None) + + Construct the PyBaMM model if not already built. + + .. method:: set_init_soc(init_soc) + + Set the initial state of charge for the battery model. + + .. method:: set_params() + + Assign the parameters to the model. + + .. method:: simulate(inputs, t_eval) + + Execute the forward model simulation and return the result. + + .. method:: simulateS1(inputs, t_eval) + + Perform the forward model simulation with sensitivities. + + .. method:: predict(inputs=None, t_eval=None, parameter_set=None, experiment=None, init_soc=None) + + Solve the model using PyBaMM's simulation framework and return the solution. + .. py:property:: built_model @@ -51,33 +81,98 @@ Classes .. py:method:: build(dataset=None, parameters=None, check_model=True, init_soc=None) - Build the PyBOP model (if not built already). - For PyBaMM forward models, this method follows a - similar process to pybamm.Simulation.build(). + Construct the PyBaMM model if not already built, and set parameters. + + This method initializes the model components, applies the given parameters, + sets up the mesh and discretization if needed, and prepares the model + for simulations. + + :param dataset: The dataset to be used in the model construction. + :type dataset: pybamm.Dataset, optional + :param parameters: A dictionary containing parameter values to apply to the model. + :type parameters: dict, optional + :param check_model: If True, the model will be checked for correctness after construction. + :type check_model: bool, optional + :param init_soc: The initial state of charge to be used in simulations. + :type init_soc: float, optional .. py:method:: predict(inputs=None, t_eval=None, parameter_set=None, experiment=None, init_soc=None) - Create a PyBaMM simulation object, solve it, and return a solution object. + Solve the model using PyBaMM's simulation framework and return the solution. + + This method sets up a PyBaMM simulation by configuring the model, parameters, experiment + (if any), and initial state of charge (if provided). It then solves the simulation and + returns the resulting solution object. + + :param inputs: Input parameters for the simulation. If the input is array-like, it is converted + to a dictionary using the model's fitting keys. Defaults to None, indicating + that the default parameters should be used. + :type inputs: dict or array-like, optional + :param t_eval: An array of time points at which to evaluate the solution. Defaults to None, + which means the time points need to be specified within experiment or elsewhere. + :type t_eval: array-like, optional + :param parameter_set: A PyBaMM ParameterValues object or a dictionary containing the parameter values + to use for the simulation. Defaults to the model's current ParameterValues if None. + :type parameter_set: pybamm.ParameterValues, optional + :param experiment: A PyBaMM Experiment object specifying the experimental conditions under which + the simulation should be run. Defaults to None, indicating no experiment. + :type experiment: pybamm.Experiment, optional + :param init_soc: The initial state of charge for the simulation, as a fraction (between 0 and 1). + Defaults to None. + :type init_soc: float, optional + + :returns: The solution object returned after solving the simulation. + :rtype: pybamm.Solution + + :raises ValueError: If the model has not been configured properly before calling this method or + if PyBaMM models are not supported by the current simulation method. .. py:method:: set_init_soc(init_soc) - Set the initial state of charge. + Set the initial state of charge for the battery model. + + :param init_soc: The initial state of charge to be used in the model. + :type init_soc: float .. py:method:: set_params() - Set the parameters in the model. + Assign the parameters to the model. + + This method processes the model with the given parameters, sets up + the geometry, and updates the model instance. .. py:method:: simulate(inputs, t_eval) - Run the forward model and return the result in Numpy array format - aligning with Pints' ForwardModel simulate method. + Execute the forward model simulation and return the result. + + :param inputs: The input parameters for the simulation. If array-like, it will be + converted to a dictionary using the model's fit keys. + :type inputs: dict or array-like + :param t_eval: An array of time points at which to evaluate the solution. + :type t_eval: array-like + + :returns: The simulation result corresponding to the specified signal. + :rtype: array-like + + :raises ValueError: If the model has not been built before simulation. .. py:method:: simulateS1(inputs, t_eval) - Run the forward model and return the function evaulation and it's gradient - aligning with Pints' ForwardModel simulateS1 method. + Perform the forward model simulation with sensitivities. + + :param inputs: The input parameters for the simulation. If array-like, it will be + converted to a dictionary using the model's fit keys. + :type inputs: dict or array-like + :param t_eval: An array of time points at which to evaluate the solution and its + sensitivities. + :type t_eval: array-like + + :returns: A tuple containing the simulation result and the sensitivities. + :rtype: tuple + + :raises ValueError: If the model has not been built before simulation. diff --git a/docs/api/pybop/models/empirical/ecm/index.rst b/docs/api/pybop/models/empirical/ecm/index.rst new file mode 100644 index 00000000..e861789d --- /dev/null +++ b/docs/api/pybop/models/empirical/ecm/index.rst @@ -0,0 +1,47 @@ +:py:mod:`pybop.models.empirical.ecm` +==================================== + +.. py:module:: pybop.models.empirical.ecm + + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. autoapisummary:: + + pybop.models.empirical.ecm.Thevenin + + + + +.. py:class:: Thevenin(name='Equivalent Circuit Thevenin Model', parameter_set=None, geometry=None, submesh_types=None, var_pts=None, spatial_methods=None, solver=None, options=None, **kwargs) + + + Bases: :py:obj:`pybop.models.base_model.BaseModel` + + The Thevenin class represents an equivalent circuit model based on the Thevenin model in PyBaMM. + + This class encapsulates the PyBaMM equivalent circuit Thevenin model, providing an interface + to define the parameters, geometry, submesh types, variable points, spatial methods, and solver + to be used for simulations. + + :param name: A name for the model instance. Defaults to "Equivalent Circuit Thevenin Model". + :type name: str, optional + :param parameter_set: A dictionary of parameters to be used for the model. If None, the default parameters from PyBaMM are used. + :type parameter_set: dict or None, optional + :param geometry: The geometry definitions for the model. If None, the default geometry from PyBaMM is used. + :type geometry: dict or None, optional + :param submesh_types: The types of submeshes to use. If None, the default submesh types from PyBaMM are used. + :type submesh_types: dict or None, optional + :param var_pts: The number of points for each variable in the model to define the discretization. If None, the default is used. + :type var_pts: dict or None, optional + :param spatial_methods: The spatial methods to be used for discretization. If None, the default spatial methods from PyBaMM are used. + :type spatial_methods: dict or None, optional + :param solver: The solver to use for simulating the model. If None, the default solver from PyBaMM is used. + :type solver: pybamm.Solver or None, optional + :param options: A dictionary of options to pass to the PyBaMM Thevenin model. + :type options: dict or None, optional + :param \*\*kwargs: Additional arguments passed to the PyBaMM Thevenin model constructor. diff --git a/docs/api/pybop/models/empirical/index.rst b/docs/api/pybop/models/empirical/index.rst new file mode 100644 index 00000000..0adb3d9e --- /dev/null +++ b/docs/api/pybop/models/empirical/index.rst @@ -0,0 +1,56 @@ +:py:mod:`pybop.models.empirical` +================================ + +.. py:module:: pybop.models.empirical + + +Submodules +---------- +.. toctree:: + :titlesonly: + :maxdepth: 1 + + ecm/index.rst + + +Package Contents +---------------- + +Classes +~~~~~~~ + +.. autoapisummary:: + + pybop.models.empirical.Thevenin + + + + +.. py:class:: Thevenin(name='Equivalent Circuit Thevenin Model', parameter_set=None, geometry=None, submesh_types=None, var_pts=None, spatial_methods=None, solver=None, options=None, **kwargs) + + + Bases: :py:obj:`pybop.models.base_model.BaseModel` + + The Thevenin class represents an equivalent circuit model based on the Thevenin model in PyBaMM. + + This class encapsulates the PyBaMM equivalent circuit Thevenin model, providing an interface + to define the parameters, geometry, submesh types, variable points, spatial methods, and solver + to be used for simulations. + + :param name: A name for the model instance. Defaults to "Equivalent Circuit Thevenin Model". + :type name: str, optional + :param parameter_set: A dictionary of parameters to be used for the model. If None, the default parameters from PyBaMM are used. + :type parameter_set: dict or None, optional + :param geometry: The geometry definitions for the model. If None, the default geometry from PyBaMM is used. + :type geometry: dict or None, optional + :param submesh_types: The types of submeshes to use. If None, the default submesh types from PyBaMM are used. + :type submesh_types: dict or None, optional + :param var_pts: The number of points for each variable in the model to define the discretization. If None, the default is used. + :type var_pts: dict or None, optional + :param spatial_methods: The spatial methods to be used for discretization. If None, the default spatial methods from PyBaMM are used. + :type spatial_methods: dict or None, optional + :param solver: The solver to use for simulating the model. If None, the default solver from PyBaMM is used. + :type solver: pybamm.Solver or None, optional + :param options: A dictionary of options to pass to the PyBaMM Thevenin model. + :type options: dict or None, optional + :param \*\*kwargs: Additional arguments passed to the PyBaMM Thevenin model constructor. diff --git a/docs/api/pybop/models/index.rst b/docs/api/pybop/models/index.rst index 6b06a221..20988ab8 100644 --- a/docs/api/pybop/models/index.rst +++ b/docs/api/pybop/models/index.rst @@ -10,6 +10,7 @@ Subpackages :titlesonly: :maxdepth: 3 + empirical/index.rst lithium_ion/index.rst diff --git a/docs/api/pybop/models/lithium_ion/base_echem/index.rst b/docs/api/pybop/models/lithium_ion/base_echem/index.rst deleted file mode 100644 index 7348059d..00000000 --- a/docs/api/pybop/models/lithium_ion/base_echem/index.rst +++ /dev/null @@ -1,35 +0,0 @@ -:py:mod:`pybop.models.lithium_ion.base_echem` -============================================= - -.. py:module:: pybop.models.lithium_ion.base_echem - - -Module Contents ---------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - pybop.models.lithium_ion.base_echem.SPM - pybop.models.lithium_ion.base_echem.SPMe - - - - -.. py:class:: SPM(name='Single Particle Model', parameter_set=None, geometry=None, submesh_types=None, var_pts=None, spatial_methods=None, solver=None, options=None) - - - Bases: :py:obj:`pybop.models.base_model.BaseModel` - - Composition of the PyBaMM Single Particle Model class. - - - -.. py:class:: SPMe(name='Single Particle Model with Electrolyte', parameter_set=None, geometry=None, submesh_types=None, var_pts=None, spatial_methods=None, solver=None, options=None) - - - Bases: :py:obj:`pybop.models.base_model.BaseModel` - - Composition of the PyBaMM Single Particle Model with Electrolyte class. diff --git a/docs/api/pybop/models/lithium_ion/echem/index.rst b/docs/api/pybop/models/lithium_ion/echem/index.rst new file mode 100644 index 00000000..4c115a68 --- /dev/null +++ b/docs/api/pybop/models/lithium_ion/echem/index.rst @@ -0,0 +1,76 @@ +:py:mod:`pybop.models.lithium_ion.echem` +======================================== + +.. py:module:: pybop.models.lithium_ion.echem + + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. autoapisummary:: + + pybop.models.lithium_ion.echem.SPM + pybop.models.lithium_ion.echem.SPMe + + + + +.. py:class:: SPM(name='Single Particle Model', parameter_set=None, geometry=None, submesh_types=None, var_pts=None, spatial_methods=None, solver=None, options=None) + + + Bases: :py:obj:`pybop.models.base_model.BaseModel` + + Wraps the Single Particle Model (SPM) for simulating lithium-ion batteries, as implemented in PyBaMM. + + The SPM is a simplified physics-based model that represents a lithium-ion cell using a single + spherical particle to simulate the behavior of the negative and positive electrodes. + + :param name: The name for the model instance, defaulting to "Single Particle Model". + :type name: str, optional + :param parameter_set: The parameters for the model. If None, default parameters provided by PyBaMM are used. + :type parameter_set: pybamm.ParameterValues or dict, optional + :param geometry: The geometry definitions for the model. If None, default geometry from PyBaMM is used. + :type geometry: dict, optional + :param submesh_types: The types of submeshes to use. If None, default submesh types from PyBaMM are used. + :type submesh_types: dict, optional + :param var_pts: The discretization points for each variable in the model. If None, default points from PyBaMM are used. + :type var_pts: dict, optional + :param spatial_methods: The spatial methods used for discretization. If None, default spatial methods from PyBaMM are used. + :type spatial_methods: dict, optional + :param solver: The solver to use for simulating the model. If None, the default solver from PyBaMM is used. + :type solver: pybamm.Solver, optional + :param options: A dictionary of options to customize the behavior of the PyBaMM model. + :type options: dict, optional + + +.. py:class:: SPMe(name='Single Particle Model with Electrolyte', parameter_set=None, geometry=None, submesh_types=None, var_pts=None, spatial_methods=None, solver=None, options=None) + + + Bases: :py:obj:`pybop.models.base_model.BaseModel` + + Represents the Single Particle Model with Electrolyte (SPMe) for lithium-ion batteries. + + The SPMe extends the basic Single Particle Model (SPM) by incorporating electrolyte dynamics, + making it suitable for simulations where electrolyte effects are non-negligible. This class + provides a framework to define the model parameters, geometry, mesh types, discretization + points, spatial methods, and numerical solvers for simulation within the PyBaMM ecosystem. + + :param name: A name for the model instance, defaults to "Single Particle Model with Electrolyte". + :type name: str, optional + :param parameter_set: A dictionary or a ParameterValues object containing the parameters for the model. If None, the default PyBaMM parameters for SPMe are used. + :type parameter_set: pybamm.ParameterValues or dict, optional + :param geometry: A dictionary defining the model's geometry. If None, the default PyBaMM geometry for SPMe is used. + :type geometry: dict, optional + :param submesh_types: A dictionary defining the types of submeshes to use. If None, the default PyBaMM submesh types for SPMe are used. + :type submesh_types: dict, optional + :param var_pts: A dictionary specifying the number of points for each variable for discretization. If None, the default PyBaMM variable points for SPMe are used. + :type var_pts: dict, optional + :param spatial_methods: A dictionary specifying the spatial methods for discretization. If None, the default PyBaMM spatial methods for SPMe are used. + :type spatial_methods: dict, optional + :param solver: The solver to use for simulating the model. If None, the default PyBaMM solver for SPMe is used. + :type solver: pybamm.Solver, optional + :param options: A dictionary of options to customize the behavior of the PyBaMM model. + :type options: dict, optional diff --git a/docs/api/pybop/models/lithium_ion/index.rst b/docs/api/pybop/models/lithium_ion/index.rst index dfc4c95b..4200a205 100644 --- a/docs/api/pybop/models/lithium_ion/index.rst +++ b/docs/api/pybop/models/lithium_ion/index.rst @@ -10,7 +10,7 @@ Submodules :titlesonly: :maxdepth: 1 - base_echem/index.rst + echem/index.rst Package Contents @@ -32,8 +32,27 @@ Classes Bases: :py:obj:`pybop.models.base_model.BaseModel` - Composition of the PyBaMM Single Particle Model class. - + Wraps the Single Particle Model (SPM) for simulating lithium-ion batteries, as implemented in PyBaMM. + + The SPM is a simplified physics-based model that represents a lithium-ion cell using a single + spherical particle to simulate the behavior of the negative and positive electrodes. + + :param name: The name for the model instance, defaulting to "Single Particle Model". + :type name: str, optional + :param parameter_set: The parameters for the model. If None, default parameters provided by PyBaMM are used. + :type parameter_set: pybamm.ParameterValues or dict, optional + :param geometry: The geometry definitions for the model. If None, default geometry from PyBaMM is used. + :type geometry: dict, optional + :param submesh_types: The types of submeshes to use. If None, default submesh types from PyBaMM are used. + :type submesh_types: dict, optional + :param var_pts: The discretization points for each variable in the model. If None, default points from PyBaMM are used. + :type var_pts: dict, optional + :param spatial_methods: The spatial methods used for discretization. If None, default spatial methods from PyBaMM are used. + :type spatial_methods: dict, optional + :param solver: The solver to use for simulating the model. If None, the default solver from PyBaMM is used. + :type solver: pybamm.Solver, optional + :param options: A dictionary of options to customize the behavior of the PyBaMM model. + :type options: dict, optional .. py:class:: SPMe(name='Single Particle Model with Electrolyte', parameter_set=None, geometry=None, submesh_types=None, var_pts=None, spatial_methods=None, solver=None, options=None) @@ -41,4 +60,26 @@ Classes Bases: :py:obj:`pybop.models.base_model.BaseModel` - Composition of the PyBaMM Single Particle Model with Electrolyte class. + Represents the Single Particle Model with Electrolyte (SPMe) for lithium-ion batteries. + + The SPMe extends the basic Single Particle Model (SPM) by incorporating electrolyte dynamics, + making it suitable for simulations where electrolyte effects are non-negligible. This class + provides a framework to define the model parameters, geometry, mesh types, discretization + points, spatial methods, and numerical solvers for simulation within the PyBaMM ecosystem. + + :param name: A name for the model instance, defaults to "Single Particle Model with Electrolyte". + :type name: str, optional + :param parameter_set: A dictionary or a ParameterValues object containing the parameters for the model. If None, the default PyBaMM parameters for SPMe are used. + :type parameter_set: pybamm.ParameterValues or dict, optional + :param geometry: A dictionary defining the model's geometry. If None, the default PyBaMM geometry for SPMe is used. + :type geometry: dict, optional + :param submesh_types: A dictionary defining the types of submeshes to use. If None, the default PyBaMM submesh types for SPMe are used. + :type submesh_types: dict, optional + :param var_pts: A dictionary specifying the number of points for each variable for discretization. If None, the default PyBaMM variable points for SPMe are used. + :type var_pts: dict, optional + :param spatial_methods: A dictionary specifying the spatial methods for discretization. If None, the default PyBaMM spatial methods for SPMe are used. + :type spatial_methods: dict, optional + :param solver: The solver to use for simulating the model. If None, the default PyBaMM solver for SPMe is used. + :type solver: pybamm.Solver, optional + :param options: A dictionary of options to customize the behavior of the PyBaMM model. + :type options: dict, optional diff --git a/docs/api/pybop/optimisation/index.rst b/docs/api/pybop/optimisation/index.rst index 9fca5c5a..619f9eee 100644 --- a/docs/api/pybop/optimisation/index.rst +++ b/docs/api/pybop/optimisation/index.rst @@ -118,3 +118,8 @@ Classes ``False``. Credit: PINTS + + + .. py:method:: store_optimised_parameters(x) + + Store the optimised parameters in the PyBOP parameter class. diff --git a/docs/api/pybop/optimisers/base_optimiser/index.rst b/docs/api/pybop/optimisers/base_optimiser/index.rst index 932d64b5..4f34d0c2 100644 --- a/docs/api/pybop/optimisers/base_optimiser/index.rst +++ b/docs/api/pybop/optimisers/base_optimiser/index.rst @@ -20,20 +20,64 @@ Classes .. py:class:: BaseOptimiser - Base class for the optimisation methods. + A base class for defining optimisation methods. + + This class serves as a template for creating optimisers. It provides a basic structure for + an optimisation algorithm, including the initial setup and a method stub for performing + the optimisation process. Child classes should override the optimise and _runoptimise + methods with specific algorithms. + + .. method:: optimise(cost_function, x0=None, bounds=None, maxiter=None) + + Initiates the optimisation process. This is a stub and should be implemented in child classes. + + .. method:: _runoptimise(cost_function, x0=None, bounds=None) + + Contains the logic for the optimisation algorithm. This is a stub and should be implemented in child classes. + + .. method:: name() + + Returns the name of the optimiser. .. py:method:: _runoptimise(cost_function, x0=None, bounds=None) - Run optimisation method, to be overloaded by child classes. + Contains the logic for the optimisation algorithm. + + This method should be implemented by child classes to perform the actual optimisation. + :param cost_function: The cost function to be minimised by the optimiser. + :type cost_function: callable + :param x0: Initial guess for the parameters. Default is None. + :type x0: ndarray, optional + :param bounds: Bounds on the parameters. Default is None. + :type bounds: sequence or Bounds, optional + + :returns: * *This method is expected to return the result of the optimisation, the format of which* + * *will be determined by the child class implementation.* .. py:method:: name() Returns the name of the optimiser. + :returns: The name of the optimiser, which is "BaseOptimiser" for this base class. + :rtype: str + + + .. py:method:: optimise(cost_function, x0=None, bounds=None, maxiter=None) + + Initiates the optimisation process. + + This method should be overridden by child classes with the specific optimisation algorithm. - .. py:method:: optimise(cost_function, x0=None, bounds=None) + :param cost_function: The cost function to be minimised by the optimiser. + :type cost_function: callable + :param x0: Initial guess for the parameters. Default is None. + :type x0: ndarray, optional + :param bounds: Bounds on the parameters. Default is None. + :type bounds: sequence or Bounds, optional + :param maxiter: Maximum number of iterations to perform. Default is None. + :type maxiter: int, optional - Optimisiation method to be overloaded by child classes. + :rtype: The result of the optimisation process. The specific type of this result will depend on the child implementation. diff --git a/docs/api/pybop/optimisers/index.rst b/docs/api/pybop/optimisers/index.rst index 1524300b..8bffb2f0 100644 --- a/docs/api/pybop/optimisers/index.rst +++ b/docs/api/pybop/optimisers/index.rst @@ -13,4 +13,4 @@ Submodules base_optimiser/index.rst nlopt_optimize/index.rst pints_optimisers/index.rst - scipy_minimize/index.rst + scipy_optimisers/index.rst diff --git a/docs/api/pybop/optimisers/nlopt_optimize/index.rst b/docs/api/pybop/optimisers/nlopt_optimize/index.rst index b210161f..29273b74 100644 --- a/docs/api/pybop/optimisers/nlopt_optimize/index.rst +++ b/docs/api/pybop/optimisers/nlopt_optimize/index.rst @@ -17,30 +17,65 @@ Classes -.. py:class:: NLoptOptimize(n_param, xtol=None, method=None) +.. py:class:: NLoptOptimize(n_param, xtol=None, method=None, maxiter=None) Bases: :py:obj:`pybop.optimisers.base_optimiser.BaseOptimiser` - Wrapper class for the NLOpt optimiser class. Extends the BaseOptimiser class. + Extends BaseOptimiser to utilize the NLopt library for nonlinear optimization. + + This class serves as an interface to the NLopt optimization algorithms. It allows the user to + define an optimization problem with bounds, initial guesses, and to select an optimization method + provided by NLopt. + + :param n_param: Number of parameters to optimize. + :type n_param: int + :param xtol: The relative tolerance for optimization (stopping criteria). If not provided, a default of 1e-5 is used. + :type xtol: float, optional + :param method: The NLopt algorithm to use for optimization. If not provided, LN_BOBYQA is used by default. + :type method: nlopt.algorithm, optional + :param maxiter: The maximum number of iterations to perform during optimization. If not provided, NLopt's default is used. + :type maxiter: int, optional + + .. method:: _runoptimise(cost_function, x0, bounds) + + Performs the optimization using the NLopt library. + + .. method:: needs_sensitivities() + + Indicates whether the optimizer requires gradient information. + + .. method:: name() + + Returns the name of the optimizer. + .. py:method:: _runoptimise(cost_function, x0, bounds) - Run the NLOpt optimisation method. + Runs the optimization process using the NLopt library. - Inputs - ---------- - cost_function: function for optimising - method: optimisation algorithm - x0: initialisation array - bounds: bounds array + :param cost_function: The objective function to minimize. It should take an array of parameter values and return the scalar cost. + :type cost_function: callable + :param x0: The initial guess for the parameters. + :type x0: array_like + :param bounds: A dictionary containing the 'lower' and 'upper' bounds arrays for the parameters. + :type bounds: dict + + :returns: A tuple containing the optimized parameter values and the final cost. + :rtype: tuple .. py:method:: name() - Returns the name of the optimiser. + Returns the name of this optimizer instance. + + :returns: The name 'NLoptOptimize' representing this NLopt optimization class. + :rtype: str .. py:method:: needs_sensitivities() - Returns True if the optimiser needs sensitivities. + Indicates if the optimizer requires gradient information for the cost function. + + :returns: False, as the default NLopt algorithms do not require gradient information. + :rtype: bool diff --git a/docs/api/pybop/optimisers/pints_optimisers/index.rst b/docs/api/pybop/optimisers/pints_optimisers/index.rst index 68226d79..3b3ce69c 100644 --- a/docs/api/pybop/optimisers/pints_optimisers/index.rst +++ b/docs/api/pybop/optimisers/pints_optimisers/index.rst @@ -28,8 +28,23 @@ Classes Bases: :py:obj:`pints.Adam` - Adam optimiser. Inherits from the PINTS Adam class. - https://github.com/pints-team/pints/blob/main/pints/_optimisers/_adam.py + Implements the Adam optimization algorithm. + + This class extends the Adam optimizer from the PINTS library, which combines + ideas from RMSProp and Stochastic Gradient Descent with momentum. Note that + this optimizer does not support boundary constraints. + + :param x0: Initial position from which optimization will start. + :type x0: array_like + :param sigma0: Initial step size (default is 0.1). + :type sigma0: float, optional + :param bounds: Ignored by this optimizer, provided for API consistency. + :type bounds: sequence or ``Bounds``, optional + + .. seealso:: + + :obj:`pints.Adam` + The PINTS implementation this class is based on. .. py:class:: CMAES(x0, sigma0=0.1, bounds=None) @@ -37,8 +52,23 @@ Classes Bases: :py:obj:`pints.CMAES` - Class for the PINTS optimisation. Extends the BaseOptimiser class. - https://github.com/pints-team/pints/blob/main/pints/_optimisers/_cmaes.py + Adapter for the Covariance Matrix Adaptation Evolution Strategy (CMA-ES) optimizer in PINTS. + + CMA-ES is an evolutionary algorithm for difficult non-linear non-convex optimization problems. + It adapts the covariance matrix of a multivariate normal distribution to capture the shape of the cost landscape. + + :param x0: The initial parameter vector to optimize. + :type x0: array_like + :param sigma0: Initial standard deviation of the sampling distribution, defaults to 0.1. + :type sigma0: float, optional + :param bounds: A dictionary with 'lower' and 'upper' keys containing arrays for lower and upper bounds on the parameters. + If ``None``, no bounds are enforced. + :type bounds: dict, optional + + .. seealso:: + + :obj:`pints.CMAES` + PINTS implementation of CMA-ES algorithm. .. py:class:: GradientDescent(x0, sigma0=0.1, bounds=None) @@ -46,8 +76,23 @@ Classes Bases: :py:obj:`pints.GradientDescent` - Gradient descent optimiser. Inherits from the PINTS gradient descent class. - https://github.com/pints-team/pints/blob/main/pints/_optimisers/_gradient_descent.py + Implements a simple gradient descent optimization algorithm. + + This class extends the gradient descent optimizer from the PINTS library, designed + to minimize a scalar function of one or more variables. Note that this optimizer + does not support boundary constraints. + + :param x0: Initial position from which optimization will start. + :type x0: array_like + :param sigma0: Initial step size (default is 0.1). + :type sigma0: float, optional + :param bounds: Ignored by this optimizer, provided for API consistency. + :type bounds: sequence or ``Bounds``, optional + + .. seealso:: + + :obj:`pints.GradientDescent` + The PINTS implementation this class is based on. .. py:class:: IRPropMin(x0, sigma0=0.1, bounds=None) @@ -55,8 +100,23 @@ Classes Bases: :py:obj:`pints.IRPropMin` - IRProp- optimiser. Inherits from the PINTS IRPropMinus class. - https://github.com/pints-team/pints/blob/main/pints/_optimisers/_irpropmin.py + Implements the iRpropMin optimization algorithm. + + This class inherits from the PINTS IRPropMin class, which is an optimizer that + uses resilient backpropagation with weight-backtracking. It is designed to handle + problems with large plateaus, noisy gradients, and local minima. + + :param x0: Initial position from which optimization will start. + :type x0: array_like + :param sigma0: Initial step size (default is 0.1). + :type sigma0: float, optional + :param bounds: Lower and upper bounds for each optimization parameter. + :type bounds: dict, optional + + .. seealso:: + + :obj:`pints.IRPropMin` + The PINTS implementation this class is based on. .. py:class:: PSO(x0, sigma0=0.1, bounds=None) @@ -64,8 +124,23 @@ Classes Bases: :py:obj:`pints.PSO` - Particle swarm optimiser. Inherits from the PINTS PSO class. - https://github.com/pints-team/pints/blob/main/pints/_optimisers/_pso.py + Implements a particle swarm optimization (PSO) algorithm. + + This class extends the PSO optimizer from the PINTS library. PSO is a + metaheuristic optimization method inspired by the social behavior of birds + flocking or fish schooling, suitable for global optimization problems. + + :param x0: Initial positions of particles, which the optimization will use. + :type x0: array_like + :param sigma0: Spread of the initial particle positions (default is 0.1). + :type sigma0: float, optional + :param bounds: Lower and upper bounds for each optimization parameter. + :type bounds: dict, optional + + .. seealso:: + + :obj:`pints.PSO` + The PINTS implementation this class is based on. .. py:class:: SNES(x0, sigma0=0.1, bounds=None) @@ -73,8 +148,23 @@ Classes Bases: :py:obj:`pints.SNES` - Stochastic natural evolution strategy optimiser. Inherits from the PINTS SNES class. - https://github.com/pints-team/pints/blob/main/pints/_optimisers/_snes.py + Implements the stochastic natural evolution strategy (SNES) optimization algorithm. + + Inheriting from the PINTS SNES class, this optimizer is an evolutionary algorithm + that evolves a probability distribution on the parameter space, guiding the search + for the optimum based on the natural gradient of expected fitness. + + :param x0: Initial position from which optimization will start. + :type x0: array_like + :param sigma0: Initial step size (default is 0.1). + :type sigma0: float, optional + :param bounds: Lower and upper bounds for each optimization parameter. + :type bounds: dict, optional + + .. seealso:: + + :obj:`pints.SNES` + The PINTS implementation this class is based on. .. py:class:: XNES(x0, sigma0=0.1, bounds=None) @@ -82,5 +172,18 @@ Classes Bases: :py:obj:`pints.XNES` - Exponential natural evolution strategy optimiser. Inherits from the PINTS XNES class. - https://github.com/pints-team/pints/blob/main/pints/_optimisers/_xnes.py + Implements the Exponential Natural Evolution Strategy (XNES) optimizer from PINTS. + + XNES is an evolutionary algorithm that samples from a multivariate normal distribution, which is updated iteratively to fit the distribution of successful solutions. + + :param x0: The initial parameter vector to optimize. + :type x0: array_like + :param sigma0: Initial standard deviation of the sampling distribution, defaults to 0.1. + :type sigma0: float, optional + :param bounds: A dictionary with 'lower' and 'upper' keys containing arrays for lower and upper bounds on the parameters. If ``None``, no bounds are enforced. + :type bounds: dict, optional + + .. seealso:: + + :obj:`pints.XNES` + PINTS implementation of XNES algorithm. diff --git a/docs/api/pybop/optimisers/scipy_minimize/index.rst b/docs/api/pybop/optimisers/scipy_minimize/index.rst deleted file mode 100644 index 4d8c9233..00000000 --- a/docs/api/pybop/optimisers/scipy_minimize/index.rst +++ /dev/null @@ -1,46 +0,0 @@ -:py:mod:`pybop.optimisers.scipy_minimize` -========================================= - -.. py:module:: pybop.optimisers.scipy_minimize - - -Module Contents ---------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - pybop.optimisers.scipy_minimize.SciPyMinimize - - - - -.. py:class:: SciPyMinimize(method=None, bounds=None) - - - Bases: :py:obj:`pybop.optimisers.base_optimiser.BaseOptimiser` - - Wrapper class for the SciPy optimisation class. Extends the BaseOptimiser class. - - .. py:method:: _runoptimise(cost_function, x0, bounds) - - Run the SciPy optimisation method. - - Inputs - ---------- - cost_function: function for optimising - method: optimisation algorithm - x0: initialisation array - bounds: bounds array - - - .. py:method:: name() - - Returns the name of the optimiser. - - - .. py:method:: needs_sensitivities() - - Returns True if the optimiser needs sensitivities. diff --git a/docs/api/pybop/optimisers/scipy_optimisers/index.rst b/docs/api/pybop/optimisers/scipy_optimisers/index.rst new file mode 100644 index 00000000..5080cb51 --- /dev/null +++ b/docs/api/pybop/optimisers/scipy_optimisers/index.rst @@ -0,0 +1,115 @@ +:py:mod:`pybop.optimisers.scipy_optimisers` +=========================================== + +.. py:module:: pybop.optimisers.scipy_optimisers + + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. autoapisummary:: + + pybop.optimisers.scipy_optimisers.SciPyDifferentialEvolution + pybop.optimisers.scipy_optimisers.SciPyMinimize + + + + +.. py:class:: SciPyDifferentialEvolution(bounds=None, strategy='best1bin', maxiter=1000, popsize=15) + + + Bases: :py:obj:`pybop.optimisers.base_optimiser.BaseOptimiser` + + Adapts SciPy's differential_evolution function for global optimization. + + This class provides a global optimization strategy based on differential evolution, useful for problems involving continuous parameters and potentially multiple local minima. + + :param bounds: Bounds for variables. Must be provided as it is essential for differential evolution. + :type bounds: sequence or ``Bounds`` + :param strategy: The differential evolution strategy to use. Defaults to 'best1bin'. + :type strategy: str, optional + :param maxiter: Maximum number of iterations to perform. Defaults to 1000. + :type maxiter: int, optional + :param popsize: The number of individuals in the population. Defaults to 15. + :type popsize: int, optional + + .. py:method:: _runoptimise(cost_function, x0=None, bounds=None) + + Executes the optimization process using SciPy's differential_evolution function. + + :param cost_function: The objective function to minimize. + :type cost_function: callable + :param x0: Ignored parameter, provided for API consistency. + :type x0: array_like, optional + :param bounds: Bounds for the variables, required for differential evolution. + :type bounds: sequence or ``Bounds`` + + :returns: A tuple (x, final_cost) containing the optimized parameters and the value of ``cost_function`` at the optimum. + :rtype: tuple + + + .. py:method:: name() + + Provides the name of the optimization strategy. + + :returns: The name 'SciPyDifferentialEvolution'. + :rtype: str + + + .. py:method:: needs_sensitivities() + + Determines if the optimization algorithm requires gradient information. + + :returns: False, indicating that gradient information is not required for differential evolution. + :rtype: bool + + + +.. py:class:: SciPyMinimize(method=None, bounds=None, maxiter=None) + + + Bases: :py:obj:`pybop.optimisers.base_optimiser.BaseOptimiser` + + Adapts SciPy's minimize function for use as an optimization strategy. + + This class provides an interface to various scalar minimization algorithms implemented in SciPy, allowing fine-tuning of the optimization process through method selection and option configuration. + + :param method: The type of solver to use. If not specified, defaults to 'COBYLA'. + :type method: str, optional + :param bounds: Bounds for variables as supported by the selected method. + :type bounds: sequence or ``Bounds``, optional + :param maxiter: Maximum number of iterations to perform. + :type maxiter: int, optional + + .. py:method:: _runoptimise(cost_function, x0, bounds) + + Executes the optimization process using SciPy's minimize function. + + :param cost_function: The objective function to minimize. + :type cost_function: callable + :param x0: Initial guess for the parameters. + :type x0: array_like + :param bounds: Bounds for the variables. + :type bounds: sequence or `Bounds` + + :returns: A tuple (x, final_cost) containing the optimized parameters and the value of `cost_function` at the optimum. + :rtype: tuple + + + .. py:method:: name() + + Provides the name of the optimization strategy. + + :returns: The name 'SciPyMinimize'. + :rtype: str + + + .. py:method:: needs_sensitivities() + + Determines if the optimization algorithm requires gradient information. + + :returns: False, indicating that gradient information is not required. + :rtype: bool diff --git a/docs/api/pybop/parameters/base_parameter/index.rst b/docs/api/pybop/parameters/base_parameter/index.rst deleted file mode 100644 index 5bad5034..00000000 --- a/docs/api/pybop/parameters/base_parameter/index.rst +++ /dev/null @@ -1,41 +0,0 @@ -:py:mod:`pybop.parameters.base_parameter` -========================================= - -.. py:module:: pybop.parameters.base_parameter - - -Module Contents ---------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - pybop.parameters.base_parameter.Parameter - - - - -.. py:class:: Parameter(name, value=None, prior=None, bounds=None) - - - "" - Class for creating parameters in PyBOP. - - .. py:method:: __repr__() - - Return repr(self). - - - .. py:method:: rvs(n_samples) - - Returns a random value sample from the prior distribution. - - - .. py:method:: set_margin(margin) - - Sets the margin for the parameter. - - - .. py:method:: update(value) diff --git a/docs/api/pybop/parameters/base_parameter_set/index.rst b/docs/api/pybop/parameters/base_parameter_set/index.rst deleted file mode 100644 index d63a2ef0..00000000 --- a/docs/api/pybop/parameters/base_parameter_set/index.rst +++ /dev/null @@ -1,23 +0,0 @@ -:py:mod:`pybop.parameters.base_parameter_set` -============================================= - -.. py:module:: pybop.parameters.base_parameter_set - - -Module Contents ---------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - pybop.parameters.base_parameter_set.ParameterSet - - - - -.. py:class:: ParameterSet - - - Class for creating parameter sets in PyBOP. diff --git a/docs/api/pybop/parameters/index.rst b/docs/api/pybop/parameters/index.rst index 43843f7f..9e385c56 100644 --- a/docs/api/pybop/parameters/index.rst +++ b/docs/api/pybop/parameters/index.rst @@ -10,6 +10,6 @@ Submodules :titlesonly: :maxdepth: 1 - base_parameter/index.rst - base_parameter_set/index.rst + parameter/index.rst + parameter_set/index.rst priors/index.rst diff --git a/docs/api/pybop/parameters/parameter/index.rst b/docs/api/pybop/parameters/parameter/index.rst new file mode 100644 index 00000000..881ec13d --- /dev/null +++ b/docs/api/pybop/parameters/parameter/index.rst @@ -0,0 +1,95 @@ +:py:mod:`pybop.parameters.parameter` +==================================== + +.. py:module:: pybop.parameters.parameter + + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. autoapisummary:: + + pybop.parameters.parameter.Parameter + + + + +.. py:class:: Parameter(name, initial_value=None, prior=None, bounds=None) + + + Represents a parameter within the PyBOP framework. + + This class encapsulates the definition of a parameter, including its name, prior + distribution, initial value, bounds, and a margin to ensure the parameter stays + within feasible limits during optimization or sampling. + + :param name: The name of the parameter. + :type name: str + :param initial_value: The initial value to be assigned to the parameter. Defaults to None. + :type initial_value: float, optional + :param prior: The prior distribution from which parameter values are drawn. Defaults to None. + :type prior: scipy.stats distribution, optional + :param bounds: A tuple defining the lower and upper bounds for the parameter. + Defaults to None. + :type bounds: tuple, optional + + .. method:: rvs(n_samples) + + Draw random samples from the parameter's prior distribution. + + .. method:: update(value) + + Update the parameter's current value. + + .. method:: set_margin(margin) + + Set the margin to a specified positive value less than 1. + + + :raises ValueError: If the lower bound is not strictly less than the upper bound, or if + the margin is set outside the interval (0, 1). + + .. py:method:: __repr__() + + Return a string representation of the Parameter instance. + + :returns: A string including the parameter's name, prior, bounds, and current value. + :rtype: str + + + .. py:method:: rvs(n_samples) + + Draw random samples from the parameter's prior distribution. + + The samples are constrained to be within the parameter's bounds, excluding + a predefined margin at the boundaries. + + :param n_samples: The number of samples to draw. + :type n_samples: int + + :returns: An array of samples drawn from the prior distribution within the parameter's bounds. + :rtype: array-like + + + .. py:method:: set_margin(margin) + + Set the margin to a specified positive value less than 1. + + The margin is used to ensure parameter samples are not drawn exactly at the bounds, + which may be problematic in some optimization or sampling algorithms. + + :param margin: The new margin value to be used, which must be in the interval (0, 1). + :type margin: float + + :raises ValueError: If the margin is not between 0 and 1. + + + .. py:method:: update(value) + + Update the parameter's current value. + + :param value: The new value to be assigned to the parameter. + :type value: float diff --git a/docs/api/pybop/parameters/parameter_set/index.rst b/docs/api/pybop/parameters/parameter_set/index.rst new file mode 100644 index 00000000..2b22be47 --- /dev/null +++ b/docs/api/pybop/parameters/parameter_set/index.rst @@ -0,0 +1,95 @@ +:py:mod:`pybop.parameters.parameter_set` +======================================== + +.. py:module:: pybop.parameters.parameter_set + + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. autoapisummary:: + + pybop.parameters.parameter_set.ParameterSet + + + + +.. py:class:: ParameterSet(json_path=None, params_dict=None) + + + Handles the import and export of parameter sets for battery models. + + This class provides methods to load parameters from a JSON file and to export them + back to a JSON file. It also includes custom logic to handle special cases, such + as parameter values that require specific initialization. + + :param json_path: Path to a JSON file containing parameter data. If provided, parameters will be imported from this file during initialization. + :type json_path: str, optional + :param params_dict: A dictionary of parameters to initialize the ParameterSet with. If not provided, an empty dictionary is used. + :type params_dict: dict, optional + + .. py:method:: _handle_special_cases() + + Processes special cases for parameter values that require custom handling. + + For example, if the open-circuit voltage is specified as 'default', it will + fetch the default value from the PyBaMM empirical Thevenin model. + + + .. py:method:: export_parameters(output_json_path, fit_params=None) + + Exports parameters to a JSON file specified by `output_json_path`. + + The current state of the `params` attribute is written to the file. If `fit_params` + is provided, these parameters are updated before export. Non-serializable values + are handled and noted in the output JSON. + + :param output_json_path: The file path where the JSON output will be saved. + :type output_json_path: str + :param fit_params: Parameters that have been fitted and need to be included in the export. + :type fit_params: list of fitted parameter objects, optional + + :raises ValueError: If there are no parameters to export. + + + .. py:method:: import_parameters(json_path=None) + + Imports parameters from a JSON file specified by the `json_path` attribute. + + If a `json_path` is provided at initialization or as an argument, that JSON file + is loaded and the parameters are stored in the `params` attribute. Special cases + are handled appropriately. + + :param json_path: Path to the JSON file from which to import parameters. If provided, it overrides the instance's `json_path`. + :type json_path: str, optional + + :returns: The dictionary containing the imported parameters. + :rtype: dict + + :raises FileNotFoundError: If the specified JSON file cannot be found. + + + .. py:method:: is_json_serializable(value) + + Determines if the given `value` can be serialized to JSON format. + + :param value: The value to check for JSON serializability. + :type value: any + + :returns: True if the value is JSON serializable, False otherwise. + :rtype: bool + + + .. py:method:: pybamm(name) + :classmethod: + + Retrieves a PyBaMM parameter set by name. + + :param name: The name of the PyBaMM parameter set to retrieve. + :type name: str + + :returns: A PyBaMM parameter set corresponding to the provided name. + :rtype: pybamm.ParameterValues diff --git a/docs/api/pybop/parameters/priors/index.rst b/docs/api/pybop/parameters/priors/index.rst index 05f5b79e..9e633272 100644 --- a/docs/api/pybop/parameters/priors/index.rst +++ b/docs/api/pybop/parameters/priors/index.rst @@ -22,57 +22,157 @@ Classes .. py:class:: Exponential(scale) - Exponential prior class. + Represents an exponential distribution with a specified scale parameter. + + This class provides methods to calculate the pdf, the log pdf, and to generate random + variates from the distribution. + + :param scale: The scale parameter (lambda) of the exponential distribution. + :type scale: float .. py:method:: __repr__() - Return repr(self). + Returns a string representation of the Uniform object. .. py:method:: logpdf(x) + Calculates the logarithm of the pdf of the exponential distribution at x. + + :param x: The point at which to evaluate the log pdf. + :type x: float + + :returns: The log of the probability density function value at x. + :rtype: float + .. py:method:: pdf(x) + Calculates the probability density function of the exponential distribution at x. + + :param x: The point at which to evaluate the pdf. + :type x: float + + :returns: The probability density function value at x. + :rtype: float + .. py:method:: rvs(size) + Generates random variates from the exponential distribution. + + :param size: The number of random variates to generate. + :type size: int + + :returns: An array of random variates from the exponential distribution. + :rtype: array_like + + :raises ValueError: If the size parameter is not positive. + .. py:class:: Gaussian(mean, sigma) - Gaussian prior class. + Represents a Gaussian (normal) distribution with a given mean and standard deviation. + + This class provides methods to calculate the probability density function (pdf), + the logarithm of the pdf, and to generate random variates (rvs) from the distribution. + + :param mean: The mean (mu) of the Gaussian distribution. + :type mean: float + :param sigma: The standard deviation (sigma) of the Gaussian distribution. + :type sigma: float .. py:method:: __repr__() - Return repr(self). + Returns a string representation of the Gaussian object. .. py:method:: logpdf(x) + Calculates the logarithm of the probability density function of the Gaussian distribution at x. + + :param x: The point at which to evaluate the log pdf. + :type x: float + + :returns: The logarithm of the probability density function value at x. + :rtype: float + .. py:method:: pdf(x) + Calculates the probability density function of the Gaussian distribution at x. + + :param x: The point at which to evaluate the pdf. + :type x: float + + :returns: The probability density function value at x. + :rtype: float + .. py:method:: rvs(size) + Generates random variates from the Gaussian distribution. + + :param size: The number of random variates to generate. + :type size: int + + :returns: An array of random variates from the Gaussian distribution. + :rtype: array_like + + :raises ValueError: If the size parameter is not positive. + .. py:class:: Uniform(lower, upper) - Uniform prior class. + Represents a uniform distribution over a specified interval. + + This class provides methods to calculate the pdf, the log pdf, and to generate + random variates from the distribution. + + :param lower: The lower bound of the distribution. + :type lower: float + :param upper: The upper bound of the distribution. + :type upper: float .. py:method:: __repr__() - Return repr(self). + Returns a string representation of the Uniform object. .. py:method:: logpdf(x) + Calculates the logarithm of the pdf of the uniform distribution at x. + + :param x: The point at which to evaluate the log pdf. + :type x: float + + :returns: The log of the probability density function value at x. + :rtype: float + .. py:method:: pdf(x) + Calculates the probability density function of the uniform distribution at x. + + :param x: The point at which to evaluate the pdf. + :type x: float + + :returns: The probability density function value at x. + :rtype: float + .. py:method:: rvs(size) + + Generates random variates from the uniform distribution. + + :param size: The number of random variates to generate. + :type size: int + + :returns: An array of random variates from the uniform distribution. + :rtype: array_like + + :raises ValueError: If the size parameter is not positive. diff --git a/docs/conf.py b/docs/conf.py index 84364515..f3e3ce0c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -37,6 +37,7 @@ ] templates_path = ["_templates"] +autoapi_template_dir = "_templates/autoapi" exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] # -- Options for autoapi ------------------------------------------------------- diff --git a/pybop/models/base_model.py b/pybop/models/base_model.py index 848ab029..f2b67495 100644 --- a/pybop/models/base_model.py +++ b/pybop/models/base_model.py @@ -4,10 +4,38 @@ class BaseModel: """ - Base class for pybop models. + A base class for constructing and simulating models using PyBaMM. + + This class serves as a foundation for building specific models in PyBaMM. + It provides methods to set up the model, define parameters, and perform + simulations. The class is designed to be subclassed for creating models + with custom behavior. + + Methods + ------- + build(dataset=None, parameters=None, check_model=True, init_soc=None) + Construct the PyBaMM model if not already built. + set_init_soc(init_soc) + Set the initial state of charge for the battery model. + set_params() + Assign the parameters to the model. + simulate(inputs, t_eval) + Execute the forward model simulation and return the result. + simulateS1(inputs, t_eval) + Perform the forward model simulation with sensitivities. + predict(inputs=None, t_eval=None, parameter_set=None, experiment=None, init_soc=None) + Solve the model using PyBaMM's simulation framework and return the solution. """ def __init__(self, name="Base Model"): + """ + Initialize the BaseModel with an optional name. + + Parameters + ---------- + name : str, optional + The name given to the model instance. + """ self.name = name self.pybamm_model = None self.parameters = None @@ -22,9 +50,22 @@ def build( init_soc=None, ): """ - Build the PyBOP model (if not built already). - For PyBaMM forward models, this method follows a - similar process to pybamm.Simulation.build(). + Construct the PyBaMM model if not already built, and set parameters. + + This method initializes the model components, applies the given parameters, + sets up the mesh and discretization if needed, and prepares the model + for simulations. + + Parameters + ---------- + dataset : pybamm.Dataset, optional + The dataset to be used in the model construction. + parameters : dict, optional + A dictionary containing parameter values to apply to the model. + check_model : bool, optional + If True, the model will be checked for correctness after construction. + init_soc : float, optional + The initial state of charge to be used in simulations. """ self.dataset = dataset self.parameters = parameters @@ -53,7 +94,12 @@ def build( def set_init_soc(self, init_soc): """ - Set the initial state of charge. + Set the initial state of charge for the battery model. + + Parameters + ---------- + init_soc : float + The initial state of charge to be used in the model. """ if self._built_initial_soc != init_soc: # reset @@ -73,7 +119,10 @@ def set_init_soc(self, init_soc): def set_params(self): """ - Set the parameters in the model. + Assign the parameters to the model. + + This method processes the model with the given parameters, sets up + the geometry, and updates the model instance. """ if self.model_with_set_params: return @@ -101,8 +150,25 @@ def set_params(self): def simulate(self, inputs, t_eval): """ - Run the forward model and return the result in Numpy array format - aligning with Pints' ForwardModel simulate method. + Execute the forward model simulation and return the result. + + Parameters + ---------- + inputs : dict or array-like + The input parameters for the simulation. If array-like, it will be + converted to a dictionary using the model's fit keys. + t_eval : array-like + An array of time points at which to evaluate the solution. + + Returns + ------- + array-like + The simulation result corresponding to the specified signal. + + Raises + ------ + ValueError + If the model has not been built before simulation. """ if self._built_model is None: @@ -117,8 +183,26 @@ def simulate(self, inputs, t_eval): def simulateS1(self, inputs, t_eval): """ - Run the forward model and return the function evaulation and it's gradient - aligning with Pints' ForwardModel simulateS1 method. + Perform the forward model simulation with sensitivities. + + Parameters + ---------- + inputs : dict or array-like + The input parameters for the simulation. If array-like, it will be + converted to a dictionary using the model's fit keys. + t_eval : array-like + An array of time points at which to evaluate the solution and its + sensitivities. + + Returns + ------- + tuple + A tuple containing the simulation result and the sensitivities. + + Raises + ------ + ValueError + If the model has not been built before simulation. """ if self._built_model is None: @@ -153,7 +237,42 @@ def predict( init_soc=None, ): """ - Create a PyBaMM simulation object, solve it, and return a solution object. + Solve the model using PyBaMM's simulation framework and return the solution. + + This method sets up a PyBaMM simulation by configuring the model, parameters, experiment + (if any), and initial state of charge (if provided). It then solves the simulation and + returns the resulting solution object. + + Parameters + ---------- + inputs : dict or array-like, optional + Input parameters for the simulation. If the input is array-like, it is converted + to a dictionary using the model's fitting keys. Defaults to None, indicating + that the default parameters should be used. + t_eval : array-like, optional + An array of time points at which to evaluate the solution. Defaults to None, + which means the time points need to be specified within experiment or elsewhere. + parameter_set : pybamm.ParameterValues, optional + A PyBaMM ParameterValues object or a dictionary containing the parameter values + to use for the simulation. Defaults to the model's current ParameterValues if None. + experiment : pybamm.Experiment, optional + A PyBaMM Experiment object specifying the experimental conditions under which + the simulation should be run. Defaults to None, indicating no experiment. + init_soc : float, optional + The initial state of charge for the simulation, as a fraction (between 0 and 1). + Defaults to None. + + Returns + ------- + pybamm.Solution + The solution object returned after solving the simulation. + + Raises + ------ + ValueError + If the model has not been configured properly before calling this method or + if PyBaMM models are not supported by the current simulation method. + """ parameter_set = parameter_set or self._parameter_set if inputs is not None: diff --git a/pybop/models/empirical/__init__.py b/pybop/models/empirical/__init__.py index 7f57d913..58790627 100644 --- a/pybop/models/empirical/__init__.py +++ b/pybop/models/empirical/__init__.py @@ -1,4 +1,4 @@ # # Import lithium ion based models # -from .base_ecm import Thevenin +from .ecm import Thevenin diff --git a/pybop/models/empirical/base_ecm.py b/pybop/models/empirical/ecm.py similarity index 51% rename from pybop/models/empirical/base_ecm.py rename to pybop/models/empirical/ecm.py index 85b21d1c..e6d29c3b 100644 --- a/pybop/models/empirical/base_ecm.py +++ b/pybop/models/empirical/ecm.py @@ -4,8 +4,32 @@ class Thevenin(BaseModel): """ - Composition of the PyBaMM Single Particle Model class. + The Thevenin class represents an equivalent circuit model based on the Thevenin model in PyBaMM. + This class encapsulates the PyBaMM equivalent circuit Thevenin model, providing an interface + to define the parameters, geometry, submesh types, variable points, spatial methods, and solver + to be used for simulations. + + Parameters + ---------- + name : str, optional + A name for the model instance. Defaults to "Equivalent Circuit Thevenin Model". + parameter_set : dict or None, optional + A dictionary of parameters to be used for the model. If None, the default parameters from PyBaMM are used. + geometry : dict or None, optional + The geometry definitions for the model. If None, the default geometry from PyBaMM is used. + submesh_types : dict or None, optional + The types of submeshes to use. If None, the default submesh types from PyBaMM are used. + var_pts : dict or None, optional + The number of points for each variable in the model to define the discretization. If None, the default is used. + spatial_methods : dict or None, optional + The spatial methods to be used for discretization. If None, the default spatial methods from PyBaMM are used. + solver : pybamm.Solver or None, optional + The solver to use for simulating the model. If None, the default solver from PyBaMM is used. + options : dict or None, optional + A dictionary of options to pass to the PyBaMM Thevenin model. + **kwargs : + Additional arguments passed to the PyBaMM Thevenin model constructor. """ def __init__( diff --git a/pybop/models/lithium_ion/__init__.py b/pybop/models/lithium_ion/__init__.py index 69b51653..d61591b4 100644 --- a/pybop/models/lithium_ion/__init__.py +++ b/pybop/models/lithium_ion/__init__.py @@ -1,4 +1,4 @@ # # Import lithium ion based models # -from .base_echem import SPM, SPMe +from .echem import SPM, SPMe diff --git a/pybop/models/lithium_ion/base_echem.py b/pybop/models/lithium_ion/base_echem.py deleted file mode 100644 index d22a99e6..00000000 --- a/pybop/models/lithium_ion/base_echem.py +++ /dev/null @@ -1,88 +0,0 @@ -import pybamm -from ..base_model import BaseModel - - -class SPM(BaseModel): - """ - Composition of the PyBaMM Single Particle Model class. - - """ - - def __init__( - self, - name="Single Particle Model", - parameter_set=None, - geometry=None, - submesh_types=None, - var_pts=None, - spatial_methods=None, - solver=None, - options=None, - ): - super().__init__() - self.pybamm_model = pybamm.lithium_ion.SPM(options=options) - self._unprocessed_model = self.pybamm_model - self.name = name - - self.default_parameter_values = self.pybamm_model.default_parameter_values - self._parameter_set = ( - parameter_set or self.pybamm_model.default_parameter_values - ) - self._unprocessed_parameter_set = self._parameter_set - - self.geometry = geometry or self.pybamm_model.default_geometry - self.submesh_types = submesh_types or self.pybamm_model.default_submesh_types - self.var_pts = var_pts or self.pybamm_model.default_var_pts - self.spatial_methods = ( - spatial_methods or self.pybamm_model.default_spatial_methods - ) - self.solver = solver or self.pybamm_model.default_solver - - self._model_with_set_params = None - self._built_model = None - self._built_initial_soc = None - self._mesh = None - self._disc = None - - -class SPMe(BaseModel): - """ - Composition of the PyBaMM Single Particle Model with Electrolyte class. - - """ - - def __init__( - self, - name="Single Particle Model with Electrolyte", - parameter_set=None, - geometry=None, - submesh_types=None, - var_pts=None, - spatial_methods=None, - solver=None, - options=None, - ): - super().__init__() - self.pybamm_model = pybamm.lithium_ion.SPMe(options=options) - self._unprocessed_model = self.pybamm_model - self.name = name - - self.default_parameter_values = self.pybamm_model.default_parameter_values - self._parameter_set = ( - parameter_set or self.pybamm_model.default_parameter_values - ) - self._unprocessed_parameter_set = self._parameter_set - - self.geometry = geometry or self.pybamm_model.default_geometry - self.submesh_types = submesh_types or self.pybamm_model.default_submesh_types - self.var_pts = var_pts or self.pybamm_model.default_var_pts - self.spatial_methods = ( - spatial_methods or self.pybamm_model.default_spatial_methods - ) - self.solver = solver or self.pybamm_model.default_solver - - self._model_with_set_params = None - self._built_model = None - self._built_initial_soc = None - self._mesh = None - self._disc = None diff --git a/pybop/models/lithium_ion/echem.py b/pybop/models/lithium_ion/echem.py new file mode 100644 index 00000000..35086fe8 --- /dev/null +++ b/pybop/models/lithium_ion/echem.py @@ -0,0 +1,138 @@ +import pybamm +from ..base_model import BaseModel + + +class SPM(BaseModel): + """ + Wraps the Single Particle Model (SPM) for simulating lithium-ion batteries, as implemented in PyBaMM. + + The SPM is a simplified physics-based model that represents a lithium-ion cell using a single + spherical particle to simulate the behavior of the negative and positive electrodes. + + Parameters + ---------- + name : str, optional + The name for the model instance, defaulting to "Single Particle Model". + parameter_set : pybamm.ParameterValues or dict, optional + The parameters for the model. If None, default parameters provided by PyBaMM are used. + geometry : dict, optional + The geometry definitions for the model. If None, default geometry from PyBaMM is used. + submesh_types : dict, optional + The types of submeshes to use. If None, default submesh types from PyBaMM are used. + var_pts : dict, optional + The discretization points for each variable in the model. If None, default points from PyBaMM are used. + spatial_methods : dict, optional + The spatial methods used for discretization. If None, default spatial methods from PyBaMM are used. + solver : pybamm.Solver, optional + The solver to use for simulating the model. If None, the default solver from PyBaMM is used. + options : dict, optional + A dictionary of options to customize the behavior of the PyBaMM model. + """ + + def __init__( + self, + name="Single Particle Model", + parameter_set=None, + geometry=None, + submesh_types=None, + var_pts=None, + spatial_methods=None, + solver=None, + options=None, + ): + super().__init__() + self.pybamm_model = pybamm.lithium_ion.SPM(options=options) + self._unprocessed_model = self.pybamm_model + self.name = name + + # Set parameters, using either the provided ones or the default + self.default_parameter_values = self.pybamm_model.default_parameter_values + self._parameter_set = ( + parameter_set or self.pybamm_model.default_parameter_values + ) + self._unprocessed_parameter_set = self._parameter_set + + # Define model geometry and discretization + self.geometry = geometry or self.pybamm_model.default_geometry + self.submesh_types = submesh_types or self.pybamm_model.default_submesh_types + self.var_pts = var_pts or self.pybamm_model.default_var_pts + self.spatial_methods = ( + spatial_methods or self.pybamm_model.default_spatial_methods + ) + self.solver = solver or self.pybamm_model.default_solver + + # Internal attributes for the built model are initialized but not set + self._model_with_set_params = None + self._built_model = None + self._built_initial_soc = None + self._mesh = None + self._disc = None + + +class SPMe(BaseModel): + """ + Represents the Single Particle Model with Electrolyte (SPMe) for lithium-ion batteries. + + The SPMe extends the basic Single Particle Model (SPM) by incorporating electrolyte dynamics, + making it suitable for simulations where electrolyte effects are non-negligible. This class + provides a framework to define the model parameters, geometry, mesh types, discretization + points, spatial methods, and numerical solvers for simulation within the PyBaMM ecosystem. + + Parameters + ---------- + name: str, optional + A name for the model instance, defaults to "Single Particle Model with Electrolyte". + parameter_set: pybamm.ParameterValues or dict, optional + A dictionary or a ParameterValues object containing the parameters for the model. If None, the default PyBaMM parameters for SPMe are used. + geometry: dict, optional + A dictionary defining the model's geometry. If None, the default PyBaMM geometry for SPMe is used. + submesh_types: dict, optional + A dictionary defining the types of submeshes to use. If None, the default PyBaMM submesh types for SPMe are used. + var_pts: dict, optional + A dictionary specifying the number of points for each variable for discretization. If None, the default PyBaMM variable points for SPMe are used. + spatial_methods: dict, optional + A dictionary specifying the spatial methods for discretization. If None, the default PyBaMM spatial methods for SPMe are used. + solver: pybamm.Solver, optional + The solver to use for simulating the model. If None, the default PyBaMM solver for SPMe is used. + options: dict, optional + A dictionary of options to customize the behavior of the PyBaMM model. + """ + + def __init__( + self, + name="Single Particle Model with Electrolyte", + parameter_set=None, + geometry=None, + submesh_types=None, + var_pts=None, + spatial_methods=None, + solver=None, + options=None, + ): + super().__init__() + self.pybamm_model = pybamm.lithium_ion.SPMe(options=options) + self._unprocessed_model = self.pybamm_model + self.name = name + + # Set parameters, using either the provided ones or the default + self.default_parameter_values = self.pybamm_model.default_parameter_values + self._parameter_set = ( + parameter_set or self.pybamm_model.default_parameter_values + ) + self._unprocessed_parameter_set = self._parameter_set + + # Define model geometry and discretization + self.geometry = geometry or self.pybamm_model.default_geometry + self.submesh_types = submesh_types or self.pybamm_model.default_submesh_types + self.var_pts = var_pts or self.pybamm_model.default_var_pts + self.spatial_methods = ( + spatial_methods or self.pybamm_model.default_spatial_methods + ) + self.solver = solver or self.pybamm_model.default_solver + + # Internal attributes for the built model are initialized but not set + self._model_with_set_params = None + self._built_model = None + self._built_initial_soc = None + self._mesh = None + self._disc = None diff --git a/pybop/optimisers/base_optimiser.py b/pybop/optimisers/base_optimiser.py index b0b13385..c15fcb92 100644 --- a/pybop/optimisers/base_optimiser.py +++ b/pybop/optimisers/base_optimiser.py @@ -1,17 +1,48 @@ class BaseOptimiser: """ + A base class for defining optimisation methods. - Base class for the optimisation methods. + This class serves as a template for creating optimisers. It provides a basic structure for + an optimisation algorithm, including the initial setup and a method stub for performing + the optimisation process. Child classes should override the optimise and _runoptimise + methods with specific algorithms. + Methods + ------- + optimise(cost_function, x0=None, bounds=None, maxiter=None) + Initiates the optimisation process. This is a stub and should be implemented in child classes. + _runoptimise(cost_function, x0=None, bounds=None) + Contains the logic for the optimisation algorithm. This is a stub and should be implemented in child classes. + name() + Returns the name of the optimiser. """ def __init__(self): + """ + Initializes the BaseOptimiser. + """ pass def optimise(self, cost_function, x0=None, bounds=None, maxiter=None): """ - Optimisiation method to be overloaded by child classes. + Initiates the optimisation process. + + This method should be overridden by child classes with the specific optimisation algorithm. + Parameters + ---------- + cost_function : callable + The cost function to be minimised by the optimiser. + x0 : ndarray, optional + Initial guess for the parameters. Default is None. + bounds : sequence or Bounds, optional + Bounds on the parameters. Default is None. + maxiter : int, optional + Maximum number of iterations to perform. Default is None. + + Returns + ------- + The result of the optimisation process. The specific type of this result will depend on the child implementation. """ self.cost_function = cost_function self.x0 = x0 @@ -25,13 +56,33 @@ def optimise(self, cost_function, x0=None, bounds=None, maxiter=None): def _runoptimise(self, cost_function, x0=None, bounds=None): """ - Run optimisation method, to be overloaded by child classes. + Contains the logic for the optimisation algorithm. + + This method should be implemented by child classes to perform the actual optimisation. + Parameters + ---------- + cost_function : callable + The cost function to be minimised by the optimiser. + x0 : ndarray, optional + Initial guess for the parameters. Default is None. + bounds : sequence or Bounds, optional + Bounds on the parameters. Default is None. + + Returns + ------- + This method is expected to return the result of the optimisation, the format of which + will be determined by the child class implementation. """ pass def name(self): """ Returns the name of the optimiser. + + Returns + ------- + str + The name of the optimiser, which is "BaseOptimiser" for this base class. """ - return "Base Optimiser" + return "BaseOptimiser" diff --git a/pybop/optimisers/nlopt_optimize.py b/pybop/optimisers/nlopt_optimize.py index 7d78a699..26f802a4 100644 --- a/pybop/optimisers/nlopt_optimize.py +++ b/pybop/optimisers/nlopt_optimize.py @@ -5,7 +5,31 @@ class NLoptOptimize(BaseOptimiser): """ - Wrapper class for the NLOpt optimiser class. Extends the BaseOptimiser class. + Extends BaseOptimiser to utilize the NLopt library for nonlinear optimization. + + This class serves as an interface to the NLopt optimization algorithms. It allows the user to + define an optimization problem with bounds, initial guesses, and to select an optimization method + provided by NLopt. + + Parameters + ---------- + n_param : int + Number of parameters to optimize. + xtol : float, optional + The relative tolerance for optimization (stopping criteria). If not provided, a default of 1e-5 is used. + method : nlopt.algorithm, optional + The NLopt algorithm to use for optimization. If not provided, LN_BOBYQA is used by default. + maxiter : int, optional + The maximum number of iterations to perform during optimization. If not provided, NLopt's default is used. + + Methods + ------- + _runoptimise(cost_function, x0, bounds) + Performs the optimization using the NLopt library. + needs_sensitivities() + Indicates whether the optimizer requires gradient information. + name() + Returns the name of the optimizer. """ def __init__(self, n_param, xtol=None, method=None, maxiter=None): @@ -25,14 +49,21 @@ def __init__(self, n_param, xtol=None, method=None, maxiter=None): def _runoptimise(self, cost_function, x0, bounds): """ - Run the NLOpt optimisation method. + Runs the optimization process using the NLopt library. - Inputs + Parameters ---------- - cost_function: function for optimising - method: optimisation algorithm - x0: initialisation array - bounds: bounds array + cost_function : callable + The objective function to minimize. It should take an array of parameter values and return the scalar cost. + x0 : array_like + The initial guess for the parameters. + bounds : dict + A dictionary containing the 'lower' and 'upper' bounds arrays for the parameters. + + Returns + ------- + tuple + A tuple containing the optimized parameter values and the final cost. """ # Add callback storing history of parameter values @@ -61,12 +92,22 @@ def cost_wrapper(x, grad): def needs_sensitivities(self): """ - Returns True if the optimiser needs sensitivities. + Indicates if the optimizer requires gradient information for the cost function. + + Returns + ------- + bool + False, as the default NLopt algorithms do not require gradient information. """ return False def name(self): """ - Returns the name of the optimiser. + Returns the name of this optimizer instance. + + Returns + ------- + str + The name 'NLoptOptimize' representing this NLopt optimization class. """ return "NLoptOptimize" diff --git a/pybop/optimisers/pints_optimisers.py b/pybop/optimisers/pints_optimisers.py index f8e17790..765b43c9 100644 --- a/pybop/optimisers/pints_optimisers.py +++ b/pybop/optimisers/pints_optimisers.py @@ -3,8 +3,24 @@ class GradientDescent(pints.GradientDescent): """ - Gradient descent optimiser. Inherits from the PINTS gradient descent class. - https://github.com/pints-team/pints/blob/main/pints/_optimisers/_gradient_descent.py + Implements a simple gradient descent optimization algorithm. + + This class extends the gradient descent optimizer from the PINTS library, designed + to minimize a scalar function of one or more variables. Note that this optimizer + does not support boundary constraints. + + Parameters + ---------- + x0 : array_like + Initial position from which optimization will start. + sigma0 : float, optional + Initial step size (default is 0.1). + bounds : sequence or ``Bounds``, optional + Ignored by this optimizer, provided for API consistency. + + See Also + -------- + pints.GradientDescent : The PINTS implementation this class is based on. """ def __init__(self, x0, sigma0=0.1, bounds=None): @@ -17,8 +33,24 @@ def __init__(self, x0, sigma0=0.1, bounds=None): class Adam(pints.Adam): """ - Adam optimiser. Inherits from the PINTS Adam class. - https://github.com/pints-team/pints/blob/main/pints/_optimisers/_adam.py + Implements the Adam optimization algorithm. + + This class extends the Adam optimizer from the PINTS library, which combines + ideas from RMSProp and Stochastic Gradient Descent with momentum. Note that + this optimizer does not support boundary constraints. + + Parameters + ---------- + x0 : array_like + Initial position from which optimization will start. + sigma0 : float, optional + Initial step size (default is 0.1). + bounds : sequence or ``Bounds``, optional + Ignored by this optimizer, provided for API consistency. + + See Also + -------- + pints.Adam : The PINTS implementation this class is based on. """ def __init__(self, x0, sigma0=0.1, bounds=None): @@ -31,8 +63,24 @@ def __init__(self, x0, sigma0=0.1, bounds=None): class IRPropMin(pints.IRPropMin): """ - IRProp- optimiser. Inherits from the PINTS IRPropMinus class. - https://github.com/pints-team/pints/blob/main/pints/_optimisers/_irpropmin.py + Implements the iRpropMin optimization algorithm. + + This class inherits from the PINTS IRPropMin class, which is an optimizer that + uses resilient backpropagation with weight-backtracking. It is designed to handle + problems with large plateaus, noisy gradients, and local minima. + + Parameters + ---------- + x0 : array_like + Initial position from which optimization will start. + sigma0 : float, optional + Initial step size (default is 0.1). + bounds : dict, optional + Lower and upper bounds for each optimization parameter. + + See Also + -------- + pints.IRPropMin : The PINTS implementation this class is based on. """ def __init__(self, x0, sigma0=0.1, bounds=None): @@ -47,8 +95,24 @@ def __init__(self, x0, sigma0=0.1, bounds=None): class PSO(pints.PSO): """ - Particle swarm optimiser. Inherits from the PINTS PSO class. - https://github.com/pints-team/pints/blob/main/pints/_optimisers/_pso.py + Implements a particle swarm optimization (PSO) algorithm. + + This class extends the PSO optimizer from the PINTS library. PSO is a + metaheuristic optimization method inspired by the social behavior of birds + flocking or fish schooling, suitable for global optimization problems. + + Parameters + ---------- + x0 : array_like + Initial positions of particles, which the optimization will use. + sigma0 : float, optional + Spread of the initial particle positions (default is 0.1). + bounds : dict, optional + Lower and upper bounds for each optimization parameter. + + See Also + -------- + pints.PSO : The PINTS implementation this class is based on. """ def __init__(self, x0, sigma0=0.1, bounds=None): @@ -63,8 +127,24 @@ def __init__(self, x0, sigma0=0.1, bounds=None): class SNES(pints.SNES): """ - Stochastic natural evolution strategy optimiser. Inherits from the PINTS SNES class. - https://github.com/pints-team/pints/blob/main/pints/_optimisers/_snes.py + Implements the stochastic natural evolution strategy (SNES) optimization algorithm. + + Inheriting from the PINTS SNES class, this optimizer is an evolutionary algorithm + that evolves a probability distribution on the parameter space, guiding the search + for the optimum based on the natural gradient of expected fitness. + + Parameters + ---------- + x0 : array_like + Initial position from which optimization will start. + sigma0 : float, optional + Initial step size (default is 0.1). + bounds : dict, optional + Lower and upper bounds for each optimization parameter. + + See Also + -------- + pints.SNES : The PINTS implementation this class is based on. """ def __init__(self, x0, sigma0=0.1, bounds=None): @@ -79,8 +159,22 @@ def __init__(self, x0, sigma0=0.1, bounds=None): class XNES(pints.XNES): """ - Exponential natural evolution strategy optimiser. Inherits from the PINTS XNES class. - https://github.com/pints-team/pints/blob/main/pints/_optimisers/_xnes.py + Implements the Exponential Natural Evolution Strategy (XNES) optimizer from PINTS. + + XNES is an evolutionary algorithm that samples from a multivariate normal distribution, which is updated iteratively to fit the distribution of successful solutions. + + Parameters + ---------- + x0 : array_like + The initial parameter vector to optimize. + sigma0 : float, optional + Initial standard deviation of the sampling distribution, defaults to 0.1. + bounds : dict, optional + A dictionary with 'lower' and 'upper' keys containing arrays for lower and upper bounds on the parameters. If ``None``, no bounds are enforced. + + See Also + -------- + pints.XNES : PINTS implementation of XNES algorithm. """ def __init__(self, x0, sigma0=0.1, bounds=None): @@ -95,8 +189,24 @@ def __init__(self, x0, sigma0=0.1, bounds=None): class CMAES(pints.CMAES): """ - Class for the PINTS optimisation. Extends the BaseOptimiser class. - https://github.com/pints-team/pints/blob/main/pints/_optimisers/_cmaes.py + Adapter for the Covariance Matrix Adaptation Evolution Strategy (CMA-ES) optimizer in PINTS. + + CMA-ES is an evolutionary algorithm for difficult non-linear non-convex optimization problems. + It adapts the covariance matrix of a multivariate normal distribution to capture the shape of the cost landscape. + + Parameters + ---------- + x0 : array_like + The initial parameter vector to optimize. + sigma0 : float, optional + Initial standard deviation of the sampling distribution, defaults to 0.1. + bounds : dict, optional + A dictionary with 'lower' and 'upper' keys containing arrays for lower and upper bounds on the parameters. + If ``None``, no bounds are enforced. + + See Also + -------- + pints.CMAES : PINTS implementation of CMA-ES algorithm. """ def __init__(self, x0, sigma0=0.1, bounds=None): diff --git a/pybop/optimisers/scipy_optimisers.py b/pybop/optimisers/scipy_optimisers.py index 59f9e638..ce7e4fe5 100644 --- a/pybop/optimisers/scipy_optimisers.py +++ b/pybop/optimisers/scipy_optimisers.py @@ -4,7 +4,18 @@ class SciPyMinimize(BaseOptimiser): """ - Wrapper class for the SciPy optimisation class. Extends the BaseOptimiser class. + Adapts SciPy's minimize function for use as an optimization strategy. + + This class provides an interface to various scalar minimization algorithms implemented in SciPy, allowing fine-tuning of the optimization process through method selection and option configuration. + + Parameters + ---------- + method : str, optional + The type of solver to use. If not specified, defaults to 'COBYLA'. + bounds : sequence or ``Bounds``, optional + Bounds for variables as supported by the selected method. + maxiter : int, optional + Maximum number of iterations to perform. """ def __init__(self, method=None, bounds=None, maxiter=None): @@ -22,14 +33,21 @@ def __init__(self, method=None, bounds=None, maxiter=None): def _runoptimise(self, cost_function, x0, bounds): """ - Run the SciPy optimisation method. + Executes the optimization process using SciPy's minimize function. - Inputs + Parameters ---------- - cost_function: function for optimising - method: optimisation algorithm - x0: initialisation array - bounds: bounds array + cost_function : callable + The objective function to minimize. + x0 : array_like + Initial guess for the parameters. + bounds : sequence or `Bounds` + Bounds for the variables. + + Returns + ------- + tuple + A tuple (x, final_cost) containing the optimized parameters and the value of `cost_function` at the optimum. """ # Add callback storing history of parameter values @@ -61,20 +79,43 @@ def callback(x): def needs_sensitivities(self): """ - Returns True if the optimiser needs sensitivities. + Determines if the optimization algorithm requires gradient information. + + Returns + ------- + bool + False, indicating that gradient information is not required. """ return False def name(self): """ - Returns the name of the optimiser. + Provides the name of the optimization strategy. + + Returns + ------- + str + The name 'SciPyMinimize'. """ return "SciPyMinimize" class SciPyDifferentialEvolution(BaseOptimiser): """ - Wrapper class for the SciPy differential_evolution optimisation method. Extends the BaseOptimiser class. + Adapts SciPy's differential_evolution function for global optimization. + + This class provides a global optimization strategy based on differential evolution, useful for problems involving continuous parameters and potentially multiple local minima. + + Parameters + ---------- + bounds : sequence or ``Bounds`` + Bounds for variables. Must be provided as it is essential for differential evolution. + strategy : str, optional + The differential evolution strategy to use. Defaults to 'best1bin'. + maxiter : int, optional + Maximum number of iterations to perform. Defaults to 1000. + popsize : int, optional + The number of individuals in the population. Defaults to 15. """ def __init__(self, bounds=None, strategy="best1bin", maxiter=1000, popsize=15): @@ -86,18 +127,21 @@ def __init__(self, bounds=None, strategy="best1bin", maxiter=1000, popsize=15): def _runoptimise(self, cost_function, x0=None, bounds=None): """ - Run the SciPy differential_evolution optimisation method. + Executes the optimization process using SciPy's differential_evolution function. - Inputs + Parameters ---------- - cost_function : function - The objective function to be minimized. - x0 : array_like - Initial guess. Only used to determine the dimensionality of the problem. - bounds : sequence or `Bounds` - Bounds for variables. There are two ways to specify the bounds: - 1. Instance of `Bounds` class. - 2. Sequence of (min, max) pairs for each element in x, defining the finite lower and upper bounds for the optimizing argument of `cost_function`. + cost_function : callable + The objective function to minimize. + x0 : array_like, optional + Ignored parameter, provided for API consistency. + bounds : sequence or ``Bounds`` + Bounds for the variables, required for differential evolution. + + Returns + ------- + tuple + A tuple (x, final_cost) containing the optimized parameters and the value of ``cost_function`` at the optimum. """ if bounds is None: @@ -137,12 +181,22 @@ def callback(x, convergence): def needs_sensitivities(self): """ - Returns False as differential_evolution does not need sensitivities. + Determines if the optimization algorithm requires gradient information. + + Returns + ------- + bool + False, indicating that gradient information is not required for differential evolution. """ return False def name(self): """ - Returns the name of the optimiser. + Provides the name of the optimization strategy. + + Returns + ------- + str + The name 'SciPyDifferentialEvolution'. """ return "SciPyDifferentialEvolution" diff --git a/pybop/parameters/parameter.py b/pybop/parameters/parameter.py index 9cdf8bc2..37514bfc 100644 --- a/pybop/parameters/parameter.py +++ b/pybop/parameters/parameter.py @@ -2,11 +2,45 @@ class Parameter: - """ "" - Class for creating parameters in PyBOP. + """ + Represents a parameter within the PyBOP framework. + + This class encapsulates the definition of a parameter, including its name, prior + distribution, initial value, bounds, and a margin to ensure the parameter stays + within feasible limits during optimization or sampling. + + Parameters + ---------- + name : str + The name of the parameter. + initial_value : float, optional + The initial value to be assigned to the parameter. Defaults to None. + prior : scipy.stats distribution, optional + The prior distribution from which parameter values are drawn. Defaults to None. + bounds : tuple, optional + A tuple defining the lower and upper bounds for the parameter. + Defaults to None. + + Methods + ------- + rvs(n_samples) + Draw random samples from the parameter's prior distribution. + update(value) + Update the parameter's current value. + set_margin(margin) + Set the margin to a specified positive value less than 1. + + Raises + ------ + ValueError + If the lower bound is not strictly less than the upper bound, or if + the margin is set outside the interval (0, 1). """ def __init__(self, name, initial_value=None, prior=None, bounds=None): + """ + Construct the parameter class with a name, initial value, prior, and bounds. + """ self.name = name self.prior = prior self.initial_value = initial_value @@ -21,7 +55,20 @@ def __init__(self, name, initial_value=None, prior=None, bounds=None): def rvs(self, n_samples): """ - Returns a random value sample from the prior distribution. + Draw random samples from the parameter's prior distribution. + + The samples are constrained to be within the parameter's bounds, excluding + a predefined margin at the boundaries. + + Parameters + ---------- + n_samples : int + The number of samples to draw. + + Returns + ------- + array-like + An array of samples drawn from the prior distribution within the parameter's bounds. """ samples = self.prior.rvs(n_samples) @@ -32,14 +79,43 @@ def rvs(self, n_samples): return samples def update(self, value): + """ + Update the parameter's current value. + + Parameters + ---------- + value : float + The new value to be assigned to the parameter. + """ self.value = value def __repr__(self): + """ + Return a string representation of the Parameter instance. + + Returns + ------- + str + A string including the parameter's name, prior, bounds, and current value. + """ return f"Parameter: {self.name} \n Prior: {self.prior} \n Bounds: {self.bounds} \n Value: {self.value}" def set_margin(self, margin): """ - Sets the margin for the parameter. + Set the margin to a specified positive value less than 1. + + The margin is used to ensure parameter samples are not drawn exactly at the bounds, + which may be problematic in some optimization or sampling algorithms. + + Parameters + ---------- + margin : float + The new margin value to be used, which must be in the interval (0, 1). + + Raises + ------ + ValueError + If the margin is not between 0 and 1. """ if not 0 < margin < 1: raise ValueError("Margin must be between 0 and 1") diff --git a/pybop/parameters/parameter_set.py b/pybop/parameters/parameter_set.py index 8db93f8c..946d05ba 100644 --- a/pybop/parameters/parameter_set.py +++ b/pybop/parameters/parameter_set.py @@ -6,11 +6,18 @@ class ParameterSet: """ - A class to manage the import and export of parameter sets for battery models. + Handles the import and export of parameter sets for battery models. - Attributes: - json_path (str): The file path to a JSON file containing parameter data. - params (dict): A dictionary containing parameter key-value pairs. + This class provides methods to load parameters from a JSON file and to export them + back to a JSON file. It also includes custom logic to handle special cases, such + as parameter values that require specific initialization. + + Parameters + ---------- + json_path : str, optional + Path to a JSON file containing parameter data. If provided, parameters will be imported from this file during initialization. + params_dict : dict, optional + A dictionary of parameters to initialize the ParameterSet with. If not provided, an empty dictionary is used. """ def __init__(self, json_path=None, params_dict=None): @@ -20,7 +27,26 @@ def __init__(self, json_path=None, params_dict=None): def import_parameters(self, json_path=None): """ - Import parameters from a JSON file. + Imports parameters from a JSON file specified by the `json_path` attribute. + + If a `json_path` is provided at initialization or as an argument, that JSON file + is loaded and the parameters are stored in the `params` attribute. Special cases + are handled appropriately. + + Parameters + ---------- + json_path : str, optional + Path to the JSON file from which to import parameters. If provided, it overrides the instance's `json_path`. + + Returns + ------- + dict + The dictionary containing the imported parameters. + + Raises + ------ + FileNotFoundError + If the specified JSON file cannot be found. """ # Read JSON file @@ -34,7 +60,10 @@ def import_parameters(self, json_path=None): def _handle_special_cases(self): """ - Handles special cases for parameter values that require custom logic. + Processes special cases for parameter values that require custom handling. + + For example, if the open-circuit voltage is specified as 'default', it will + fetch the default value from the PyBaMM empirical Thevenin model. """ if ( "Open-circuit voltage [V]" in self.params @@ -48,7 +77,23 @@ def _handle_special_cases(self): def export_parameters(self, output_json_path, fit_params=None): """ - Export parameters to a JSON file. + Exports parameters to a JSON file specified by `output_json_path`. + + The current state of the `params` attribute is written to the file. If `fit_params` + is provided, these parameters are updated before export. Non-serializable values + are handled and noted in the output JSON. + + Parameters + ---------- + output_json_path : str + The file path where the JSON output will be saved. + fit_params : list of fitted parameter objects, optional + Parameters that have been fitted and need to be included in the export. + + Raises + ------ + ValueError + If there are no parameters to export. """ if not self.params: raise ValueError("No parameters to export. Please import parameters first.") @@ -74,7 +119,17 @@ def export_parameters(self, output_json_path, fit_params=None): def is_json_serializable(self, value): """ - Check if the value is serializable to JSON. + Determines if the given `value` can be serialized to JSON format. + + Parameters + ---------- + value : any + The value to check for JSON serializability. + + Returns + ------- + bool + True if the value is JSON serializable, False otherwise. """ try: json.dumps(value) @@ -85,6 +140,16 @@ def is_json_serializable(self, value): @classmethod def pybamm(cls, name): """ - Create a PyBaMM parameter set. + Retrieves a PyBaMM parameter set by name. + + Parameters + ---------- + name : str + The name of the PyBaMM parameter set to retrieve. + + Returns + ------- + pybamm.ParameterValues + A PyBaMM parameter set corresponding to the provided name. """ return pybamm.ParameterValues(name).copy() diff --git a/pybop/parameters/priors.py b/pybop/parameters/priors.py index f98e9b76..088e584d 100644 --- a/pybop/parameters/priors.py +++ b/pybop/parameters/priors.py @@ -3,7 +3,17 @@ class Gaussian: """ - Gaussian prior class. + Represents a Gaussian (normal) distribution with a given mean and standard deviation. + + This class provides methods to calculate the probability density function (pdf), + the logarithm of the pdf, and to generate random variates (rvs) from the distribution. + + Parameters + ---------- + mean : float + The mean (mu) of the Gaussian distribution. + sigma : float + The standard deviation (sigma) of the Gaussian distribution. """ def __init__(self, mean, sigma): @@ -12,24 +22,81 @@ def __init__(self, mean, sigma): self.sigma = sigma def pdf(self, x): + """ + Calculates the probability density function of the Gaussian distribution at x. + + Parameters + ---------- + x : float + The point at which to evaluate the pdf. + + Returns + ------- + float + The probability density function value at x. + """ return stats.norm.pdf(x, loc=self.mean, scale=self.sigma) def logpdf(self, x): + """ + Calculates the logarithm of the probability density function of the Gaussian distribution at x. + + Parameters + ---------- + x : float + The point at which to evaluate the log pdf. + + Returns + ------- + float + The logarithm of the probability density function value at x. + """ return stats.norm.logpdf(x, loc=self.mean, scale=self.sigma) def rvs(self, size): + """ + Generates random variates from the Gaussian distribution. + + Parameters + ---------- + size : int + The number of random variates to generate. + + Returns + ------- + array_like + An array of random variates from the Gaussian distribution. + + Raises + ------ + ValueError + If the size parameter is not positive. + """ if size < 0: raise ValueError("size must be positive") else: return stats.norm.rvs(loc=self.mean, scale=self.sigma, size=size) def __repr__(self): + """ + Returns a string representation of the Gaussian object. + """ return f"{self.name}, mean: {self.mean}, sigma: {self.sigma}" class Uniform: """ - Uniform prior class. + Represents a uniform distribution over a specified interval. + + This class provides methods to calculate the pdf, the log pdf, and to generate + random variates from the distribution. + + Parameters + ---------- + lower : float + The lower bound of the distribution. + upper : float + The upper bound of the distribution. """ def __init__(self, lower, upper): @@ -38,12 +105,56 @@ def __init__(self, lower, upper): self.upper = upper def pdf(self, x): + """ + Calculates the probability density function of the uniform distribution at x. + + Parameters + ---------- + x : float + The point at which to evaluate the pdf. + + Returns + ------- + float + The probability density function value at x. + """ return stats.uniform.pdf(x, loc=self.lower, scale=self.upper - self.lower) def logpdf(self, x): + """ + Calculates the logarithm of the pdf of the uniform distribution at x. + + Parameters + ---------- + x : float + The point at which to evaluate the log pdf. + + Returns + ------- + float + The log of the probability density function value at x. + """ return stats.uniform.logpdf(x, loc=self.lower, scale=self.upper - self.lower) def rvs(self, size): + """ + Generates random variates from the uniform distribution. + + Parameters + ---------- + size : int + The number of random variates to generate. + + Returns + ------- + array_like + An array of random variates from the uniform distribution. + + Raises + ------ + ValueError + If the size parameter is not positive. + """ if size < 0: raise ValueError("size must be positive") else: @@ -52,12 +163,23 @@ def rvs(self, size): ) def __repr__(self): + """ + Returns a string representation of the Uniform object. + """ return f"{self.name}, lower: {self.lower}, upper: {self.upper}" class Exponential: """ - Exponential prior class. + Represents an exponential distribution with a specified scale parameter. + + This class provides methods to calculate the pdf, the log pdf, and to generate random + variates from the distribution. + + Parameters + ---------- + scale : float + The scale parameter (lambda) of the exponential distribution. """ def __init__(self, scale): @@ -65,16 +187,63 @@ def __init__(self, scale): self.scale = scale def pdf(self, x): + """ + Calculates the probability density function of the exponential distribution at x. + + Parameters + ---------- + x : float + The point at which to evaluate the pdf. + + Returns + ------- + float + The probability density function value at x. + """ return stats.expon.pdf(x, scale=self.scale) def logpdf(self, x): + """ + Calculates the logarithm of the pdf of the exponential distribution at x. + + Parameters + ---------- + x : float + The point at which to evaluate the log pdf. + + Returns + ------- + float + The log of the probability density function value at x. + """ return stats.expon.logpdf(x, scale=self.scale) def rvs(self, size): + """ + Generates random variates from the exponential distribution. + + Parameters + ---------- + size : int + The number of random variates to generate. + + Returns + ------- + array_like + An array of random variates from the exponential distribution. + + Raises + ------ + ValueError + If the size parameter is not positive. + """ if size < 0: raise ValueError("size must be positive") else: return stats.expon.rvs(scale=self.scale, size=size) def __repr__(self): + """ + Returns a string representation of the Uniform object. + """ return f"{self.name}, scale: {self.scale}" From 8743034a56d5b0debd295faa7abf877d6eed2370 Mon Sep 17 00:00:00 2001 From: Brady Planden Date: Mon, 11 Dec 2023 11:03:35 +0000 Subject: [PATCH 07/22] Add deploy docs workflow --- .github/workflows/deploy-docs.yaml | 37 ++++++++++++++++++++++++++ .github/workflows/scheduled_tests.yaml | 2 +- 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/deploy-docs.yaml diff --git a/.github/workflows/deploy-docs.yaml b/.github/workflows/deploy-docs.yaml new file mode 100644 index 00000000..4f080fd0 --- /dev/null +++ b/.github/workflows/deploy-docs.yaml @@ -0,0 +1,37 @@ +name: Deploy Documentation + +on: + # release: + # types: [created] + push: + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + steps: + - name: Check out PyBOP repository + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + id: setup-python + uses: actions/setup-python@v4 + with: + python-version: 3.11 + cache: 'pip' + cache-dependency-path: setup.py + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -e .[docs] + + - name: Build documentation with sphinx-build + run: | + sphinx-build -b html docs/ docs/_build/html + + - name: Deploy to GitHub Pages + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./docs/_build/html + publish_branch: gh-pages diff --git a/.github/workflows/scheduled_tests.yaml b/.github/workflows/scheduled_tests.yaml index 2de1a0f8..d1a0e02d 100644 --- a/.github/workflows/scheduled_tests.yaml +++ b/.github/workflows/scheduled_tests.yaml @@ -32,7 +32,7 @@ jobs: python -m nox -s unit python -m nox -s notebooks - #M-series Mac Mini + #M-series Mac Mini build-apple-mseries: runs-on: [self-hosted, macOS, ARM64] env: From 17e60ca8bf9c0aaca834ea0d2104aced0679f161 Mon Sep 17 00:00:00 2001 From: Brady Planden Date: Mon, 11 Dec 2023 11:17:23 +0000 Subject: [PATCH 08/22] Add workflow dispatch to deploy workflow --- .github/workflows/deploy-docs.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/deploy-docs.yaml b/.github/workflows/deploy-docs.yaml index 4f080fd0..de0003e6 100644 --- a/.github/workflows/deploy-docs.yaml +++ b/.github/workflows/deploy-docs.yaml @@ -3,6 +3,7 @@ name: Deploy Documentation on: # release: # types: [created] + workflow_dispatch: push: jobs: @@ -11,6 +12,8 @@ jobs: steps: - name: Check out PyBOP repository uses: actions/checkout@v4 + with: + fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod - name: Set up Python 3.11 id: setup-python From 6909d3002fd3462d77a4940146ea4c7ef1eeafe5 Mon Sep 17 00:00:00 2001 From: Brady Planden Date: Mon, 11 Dec 2023 11:28:30 +0000 Subject: [PATCH 09/22] updt permissions for deployment action --- .github/workflows/deploy-docs.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/deploy-docs.yaml b/.github/workflows/deploy-docs.yaml index de0003e6..390b12a9 100644 --- a/.github/workflows/deploy-docs.yaml +++ b/.github/workflows/deploy-docs.yaml @@ -6,6 +6,9 @@ on: workflow_dispatch: push: +permissions: + contents: write # allow write access for docs deployment + jobs: build-and-deploy: runs-on: ubuntu-latest From 5dfec0bfd23f9cd9cb848c1fa39ff4d34b1148b0 Mon Sep 17 00:00:00 2001 From: Brady Planden Date: Mon, 11 Dec 2023 14:04:18 +0000 Subject: [PATCH 10/22] Finish docstring update, add pypi icon, update links & frontpage --- docs/_static/custom-icon.js | 17 + docs/api/index.rst | 12 - docs/api/pybop/_costs/index.rst | 153 -- docs/api/pybop/_dataset/index.rst | 50 - docs/api/pybop/_problem/index.rst | 85 - docs/api/pybop/index.rst | 1537 ----------------- docs/api/pybop/models/base_model/index.rst | 178 -- docs/api/pybop/models/empirical/ecm/index.rst | 47 - docs/api/pybop/models/empirical/index.rst | 56 - docs/api/pybop/models/index.rst | 23 - .../pybop/models/lithium_ion/echem/index.rst | 76 - docs/api/pybop/models/lithium_ion/index.rst | 85 - docs/api/pybop/optimisation/index.rst | 125 -- .../pybop/optimisers/base_optimiser/index.rst | 83 - docs/api/pybop/optimisers/index.rst | 16 - .../pybop/optimisers/nlopt_optimize/index.rst | 81 - .../optimisers/pints_optimisers/index.rst | 189 -- .../optimisers/scipy_optimisers/index.rst | 115 -- docs/api/pybop/parameters/index.rst | 15 - docs/api/pybop/parameters/parameter/index.rst | 95 - .../pybop/parameters/parameter_set/index.rst | 95 - docs/api/pybop/parameters/priors/index.rst | 178 -- docs/api/pybop/plotting/index.rst | 17 - .../pybop/plotting/plot_convergence/index.rst | 38 - docs/api/pybop/plotting/plot_cost2d/index.rst | 54 - .../pybop/plotting/plot_parameters/index.rst | 89 - .../pybop/plotting/plotly_manager/index.rst | 70 - docs/api/pybop/plotting/quick_plot/index.rst | 123 -- docs/api/pybop/version/index.rst | 11 - docs/conf.py | 8 +- docs/index.md | 2 +- docs/user_guide/installation.rst | 5 +- pybop/_problem.py | 105 +- pybop/optimisation.py | 160 +- pybop/plotting/plot_cost2d.py | 84 +- pybop/plotting/plot_parameters.py | 103 +- pybop/plotting/plotly_manager.py | 81 +- pybop/plotting/quick_plot.py | 134 +- 38 files changed, 468 insertions(+), 3927 deletions(-) create mode 100644 docs/_static/custom-icon.js delete mode 100644 docs/api/index.rst delete mode 100644 docs/api/pybop/_costs/index.rst delete mode 100644 docs/api/pybop/_dataset/index.rst delete mode 100644 docs/api/pybop/_problem/index.rst delete mode 100644 docs/api/pybop/index.rst delete mode 100644 docs/api/pybop/models/base_model/index.rst delete mode 100644 docs/api/pybop/models/empirical/ecm/index.rst delete mode 100644 docs/api/pybop/models/empirical/index.rst delete mode 100644 docs/api/pybop/models/index.rst delete mode 100644 docs/api/pybop/models/lithium_ion/echem/index.rst delete mode 100644 docs/api/pybop/models/lithium_ion/index.rst delete mode 100644 docs/api/pybop/optimisation/index.rst delete mode 100644 docs/api/pybop/optimisers/base_optimiser/index.rst delete mode 100644 docs/api/pybop/optimisers/index.rst delete mode 100644 docs/api/pybop/optimisers/nlopt_optimize/index.rst delete mode 100644 docs/api/pybop/optimisers/pints_optimisers/index.rst delete mode 100644 docs/api/pybop/optimisers/scipy_optimisers/index.rst delete mode 100644 docs/api/pybop/parameters/index.rst delete mode 100644 docs/api/pybop/parameters/parameter/index.rst delete mode 100644 docs/api/pybop/parameters/parameter_set/index.rst delete mode 100644 docs/api/pybop/parameters/priors/index.rst delete mode 100644 docs/api/pybop/plotting/index.rst delete mode 100644 docs/api/pybop/plotting/plot_convergence/index.rst delete mode 100644 docs/api/pybop/plotting/plot_cost2d/index.rst delete mode 100644 docs/api/pybop/plotting/plot_parameters/index.rst delete mode 100644 docs/api/pybop/plotting/plotly_manager/index.rst delete mode 100644 docs/api/pybop/plotting/quick_plot/index.rst delete mode 100644 docs/api/pybop/version/index.rst diff --git a/docs/_static/custom-icon.js b/docs/_static/custom-icon.js new file mode 100644 index 00000000..ac9c6c91 --- /dev/null +++ b/docs/_static/custom-icon.js @@ -0,0 +1,17 @@ +/******************************************************************************* + * Set a custom icon for pypi as it's not available in the fa built-in brands + * Taken from: https://github.com/pydata/pydata-sphinx-theme/blob/main/docs/_static/custom-icon.js + */ +FontAwesome.library.add( + (faListOldStyle = { + prefix: "fa-custom", + iconName: "pypi", + icon: [ + 17.313, // viewBox width + 19.807, // viewBox height + [], // ligature + "e001", // unicode codepoint - private use area + "m10.383 0.2-3.239 1.1769 3.1883 1.1614 3.239-1.1798zm-3.4152 1.2411-3.2362 1.1769 3.1855 1.1614 3.2369-1.1769zm6.7177 0.00281-3.2947 1.2009v3.8254l3.2947-1.1988zm-3.4145 1.2439-3.2926 1.1981v3.8254l0.17548-0.064132 3.1171-1.1347zm-6.6564 0.018325v3.8247l3.244 1.1805v-3.8254zm10.191 0.20931v2.3137l3.1777-1.1558zm3.2947 1.2425-3.2947 1.1988v3.8254l3.2947-1.1988zm-8.7058 0.45739c0.00929-1.931e-4 0.018327-2.977e-4 0.027485 0 0.25633 0.00851 0.4263 0.20713 0.42638 0.49826 1.953e-4 0.38532-0.29327 0.80469-0.65542 0.93662-0.36226 0.13215-0.65608-0.073306-0.65613-0.4588-6.28e-5 -0.38556 0.2938-0.80504 0.65613-0.93662 0.068422-0.024919 0.13655-0.038114 0.20156-0.039466zm5.2913 0.78369-3.2947 1.1988v3.8247l3.2947-1.1981zm-10.132 1.239-3.2362 1.1769 3.1883 1.1614 3.2362-1.1769zm6.7177 0.00213-3.2926 1.2016v3.8247l3.2926-1.2009zm-3.4124 1.2439-3.2947 1.1988v3.8254l3.2947-1.1988zm-6.6585 0.016195v3.8275l3.244 1.1805v-3.8254zm16.9 0.21143-3.2947 1.1988v3.8247l3.2947-1.1981zm-3.4145 1.2411-3.2926 1.2016v3.8247l3.2926-1.2009zm-3.4145 1.2411-3.2926 1.2016v3.8247l3.2926-1.2009zm-3.4124 1.2432-3.2947 1.1988v3.8254l3.2947-1.1988zm-6.6585 0.019027v3.8247l3.244 1.1805v-3.8254zm13.485 1.4497-3.2947 1.1988v3.8247l3.2947-1.1981zm-3.4145 1.2411-3.2926 1.2016v3.8247l3.2926-1.2009zm2.4018 0.38127c0.0093-1.83e-4 0.01833-3.16e-4 0.02749 0 0.25633 0.0085 0.4263 0.20713 0.42638 0.49826 1.97e-4 0.38532-0.29327 0.80469-0.65542 0.93662-0.36188 0.1316-0.65525-0.07375-0.65542-0.4588-1.95e-4 -0.38532 0.29328-0.80469 0.65542-0.93662 0.06842-0.02494 0.13655-0.03819 0.20156-0.03947zm-5.8142 0.86403-3.244 1.1805v1.4201l3.244 1.1805z", // svg path (https://simpleicons.org/icons/pypi.svg) + ], + }) +); diff --git a/docs/api/index.rst b/docs/api/index.rst deleted file mode 100644 index a248a75b..00000000 --- a/docs/api/index.rst +++ /dev/null @@ -1,12 +0,0 @@ -API Reference -============= - -This page contains auto-generated API reference documentation [#f1]_. - -.. toctree:: - :titlesonly: - :maxdepth: 2 - - /api/pybop/index - -.. [#f1] Created with `sphinx-autoapi `_ diff --git a/docs/api/pybop/_costs/index.rst b/docs/api/pybop/_costs/index.rst deleted file mode 100644 index 36d8cab8..00000000 --- a/docs/api/pybop/_costs/index.rst +++ /dev/null @@ -1,153 +0,0 @@ -:py:mod:`pybop._costs` -====================== - -.. py:module:: pybop._costs - - -Module Contents ---------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - pybop._costs.BaseCost - pybop._costs.RootMeanSquaredError - pybop._costs.SumSquaredError - - - - -.. py:class:: BaseCost(problem) - - - Base class for defining cost functions. - - This class is intended to be subclassed to create specific cost functions - for evaluating model predictions against a set of data. The cost function - quantifies the goodness-of-fit between the model predictions and the - observed data, with a lower cost value indicating a better fit. - - :param problem: A problem instance containing the data and functions necessary for - evaluating the cost function. - :type problem: object - :param _target: An array containing the target data to fit. - :type _target: array-like - :param x0: The initial guess for the model parameters. - :type x0: array-like - :param bounds: The bounds for the model parameters. - :type bounds: tuple - :param n_parameters: The number of parameters in the model. - :type n_parameters: int - - .. py:method:: __call__(x, grad=None) - :abstractmethod: - - Calculate the cost function value for a given set of parameters. - - This method must be implemented by subclasses. - - :param x: The parameters for which to evaluate the cost. - :type x: array-like - :param grad: An array to store the gradient of the cost function with respect - to the parameters. - :type grad: array-like, optional - - :returns: The calculated cost function value. - :rtype: float - - :raises NotImplementedError: If the method has not been implemented by the subclass. - - - -.. py:class:: RootMeanSquaredError(problem) - - - Bases: :py:obj:`BaseCost` - - Root mean square error cost function. - - Computes the root mean square error between model predictions and the target - data, providing a measure of the differences between predicted values and - observed values. - - Inherits all parameters and attributes from ``BaseCost``. - - - .. py:method:: __call__(x, grad=None) - - Calculate the root mean square error for a given set of parameters. - - :param x: The parameters for which to evaluate the cost. - :type x: array-like - :param grad: An array to store the gradient of the cost function with respect - to the parameters. - :type grad: array-like, optional - - :returns: The root mean square error. - :rtype: float - - :raises ValueError: If an error occurs during the calculation of the cost. - - - -.. py:class:: SumSquaredError(problem) - - - Bases: :py:obj:`BaseCost` - - Sum of squared errors cost function. - - Computes the sum of the squares of the differences between model predictions - and target data, which serves as a measure of the total error between the - predicted and observed values. - - Inherits all parameters and attributes from ``BaseCost``. - - Additional Attributes - --------------------- - _de : float - The gradient of the cost function to use if an error occurs during - evaluation. Defaults to 1.0. - - - .. py:method:: __call__(x, grad=None) - - Calculate the sum of squared errors for a given set of parameters. - - :param x: The parameters for which to evaluate the cost. - :type x: array-like - :param grad: An array to store the gradient of the cost function with respect - to the parameters. - :type grad: array-like, optional - - :returns: The sum of squared errors. - :rtype: float - - :raises ValueError: If an error occurs during the calculation of the cost. - - - .. py:method:: evaluateS1(x) - - Compute the cost and its gradient with respect to the parameters. - - :param x: The parameters for which to compute the cost and gradient. - :type x: array-like - - :returns: A tuple containing the cost and the gradient. The cost is a float, - and the gradient is an array-like of the same length as `x`. - :rtype: tuple - - :raises ValueError: If an error occurs during the calculation of the cost or gradient. - - - .. py:method:: set_fail_gradient(de) - - Set the fail gradient to a specified value. - - The fail gradient is used if an error occurs during the calculation - of the gradient. This method allows updating the default gradient value. - - :param de: The new fail gradient value to be used. - :type de: float diff --git a/docs/api/pybop/_dataset/index.rst b/docs/api/pybop/_dataset/index.rst deleted file mode 100644 index 53913bed..00000000 --- a/docs/api/pybop/_dataset/index.rst +++ /dev/null @@ -1,50 +0,0 @@ -:py:mod:`pybop._dataset` -======================== - -.. py:module:: pybop._dataset - - -Module Contents ---------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - pybop._dataset.Dataset - - - - -.. py:class:: Dataset(name, data) - - - Represents a collection of experimental observations. - - This class provides a structured way to store and work with experimental data, - which may include applying operations such as interpolation. - - :param name: The name of the dataset, providing a label for identification. - :type name: str - :param data: The actual experimental data, typically in a structured form such as - a NumPy array or a pandas DataFrame. - :type data: array-like - - .. py:method:: Interpolant() - - Create an interpolation function of the dataset based on the independent variable. - - Currently, only time-based interpolation is supported. This method modifies - the instance's Interpolant attribute to be an interpolation function that - can be evaluated at different points in time. - - :raises NotImplementedError: If the independent variable for interpolation is not supported. - - - .. py:method:: __repr__() - - Return a string representation of the Dataset instance. - - :returns: A string that includes the name and data of the dataset. - :rtype: str diff --git a/docs/api/pybop/_problem/index.rst b/docs/api/pybop/_problem/index.rst deleted file mode 100644 index 58091c11..00000000 --- a/docs/api/pybop/_problem/index.rst +++ /dev/null @@ -1,85 +0,0 @@ -:py:mod:`pybop._problem` -======================== - -.. py:module:: pybop._problem - - -Module Contents ---------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - pybop._problem.BaseProblem - pybop._problem.DesignProblem - pybop._problem.FittingProblem - - - - -.. py:class:: BaseProblem(parameters, model=None, check_model=True, init_soc=None, x0=None) - - - Defines the PyBOP base problem, following the PINTS interface. - - .. py:method:: evaluate(x) - :abstractmethod: - - Evaluate the model with the given parameters and return the signal. - - - .. py:method:: evaluateS1(x) - :abstractmethod: - - Evaluate the model with the given parameters and return the signal and - its derivatives. - - - -.. py:class:: DesignProblem(model, parameters, experiment, check_model=True, init_soc=None, x0=None) - - - Bases: :py:obj:`BaseProblem` - - Defines the problem class for a design optimiation problem. - - .. py:method:: evaluate(x) - - Evaluate the model with the given parameters and return the signal. - - - .. py:method:: evaluateS1(x) - - Evaluate the model with the given parameters and return the signal and - its derivatives. - - - .. py:method:: target() - - Returns the target dataset. - - - -.. py:class:: FittingProblem(model, parameters, dataset, signal='Voltage [V]', check_model=True, init_soc=None, x0=None) - - - Bases: :py:obj:`BaseProblem` - - Defines the problem class for a fitting (parameter estimation) problem. - - .. py:method:: evaluate(x) - - Evaluate the model with the given parameters and return the signal. - - - .. py:method:: evaluateS1(x) - - Evaluate the model with the given parameters and return the signal and - its derivatives. - - - .. py:method:: target() - - Returns the target dataset. diff --git a/docs/api/pybop/index.rst b/docs/api/pybop/index.rst deleted file mode 100644 index a3132137..00000000 --- a/docs/api/pybop/index.rst +++ /dev/null @@ -1,1537 +0,0 @@ -:py:mod:`pybop` -=============== - -.. py:module:: pybop - - -Subpackages ------------ -.. toctree:: - :titlesonly: - :maxdepth: 3 - - models/index.rst - optimisers/index.rst - parameters/index.rst - plotting/index.rst - - -Submodules ----------- -.. toctree:: - :titlesonly: - :maxdepth: 1 - - _costs/index.rst - _dataset/index.rst - _problem/index.rst - optimisation/index.rst - version/index.rst - - -Package Contents ----------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - pybop.Adam - pybop.BaseCost - pybop.BaseModel - pybop.BaseOptimiser - pybop.CMAES - pybop.Dataset - pybop.DesignProblem - pybop.Exponential - pybop.FittingProblem - pybop.Gaussian - pybop.GradientDescent - pybop.IRPropMin - pybop.NLoptOptimize - pybop.Optimisation - pybop.PSO - pybop.Parameter - pybop.ParameterSet - pybop.PlotlyManager - pybop.RootMeanSquaredError - pybop.SNES - pybop.SciPyDifferentialEvolution - pybop.SciPyMinimize - pybop.StandardPlot - pybop.SumSquaredError - pybop.Uniform - pybop.XNES - - - -Functions -~~~~~~~~~ - -.. autoapisummary:: - - pybop.plot_convergence - pybop.plot_cost2d - pybop.plot_parameters - pybop.quick_plot - - - -Attributes -~~~~~~~~~~ - -.. autoapisummary:: - - pybop.FLOAT_FORMAT - pybop.__version__ - pybop.script_path - - -.. py:class:: Adam(x0, sigma0=0.1, bounds=None) - - - Bases: :py:obj:`pints.Adam` - - Implements the Adam optimization algorithm. - - This class extends the Adam optimizer from the PINTS library, which combines - ideas from RMSProp and Stochastic Gradient Descent with momentum. Note that - this optimizer does not support boundary constraints. - - :param x0: Initial position from which optimization will start. - :type x0: array_like - :param sigma0: Initial step size (default is 0.1). - :type sigma0: float, optional - :param bounds: Ignored by this optimizer, provided for API consistency. - :type bounds: sequence or ``Bounds``, optional - - .. seealso:: - - :obj:`pints.Adam` - The PINTS implementation this class is based on. - - -.. py:class:: BaseCost(problem) - - - Base class for defining cost functions. - - This class is intended to be subclassed to create specific cost functions - for evaluating model predictions against a set of data. The cost function - quantifies the goodness-of-fit between the model predictions and the - observed data, with a lower cost value indicating a better fit. - - :param problem: A problem instance containing the data and functions necessary for - evaluating the cost function. - :type problem: object - :param _target: An array containing the target data to fit. - :type _target: array-like - :param x0: The initial guess for the model parameters. - :type x0: array-like - :param bounds: The bounds for the model parameters. - :type bounds: tuple - :param n_parameters: The number of parameters in the model. - :type n_parameters: int - - .. py:method:: __call__(x, grad=None) - :abstractmethod: - - Calculate the cost function value for a given set of parameters. - - This method must be implemented by subclasses. - - :param x: The parameters for which to evaluate the cost. - :type x: array-like - :param grad: An array to store the gradient of the cost function with respect - to the parameters. - :type grad: array-like, optional - - :returns: The calculated cost function value. - :rtype: float - - :raises NotImplementedError: If the method has not been implemented by the subclass. - - - -.. py:class:: BaseModel(name='Base Model') - - - A base class for constructing and simulating models using PyBaMM. - - This class serves as a foundation for building specific models in PyBaMM. - It provides methods to set up the model, define parameters, and perform - simulations. The class is designed to be subclassed for creating models - with custom behavior. - - .. method:: build(dataset=None, parameters=None, check_model=True, init_soc=None) - - Construct the PyBaMM model if not already built. - - .. method:: set_init_soc(init_soc) - - Set the initial state of charge for the battery model. - - .. method:: set_params() - - Assign the parameters to the model. - - .. method:: simulate(inputs, t_eval) - - Execute the forward model simulation and return the result. - - .. method:: simulateS1(inputs, t_eval) - - Perform the forward model simulation with sensitivities. - - .. method:: predict(inputs=None, t_eval=None, parameter_set=None, experiment=None, init_soc=None) - - Solve the model using PyBaMM's simulation framework and return the solution. - - - .. py:property:: built_model - - - .. py:property:: geometry - - - .. py:property:: mesh - - - .. py:property:: model_with_set_params - - - .. py:property:: parameter_set - - - .. py:property:: solver - - - .. py:property:: spatial_methods - - - .. py:property:: submesh_types - - - .. py:property:: var_pts - - - .. py:method:: build(dataset=None, parameters=None, check_model=True, init_soc=None) - - Construct the PyBaMM model if not already built, and set parameters. - - This method initializes the model components, applies the given parameters, - sets up the mesh and discretization if needed, and prepares the model - for simulations. - - :param dataset: The dataset to be used in the model construction. - :type dataset: pybamm.Dataset, optional - :param parameters: A dictionary containing parameter values to apply to the model. - :type parameters: dict, optional - :param check_model: If True, the model will be checked for correctness after construction. - :type check_model: bool, optional - :param init_soc: The initial state of charge to be used in simulations. - :type init_soc: float, optional - - - .. py:method:: predict(inputs=None, t_eval=None, parameter_set=None, experiment=None, init_soc=None) - - Solve the model using PyBaMM's simulation framework and return the solution. - - This method sets up a PyBaMM simulation by configuring the model, parameters, experiment - (if any), and initial state of charge (if provided). It then solves the simulation and - returns the resulting solution object. - - :param inputs: Input parameters for the simulation. If the input is array-like, it is converted - to a dictionary using the model's fitting keys. Defaults to None, indicating - that the default parameters should be used. - :type inputs: dict or array-like, optional - :param t_eval: An array of time points at which to evaluate the solution. Defaults to None, - which means the time points need to be specified within experiment or elsewhere. - :type t_eval: array-like, optional - :param parameter_set: A PyBaMM ParameterValues object or a dictionary containing the parameter values - to use for the simulation. Defaults to the model's current ParameterValues if None. - :type parameter_set: pybamm.ParameterValues, optional - :param experiment: A PyBaMM Experiment object specifying the experimental conditions under which - the simulation should be run. Defaults to None, indicating no experiment. - :type experiment: pybamm.Experiment, optional - :param init_soc: The initial state of charge for the simulation, as a fraction (between 0 and 1). - Defaults to None. - :type init_soc: float, optional - - :returns: The solution object returned after solving the simulation. - :rtype: pybamm.Solution - - :raises ValueError: If the model has not been configured properly before calling this method or - if PyBaMM models are not supported by the current simulation method. - - - .. py:method:: set_init_soc(init_soc) - - Set the initial state of charge for the battery model. - - :param init_soc: The initial state of charge to be used in the model. - :type init_soc: float - - - .. py:method:: set_params() - - Assign the parameters to the model. - - This method processes the model with the given parameters, sets up - the geometry, and updates the model instance. - - - .. py:method:: simulate(inputs, t_eval) - - Execute the forward model simulation and return the result. - - :param inputs: The input parameters for the simulation. If array-like, it will be - converted to a dictionary using the model's fit keys. - :type inputs: dict or array-like - :param t_eval: An array of time points at which to evaluate the solution. - :type t_eval: array-like - - :returns: The simulation result corresponding to the specified signal. - :rtype: array-like - - :raises ValueError: If the model has not been built before simulation. - - - .. py:method:: simulateS1(inputs, t_eval) - - Perform the forward model simulation with sensitivities. - - :param inputs: The input parameters for the simulation. If array-like, it will be - converted to a dictionary using the model's fit keys. - :type inputs: dict or array-like - :param t_eval: An array of time points at which to evaluate the solution and its - sensitivities. - :type t_eval: array-like - - :returns: A tuple containing the simulation result and the sensitivities. - :rtype: tuple - - :raises ValueError: If the model has not been built before simulation. - - - -.. py:class:: BaseOptimiser - - - A base class for defining optimisation methods. - - This class serves as a template for creating optimisers. It provides a basic structure for - an optimisation algorithm, including the initial setup and a method stub for performing - the optimisation process. Child classes should override the optimise and _runoptimise - methods with specific algorithms. - - .. method:: optimise(cost_function, x0=None, bounds=None, maxiter=None) - - Initiates the optimisation process. This is a stub and should be implemented in child classes. - - .. method:: _runoptimise(cost_function, x0=None, bounds=None) - - Contains the logic for the optimisation algorithm. This is a stub and should be implemented in child classes. - - .. method:: name() - - Returns the name of the optimiser. - - - .. py:method:: _runoptimise(cost_function, x0=None, bounds=None) - - Contains the logic for the optimisation algorithm. - - This method should be implemented by child classes to perform the actual optimisation. - - :param cost_function: The cost function to be minimised by the optimiser. - :type cost_function: callable - :param x0: Initial guess for the parameters. Default is None. - :type x0: ndarray, optional - :param bounds: Bounds on the parameters. Default is None. - :type bounds: sequence or Bounds, optional - - :returns: * *This method is expected to return the result of the optimisation, the format of which* - * *will be determined by the child class implementation.* - - - .. py:method:: name() - - Returns the name of the optimiser. - - :returns: The name of the optimiser, which is "BaseOptimiser" for this base class. - :rtype: str - - - .. py:method:: optimise(cost_function, x0=None, bounds=None, maxiter=None) - - Initiates the optimisation process. - - This method should be overridden by child classes with the specific optimisation algorithm. - - :param cost_function: The cost function to be minimised by the optimiser. - :type cost_function: callable - :param x0: Initial guess for the parameters. Default is None. - :type x0: ndarray, optional - :param bounds: Bounds on the parameters. Default is None. - :type bounds: sequence or Bounds, optional - :param maxiter: Maximum number of iterations to perform. Default is None. - :type maxiter: int, optional - - :rtype: The result of the optimisation process. The specific type of this result will depend on the child implementation. - - - -.. py:class:: CMAES(x0, sigma0=0.1, bounds=None) - - - Bases: :py:obj:`pints.CMAES` - - Adapter for the Covariance Matrix Adaptation Evolution Strategy (CMA-ES) optimizer in PINTS. - - CMA-ES is an evolutionary algorithm for difficult non-linear non-convex optimization problems. - It adapts the covariance matrix of a multivariate normal distribution to capture the shape of the cost landscape. - - :param x0: The initial parameter vector to optimize. - :type x0: array_like - :param sigma0: Initial standard deviation of the sampling distribution, defaults to 0.1. - :type sigma0: float, optional - :param bounds: A dictionary with 'lower' and 'upper' keys containing arrays for lower and upper bounds on the parameters. - If ``None``, no bounds are enforced. - :type bounds: dict, optional - - .. seealso:: - - :obj:`pints.CMAES` - PINTS implementation of CMA-ES algorithm. - - -.. py:class:: Dataset(name, data) - - - Represents a collection of experimental observations. - - This class provides a structured way to store and work with experimental data, - which may include applying operations such as interpolation. - - :param name: The name of the dataset, providing a label for identification. - :type name: str - :param data: The actual experimental data, typically in a structured form such as - a NumPy array or a pandas DataFrame. - :type data: array-like - - .. py:method:: Interpolant() - - Create an interpolation function of the dataset based on the independent variable. - - Currently, only time-based interpolation is supported. This method modifies - the instance's Interpolant attribute to be an interpolation function that - can be evaluated at different points in time. - - :raises NotImplementedError: If the independent variable for interpolation is not supported. - - - .. py:method:: __repr__() - - Return a string representation of the Dataset instance. - - :returns: A string that includes the name and data of the dataset. - :rtype: str - - - -.. py:class:: DesignProblem(model, parameters, experiment, check_model=True, init_soc=None, x0=None) - - - Bases: :py:obj:`BaseProblem` - - Defines the problem class for a design optimiation problem. - - .. py:method:: evaluate(x) - - Evaluate the model with the given parameters and return the signal. - - - .. py:method:: evaluateS1(x) - - Evaluate the model with the given parameters and return the signal and - its derivatives. - - - .. py:method:: target() - - Returns the target dataset. - - - -.. py:class:: Exponential(scale) - - - Represents an exponential distribution with a specified scale parameter. - - This class provides methods to calculate the pdf, the log pdf, and to generate random - variates from the distribution. - - :param scale: The scale parameter (lambda) of the exponential distribution. - :type scale: float - - .. py:method:: __repr__() - - Returns a string representation of the Uniform object. - - - .. py:method:: logpdf(x) - - Calculates the logarithm of the pdf of the exponential distribution at x. - - :param x: The point at which to evaluate the log pdf. - :type x: float - - :returns: The log of the probability density function value at x. - :rtype: float - - - .. py:method:: pdf(x) - - Calculates the probability density function of the exponential distribution at x. - - :param x: The point at which to evaluate the pdf. - :type x: float - - :returns: The probability density function value at x. - :rtype: float - - - .. py:method:: rvs(size) - - Generates random variates from the exponential distribution. - - :param size: The number of random variates to generate. - :type size: int - - :returns: An array of random variates from the exponential distribution. - :rtype: array_like - - :raises ValueError: If the size parameter is not positive. - - - -.. py:class:: FittingProblem(model, parameters, dataset, signal='Voltage [V]', check_model=True, init_soc=None, x0=None) - - - Bases: :py:obj:`BaseProblem` - - Defines the problem class for a fitting (parameter estimation) problem. - - .. py:method:: evaluate(x) - - Evaluate the model with the given parameters and return the signal. - - - .. py:method:: evaluateS1(x) - - Evaluate the model with the given parameters and return the signal and - its derivatives. - - - .. py:method:: target() - - Returns the target dataset. - - - -.. py:class:: Gaussian(mean, sigma) - - - Represents a Gaussian (normal) distribution with a given mean and standard deviation. - - This class provides methods to calculate the probability density function (pdf), - the logarithm of the pdf, and to generate random variates (rvs) from the distribution. - - :param mean: The mean (mu) of the Gaussian distribution. - :type mean: float - :param sigma: The standard deviation (sigma) of the Gaussian distribution. - :type sigma: float - - .. py:method:: __repr__() - - Returns a string representation of the Gaussian object. - - - .. py:method:: logpdf(x) - - Calculates the logarithm of the probability density function of the Gaussian distribution at x. - - :param x: The point at which to evaluate the log pdf. - :type x: float - - :returns: The logarithm of the probability density function value at x. - :rtype: float - - - .. py:method:: pdf(x) - - Calculates the probability density function of the Gaussian distribution at x. - - :param x: The point at which to evaluate the pdf. - :type x: float - - :returns: The probability density function value at x. - :rtype: float - - - .. py:method:: rvs(size) - - Generates random variates from the Gaussian distribution. - - :param size: The number of random variates to generate. - :type size: int - - :returns: An array of random variates from the Gaussian distribution. - :rtype: array_like - - :raises ValueError: If the size parameter is not positive. - - - -.. py:class:: GradientDescent(x0, sigma0=0.1, bounds=None) - - - Bases: :py:obj:`pints.GradientDescent` - - Implements a simple gradient descent optimization algorithm. - - This class extends the gradient descent optimizer from the PINTS library, designed - to minimize a scalar function of one or more variables. Note that this optimizer - does not support boundary constraints. - - :param x0: Initial position from which optimization will start. - :type x0: array_like - :param sigma0: Initial step size (default is 0.1). - :type sigma0: float, optional - :param bounds: Ignored by this optimizer, provided for API consistency. - :type bounds: sequence or ``Bounds``, optional - - .. seealso:: - - :obj:`pints.GradientDescent` - The PINTS implementation this class is based on. - - -.. py:class:: IRPropMin(x0, sigma0=0.1, bounds=None) - - - Bases: :py:obj:`pints.IRPropMin` - - Implements the iRpropMin optimization algorithm. - - This class inherits from the PINTS IRPropMin class, which is an optimizer that - uses resilient backpropagation with weight-backtracking. It is designed to handle - problems with large plateaus, noisy gradients, and local minima. - - :param x0: Initial position from which optimization will start. - :type x0: array_like - :param sigma0: Initial step size (default is 0.1). - :type sigma0: float, optional - :param bounds: Lower and upper bounds for each optimization parameter. - :type bounds: dict, optional - - .. seealso:: - - :obj:`pints.IRPropMin` - The PINTS implementation this class is based on. - - -.. py:class:: NLoptOptimize(n_param, xtol=None, method=None, maxiter=None) - - - Bases: :py:obj:`pybop.optimisers.base_optimiser.BaseOptimiser` - - Extends BaseOptimiser to utilize the NLopt library for nonlinear optimization. - - This class serves as an interface to the NLopt optimization algorithms. It allows the user to - define an optimization problem with bounds, initial guesses, and to select an optimization method - provided by NLopt. - - :param n_param: Number of parameters to optimize. - :type n_param: int - :param xtol: The relative tolerance for optimization (stopping criteria). If not provided, a default of 1e-5 is used. - :type xtol: float, optional - :param method: The NLopt algorithm to use for optimization. If not provided, LN_BOBYQA is used by default. - :type method: nlopt.algorithm, optional - :param maxiter: The maximum number of iterations to perform during optimization. If not provided, NLopt's default is used. - :type maxiter: int, optional - - .. method:: _runoptimise(cost_function, x0, bounds) - - Performs the optimization using the NLopt library. - - .. method:: needs_sensitivities() - - Indicates whether the optimizer requires gradient information. - - .. method:: name() - - Returns the name of the optimizer. - - - .. py:method:: _runoptimise(cost_function, x0, bounds) - - Runs the optimization process using the NLopt library. - - :param cost_function: The objective function to minimize. It should take an array of parameter values and return the scalar cost. - :type cost_function: callable - :param x0: The initial guess for the parameters. - :type x0: array_like - :param bounds: A dictionary containing the 'lower' and 'upper' bounds arrays for the parameters. - :type bounds: dict - - :returns: A tuple containing the optimized parameter values and the final cost. - :rtype: tuple - - - .. py:method:: name() - - Returns the name of this optimizer instance. - - :returns: The name 'NLoptOptimize' representing this NLopt optimization class. - :rtype: str - - - .. py:method:: needs_sensitivities() - - Indicates if the optimizer requires gradient information for the cost function. - - :returns: False, as the default NLopt algorithms do not require gradient information. - :rtype: bool - - - -.. py:class:: Optimisation(cost, optimiser=None, sigma0=None, verbose=False) - - - Optimisation class for PyBOP. - This class provides functionality for PyBOP optimisers and Pints optimisers. - :param cost: PyBOP cost function - :param optimiser: A PyBOP or Pints optimiser - :param sigma0: initial step size - :param verbose: print optimisation progress - - .. py:method:: _run_pints() - - Run method for PINTS optimisers. - This method is heavily based on the run method in the PINTS.OptimisationController class. - :returns: best parameters - final_cost: final cost - :rtype: x - - - .. py:method:: _run_pybop() - - Run method for PyBOP based optimisers. - :returns: best parameters - final_cost: final cost - :rtype: x - - - .. py:method:: f_guessed_tracking() - - Returns ``True`` if f_guessed instead of f_best is being tracked, - ``False`` otherwise. See also :meth:`set_f_guessed_tracking`. - - Credit: PINTS - - - .. py:method:: run() - - Run the optimisation algorithm. - Selects between PyBOP backend or Pints backend. - :returns: best parameters - final_cost: final cost - :rtype: x - - - .. py:method:: set_f_guessed_tracking(use_f_guessed=False) - - Sets the method used to track the optimiser progress to - :meth:`pints.Optimiser.f_guessed()` or - :meth:`pints.Optimiser.f_best()` (default). - - The tracked ``f`` value is used to evaluate stopping criteria. - - Credit: PINTS - - - .. py:method:: set_max_evaluations(evaluations=None) - - Adds a stopping criterion, allowing the routine to halt after the - given number of ``evaluations``. - - This criterion is disabled by default. To enable, pass in any positive - integer. To disable again, use ``set_max_evaluations(None)``. - - Credit: PINTS - - - .. py:method:: set_max_iterations(iterations=1000) - - Adds a stopping criterion, allowing the routine to halt after the - given number of ``iterations``. - - This criterion is enabled by default. To disable it, use - ``set_max_iterations(None)``. - - Credit: PINTS - - - .. py:method:: set_max_unchanged_iterations(iterations=25, threshold=1e-05) - - Adds a stopping criterion, allowing the routine to halt if the - objective function doesn't change by more than ``threshold`` for the - given number of ``iterations``. - - This criterion is enabled by default. To disable it, use - ``set_max_unchanged_iterations(None)``. - - Credit: PINTS - - - .. py:method:: set_parallel(parallel=False) - - Enables/disables parallel evaluation. - - If ``parallel=True``, the method will run using a number of worker - processes equal to the detected cpu core count. The number of workers - can be set explicitly by setting ``parallel`` to an integer greater - than 0. - Parallelisation can be disabled by setting ``parallel`` to ``0`` or - ``False``. - - Credit: PINTS - - - .. py:method:: store_optimised_parameters(x) - - Store the optimised parameters in the PyBOP parameter class. - - - -.. py:class:: PSO(x0, sigma0=0.1, bounds=None) - - - Bases: :py:obj:`pints.PSO` - - Implements a particle swarm optimization (PSO) algorithm. - - This class extends the PSO optimizer from the PINTS library. PSO is a - metaheuristic optimization method inspired by the social behavior of birds - flocking or fish schooling, suitable for global optimization problems. - - :param x0: Initial positions of particles, which the optimization will use. - :type x0: array_like - :param sigma0: Spread of the initial particle positions (default is 0.1). - :type sigma0: float, optional - :param bounds: Lower and upper bounds for each optimization parameter. - :type bounds: dict, optional - - .. seealso:: - - :obj:`pints.PSO` - The PINTS implementation this class is based on. - - -.. py:class:: Parameter(name, initial_value=None, prior=None, bounds=None) - - - Represents a parameter within the PyBOP framework. - - This class encapsulates the definition of a parameter, including its name, prior - distribution, initial value, bounds, and a margin to ensure the parameter stays - within feasible limits during optimization or sampling. - - :param name: The name of the parameter. - :type name: str - :param initial_value: The initial value to be assigned to the parameter. Defaults to None. - :type initial_value: float, optional - :param prior: The prior distribution from which parameter values are drawn. Defaults to None. - :type prior: scipy.stats distribution, optional - :param bounds: A tuple defining the lower and upper bounds for the parameter. - Defaults to None. - :type bounds: tuple, optional - - .. method:: rvs(n_samples) - - Draw random samples from the parameter's prior distribution. - - .. method:: update(value) - - Update the parameter's current value. - - .. method:: set_margin(margin) - - Set the margin to a specified positive value less than 1. - - - :raises ValueError: If the lower bound is not strictly less than the upper bound, or if - the margin is set outside the interval (0, 1). - - .. py:method:: __repr__() - - Return a string representation of the Parameter instance. - - :returns: A string including the parameter's name, prior, bounds, and current value. - :rtype: str - - - .. py:method:: rvs(n_samples) - - Draw random samples from the parameter's prior distribution. - - The samples are constrained to be within the parameter's bounds, excluding - a predefined margin at the boundaries. - - :param n_samples: The number of samples to draw. - :type n_samples: int - - :returns: An array of samples drawn from the prior distribution within the parameter's bounds. - :rtype: array-like - - - .. py:method:: set_margin(margin) - - Set the margin to a specified positive value less than 1. - - The margin is used to ensure parameter samples are not drawn exactly at the bounds, - which may be problematic in some optimization or sampling algorithms. - - :param margin: The new margin value to be used, which must be in the interval (0, 1). - :type margin: float - - :raises ValueError: If the margin is not between 0 and 1. - - - .. py:method:: update(value) - - Update the parameter's current value. - - :param value: The new value to be assigned to the parameter. - :type value: float - - - -.. py:class:: ParameterSet(json_path=None, params_dict=None) - - - Handles the import and export of parameter sets for battery models. - - This class provides methods to load parameters from a JSON file and to export them - back to a JSON file. It also includes custom logic to handle special cases, such - as parameter values that require specific initialization. - - :param json_path: Path to a JSON file containing parameter data. If provided, parameters will be imported from this file during initialization. - :type json_path: str, optional - :param params_dict: A dictionary of parameters to initialize the ParameterSet with. If not provided, an empty dictionary is used. - :type params_dict: dict, optional - - .. py:method:: _handle_special_cases() - - Processes special cases for parameter values that require custom handling. - - For example, if the open-circuit voltage is specified as 'default', it will - fetch the default value from the PyBaMM empirical Thevenin model. - - - .. py:method:: export_parameters(output_json_path, fit_params=None) - - Exports parameters to a JSON file specified by `output_json_path`. - - The current state of the `params` attribute is written to the file. If `fit_params` - is provided, these parameters are updated before export. Non-serializable values - are handled and noted in the output JSON. - - :param output_json_path: The file path where the JSON output will be saved. - :type output_json_path: str - :param fit_params: Parameters that have been fitted and need to be included in the export. - :type fit_params: list of fitted parameter objects, optional - - :raises ValueError: If there are no parameters to export. - - - .. py:method:: import_parameters(json_path=None) - - Imports parameters from a JSON file specified by the `json_path` attribute. - - If a `json_path` is provided at initialization or as an argument, that JSON file - is loaded and the parameters are stored in the `params` attribute. Special cases - are handled appropriately. - - :param json_path: Path to the JSON file from which to import parameters. If provided, it overrides the instance's `json_path`. - :type json_path: str, optional - - :returns: The dictionary containing the imported parameters. - :rtype: dict - - :raises FileNotFoundError: If the specified JSON file cannot be found. - - - .. py:method:: is_json_serializable(value) - - Determines if the given `value` can be serialized to JSON format. - - :param value: The value to check for JSON serializability. - :type value: any - - :returns: True if the value is JSON serializable, False otherwise. - :rtype: bool - - - .. py:method:: pybamm(name) - :classmethod: - - Retrieves a PyBaMM parameter set by name. - - :param name: The name of the PyBaMM parameter set to retrieve. - :type name: str - - :returns: A PyBaMM parameter set corresponding to the provided name. - :rtype: pybamm.ParameterValues - - - -.. py:class:: PlotlyManager - - - Manages the installation and configuration of Plotly for generating visualisations. - - This class checks if Plotly is installed and, if not, prompts the user to install it. - It also ensures that the Plotly renderer and browser settings are properly configured - to display plots. - - Methods: - ``ensure_plotly_installed``: Verifies if Plotly is installed and installs it if necessary. - ``prompt_for_plotly_installation``: Prompts the user for permission to install Plotly. - ``install_plotly_package``: Installs the Plotly package using pip. - ``post_install_setup``: Sets up Plotly default renderer after installation. - ``check_renderer_settings``: Verifies that the Plotly renderer is correctly set. - ``check_browser_availability``: Checks if a web browser is available for rendering plots. - - Usage: - Instantiate the PlotlyManager class to automatically ensure Plotly is installed - and configured correctly when creating an instance. - Example: - plotly_manager = PlotlyManager() - - .. py:method:: check_browser_availability() - - Ensures a web browser is available for rendering plots with the 'browser' renderer and provides guidance if not. - - - .. py:method:: check_renderer_settings() - - Checks if the Plotly renderer is set and provides information on how to set it if empty. - - - .. py:method:: ensure_plotly_installed() - - Verifies if Plotly is installed, importing necessary modules and prompting for installation if missing. - - - .. py:method:: install_plotly() - - Attempts to install the Plotly package using pip and exits if installation fails. - - - .. py:method:: post_install_setup() - - After successful installation, imports Plotly and sets the default renderer if necessary. - - - .. py:method:: prompt_for_plotly_installation() - - Prompts the user for permission to install Plotly and proceeds with installation if consented. - - - -.. py:class:: RootMeanSquaredError(problem) - - - Bases: :py:obj:`BaseCost` - - Root mean square error cost function. - - Computes the root mean square error between model predictions and the target - data, providing a measure of the differences between predicted values and - observed values. - - Inherits all parameters and attributes from ``BaseCost``. - - - .. py:method:: __call__(x, grad=None) - - Calculate the root mean square error for a given set of parameters. - - :param x: The parameters for which to evaluate the cost. - :type x: array-like - :param grad: An array to store the gradient of the cost function with respect - to the parameters. - :type grad: array-like, optional - - :returns: The root mean square error. - :rtype: float - - :raises ValueError: If an error occurs during the calculation of the cost. - - - -.. py:class:: SNES(x0, sigma0=0.1, bounds=None) - - - Bases: :py:obj:`pints.SNES` - - Implements the stochastic natural evolution strategy (SNES) optimization algorithm. - - Inheriting from the PINTS SNES class, this optimizer is an evolutionary algorithm - that evolves a probability distribution on the parameter space, guiding the search - for the optimum based on the natural gradient of expected fitness. - - :param x0: Initial position from which optimization will start. - :type x0: array_like - :param sigma0: Initial step size (default is 0.1). - :type sigma0: float, optional - :param bounds: Lower and upper bounds for each optimization parameter. - :type bounds: dict, optional - - .. seealso:: - - :obj:`pints.SNES` - The PINTS implementation this class is based on. - - -.. py:class:: SciPyDifferentialEvolution(bounds=None, strategy='best1bin', maxiter=1000, popsize=15) - - - Bases: :py:obj:`pybop.optimisers.base_optimiser.BaseOptimiser` - - Adapts SciPy's differential_evolution function for global optimization. - - This class provides a global optimization strategy based on differential evolution, useful for problems involving continuous parameters and potentially multiple local minima. - - :param bounds: Bounds for variables. Must be provided as it is essential for differential evolution. - :type bounds: sequence or ``Bounds`` - :param strategy: The differential evolution strategy to use. Defaults to 'best1bin'. - :type strategy: str, optional - :param maxiter: Maximum number of iterations to perform. Defaults to 1000. - :type maxiter: int, optional - :param popsize: The number of individuals in the population. Defaults to 15. - :type popsize: int, optional - - .. py:method:: _runoptimise(cost_function, x0=None, bounds=None) - - Executes the optimization process using SciPy's differential_evolution function. - - :param cost_function: The objective function to minimize. - :type cost_function: callable - :param x0: Ignored parameter, provided for API consistency. - :type x0: array_like, optional - :param bounds: Bounds for the variables, required for differential evolution. - :type bounds: sequence or ``Bounds`` - - :returns: A tuple (x, final_cost) containing the optimized parameters and the value of ``cost_function`` at the optimum. - :rtype: tuple - - - .. py:method:: name() - - Provides the name of the optimization strategy. - - :returns: The name 'SciPyDifferentialEvolution'. - :rtype: str - - - .. py:method:: needs_sensitivities() - - Determines if the optimization algorithm requires gradient information. - - :returns: False, indicating that gradient information is not required for differential evolution. - :rtype: bool - - - -.. py:class:: SciPyMinimize(method=None, bounds=None, maxiter=None) - - - Bases: :py:obj:`pybop.optimisers.base_optimiser.BaseOptimiser` - - Adapts SciPy's minimize function for use as an optimization strategy. - - This class provides an interface to various scalar minimization algorithms implemented in SciPy, allowing fine-tuning of the optimization process through method selection and option configuration. - - :param method: The type of solver to use. If not specified, defaults to 'COBYLA'. - :type method: str, optional - :param bounds: Bounds for variables as supported by the selected method. - :type bounds: sequence or ``Bounds``, optional - :param maxiter: Maximum number of iterations to perform. - :type maxiter: int, optional - - .. py:method:: _runoptimise(cost_function, x0, bounds) - - Executes the optimization process using SciPy's minimize function. - - :param cost_function: The objective function to minimize. - :type cost_function: callable - :param x0: Initial guess for the parameters. - :type x0: array_like - :param bounds: Bounds for the variables. - :type bounds: sequence or `Bounds` - - :returns: A tuple (x, final_cost) containing the optimized parameters and the value of `cost_function` at the optimum. - :rtype: tuple - - - .. py:method:: name() - - Provides the name of the optimization strategy. - - :returns: The name 'SciPyMinimize'. - :rtype: str - - - .. py:method:: needs_sensitivities() - - Determines if the optimization algorithm requires gradient information. - - :returns: False, indicating that gradient information is not required. - :rtype: bool - - - -.. py:class:: StandardPlot(x, y, cost, y2=None, title=None, xaxis_title=None, yaxis_title=None, trace_name=None, width=1024, height=576) - - - A class for creating and displaying a plotly figure that compares a target dataset against a simulated model output. - - This class provides an interface for generating interactive plots using Plotly, with the ability to include an - optional secondary dataset and visualize uncertainty if provided. - - Attributes: - ----------- - x : list - The x-axis data points. - y : list or np.ndarray - The primary y-axis data points representing the simulated model output. - y2 : list or np.ndarray, optional - An optional secondary y-axis data points representing the target dataset against which the model output is compared. - cost : float - The cost associated with the model output. - title : str, optional - The title of the plot. - xaxis_title : str, optional - The title for the x-axis. - yaxis_title : str, optional - The title for the y-axis. - trace_name : str, optional - The name of the primary trace representing the model output. Defaults to "Simulated". - width : int, optional - The width of the figure in pixels. Defaults to 720. - height : int, optional - The height of the figure in pixels. Defaults to 540. - - Example: - ---------- - >>> x_data = [1, 2, 3, 4] - >>> y_simulated = [10, 15, 13, 17] - >>> y_target = [11, 14, 12, 16] - >>> plot = pybop.StandardPlot(x_data, y_simulated, cost=0.05, y2=y_target, - title="Model vs. Target", xaxis_title="X Axis", yaxis_title="Y Axis") - >>> fig = plot() # Generate the figure - >>> fig.show() # Display the figure in a browser - - .. py:method:: __call__() - - Generate the plotly figure. - - - .. py:method:: create_layout() - - Create the layout for the plot. - - - .. py:method:: create_traces() - - Create the traces for the plot. - - - .. py:method:: wrap_text(text, width) - :staticmethod: - - Wrap text to a specified width. - - Parameters: - ----------- - text: str - Text to be wrapped. - width: int - Width to wrap text to. - - Returns: - ---------- - str - Wrapped text with HTML line breaks. - - - -.. py:class:: SumSquaredError(problem) - - - Bases: :py:obj:`BaseCost` - - Sum of squared errors cost function. - - Computes the sum of the squares of the differences between model predictions - and target data, which serves as a measure of the total error between the - predicted and observed values. - - Inherits all parameters and attributes from ``BaseCost``. - - Additional Attributes - --------------------- - _de : float - The gradient of the cost function to use if an error occurs during - evaluation. Defaults to 1.0. - - - .. py:method:: __call__(x, grad=None) - - Calculate the sum of squared errors for a given set of parameters. - - :param x: The parameters for which to evaluate the cost. - :type x: array-like - :param grad: An array to store the gradient of the cost function with respect - to the parameters. - :type grad: array-like, optional - - :returns: The sum of squared errors. - :rtype: float - - :raises ValueError: If an error occurs during the calculation of the cost. - - - .. py:method:: evaluateS1(x) - - Compute the cost and its gradient with respect to the parameters. - - :param x: The parameters for which to compute the cost and gradient. - :type x: array-like - - :returns: A tuple containing the cost and the gradient. The cost is a float, - and the gradient is an array-like of the same length as `x`. - :rtype: tuple - - :raises ValueError: If an error occurs during the calculation of the cost or gradient. - - - .. py:method:: set_fail_gradient(de) - - Set the fail gradient to a specified value. - - The fail gradient is used if an error occurs during the calculation - of the gradient. This method allows updating the default gradient value. - - :param de: The new fail gradient value to be used. - :type de: float - - - -.. py:class:: Uniform(lower, upper) - - - Represents a uniform distribution over a specified interval. - - This class provides methods to calculate the pdf, the log pdf, and to generate - random variates from the distribution. - - :param lower: The lower bound of the distribution. - :type lower: float - :param upper: The upper bound of the distribution. - :type upper: float - - .. py:method:: __repr__() - - Returns a string representation of the Uniform object. - - - .. py:method:: logpdf(x) - - Calculates the logarithm of the pdf of the uniform distribution at x. - - :param x: The point at which to evaluate the log pdf. - :type x: float - - :returns: The log of the probability density function value at x. - :rtype: float - - - .. py:method:: pdf(x) - - Calculates the probability density function of the uniform distribution at x. - - :param x: The point at which to evaluate the pdf. - :type x: float - - :returns: The probability density function value at x. - :rtype: float - - - .. py:method:: rvs(size) - - Generates random variates from the uniform distribution. - - :param size: The number of random variates to generate. - :type size: int - - :returns: An array of random variates from the uniform distribution. - :rtype: array_like - - :raises ValueError: If the size parameter is not positive. - - - -.. py:class:: XNES(x0, sigma0=0.1, bounds=None) - - - Bases: :py:obj:`pints.XNES` - - Implements the Exponential Natural Evolution Strategy (XNES) optimizer from PINTS. - - XNES is an evolutionary algorithm that samples from a multivariate normal distribution, which is updated iteratively to fit the distribution of successful solutions. - - :param x0: The initial parameter vector to optimize. - :type x0: array_like - :param sigma0: Initial standard deviation of the sampling distribution, defaults to 0.1. - :type sigma0: float, optional - :param bounds: A dictionary with 'lower' and 'upper' keys containing arrays for lower and upper bounds on the parameters. If ``None``, no bounds are enforced. - :type bounds: dict, optional - - .. seealso:: - - :obj:`pints.XNES` - PINTS implementation of XNES algorithm. - - -.. py:function:: plot_convergence(optim, xaxis_title='Iteration', yaxis_title='Cost', title='Convergence') - - Plot the convergence of the optimisation algorithm. - - Parameters: - ---------- - optim : optimisation object - Optimisation object containing the cost function and optimiser. - xaxis_title : str, optional - Title for the x-axis (default is "Iteration"). - yaxis_title : str, optional - Title for the y-axis (default is "Cost"). - title : str, optional - Title of the plot (default is "Convergence"). - - Returns: - ---------- - fig : plotly.graph_objs.Figure - The Plotly figure object for the convergence plot. - - -.. py:function:: plot_cost2d(cost, bounds=None, optim=None, steps=10) - - Query the cost landscape for a given parameter space and plot it using Plotly. - - This function creates a 2D plot that visualizes the cost landscape over a grid - of points within specified parameter bounds. If no bounds are provided, it determines - them from the bounds on the parameter class. - - :param cost: A callable representing the cost function to be queried. It should - take a list of parameters and return a cost value. - :type cost: callable - :param bounds: The bounds for the parameter space as a 2x2 array, with each - sub-array representing the min and max bounds for a parameter. - If None, bounds will be determined by `get_param_bounds`. - :type bounds: numpy.ndarray, optional - :param optim: An optional optimizer instance. If provided, it will be used to - overlay optimizer-specific information on the plot. - :type optim: object, optional - :param steps: The number of steps to divide the parameter space grid. More steps - result in finer resolution but increase computational cost. - :type steps: int, optional - :return: A Plotly figure object representing the cost landscape plot. - :rtype: plotly.graph_objs.Figure - - :raises ValueError: If the cost function does not behave as expected. - - -.. py:function:: plot_parameters(optim, xaxis_titles='Iteration', yaxis_titles=None, title='Convergence') - - Plot the evolution of the parameters during the optimisation process. - - Parameters: - ------------ - optim : optimisation object - An object representing the optimisation process, which should contain - information about the cost function, optimiser, and the history of the - parameter values throughout the iterations. - xaxis_title : str, optional - Title for the x-axis, representing the iteration number or a similar - discrete time step in the optimisation process (default is "Iteration"). - yaxis_title : str, optional - Title for the y-axis, which typically represents the metric being - optimised, such as cost or loss (default is "Cost"). - title : str, optional - Title of the plot, which provides an overall description of what the - plot represents (default is "Convergence"). - - Returns: - ---------- - fig : plotly.graph_objs.Figure - The Plotly figure object for the plot depicting how the parameters of - the optimisation algorithm evolve over its course. This can be useful - for diagnosing the behaviour of the optimisation algorithm. - - Notes: - ---------- - The function assumes that the 'optim' object has a 'cost.problem.parameters' - attribute containing the parameters of the optimisation algorithm and a 'log' - attribute containing a history of the iterations. - - -.. py:function:: quick_plot(params, cost, title='Scatter Plot', width=1024, height=576) - - Plot the target dataset against the minimised model output. - - Parameters: - ----------- - params : array-like - Optimised parameters. - cost : cost object - Cost object containing the problem, dataset, and signal. - title : str, optional - Title of the plot (default is "Scatter Plot"). - width : int, optional - Width of the figure in pixels (default is 720). - height : int, optional - Height of the figure in pixels (default is 540). - - Returns: - ---------- - fig : plotly.graph_objs.Figure - The Plotly figure object for the scatter plot. - - -.. py:data:: FLOAT_FORMAT - :value: '{: .17e}' - - - -.. py:data:: __version__ - :value: '23.11' - - - -.. py:data:: script_path diff --git a/docs/api/pybop/models/base_model/index.rst b/docs/api/pybop/models/base_model/index.rst deleted file mode 100644 index ab17a5db..00000000 --- a/docs/api/pybop/models/base_model/index.rst +++ /dev/null @@ -1,178 +0,0 @@ -:py:mod:`pybop.models.base_model` -================================= - -.. py:module:: pybop.models.base_model - - -Module Contents ---------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - pybop.models.base_model.BaseModel - - - - -.. py:class:: BaseModel(name='Base Model') - - - A base class for constructing and simulating models using PyBaMM. - - This class serves as a foundation for building specific models in PyBaMM. - It provides methods to set up the model, define parameters, and perform - simulations. The class is designed to be subclassed for creating models - with custom behavior. - - .. method:: build(dataset=None, parameters=None, check_model=True, init_soc=None) - - Construct the PyBaMM model if not already built. - - .. method:: set_init_soc(init_soc) - - Set the initial state of charge for the battery model. - - .. method:: set_params() - - Assign the parameters to the model. - - .. method:: simulate(inputs, t_eval) - - Execute the forward model simulation and return the result. - - .. method:: simulateS1(inputs, t_eval) - - Perform the forward model simulation with sensitivities. - - .. method:: predict(inputs=None, t_eval=None, parameter_set=None, experiment=None, init_soc=None) - - Solve the model using PyBaMM's simulation framework and return the solution. - - - .. py:property:: built_model - - - .. py:property:: geometry - - - .. py:property:: mesh - - - .. py:property:: model_with_set_params - - - .. py:property:: parameter_set - - - .. py:property:: solver - - - .. py:property:: spatial_methods - - - .. py:property:: submesh_types - - - .. py:property:: var_pts - - - .. py:method:: build(dataset=None, parameters=None, check_model=True, init_soc=None) - - Construct the PyBaMM model if not already built, and set parameters. - - This method initializes the model components, applies the given parameters, - sets up the mesh and discretization if needed, and prepares the model - for simulations. - - :param dataset: The dataset to be used in the model construction. - :type dataset: pybamm.Dataset, optional - :param parameters: A dictionary containing parameter values to apply to the model. - :type parameters: dict, optional - :param check_model: If True, the model will be checked for correctness after construction. - :type check_model: bool, optional - :param init_soc: The initial state of charge to be used in simulations. - :type init_soc: float, optional - - - .. py:method:: predict(inputs=None, t_eval=None, parameter_set=None, experiment=None, init_soc=None) - - Solve the model using PyBaMM's simulation framework and return the solution. - - This method sets up a PyBaMM simulation by configuring the model, parameters, experiment - (if any), and initial state of charge (if provided). It then solves the simulation and - returns the resulting solution object. - - :param inputs: Input parameters for the simulation. If the input is array-like, it is converted - to a dictionary using the model's fitting keys. Defaults to None, indicating - that the default parameters should be used. - :type inputs: dict or array-like, optional - :param t_eval: An array of time points at which to evaluate the solution. Defaults to None, - which means the time points need to be specified within experiment or elsewhere. - :type t_eval: array-like, optional - :param parameter_set: A PyBaMM ParameterValues object or a dictionary containing the parameter values - to use for the simulation. Defaults to the model's current ParameterValues if None. - :type parameter_set: pybamm.ParameterValues, optional - :param experiment: A PyBaMM Experiment object specifying the experimental conditions under which - the simulation should be run. Defaults to None, indicating no experiment. - :type experiment: pybamm.Experiment, optional - :param init_soc: The initial state of charge for the simulation, as a fraction (between 0 and 1). - Defaults to None. - :type init_soc: float, optional - - :returns: The solution object returned after solving the simulation. - :rtype: pybamm.Solution - - :raises ValueError: If the model has not been configured properly before calling this method or - if PyBaMM models are not supported by the current simulation method. - - - .. py:method:: set_init_soc(init_soc) - - Set the initial state of charge for the battery model. - - :param init_soc: The initial state of charge to be used in the model. - :type init_soc: float - - - .. py:method:: set_params() - - Assign the parameters to the model. - - This method processes the model with the given parameters, sets up - the geometry, and updates the model instance. - - - .. py:method:: simulate(inputs, t_eval) - - Execute the forward model simulation and return the result. - - :param inputs: The input parameters for the simulation. If array-like, it will be - converted to a dictionary using the model's fit keys. - :type inputs: dict or array-like - :param t_eval: An array of time points at which to evaluate the solution. - :type t_eval: array-like - - :returns: The simulation result corresponding to the specified signal. - :rtype: array-like - - :raises ValueError: If the model has not been built before simulation. - - - .. py:method:: simulateS1(inputs, t_eval) - - Perform the forward model simulation with sensitivities. - - :param inputs: The input parameters for the simulation. If array-like, it will be - converted to a dictionary using the model's fit keys. - :type inputs: dict or array-like - :param t_eval: An array of time points at which to evaluate the solution and its - sensitivities. - :type t_eval: array-like - - :returns: A tuple containing the simulation result and the sensitivities. - :rtype: tuple - - :raises ValueError: If the model has not been built before simulation. diff --git a/docs/api/pybop/models/empirical/ecm/index.rst b/docs/api/pybop/models/empirical/ecm/index.rst deleted file mode 100644 index e861789d..00000000 --- a/docs/api/pybop/models/empirical/ecm/index.rst +++ /dev/null @@ -1,47 +0,0 @@ -:py:mod:`pybop.models.empirical.ecm` -==================================== - -.. py:module:: pybop.models.empirical.ecm - - -Module Contents ---------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - pybop.models.empirical.ecm.Thevenin - - - - -.. py:class:: Thevenin(name='Equivalent Circuit Thevenin Model', parameter_set=None, geometry=None, submesh_types=None, var_pts=None, spatial_methods=None, solver=None, options=None, **kwargs) - - - Bases: :py:obj:`pybop.models.base_model.BaseModel` - - The Thevenin class represents an equivalent circuit model based on the Thevenin model in PyBaMM. - - This class encapsulates the PyBaMM equivalent circuit Thevenin model, providing an interface - to define the parameters, geometry, submesh types, variable points, spatial methods, and solver - to be used for simulations. - - :param name: A name for the model instance. Defaults to "Equivalent Circuit Thevenin Model". - :type name: str, optional - :param parameter_set: A dictionary of parameters to be used for the model. If None, the default parameters from PyBaMM are used. - :type parameter_set: dict or None, optional - :param geometry: The geometry definitions for the model. If None, the default geometry from PyBaMM is used. - :type geometry: dict or None, optional - :param submesh_types: The types of submeshes to use. If None, the default submesh types from PyBaMM are used. - :type submesh_types: dict or None, optional - :param var_pts: The number of points for each variable in the model to define the discretization. If None, the default is used. - :type var_pts: dict or None, optional - :param spatial_methods: The spatial methods to be used for discretization. If None, the default spatial methods from PyBaMM are used. - :type spatial_methods: dict or None, optional - :param solver: The solver to use for simulating the model. If None, the default solver from PyBaMM is used. - :type solver: pybamm.Solver or None, optional - :param options: A dictionary of options to pass to the PyBaMM Thevenin model. - :type options: dict or None, optional - :param \*\*kwargs: Additional arguments passed to the PyBaMM Thevenin model constructor. diff --git a/docs/api/pybop/models/empirical/index.rst b/docs/api/pybop/models/empirical/index.rst deleted file mode 100644 index 0adb3d9e..00000000 --- a/docs/api/pybop/models/empirical/index.rst +++ /dev/null @@ -1,56 +0,0 @@ -:py:mod:`pybop.models.empirical` -================================ - -.. py:module:: pybop.models.empirical - - -Submodules ----------- -.. toctree:: - :titlesonly: - :maxdepth: 1 - - ecm/index.rst - - -Package Contents ----------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - pybop.models.empirical.Thevenin - - - - -.. py:class:: Thevenin(name='Equivalent Circuit Thevenin Model', parameter_set=None, geometry=None, submesh_types=None, var_pts=None, spatial_methods=None, solver=None, options=None, **kwargs) - - - Bases: :py:obj:`pybop.models.base_model.BaseModel` - - The Thevenin class represents an equivalent circuit model based on the Thevenin model in PyBaMM. - - This class encapsulates the PyBaMM equivalent circuit Thevenin model, providing an interface - to define the parameters, geometry, submesh types, variable points, spatial methods, and solver - to be used for simulations. - - :param name: A name for the model instance. Defaults to "Equivalent Circuit Thevenin Model". - :type name: str, optional - :param parameter_set: A dictionary of parameters to be used for the model. If None, the default parameters from PyBaMM are used. - :type parameter_set: dict or None, optional - :param geometry: The geometry definitions for the model. If None, the default geometry from PyBaMM is used. - :type geometry: dict or None, optional - :param submesh_types: The types of submeshes to use. If None, the default submesh types from PyBaMM are used. - :type submesh_types: dict or None, optional - :param var_pts: The number of points for each variable in the model to define the discretization. If None, the default is used. - :type var_pts: dict or None, optional - :param spatial_methods: The spatial methods to be used for discretization. If None, the default spatial methods from PyBaMM are used. - :type spatial_methods: dict or None, optional - :param solver: The solver to use for simulating the model. If None, the default solver from PyBaMM is used. - :type solver: pybamm.Solver or None, optional - :param options: A dictionary of options to pass to the PyBaMM Thevenin model. - :type options: dict or None, optional - :param \*\*kwargs: Additional arguments passed to the PyBaMM Thevenin model constructor. diff --git a/docs/api/pybop/models/index.rst b/docs/api/pybop/models/index.rst deleted file mode 100644 index 20988ab8..00000000 --- a/docs/api/pybop/models/index.rst +++ /dev/null @@ -1,23 +0,0 @@ -:py:mod:`pybop.models` -====================== - -.. py:module:: pybop.models - - -Subpackages ------------ -.. toctree:: - :titlesonly: - :maxdepth: 3 - - empirical/index.rst - lithium_ion/index.rst - - -Submodules ----------- -.. toctree:: - :titlesonly: - :maxdepth: 1 - - base_model/index.rst diff --git a/docs/api/pybop/models/lithium_ion/echem/index.rst b/docs/api/pybop/models/lithium_ion/echem/index.rst deleted file mode 100644 index 4c115a68..00000000 --- a/docs/api/pybop/models/lithium_ion/echem/index.rst +++ /dev/null @@ -1,76 +0,0 @@ -:py:mod:`pybop.models.lithium_ion.echem` -======================================== - -.. py:module:: pybop.models.lithium_ion.echem - - -Module Contents ---------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - pybop.models.lithium_ion.echem.SPM - pybop.models.lithium_ion.echem.SPMe - - - - -.. py:class:: SPM(name='Single Particle Model', parameter_set=None, geometry=None, submesh_types=None, var_pts=None, spatial_methods=None, solver=None, options=None) - - - Bases: :py:obj:`pybop.models.base_model.BaseModel` - - Wraps the Single Particle Model (SPM) for simulating lithium-ion batteries, as implemented in PyBaMM. - - The SPM is a simplified physics-based model that represents a lithium-ion cell using a single - spherical particle to simulate the behavior of the negative and positive electrodes. - - :param name: The name for the model instance, defaulting to "Single Particle Model". - :type name: str, optional - :param parameter_set: The parameters for the model. If None, default parameters provided by PyBaMM are used. - :type parameter_set: pybamm.ParameterValues or dict, optional - :param geometry: The geometry definitions for the model. If None, default geometry from PyBaMM is used. - :type geometry: dict, optional - :param submesh_types: The types of submeshes to use. If None, default submesh types from PyBaMM are used. - :type submesh_types: dict, optional - :param var_pts: The discretization points for each variable in the model. If None, default points from PyBaMM are used. - :type var_pts: dict, optional - :param spatial_methods: The spatial methods used for discretization. If None, default spatial methods from PyBaMM are used. - :type spatial_methods: dict, optional - :param solver: The solver to use for simulating the model. If None, the default solver from PyBaMM is used. - :type solver: pybamm.Solver, optional - :param options: A dictionary of options to customize the behavior of the PyBaMM model. - :type options: dict, optional - - -.. py:class:: SPMe(name='Single Particle Model with Electrolyte', parameter_set=None, geometry=None, submesh_types=None, var_pts=None, spatial_methods=None, solver=None, options=None) - - - Bases: :py:obj:`pybop.models.base_model.BaseModel` - - Represents the Single Particle Model with Electrolyte (SPMe) for lithium-ion batteries. - - The SPMe extends the basic Single Particle Model (SPM) by incorporating electrolyte dynamics, - making it suitable for simulations where electrolyte effects are non-negligible. This class - provides a framework to define the model parameters, geometry, mesh types, discretization - points, spatial methods, and numerical solvers for simulation within the PyBaMM ecosystem. - - :param name: A name for the model instance, defaults to "Single Particle Model with Electrolyte". - :type name: str, optional - :param parameter_set: A dictionary or a ParameterValues object containing the parameters for the model. If None, the default PyBaMM parameters for SPMe are used. - :type parameter_set: pybamm.ParameterValues or dict, optional - :param geometry: A dictionary defining the model's geometry. If None, the default PyBaMM geometry for SPMe is used. - :type geometry: dict, optional - :param submesh_types: A dictionary defining the types of submeshes to use. If None, the default PyBaMM submesh types for SPMe are used. - :type submesh_types: dict, optional - :param var_pts: A dictionary specifying the number of points for each variable for discretization. If None, the default PyBaMM variable points for SPMe are used. - :type var_pts: dict, optional - :param spatial_methods: A dictionary specifying the spatial methods for discretization. If None, the default PyBaMM spatial methods for SPMe are used. - :type spatial_methods: dict, optional - :param solver: The solver to use for simulating the model. If None, the default PyBaMM solver for SPMe is used. - :type solver: pybamm.Solver, optional - :param options: A dictionary of options to customize the behavior of the PyBaMM model. - :type options: dict, optional diff --git a/docs/api/pybop/models/lithium_ion/index.rst b/docs/api/pybop/models/lithium_ion/index.rst deleted file mode 100644 index 4200a205..00000000 --- a/docs/api/pybop/models/lithium_ion/index.rst +++ /dev/null @@ -1,85 +0,0 @@ -:py:mod:`pybop.models.lithium_ion` -================================== - -.. py:module:: pybop.models.lithium_ion - - -Submodules ----------- -.. toctree:: - :titlesonly: - :maxdepth: 1 - - echem/index.rst - - -Package Contents ----------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - pybop.models.lithium_ion.SPM - pybop.models.lithium_ion.SPMe - - - - -.. py:class:: SPM(name='Single Particle Model', parameter_set=None, geometry=None, submesh_types=None, var_pts=None, spatial_methods=None, solver=None, options=None) - - - Bases: :py:obj:`pybop.models.base_model.BaseModel` - - Wraps the Single Particle Model (SPM) for simulating lithium-ion batteries, as implemented in PyBaMM. - - The SPM is a simplified physics-based model that represents a lithium-ion cell using a single - spherical particle to simulate the behavior of the negative and positive electrodes. - - :param name: The name for the model instance, defaulting to "Single Particle Model". - :type name: str, optional - :param parameter_set: The parameters for the model. If None, default parameters provided by PyBaMM are used. - :type parameter_set: pybamm.ParameterValues or dict, optional - :param geometry: The geometry definitions for the model. If None, default geometry from PyBaMM is used. - :type geometry: dict, optional - :param submesh_types: The types of submeshes to use. If None, default submesh types from PyBaMM are used. - :type submesh_types: dict, optional - :param var_pts: The discretization points for each variable in the model. If None, default points from PyBaMM are used. - :type var_pts: dict, optional - :param spatial_methods: The spatial methods used for discretization. If None, default spatial methods from PyBaMM are used. - :type spatial_methods: dict, optional - :param solver: The solver to use for simulating the model. If None, the default solver from PyBaMM is used. - :type solver: pybamm.Solver, optional - :param options: A dictionary of options to customize the behavior of the PyBaMM model. - :type options: dict, optional - - -.. py:class:: SPMe(name='Single Particle Model with Electrolyte', parameter_set=None, geometry=None, submesh_types=None, var_pts=None, spatial_methods=None, solver=None, options=None) - - - Bases: :py:obj:`pybop.models.base_model.BaseModel` - - Represents the Single Particle Model with Electrolyte (SPMe) for lithium-ion batteries. - - The SPMe extends the basic Single Particle Model (SPM) by incorporating electrolyte dynamics, - making it suitable for simulations where electrolyte effects are non-negligible. This class - provides a framework to define the model parameters, geometry, mesh types, discretization - points, spatial methods, and numerical solvers for simulation within the PyBaMM ecosystem. - - :param name: A name for the model instance, defaults to "Single Particle Model with Electrolyte". - :type name: str, optional - :param parameter_set: A dictionary or a ParameterValues object containing the parameters for the model. If None, the default PyBaMM parameters for SPMe are used. - :type parameter_set: pybamm.ParameterValues or dict, optional - :param geometry: A dictionary defining the model's geometry. If None, the default PyBaMM geometry for SPMe is used. - :type geometry: dict, optional - :param submesh_types: A dictionary defining the types of submeshes to use. If None, the default PyBaMM submesh types for SPMe are used. - :type submesh_types: dict, optional - :param var_pts: A dictionary specifying the number of points for each variable for discretization. If None, the default PyBaMM variable points for SPMe are used. - :type var_pts: dict, optional - :param spatial_methods: A dictionary specifying the spatial methods for discretization. If None, the default PyBaMM spatial methods for SPMe are used. - :type spatial_methods: dict, optional - :param solver: The solver to use for simulating the model. If None, the default PyBaMM solver for SPMe is used. - :type solver: pybamm.Solver, optional - :param options: A dictionary of options to customize the behavior of the PyBaMM model. - :type options: dict, optional diff --git a/docs/api/pybop/optimisation/index.rst b/docs/api/pybop/optimisation/index.rst deleted file mode 100644 index 619f9eee..00000000 --- a/docs/api/pybop/optimisation/index.rst +++ /dev/null @@ -1,125 +0,0 @@ -:py:mod:`pybop.optimisation` -============================ - -.. py:module:: pybop.optimisation - - -Module Contents ---------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - pybop.optimisation.Optimisation - - - - -.. py:class:: Optimisation(cost, optimiser=None, sigma0=None, verbose=False) - - - Optimisation class for PyBOP. - This class provides functionality for PyBOP optimisers and Pints optimisers. - :param cost: PyBOP cost function - :param optimiser: A PyBOP or Pints optimiser - :param sigma0: initial step size - :param verbose: print optimisation progress - - .. py:method:: _run_pints() - - Run method for PINTS optimisers. - This method is heavily based on the run method in the PINTS.OptimisationController class. - :returns: best parameters - final_cost: final cost - :rtype: x - - - .. py:method:: _run_pybop() - - Run method for PyBOP based optimisers. - :returns: best parameters - final_cost: final cost - :rtype: x - - - .. py:method:: f_guessed_tracking() - - Returns ``True`` if f_guessed instead of f_best is being tracked, - ``False`` otherwise. See also :meth:`set_f_guessed_tracking`. - - Credit: PINTS - - - .. py:method:: run() - - Run the optimisation algorithm. - Selects between PyBOP backend or Pints backend. - :returns: best parameters - final_cost: final cost - :rtype: x - - - .. py:method:: set_f_guessed_tracking(use_f_guessed=False) - - Sets the method used to track the optimiser progress to - :meth:`pints.Optimiser.f_guessed()` or - :meth:`pints.Optimiser.f_best()` (default). - - The tracked ``f`` value is used to evaluate stopping criteria. - - Credit: PINTS - - - .. py:method:: set_max_evaluations(evaluations=None) - - Adds a stopping criterion, allowing the routine to halt after the - given number of ``evaluations``. - - This criterion is disabled by default. To enable, pass in any positive - integer. To disable again, use ``set_max_evaluations(None)``. - - Credit: PINTS - - - .. py:method:: set_max_iterations(iterations=1000) - - Adds a stopping criterion, allowing the routine to halt after the - given number of ``iterations``. - - This criterion is enabled by default. To disable it, use - ``set_max_iterations(None)``. - - Credit: PINTS - - - .. py:method:: set_max_unchanged_iterations(iterations=25, threshold=1e-05) - - Adds a stopping criterion, allowing the routine to halt if the - objective function doesn't change by more than ``threshold`` for the - given number of ``iterations``. - - This criterion is enabled by default. To disable it, use - ``set_max_unchanged_iterations(None)``. - - Credit: PINTS - - - .. py:method:: set_parallel(parallel=False) - - Enables/disables parallel evaluation. - - If ``parallel=True``, the method will run using a number of worker - processes equal to the detected cpu core count. The number of workers - can be set explicitly by setting ``parallel`` to an integer greater - than 0. - Parallelisation can be disabled by setting ``parallel`` to ``0`` or - ``False``. - - Credit: PINTS - - - .. py:method:: store_optimised_parameters(x) - - Store the optimised parameters in the PyBOP parameter class. diff --git a/docs/api/pybop/optimisers/base_optimiser/index.rst b/docs/api/pybop/optimisers/base_optimiser/index.rst deleted file mode 100644 index 4f34d0c2..00000000 --- a/docs/api/pybop/optimisers/base_optimiser/index.rst +++ /dev/null @@ -1,83 +0,0 @@ -:py:mod:`pybop.optimisers.base_optimiser` -========================================= - -.. py:module:: pybop.optimisers.base_optimiser - - -Module Contents ---------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - pybop.optimisers.base_optimiser.BaseOptimiser - - - - -.. py:class:: BaseOptimiser - - - A base class for defining optimisation methods. - - This class serves as a template for creating optimisers. It provides a basic structure for - an optimisation algorithm, including the initial setup and a method stub for performing - the optimisation process. Child classes should override the optimise and _runoptimise - methods with specific algorithms. - - .. method:: optimise(cost_function, x0=None, bounds=None, maxiter=None) - - Initiates the optimisation process. This is a stub and should be implemented in child classes. - - .. method:: _runoptimise(cost_function, x0=None, bounds=None) - - Contains the logic for the optimisation algorithm. This is a stub and should be implemented in child classes. - - .. method:: name() - - Returns the name of the optimiser. - - - .. py:method:: _runoptimise(cost_function, x0=None, bounds=None) - - Contains the logic for the optimisation algorithm. - - This method should be implemented by child classes to perform the actual optimisation. - - :param cost_function: The cost function to be minimised by the optimiser. - :type cost_function: callable - :param x0: Initial guess for the parameters. Default is None. - :type x0: ndarray, optional - :param bounds: Bounds on the parameters. Default is None. - :type bounds: sequence or Bounds, optional - - :returns: * *This method is expected to return the result of the optimisation, the format of which* - * *will be determined by the child class implementation.* - - - .. py:method:: name() - - Returns the name of the optimiser. - - :returns: The name of the optimiser, which is "BaseOptimiser" for this base class. - :rtype: str - - - .. py:method:: optimise(cost_function, x0=None, bounds=None, maxiter=None) - - Initiates the optimisation process. - - This method should be overridden by child classes with the specific optimisation algorithm. - - :param cost_function: The cost function to be minimised by the optimiser. - :type cost_function: callable - :param x0: Initial guess for the parameters. Default is None. - :type x0: ndarray, optional - :param bounds: Bounds on the parameters. Default is None. - :type bounds: sequence or Bounds, optional - :param maxiter: Maximum number of iterations to perform. Default is None. - :type maxiter: int, optional - - :rtype: The result of the optimisation process. The specific type of this result will depend on the child implementation. diff --git a/docs/api/pybop/optimisers/index.rst b/docs/api/pybop/optimisers/index.rst deleted file mode 100644 index 8bffb2f0..00000000 --- a/docs/api/pybop/optimisers/index.rst +++ /dev/null @@ -1,16 +0,0 @@ -:py:mod:`pybop.optimisers` -========================== - -.. py:module:: pybop.optimisers - - -Submodules ----------- -.. toctree:: - :titlesonly: - :maxdepth: 1 - - base_optimiser/index.rst - nlopt_optimize/index.rst - pints_optimisers/index.rst - scipy_optimisers/index.rst diff --git a/docs/api/pybop/optimisers/nlopt_optimize/index.rst b/docs/api/pybop/optimisers/nlopt_optimize/index.rst deleted file mode 100644 index 29273b74..00000000 --- a/docs/api/pybop/optimisers/nlopt_optimize/index.rst +++ /dev/null @@ -1,81 +0,0 @@ -:py:mod:`pybop.optimisers.nlopt_optimize` -========================================= - -.. py:module:: pybop.optimisers.nlopt_optimize - - -Module Contents ---------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - pybop.optimisers.nlopt_optimize.NLoptOptimize - - - - -.. py:class:: NLoptOptimize(n_param, xtol=None, method=None, maxiter=None) - - - Bases: :py:obj:`pybop.optimisers.base_optimiser.BaseOptimiser` - - Extends BaseOptimiser to utilize the NLopt library for nonlinear optimization. - - This class serves as an interface to the NLopt optimization algorithms. It allows the user to - define an optimization problem with bounds, initial guesses, and to select an optimization method - provided by NLopt. - - :param n_param: Number of parameters to optimize. - :type n_param: int - :param xtol: The relative tolerance for optimization (stopping criteria). If not provided, a default of 1e-5 is used. - :type xtol: float, optional - :param method: The NLopt algorithm to use for optimization. If not provided, LN_BOBYQA is used by default. - :type method: nlopt.algorithm, optional - :param maxiter: The maximum number of iterations to perform during optimization. If not provided, NLopt's default is used. - :type maxiter: int, optional - - .. method:: _runoptimise(cost_function, x0, bounds) - - Performs the optimization using the NLopt library. - - .. method:: needs_sensitivities() - - Indicates whether the optimizer requires gradient information. - - .. method:: name() - - Returns the name of the optimizer. - - - .. py:method:: _runoptimise(cost_function, x0, bounds) - - Runs the optimization process using the NLopt library. - - :param cost_function: The objective function to minimize. It should take an array of parameter values and return the scalar cost. - :type cost_function: callable - :param x0: The initial guess for the parameters. - :type x0: array_like - :param bounds: A dictionary containing the 'lower' and 'upper' bounds arrays for the parameters. - :type bounds: dict - - :returns: A tuple containing the optimized parameter values and the final cost. - :rtype: tuple - - - .. py:method:: name() - - Returns the name of this optimizer instance. - - :returns: The name 'NLoptOptimize' representing this NLopt optimization class. - :rtype: str - - - .. py:method:: needs_sensitivities() - - Indicates if the optimizer requires gradient information for the cost function. - - :returns: False, as the default NLopt algorithms do not require gradient information. - :rtype: bool diff --git a/docs/api/pybop/optimisers/pints_optimisers/index.rst b/docs/api/pybop/optimisers/pints_optimisers/index.rst deleted file mode 100644 index 3b3ce69c..00000000 --- a/docs/api/pybop/optimisers/pints_optimisers/index.rst +++ /dev/null @@ -1,189 +0,0 @@ -:py:mod:`pybop.optimisers.pints_optimisers` -=========================================== - -.. py:module:: pybop.optimisers.pints_optimisers - - -Module Contents ---------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - pybop.optimisers.pints_optimisers.Adam - pybop.optimisers.pints_optimisers.CMAES - pybop.optimisers.pints_optimisers.GradientDescent - pybop.optimisers.pints_optimisers.IRPropMin - pybop.optimisers.pints_optimisers.PSO - pybop.optimisers.pints_optimisers.SNES - pybop.optimisers.pints_optimisers.XNES - - - - -.. py:class:: Adam(x0, sigma0=0.1, bounds=None) - - - Bases: :py:obj:`pints.Adam` - - Implements the Adam optimization algorithm. - - This class extends the Adam optimizer from the PINTS library, which combines - ideas from RMSProp and Stochastic Gradient Descent with momentum. Note that - this optimizer does not support boundary constraints. - - :param x0: Initial position from which optimization will start. - :type x0: array_like - :param sigma0: Initial step size (default is 0.1). - :type sigma0: float, optional - :param bounds: Ignored by this optimizer, provided for API consistency. - :type bounds: sequence or ``Bounds``, optional - - .. seealso:: - - :obj:`pints.Adam` - The PINTS implementation this class is based on. - - -.. py:class:: CMAES(x0, sigma0=0.1, bounds=None) - - - Bases: :py:obj:`pints.CMAES` - - Adapter for the Covariance Matrix Adaptation Evolution Strategy (CMA-ES) optimizer in PINTS. - - CMA-ES is an evolutionary algorithm for difficult non-linear non-convex optimization problems. - It adapts the covariance matrix of a multivariate normal distribution to capture the shape of the cost landscape. - - :param x0: The initial parameter vector to optimize. - :type x0: array_like - :param sigma0: Initial standard deviation of the sampling distribution, defaults to 0.1. - :type sigma0: float, optional - :param bounds: A dictionary with 'lower' and 'upper' keys containing arrays for lower and upper bounds on the parameters. - If ``None``, no bounds are enforced. - :type bounds: dict, optional - - .. seealso:: - - :obj:`pints.CMAES` - PINTS implementation of CMA-ES algorithm. - - -.. py:class:: GradientDescent(x0, sigma0=0.1, bounds=None) - - - Bases: :py:obj:`pints.GradientDescent` - - Implements a simple gradient descent optimization algorithm. - - This class extends the gradient descent optimizer from the PINTS library, designed - to minimize a scalar function of one or more variables. Note that this optimizer - does not support boundary constraints. - - :param x0: Initial position from which optimization will start. - :type x0: array_like - :param sigma0: Initial step size (default is 0.1). - :type sigma0: float, optional - :param bounds: Ignored by this optimizer, provided for API consistency. - :type bounds: sequence or ``Bounds``, optional - - .. seealso:: - - :obj:`pints.GradientDescent` - The PINTS implementation this class is based on. - - -.. py:class:: IRPropMin(x0, sigma0=0.1, bounds=None) - - - Bases: :py:obj:`pints.IRPropMin` - - Implements the iRpropMin optimization algorithm. - - This class inherits from the PINTS IRPropMin class, which is an optimizer that - uses resilient backpropagation with weight-backtracking. It is designed to handle - problems with large plateaus, noisy gradients, and local minima. - - :param x0: Initial position from which optimization will start. - :type x0: array_like - :param sigma0: Initial step size (default is 0.1). - :type sigma0: float, optional - :param bounds: Lower and upper bounds for each optimization parameter. - :type bounds: dict, optional - - .. seealso:: - - :obj:`pints.IRPropMin` - The PINTS implementation this class is based on. - - -.. py:class:: PSO(x0, sigma0=0.1, bounds=None) - - - Bases: :py:obj:`pints.PSO` - - Implements a particle swarm optimization (PSO) algorithm. - - This class extends the PSO optimizer from the PINTS library. PSO is a - metaheuristic optimization method inspired by the social behavior of birds - flocking or fish schooling, suitable for global optimization problems. - - :param x0: Initial positions of particles, which the optimization will use. - :type x0: array_like - :param sigma0: Spread of the initial particle positions (default is 0.1). - :type sigma0: float, optional - :param bounds: Lower and upper bounds for each optimization parameter. - :type bounds: dict, optional - - .. seealso:: - - :obj:`pints.PSO` - The PINTS implementation this class is based on. - - -.. py:class:: SNES(x0, sigma0=0.1, bounds=None) - - - Bases: :py:obj:`pints.SNES` - - Implements the stochastic natural evolution strategy (SNES) optimization algorithm. - - Inheriting from the PINTS SNES class, this optimizer is an evolutionary algorithm - that evolves a probability distribution on the parameter space, guiding the search - for the optimum based on the natural gradient of expected fitness. - - :param x0: Initial position from which optimization will start. - :type x0: array_like - :param sigma0: Initial step size (default is 0.1). - :type sigma0: float, optional - :param bounds: Lower and upper bounds for each optimization parameter. - :type bounds: dict, optional - - .. seealso:: - - :obj:`pints.SNES` - The PINTS implementation this class is based on. - - -.. py:class:: XNES(x0, sigma0=0.1, bounds=None) - - - Bases: :py:obj:`pints.XNES` - - Implements the Exponential Natural Evolution Strategy (XNES) optimizer from PINTS. - - XNES is an evolutionary algorithm that samples from a multivariate normal distribution, which is updated iteratively to fit the distribution of successful solutions. - - :param x0: The initial parameter vector to optimize. - :type x0: array_like - :param sigma0: Initial standard deviation of the sampling distribution, defaults to 0.1. - :type sigma0: float, optional - :param bounds: A dictionary with 'lower' and 'upper' keys containing arrays for lower and upper bounds on the parameters. If ``None``, no bounds are enforced. - :type bounds: dict, optional - - .. seealso:: - - :obj:`pints.XNES` - PINTS implementation of XNES algorithm. diff --git a/docs/api/pybop/optimisers/scipy_optimisers/index.rst b/docs/api/pybop/optimisers/scipy_optimisers/index.rst deleted file mode 100644 index 5080cb51..00000000 --- a/docs/api/pybop/optimisers/scipy_optimisers/index.rst +++ /dev/null @@ -1,115 +0,0 @@ -:py:mod:`pybop.optimisers.scipy_optimisers` -=========================================== - -.. py:module:: pybop.optimisers.scipy_optimisers - - -Module Contents ---------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - pybop.optimisers.scipy_optimisers.SciPyDifferentialEvolution - pybop.optimisers.scipy_optimisers.SciPyMinimize - - - - -.. py:class:: SciPyDifferentialEvolution(bounds=None, strategy='best1bin', maxiter=1000, popsize=15) - - - Bases: :py:obj:`pybop.optimisers.base_optimiser.BaseOptimiser` - - Adapts SciPy's differential_evolution function for global optimization. - - This class provides a global optimization strategy based on differential evolution, useful for problems involving continuous parameters and potentially multiple local minima. - - :param bounds: Bounds for variables. Must be provided as it is essential for differential evolution. - :type bounds: sequence or ``Bounds`` - :param strategy: The differential evolution strategy to use. Defaults to 'best1bin'. - :type strategy: str, optional - :param maxiter: Maximum number of iterations to perform. Defaults to 1000. - :type maxiter: int, optional - :param popsize: The number of individuals in the population. Defaults to 15. - :type popsize: int, optional - - .. py:method:: _runoptimise(cost_function, x0=None, bounds=None) - - Executes the optimization process using SciPy's differential_evolution function. - - :param cost_function: The objective function to minimize. - :type cost_function: callable - :param x0: Ignored parameter, provided for API consistency. - :type x0: array_like, optional - :param bounds: Bounds for the variables, required for differential evolution. - :type bounds: sequence or ``Bounds`` - - :returns: A tuple (x, final_cost) containing the optimized parameters and the value of ``cost_function`` at the optimum. - :rtype: tuple - - - .. py:method:: name() - - Provides the name of the optimization strategy. - - :returns: The name 'SciPyDifferentialEvolution'. - :rtype: str - - - .. py:method:: needs_sensitivities() - - Determines if the optimization algorithm requires gradient information. - - :returns: False, indicating that gradient information is not required for differential evolution. - :rtype: bool - - - -.. py:class:: SciPyMinimize(method=None, bounds=None, maxiter=None) - - - Bases: :py:obj:`pybop.optimisers.base_optimiser.BaseOptimiser` - - Adapts SciPy's minimize function for use as an optimization strategy. - - This class provides an interface to various scalar minimization algorithms implemented in SciPy, allowing fine-tuning of the optimization process through method selection and option configuration. - - :param method: The type of solver to use. If not specified, defaults to 'COBYLA'. - :type method: str, optional - :param bounds: Bounds for variables as supported by the selected method. - :type bounds: sequence or ``Bounds``, optional - :param maxiter: Maximum number of iterations to perform. - :type maxiter: int, optional - - .. py:method:: _runoptimise(cost_function, x0, bounds) - - Executes the optimization process using SciPy's minimize function. - - :param cost_function: The objective function to minimize. - :type cost_function: callable - :param x0: Initial guess for the parameters. - :type x0: array_like - :param bounds: Bounds for the variables. - :type bounds: sequence or `Bounds` - - :returns: A tuple (x, final_cost) containing the optimized parameters and the value of `cost_function` at the optimum. - :rtype: tuple - - - .. py:method:: name() - - Provides the name of the optimization strategy. - - :returns: The name 'SciPyMinimize'. - :rtype: str - - - .. py:method:: needs_sensitivities() - - Determines if the optimization algorithm requires gradient information. - - :returns: False, indicating that gradient information is not required. - :rtype: bool diff --git a/docs/api/pybop/parameters/index.rst b/docs/api/pybop/parameters/index.rst deleted file mode 100644 index 9e385c56..00000000 --- a/docs/api/pybop/parameters/index.rst +++ /dev/null @@ -1,15 +0,0 @@ -:py:mod:`pybop.parameters` -========================== - -.. py:module:: pybop.parameters - - -Submodules ----------- -.. toctree:: - :titlesonly: - :maxdepth: 1 - - parameter/index.rst - parameter_set/index.rst - priors/index.rst diff --git a/docs/api/pybop/parameters/parameter/index.rst b/docs/api/pybop/parameters/parameter/index.rst deleted file mode 100644 index 881ec13d..00000000 --- a/docs/api/pybop/parameters/parameter/index.rst +++ /dev/null @@ -1,95 +0,0 @@ -:py:mod:`pybop.parameters.parameter` -==================================== - -.. py:module:: pybop.parameters.parameter - - -Module Contents ---------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - pybop.parameters.parameter.Parameter - - - - -.. py:class:: Parameter(name, initial_value=None, prior=None, bounds=None) - - - Represents a parameter within the PyBOP framework. - - This class encapsulates the definition of a parameter, including its name, prior - distribution, initial value, bounds, and a margin to ensure the parameter stays - within feasible limits during optimization or sampling. - - :param name: The name of the parameter. - :type name: str - :param initial_value: The initial value to be assigned to the parameter. Defaults to None. - :type initial_value: float, optional - :param prior: The prior distribution from which parameter values are drawn. Defaults to None. - :type prior: scipy.stats distribution, optional - :param bounds: A tuple defining the lower and upper bounds for the parameter. - Defaults to None. - :type bounds: tuple, optional - - .. method:: rvs(n_samples) - - Draw random samples from the parameter's prior distribution. - - .. method:: update(value) - - Update the parameter's current value. - - .. method:: set_margin(margin) - - Set the margin to a specified positive value less than 1. - - - :raises ValueError: If the lower bound is not strictly less than the upper bound, or if - the margin is set outside the interval (0, 1). - - .. py:method:: __repr__() - - Return a string representation of the Parameter instance. - - :returns: A string including the parameter's name, prior, bounds, and current value. - :rtype: str - - - .. py:method:: rvs(n_samples) - - Draw random samples from the parameter's prior distribution. - - The samples are constrained to be within the parameter's bounds, excluding - a predefined margin at the boundaries. - - :param n_samples: The number of samples to draw. - :type n_samples: int - - :returns: An array of samples drawn from the prior distribution within the parameter's bounds. - :rtype: array-like - - - .. py:method:: set_margin(margin) - - Set the margin to a specified positive value less than 1. - - The margin is used to ensure parameter samples are not drawn exactly at the bounds, - which may be problematic in some optimization or sampling algorithms. - - :param margin: The new margin value to be used, which must be in the interval (0, 1). - :type margin: float - - :raises ValueError: If the margin is not between 0 and 1. - - - .. py:method:: update(value) - - Update the parameter's current value. - - :param value: The new value to be assigned to the parameter. - :type value: float diff --git a/docs/api/pybop/parameters/parameter_set/index.rst b/docs/api/pybop/parameters/parameter_set/index.rst deleted file mode 100644 index 2b22be47..00000000 --- a/docs/api/pybop/parameters/parameter_set/index.rst +++ /dev/null @@ -1,95 +0,0 @@ -:py:mod:`pybop.parameters.parameter_set` -======================================== - -.. py:module:: pybop.parameters.parameter_set - - -Module Contents ---------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - pybop.parameters.parameter_set.ParameterSet - - - - -.. py:class:: ParameterSet(json_path=None, params_dict=None) - - - Handles the import and export of parameter sets for battery models. - - This class provides methods to load parameters from a JSON file and to export them - back to a JSON file. It also includes custom logic to handle special cases, such - as parameter values that require specific initialization. - - :param json_path: Path to a JSON file containing parameter data. If provided, parameters will be imported from this file during initialization. - :type json_path: str, optional - :param params_dict: A dictionary of parameters to initialize the ParameterSet with. If not provided, an empty dictionary is used. - :type params_dict: dict, optional - - .. py:method:: _handle_special_cases() - - Processes special cases for parameter values that require custom handling. - - For example, if the open-circuit voltage is specified as 'default', it will - fetch the default value from the PyBaMM empirical Thevenin model. - - - .. py:method:: export_parameters(output_json_path, fit_params=None) - - Exports parameters to a JSON file specified by `output_json_path`. - - The current state of the `params` attribute is written to the file. If `fit_params` - is provided, these parameters are updated before export. Non-serializable values - are handled and noted in the output JSON. - - :param output_json_path: The file path where the JSON output will be saved. - :type output_json_path: str - :param fit_params: Parameters that have been fitted and need to be included in the export. - :type fit_params: list of fitted parameter objects, optional - - :raises ValueError: If there are no parameters to export. - - - .. py:method:: import_parameters(json_path=None) - - Imports parameters from a JSON file specified by the `json_path` attribute. - - If a `json_path` is provided at initialization or as an argument, that JSON file - is loaded and the parameters are stored in the `params` attribute. Special cases - are handled appropriately. - - :param json_path: Path to the JSON file from which to import parameters. If provided, it overrides the instance's `json_path`. - :type json_path: str, optional - - :returns: The dictionary containing the imported parameters. - :rtype: dict - - :raises FileNotFoundError: If the specified JSON file cannot be found. - - - .. py:method:: is_json_serializable(value) - - Determines if the given `value` can be serialized to JSON format. - - :param value: The value to check for JSON serializability. - :type value: any - - :returns: True if the value is JSON serializable, False otherwise. - :rtype: bool - - - .. py:method:: pybamm(name) - :classmethod: - - Retrieves a PyBaMM parameter set by name. - - :param name: The name of the PyBaMM parameter set to retrieve. - :type name: str - - :returns: A PyBaMM parameter set corresponding to the provided name. - :rtype: pybamm.ParameterValues diff --git a/docs/api/pybop/parameters/priors/index.rst b/docs/api/pybop/parameters/priors/index.rst deleted file mode 100644 index 9e633272..00000000 --- a/docs/api/pybop/parameters/priors/index.rst +++ /dev/null @@ -1,178 +0,0 @@ -:py:mod:`pybop.parameters.priors` -================================= - -.. py:module:: pybop.parameters.priors - - -Module Contents ---------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - pybop.parameters.priors.Exponential - pybop.parameters.priors.Gaussian - pybop.parameters.priors.Uniform - - - - -.. py:class:: Exponential(scale) - - - Represents an exponential distribution with a specified scale parameter. - - This class provides methods to calculate the pdf, the log pdf, and to generate random - variates from the distribution. - - :param scale: The scale parameter (lambda) of the exponential distribution. - :type scale: float - - .. py:method:: __repr__() - - Returns a string representation of the Uniform object. - - - .. py:method:: logpdf(x) - - Calculates the logarithm of the pdf of the exponential distribution at x. - - :param x: The point at which to evaluate the log pdf. - :type x: float - - :returns: The log of the probability density function value at x. - :rtype: float - - - .. py:method:: pdf(x) - - Calculates the probability density function of the exponential distribution at x. - - :param x: The point at which to evaluate the pdf. - :type x: float - - :returns: The probability density function value at x. - :rtype: float - - - .. py:method:: rvs(size) - - Generates random variates from the exponential distribution. - - :param size: The number of random variates to generate. - :type size: int - - :returns: An array of random variates from the exponential distribution. - :rtype: array_like - - :raises ValueError: If the size parameter is not positive. - - - -.. py:class:: Gaussian(mean, sigma) - - - Represents a Gaussian (normal) distribution with a given mean and standard deviation. - - This class provides methods to calculate the probability density function (pdf), - the logarithm of the pdf, and to generate random variates (rvs) from the distribution. - - :param mean: The mean (mu) of the Gaussian distribution. - :type mean: float - :param sigma: The standard deviation (sigma) of the Gaussian distribution. - :type sigma: float - - .. py:method:: __repr__() - - Returns a string representation of the Gaussian object. - - - .. py:method:: logpdf(x) - - Calculates the logarithm of the probability density function of the Gaussian distribution at x. - - :param x: The point at which to evaluate the log pdf. - :type x: float - - :returns: The logarithm of the probability density function value at x. - :rtype: float - - - .. py:method:: pdf(x) - - Calculates the probability density function of the Gaussian distribution at x. - - :param x: The point at which to evaluate the pdf. - :type x: float - - :returns: The probability density function value at x. - :rtype: float - - - .. py:method:: rvs(size) - - Generates random variates from the Gaussian distribution. - - :param size: The number of random variates to generate. - :type size: int - - :returns: An array of random variates from the Gaussian distribution. - :rtype: array_like - - :raises ValueError: If the size parameter is not positive. - - - -.. py:class:: Uniform(lower, upper) - - - Represents a uniform distribution over a specified interval. - - This class provides methods to calculate the pdf, the log pdf, and to generate - random variates from the distribution. - - :param lower: The lower bound of the distribution. - :type lower: float - :param upper: The upper bound of the distribution. - :type upper: float - - .. py:method:: __repr__() - - Returns a string representation of the Uniform object. - - - .. py:method:: logpdf(x) - - Calculates the logarithm of the pdf of the uniform distribution at x. - - :param x: The point at which to evaluate the log pdf. - :type x: float - - :returns: The log of the probability density function value at x. - :rtype: float - - - .. py:method:: pdf(x) - - Calculates the probability density function of the uniform distribution at x. - - :param x: The point at which to evaluate the pdf. - :type x: float - - :returns: The probability density function value at x. - :rtype: float - - - .. py:method:: rvs(size) - - Generates random variates from the uniform distribution. - - :param size: The number of random variates to generate. - :type size: int - - :returns: An array of random variates from the uniform distribution. - :rtype: array_like - - :raises ValueError: If the size parameter is not positive. diff --git a/docs/api/pybop/plotting/index.rst b/docs/api/pybop/plotting/index.rst deleted file mode 100644 index 3bbad489..00000000 --- a/docs/api/pybop/plotting/index.rst +++ /dev/null @@ -1,17 +0,0 @@ -:py:mod:`pybop.plotting` -======================== - -.. py:module:: pybop.plotting - - -Submodules ----------- -.. toctree:: - :titlesonly: - :maxdepth: 1 - - plot_convergence/index.rst - plot_cost2d/index.rst - plot_parameters/index.rst - plotly_manager/index.rst - quick_plot/index.rst diff --git a/docs/api/pybop/plotting/plot_convergence/index.rst b/docs/api/pybop/plotting/plot_convergence/index.rst deleted file mode 100644 index 79d2080c..00000000 --- a/docs/api/pybop/plotting/plot_convergence/index.rst +++ /dev/null @@ -1,38 +0,0 @@ -:py:mod:`pybop.plotting.plot_convergence` -========================================= - -.. py:module:: pybop.plotting.plot_convergence - - -Module Contents ---------------- - - -Functions -~~~~~~~~~ - -.. autoapisummary:: - - pybop.plotting.plot_convergence.plot_convergence - - - -.. py:function:: plot_convergence(optim, xaxis_title='Iteration', yaxis_title='Cost', title='Convergence') - - Plot the convergence of the optimisation algorithm. - - Parameters: - ---------- - optim : optimisation object - Optimisation object containing the cost function and optimiser. - xaxis_title : str, optional - Title for the x-axis (default is "Iteration"). - yaxis_title : str, optional - Title for the y-axis (default is "Cost"). - title : str, optional - Title of the plot (default is "Convergence"). - - Returns: - ---------- - fig : plotly.graph_objs.Figure - The Plotly figure object for the convergence plot. diff --git a/docs/api/pybop/plotting/plot_cost2d/index.rst b/docs/api/pybop/plotting/plot_cost2d/index.rst deleted file mode 100644 index 83023b5d..00000000 --- a/docs/api/pybop/plotting/plot_cost2d/index.rst +++ /dev/null @@ -1,54 +0,0 @@ -:py:mod:`pybop.plotting.plot_cost2d` -==================================== - -.. py:module:: pybop.plotting.plot_cost2d - - -Module Contents ---------------- - - -Functions -~~~~~~~~~ - -.. autoapisummary:: - - pybop.plotting.plot_cost2d.create_figure - pybop.plotting.plot_cost2d.get_param_bounds - pybop.plotting.plot_cost2d.plot_cost2d - - - -.. py:function:: create_figure(x, y, z, bounds, params, optim) - - -.. py:function:: get_param_bounds(cost) - - Use parameters bounds for range of cost landscape - - -.. py:function:: plot_cost2d(cost, bounds=None, optim=None, steps=10) - - Query the cost landscape for a given parameter space and plot it using Plotly. - - This function creates a 2D plot that visualizes the cost landscape over a grid - of points within specified parameter bounds. If no bounds are provided, it determines - them from the bounds on the parameter class. - - :param cost: A callable representing the cost function to be queried. It should - take a list of parameters and return a cost value. - :type cost: callable - :param bounds: The bounds for the parameter space as a 2x2 array, with each - sub-array representing the min and max bounds for a parameter. - If None, bounds will be determined by `get_param_bounds`. - :type bounds: numpy.ndarray, optional - :param optim: An optional optimizer instance. If provided, it will be used to - overlay optimizer-specific information on the plot. - :type optim: object, optional - :param steps: The number of steps to divide the parameter space grid. More steps - result in finer resolution but increase computational cost. - :type steps: int, optional - :return: A Plotly figure object representing the cost landscape plot. - :rtype: plotly.graph_objs.Figure - - :raises ValueError: If the cost function does not behave as expected. diff --git a/docs/api/pybop/plotting/plot_parameters/index.rst b/docs/api/pybop/plotting/plot_parameters/index.rst deleted file mode 100644 index 56416c1e..00000000 --- a/docs/api/pybop/plotting/plot_parameters/index.rst +++ /dev/null @@ -1,89 +0,0 @@ -:py:mod:`pybop.plotting.plot_parameters` -======================================== - -.. py:module:: pybop.plotting.plot_parameters - - -Module Contents ---------------- - - -Functions -~~~~~~~~~ - -.. autoapisummary:: - - pybop.plotting.plot_parameters.create_subplots_with_traces - pybop.plotting.plot_parameters.create_traces - pybop.plotting.plot_parameters.plot_parameters - - - -.. py:function:: create_subplots_with_traces(traces, plot_size=(1024, 576), title='Parameter Convergence', axis_titles=None, **layout_kwargs) - - Creates a subplot figure with the given traces. - - :param traces: List of plotly.graph_objs traces that will be added to the subplots. - :param plot_size: Tuple (width, height) representing the desired size of the plot. - :param title: The main title of the subplot figure. - :param axis_titles: List of tuples for axis titles in the form [(x_title, y_title), ...] for each subplot. - :param layout_kwargs: Additional keyword arguments to be passed to fig.update_layout for custom layout. - :return: A plotly figure object with the subplots. - - -.. py:function:: create_traces(params, trace_data, x_values=None) - - Generate a list of Plotly Scatter trace objects from provided trace data. - - This function assumes that each column in the ``trace_data`` represents a separate trace to be plotted, - and that the ``params`` list contains objects with a ``name`` attribute used for trace names. - Text wrapping for trace names is performed by ``pybop.StandardPlot.wrap_text``. - - Parameters: - - params (list): A list of objects, where each object has a ``name`` attribute used as the trace name. - The list should have the same length as the number of traces in ``trace_data``. - - trace_data (list of lists): A 2D list where each inner list represents y-values for a trace. - - x_values (list, optional): A list of x-values to be used for all traces. If not provided, a - range of integers starting from 0 will be used. - - Returns: - - list: A list of Plotly ``go.Scatter`` objects, each representing a trace to be plotted. - - Notes: - - The function depends on ``pybop.StandardPlot.wrap_text`` for text wrapping, which needs to be available - in the execution context. - - The function assumes that ``go`` from ``plotly.graph_objs`` is already imported as ``go``. - - -.. py:function:: plot_parameters(optim, xaxis_titles='Iteration', yaxis_titles=None, title='Convergence') - - Plot the evolution of the parameters during the optimisation process. - - Parameters: - ------------ - optim : optimisation object - An object representing the optimisation process, which should contain - information about the cost function, optimiser, and the history of the - parameter values throughout the iterations. - xaxis_title : str, optional - Title for the x-axis, representing the iteration number or a similar - discrete time step in the optimisation process (default is "Iteration"). - yaxis_title : str, optional - Title for the y-axis, which typically represents the metric being - optimised, such as cost or loss (default is "Cost"). - title : str, optional - Title of the plot, which provides an overall description of what the - plot represents (default is "Convergence"). - - Returns: - ---------- - fig : plotly.graph_objs.Figure - The Plotly figure object for the plot depicting how the parameters of - the optimisation algorithm evolve over its course. This can be useful - for diagnosing the behaviour of the optimisation algorithm. - - Notes: - ---------- - The function assumes that the 'optim' object has a 'cost.problem.parameters' - attribute containing the parameters of the optimisation algorithm and a 'log' - attribute containing a history of the iterations. diff --git a/docs/api/pybop/plotting/plotly_manager/index.rst b/docs/api/pybop/plotting/plotly_manager/index.rst deleted file mode 100644 index d0606b3c..00000000 --- a/docs/api/pybop/plotting/plotly_manager/index.rst +++ /dev/null @@ -1,70 +0,0 @@ -:py:mod:`pybop.plotting.plotly_manager` -======================================= - -.. py:module:: pybop.plotting.plotly_manager - - -Module Contents ---------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - pybop.plotting.plotly_manager.PlotlyManager - - - - -.. py:class:: PlotlyManager - - - Manages the installation and configuration of Plotly for generating visualisations. - - This class checks if Plotly is installed and, if not, prompts the user to install it. - It also ensures that the Plotly renderer and browser settings are properly configured - to display plots. - - Methods: - ``ensure_plotly_installed``: Verifies if Plotly is installed and installs it if necessary. - ``prompt_for_plotly_installation``: Prompts the user for permission to install Plotly. - ``install_plotly_package``: Installs the Plotly package using pip. - ``post_install_setup``: Sets up Plotly default renderer after installation. - ``check_renderer_settings``: Verifies that the Plotly renderer is correctly set. - ``check_browser_availability``: Checks if a web browser is available for rendering plots. - - Usage: - Instantiate the PlotlyManager class to automatically ensure Plotly is installed - and configured correctly when creating an instance. - Example: - plotly_manager = PlotlyManager() - - .. py:method:: check_browser_availability() - - Ensures a web browser is available for rendering plots with the 'browser' renderer and provides guidance if not. - - - .. py:method:: check_renderer_settings() - - Checks if the Plotly renderer is set and provides information on how to set it if empty. - - - .. py:method:: ensure_plotly_installed() - - Verifies if Plotly is installed, importing necessary modules and prompting for installation if missing. - - - .. py:method:: install_plotly() - - Attempts to install the Plotly package using pip and exits if installation fails. - - - .. py:method:: post_install_setup() - - After successful installation, imports Plotly and sets the default renderer if necessary. - - - .. py:method:: prompt_for_plotly_installation() - - Prompts the user for permission to install Plotly and proceeds with installation if consented. diff --git a/docs/api/pybop/plotting/quick_plot/index.rst b/docs/api/pybop/plotting/quick_plot/index.rst deleted file mode 100644 index 87d9db9c..00000000 --- a/docs/api/pybop/plotting/quick_plot/index.rst +++ /dev/null @@ -1,123 +0,0 @@ -:py:mod:`pybop.plotting.quick_plot` -=================================== - -.. py:module:: pybop.plotting.quick_plot - - -Module Contents ---------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - pybop.plotting.quick_plot.StandardPlot - - - -Functions -~~~~~~~~~ - -.. autoapisummary:: - - pybop.plotting.quick_plot.quick_plot - - - -.. py:class:: StandardPlot(x, y, cost, y2=None, title=None, xaxis_title=None, yaxis_title=None, trace_name=None, width=1024, height=576) - - - A class for creating and displaying a plotly figure that compares a target dataset against a simulated model output. - - This class provides an interface for generating interactive plots using Plotly, with the ability to include an - optional secondary dataset and visualize uncertainty if provided. - - Attributes: - ----------- - x : list - The x-axis data points. - y : list or np.ndarray - The primary y-axis data points representing the simulated model output. - y2 : list or np.ndarray, optional - An optional secondary y-axis data points representing the target dataset against which the model output is compared. - cost : float - The cost associated with the model output. - title : str, optional - The title of the plot. - xaxis_title : str, optional - The title for the x-axis. - yaxis_title : str, optional - The title for the y-axis. - trace_name : str, optional - The name of the primary trace representing the model output. Defaults to "Simulated". - width : int, optional - The width of the figure in pixels. Defaults to 720. - height : int, optional - The height of the figure in pixels. Defaults to 540. - - Example: - ---------- - >>> x_data = [1, 2, 3, 4] - >>> y_simulated = [10, 15, 13, 17] - >>> y_target = [11, 14, 12, 16] - >>> plot = pybop.StandardPlot(x_data, y_simulated, cost=0.05, y2=y_target, - title="Model vs. Target", xaxis_title="X Axis", yaxis_title="Y Axis") - >>> fig = plot() # Generate the figure - >>> fig.show() # Display the figure in a browser - - .. py:method:: __call__() - - Generate the plotly figure. - - - .. py:method:: create_layout() - - Create the layout for the plot. - - - .. py:method:: create_traces() - - Create the traces for the plot. - - - .. py:method:: wrap_text(text, width) - :staticmethod: - - Wrap text to a specified width. - - Parameters: - ----------- - text: str - Text to be wrapped. - width: int - Width to wrap text to. - - Returns: - ---------- - str - Wrapped text with HTML line breaks. - - - -.. py:function:: quick_plot(params, cost, title='Scatter Plot', width=1024, height=576) - - Plot the target dataset against the minimised model output. - - Parameters: - ----------- - params : array-like - Optimised parameters. - cost : cost object - Cost object containing the problem, dataset, and signal. - title : str, optional - Title of the plot (default is "Scatter Plot"). - width : int, optional - Width of the figure in pixels (default is 720). - height : int, optional - Height of the figure in pixels (default is 540). - - Returns: - ---------- - fig : plotly.graph_objs.Figure - The Plotly figure object for the scatter plot. diff --git a/docs/api/pybop/version/index.rst b/docs/api/pybop/version/index.rst deleted file mode 100644 index bf5679ef..00000000 --- a/docs/api/pybop/version/index.rst +++ /dev/null @@ -1,11 +0,0 @@ -:py:mod:`pybop.version` -======================= - -.. py:module:: pybop.version - - -Module Contents ---------------- - -.. py:data:: __version__ - :value: '23.11' diff --git a/docs/conf.py b/docs/conf.py index f3e3ce0c..55f6b90c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -54,16 +54,22 @@ # html_theme options html_theme_options = { + "header_links_before_dropdown": 4, "icon_links": [ + { + "name": "PyPI", + "url": "https://pypi.org/project/pybop/", + "icon": "fa-custom fa-pypi", + }, { "name": "GitHub", "url": "https://github.com/pybop-team/pybop", "icon": "fab fa-github-square", }, - # add other icon links as needed ], "search_bar_text": "Search the docs...", "show_prev_next": False, } html_static_path = ["_static"] +html_js_files = ["custom-icon.js"] diff --git a/docs/index.md b/docs/index.md index 94d276fe..622dd79d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -6,7 +6,7 @@ myst: html_theme.sidebar_secondary.remove: true --- -

Parameterise and Optimise Battery Models with PyBOP

+# PyBOP: Optimise and Parameterise Battery Models Welcome to PyBOP, a Python package dedicated to the optimization and parameterization of battery models. PyBOP is designed to streamline your workflow, whether you are conducting academic research, working in industry, or simply interested in battery technology and modelling. diff --git a/docs/user_guide/installation.rst b/docs/user_guide/installation.rst index 1482edc4..1204d725 100644 --- a/docs/user_guide/installation.rst +++ b/docs/user_guide/installation.rst @@ -50,7 +50,7 @@ For Developers If you are installing PyBOP for development purposes, such as contributing to the project, please ensure that you follow the guidelines outlined in the contributing guide. It includes additional steps that might be necessary for setting up a development environment, including the installation of dependencies and setup of pre-commit hooks. -`Contributing Guide `_ +`Contributing Guide <../contributing.html>`_ Further Assistance ------------------ @@ -62,6 +62,5 @@ Next Steps After installing PyBOP, you might want to: -* Explore the `Quick Start Guide `_ to begin using PyBOP. -* Read through the `User Manual `_ for in-depth documentation on PyBOP's features. +* Explore the `Quick Start Guide `_ to begin using PyBOP. * Check out the `API Reference <../api/index.html>`_ for detailed information on PyBOP's programming interface. diff --git a/pybop/_problem.py b/pybop/_problem.py index 8cf37ec3..5e9110d6 100644 --- a/pybop/_problem.py +++ b/pybop/_problem.py @@ -3,7 +3,20 @@ class BaseProblem: """ - Defines the PyBOP base problem, following the PINTS interface. + Base class for defining a problem within the PyBOP framework, compatible with PINTS. + + Parameters + ---------- + parameters : list + List of parameters for the problem. + model : object, optional + The model to be used for the problem (default: None). + check_model : bool, optional + Flag to indicate if the model should be checked (default: True). + init_soc : float, optional + Initial state of charge (default: None). + x0 : np.ndarray, optional + Initial parameter values (default: None). """ def __init__( @@ -42,20 +55,52 @@ def __init__( def evaluate(self, x): """ Evaluate the model with the given parameters and return the signal. + + Parameters + ---------- + x : np.ndarray + Parameter values to evaluate the model at. + + Raises + ------ + NotImplementedError + This method must be implemented by subclasses. """ raise NotImplementedError def evaluateS1(self, x): """ - Evaluate the model with the given parameters and return the signal and - its derivatives. + Evaluate the model with the given parameters and return the signal and its derivatives. + + Parameters + ---------- + x : np.ndarray + Parameter values to evaluate the model at. + + Raises + ------ + NotImplementedError + This method must be implemented by subclasses. """ raise NotImplementedError class FittingProblem(BaseProblem): """ - Defines the problem class for a fitting (parameter estimation) problem. + Problem class for fitting (parameter estimation) problems. + + Extends `BaseProblem` with specifics for fitting a model to a dataset. + + Parameters + ---------- + model : object + The model to fit. + parameters : list + List of parameters for the problem. + dataset : list + List of data objects to fit the model to. + signal : str, optional + The signal to fit (default: "Voltage [V]"). """ def __init__( @@ -104,6 +149,11 @@ def __init__( def evaluate(self, x): """ Evaluate the model with the given parameters and return the signal. + + Parameters + ---------- + x : np.ndarray + Parameter values to evaluate the model at. """ y = np.asarray(self._model.simulate(inputs=x, t_eval=self._time_data)) @@ -112,8 +162,12 @@ def evaluate(self, x): def evaluateS1(self, x): """ - Evaluate the model with the given parameters and return the signal and - its derivatives. + Evaluate the model with the given parameters and return the signal and its derivatives. + + Parameters + ---------- + x : np.ndarray + Parameter values to evaluate the model at. """ y, dy = self._model.simulateS1( @@ -125,14 +179,30 @@ def evaluateS1(self, x): def target(self): """ - Returns the target dataset. + Return the target dataset. + + Returns + ------- + np.ndarray + The target dataset array. """ return self._target class DesignProblem(BaseProblem): """ - Defines the problem class for a design optimiation problem. + Problem class for design optimization problems. + + Extends `BaseProblem` with specifics for applying a model to an experimental design. + + Parameters + ---------- + model : object + The model to apply the design to. + parameters : list + List of parameters for the problem. + experiment : object + The experimental setup to apply the model to. """ def __init__( @@ -166,6 +236,11 @@ def __init__( def evaluate(self, x): """ Evaluate the model with the given parameters and return the signal. + + Parameters + ---------- + x : np.ndarray + Parameter values to evaluate the model at. """ y = np.asarray(self._model.simulate(inputs=x, t_eval=self._time_data)) @@ -174,8 +249,12 @@ def evaluate(self, x): def evaluateS1(self, x): """ - Evaluate the model with the given parameters and return the signal and - its derivatives. + Evaluate the model with the given parameters and return the signal and its derivatives. + + Parameters + ---------- + x : np.ndarray + Parameter values to evaluate the model at. """ y, dy = self._model.simulateS1( @@ -187,6 +266,10 @@ def evaluateS1(self, x): def target(self): """ - Returns the target dataset. + Return the target dataset (not applicable for design problems). + + Returns + ------- + None """ return self._target diff --git a/pybop/optimisation.py b/pybop/optimisation.py index 5da349a0..d18c6a43 100644 --- a/pybop/optimisation.py +++ b/pybop/optimisation.py @@ -5,14 +5,31 @@ class Optimisation: """ - Optimisation class for PyBOP. - This class provides functionality for PyBOP optimisers and Pints optimisers. - args: - cost: PyBOP cost function - optimiser: A PyBOP or Pints optimiser - sigma0: initial step size - verbose: print optimisation progress - + A class for conducting optimization using PyBOP or PINTS optimizers. + + Parameters + ---------- + cost : pints.ErrorMeasure or pints.LogPDF + An objective function to be optimized, which can be either a PINTS error measure or log PDF. + optimiser : pints.Optimiser or subclass of pybop.BaseOptimizer, optional + An optimizer from either the PINTS or PyBOP framework to perform the optimization (default: None). + sigma0 : float or sequence, optional + Initial step size or standard deviation for the optimizer (default: None). + verbose : bool, optional + If True, the optimization progress is printed (default: False). + + Attributes + ---------- + x0 : numpy.ndarray + Initial parameter values for the optimization. + bounds : dict + Dictionary containing the parameter bounds with keys 'lower' and 'upper'. + n_parameters : int + Number of parameters in the optimization problem. + sigma0 : float or sequence + Initial step size or standard deviation for the optimizer. + log : list + Log of the optimization process. """ def __init__( @@ -106,11 +123,14 @@ def __init__( def run(self): """ - Run the optimisation algorithm. - Selects between PyBOP backend or Pints backend. - returns: - x: best parameters - final_cost: final cost + Run the optimization and return the optimized parameters and final cost. + + Returns + ------- + x : numpy.ndarray + The best parameter set found by the optimization. + final_cost : float + The final cost associated with the best parameters. """ if self.pints: @@ -126,10 +146,14 @@ def run(self): def _run_pybop(self): """ - Run method for PyBOP based optimisers. - returns: - x: best parameters - final_cost: final cost + Internal method to run the optimization using a PyBOP optimizer. + + Returns + ------- + x : numpy.ndarray + The best parameter set found by the optimization. + final_cost : float + The final cost associated with the best parameters. """ x, final_cost = self.optimiser.optimise( cost_function=self.cost, @@ -143,11 +167,18 @@ def _run_pybop(self): def _run_pints(self): """ - Run method for PINTS optimisers. + Internal method to run the optimization using a PINTS optimizer. + + Returns + ------- + x : numpy.ndarray + The best parameter set found by the optimization. + final_cost : float + The final cost associated with the best parameters. + + See Also + -------- This method is heavily based on the run method in the PINTS.OptimisationController class. - returns: - x: best parameters - final_cost: final cost """ # Check stopping criteria @@ -319,34 +350,37 @@ def _run_pints(self): def f_guessed_tracking(self): """ - Returns ``True`` if f_guessed instead of f_best is being tracked, - ``False`` otherwise. See also :meth:`set_f_guessed_tracking`. - + Check if f_guessed instead of f_best is being tracked. Credit: PINTS + + Returns + ------- + bool + True if f_guessed is being tracked, False otherwise. """ return self._use_f_guessed def set_f_guessed_tracking(self, use_f_guessed=False): """ - Sets the method used to track the optimiser progress to - :meth:`pints.Optimiser.f_guessed()` or - :meth:`pints.Optimiser.f_best()` (default). - - The tracked ``f`` value is used to evaluate stopping criteria. - + Set the method used to track the optimizer progress. Credit: PINTS + + Parameters + ---------- + use_f_guessed : bool, optional + If True, track f_guessed; otherwise, track f_best (default: False). """ self._use_f_guessed = bool(use_f_guessed) def set_max_evaluations(self, evaluations=None): """ - Adds a stopping criterion, allowing the routine to halt after the - given number of ``evaluations``. - - This criterion is disabled by default. To enable, pass in any positive - integer. To disable again, use ``set_max_evaluations(None)``. - + Set a maximum number of evaluations stopping criterion. Credit: PINTS + + Parameters + ---------- + evaluations : int, optional + The maximum number of evaluations after which to stop the optimization (default: None). """ if evaluations is not None: evaluations = int(evaluations) @@ -356,16 +390,14 @@ def set_max_evaluations(self, evaluations=None): def set_parallel(self, parallel=False): """ - Enables/disables parallel evaluation. - - If ``parallel=True``, the method will run using a number of worker - processes equal to the detected cpu core count. The number of workers - can be set explicitly by setting ``parallel`` to an integer greater - than 0. - Parallelisation can be disabled by setting ``parallel`` to ``0`` or - ``False``. - + Enable or disable parallel evaluation. Credit: PINTS + + Parameters + ---------- + parallel : bool or int, optional + If True, use as many worker processes as there are CPU cores. If an integer, use that many workers. + If False or 0, disable parallelism (default: False). """ if parallel is True: self._parallel = True @@ -379,13 +411,14 @@ def set_parallel(self, parallel=False): def set_max_iterations(self, iterations=1000): """ - Adds a stopping criterion, allowing the routine to halt after the - given number of ``iterations``. - - This criterion is enabled by default. To disable it, use - ``set_max_iterations(None)``. - + Set the maximum number of iterations as a stopping criterion. Credit: PINTS + + Parameters + ---------- + iterations : int, optional + The maximum number of iterations to run (default is 1000). + Set to `None` to remove this stopping criterion. """ if iterations is not None: iterations = int(iterations) @@ -395,14 +428,16 @@ def set_max_iterations(self, iterations=1000): def set_max_unchanged_iterations(self, iterations=25, threshold=1e-5): """ - Adds a stopping criterion, allowing the routine to halt if the - objective function doesn't change by more than ``threshold`` for the - given number of ``iterations``. - - This criterion is enabled by default. To disable it, use - ``set_max_unchanged_iterations(None)``. - + Set the maximum number of iterations without significant change as a stopping criterion. Credit: PINTS + + Parameters + ---------- + iterations : int, optional + The maximum number of unchanged iterations to run (default is 25). + Set to `None` to remove this stopping criterion. + threshold : float, optional + The minimum significant change in the objective function value that resets the unchanged iteration counter (default is 1e-5). """ if iterations is not None: iterations = int(iterations) @@ -418,7 +453,14 @@ def set_max_unchanged_iterations(self, iterations=25, threshold=1e-5): def store_optimised_parameters(self, x): """ - Store the optimised parameters in the PyBOP parameter class. + Update the problem parameters with optimized values. + + The optimized parameter values are stored within the associated PyBOP parameter class. + + Parameters + ---------- + x : array-like + Optimized parameter values. """ for i, param in enumerate(self.cost.problem.parameters): param.update(value=x[i]) diff --git a/pybop/plotting/plot_cost2d.py b/pybop/plotting/plot_cost2d.py index 43a84ce6..f8e7b187 100644 --- a/pybop/plotting/plot_cost2d.py +++ b/pybop/plotting/plot_cost2d.py @@ -3,29 +3,31 @@ def plot_cost2d(cost, bounds=None, optim=None, steps=10): """ - Query the cost landscape for a given parameter space and plot it using Plotly. - - This function creates a 2D plot that visualizes the cost landscape over a grid - of points within specified parameter bounds. If no bounds are provided, it determines - them from the bounds on the parameter class. - - :param cost: A callable representing the cost function to be queried. It should - take a list of parameters and return a cost value. - :type cost: callable - :param bounds: The bounds for the parameter space as a 2x2 array, with each - sub-array representing the min and max bounds for a parameter. - If None, bounds will be determined by `get_param_bounds`. - :type bounds: numpy.ndarray, optional - :param optim: An optional optimizer instance. If provided, it will be used to - overlay optimizer-specific information on the plot. - :type optim: object, optional - :param steps: The number of steps to divide the parameter space grid. More steps - result in finer resolution but increase computational cost. - :type steps: int, optional - :return: A Plotly figure object representing the cost landscape plot. - :rtype: plotly.graph_objs.Figure - - :raises ValueError: If the cost function does not behave as expected. + Plot a 2D visualization of a cost landscape using Plotly. + + This function generates a contour plot representing the cost landscape for a provided + callable cost function over a grid of parameter values within the specified bounds. + + Parameters + ---------- + cost : callable + The cost function to be evaluated. Must accept a list of parameters and return a cost value. + bounds : numpy.ndarray, optional + A 2x2 array specifying the [min, max] bounds for each parameter. If None, uses `get_param_bounds`. + optim : object, optional + An optimizer instance which, if provided, overlays its specific trace on the plot. + steps : int, optional + The number of intervals to divide the parameter space into along each dimension (default is 10). + + Returns + ------- + plotly.graph_objs.Figure + The Plotly figure object containing the cost landscape plot. + + Raises + ------ + ValueError + If the cost function does not return a valid cost when called with a parameter list. """ if bounds is None: @@ -57,7 +59,17 @@ def plot_cost2d(cost, bounds=None, optim=None, steps=10): def get_param_bounds(cost): """ - Use parameters bounds for range of cost landscape + Retrieve parameter bounds from a cost function's associated problem parameters. + + Parameters + ---------- + cost : callable + The cost function with an associated 'problem' attribute containing 'parameters'. + + Returns + ------- + numpy.ndarray + An array of shape (n_parameters, 2) containing the bounds for each parameter. """ bounds = np.empty((len(cost.problem.parameters), 2)) for i, param in enumerate(cost.problem.parameters): @@ -66,6 +78,30 @@ def get_param_bounds(cost): def create_figure(x, y, z, bounds, params, optim): + """ + Create a Plotly figure with a 2D contour plot of the cost landscape. + + Parameters + ---------- + x : numpy.ndarray + 1D array of x-coordinates for the meshgrid. + y : numpy.ndarray + 1D array of y-coordinates for the meshgrid. + z : numpy.ndarray + 2D array of cost function values corresponding to the meshgrid. + bounds : numpy.ndarray + A 2x2 array specifying the [min, max] bounds for each parameter. + params : iterable + An iterable of parameter objects with 'name' attributes for axis labeling. + optim : object + An optimizer instance with 'log' and 'x0' attributes for plotting traces. + + Returns + ------- + plotly.graph_objs.Figure + The Plotly figure object with the contour plot and optimization traces. + """ + # Import plotly only when needed import plotly.graph_objects as go diff --git a/pybop/plotting/plot_parameters.py b/pybop/plotting/plot_parameters.py index 1deab9bf..84307a72 100644 --- a/pybop/plotting/plot_parameters.py +++ b/pybop/plotting/plot_parameters.py @@ -6,36 +6,23 @@ def plot_parameters( optim, xaxis_titles="Iteration", yaxis_titles=None, title="Convergence" ): """ - Plot the evolution of the parameters during the optimisation process. - - Parameters: - ------------ - optim : optimisation object - An object representing the optimisation process, which should contain - information about the cost function, optimiser, and the history of the - parameter values throughout the iterations. - xaxis_title : str, optional - Title for the x-axis, representing the iteration number or a similar - discrete time step in the optimisation process (default is "Iteration"). - yaxis_title : str, optional - Title for the y-axis, which typically represents the metric being - optimised, such as cost or loss (default is "Cost"). - title : str, optional - Title of the plot, which provides an overall description of what the - plot represents (default is "Convergence"). + Plot the evolution of parameters during the optimization process using Plotly. - Returns: + Parameters ---------- - fig : plotly.graph_objs.Figure - The Plotly figure object for the plot depicting how the parameters of - the optimisation algorithm evolve over its course. This can be useful - for diagnosing the behaviour of the optimisation algorithm. + optim : object + The optimization object containing the history of parameter values and associated cost. + xaxis_titles : str, optional + Title for the x-axis, defaulting to "Iteration". + yaxis_titles : list of str, optional + Titles for the y-axes, one for each parameter. If None, parameter names are used. + title : str, optional + Title of the plot, defaulting to "Convergence". - Notes: - ---------- - The function assumes that the 'optim' object has a 'cost.problem.parameters' - attribute containing the parameters of the optimisation algorithm and a 'log' - attribute containing a history of the iterations. + Returns + ------- + plotly.graph_objs.Figure + A Plotly figure object showing the parameter evolution over iterations. """ # Extract parameters from the optimisation object @@ -60,26 +47,21 @@ def plot_parameters( def create_traces(params, trace_data, x_values=None): """ - Generate a list of Plotly Scatter trace objects from provided trace data. - - This function assumes that each column in the ``trace_data`` represents a separate trace to be plotted, - and that the ``params`` list contains objects with a ``name`` attribute used for trace names. - Text wrapping for trace names is performed by ``pybop.StandardPlot.wrap_text``. - - Parameters: - - params (list): A list of objects, where each object has a ``name`` attribute used as the trace name. - The list should have the same length as the number of traces in ``trace_data``. - - trace_data (list of lists): A 2D list where each inner list represents y-values for a trace. - - x_values (list, optional): A list of x-values to be used for all traces. If not provided, a - range of integers starting from 0 will be used. - - Returns: - - list: A list of Plotly ``go.Scatter`` objects, each representing a trace to be plotted. - - Notes: - - The function depends on ``pybop.StandardPlot.wrap_text`` for text wrapping, which needs to be available - in the execution context. - - The function assumes that ``go`` from ``plotly.graph_objs`` is already imported as ``go``. + Create traces for plotting parameter evolution. + + Parameters + ---------- + params : list + List of parameter objects, each having a 'name' attribute used for labeling the trace. + trace_data : list of numpy.ndarray + A list of arrays representing the historical values of each parameter. + x_values : list or numpy.ndarray, optional + The x-axis values for plotting. If None, defaults to sequential integers. + + Returns + ------- + list of plotly.graph_objs.Scatter + A list of Scatter trace objects, one for each parameter. """ # Attempt to import plotly when an instance is created @@ -121,14 +103,25 @@ def create_subplots_with_traces( **layout_kwargs, ): """ - Creates a subplot figure with the given traces. - - :param traces: List of plotly.graph_objs traces that will be added to the subplots. - :param plot_size: Tuple (width, height) representing the desired size of the plot. - :param title: The main title of the subplot figure. - :param axis_titles: List of tuples for axis titles in the form [(x_title, y_title), ...] for each subplot. - :param layout_kwargs: Additional keyword arguments to be passed to fig.update_layout for custom layout. - :return: A plotly figure object with the subplots. + Create a subplot with individual traces for each parameter. + + Parameters + ---------- + traces : list of plotly.graph_objs.Scatter + Traces to be plotted, one trace per subplot. + plot_size : tuple of int, optional + The size of the plot as (width, height), defaulting to (1024, 576). + title : str, optional + The title of the plot, defaulting to "Parameter Convergence". + axis_titles : list of tuple of str, optional + A list of (x_title, y_title) pairs for each subplot. If None, titles are omitted. + **layout_kwargs : dict + Additional keyword arguments to customize the layout. + + Returns + ------- + plotly.graph_objs.Figure + A Plotly figure object with subplots for each trace. """ # Attempt to import plotly when an instance is created diff --git a/pybop/plotting/plotly_manager.py b/pybop/plotting/plotly_manager.py index c8b80dc9..b53b15ef 100644 --- a/pybop/plotting/plotly_manager.py +++ b/pybop/plotting/plotly_manager.py @@ -5,28 +5,47 @@ class PlotlyManager: """ - Manages the installation and configuration of Plotly for generating visualisations. - - This class checks if Plotly is installed and, if not, prompts the user to install it. - It also ensures that the Plotly renderer and browser settings are properly configured - to display plots. - - Methods: - ``ensure_plotly_installed``: Verifies if Plotly is installed and installs it if necessary. - ``prompt_for_plotly_installation``: Prompts the user for permission to install Plotly. - ``install_plotly_package``: Installs the Plotly package using pip. - ``post_install_setup``: Sets up Plotly default renderer after installation. - ``check_renderer_settings``: Verifies that the Plotly renderer is correctly set. - ``check_browser_availability``: Checks if a web browser is available for rendering plots. - - Usage: - Instantiate the PlotlyManager class to automatically ensure Plotly is installed - and configured correctly when creating an instance. - Example: - plotly_manager = PlotlyManager() + Manages the installation and configuration of Plotly for generating visualizations. + + This class ensures that Plotly is installed and properly configured to display + plots in a web browser. + + Upon instantiation, it checks for Plotly's presence, installs it if missing, + and configures the default renderer and browser settings. + + Attributes + ---------- + go : module + The Plotly graph_objects module for creating figures. + pio : module + The Plotly input/output module for configuring the renderer. + make_subplots : function + The function from Plotly for creating subplot figures. + + Methods + ------- + ensure_plotly_installed() + Verifies if Plotly is installed, importing necessary modules and prompting for installation if missing. + prompt_for_plotly_installation() + Prompts the user for permission to install Plotly and proceeds with installation if consented. + install_plotly() + Installs the Plotly package using pip. + post_install_setup() + Sets up Plotly default renderer after installation. + check_renderer_settings() + Verifies that the Plotly renderer is correctly set. + check_browser_availability() + Checks if a web browser is available for rendering plots. + + Examples + -------- + >>> plotly_manager = PlotlyManager() """ def __init__(self): + """ + Initialize the PlotlyManager, ensuring Plotly is installed and configured. + """ self.go = None self.pio = None self.make_subplots = None @@ -35,7 +54,9 @@ def __init__(self): self.check_browser_availability() def ensure_plotly_installed(self): - """Verifies if Plotly is installed, importing necessary modules and prompting for installation if missing.""" + """ + Check if Plotly is installed and import necessary modules; prompt for installation if missing. + """ try: import plotly.graph_objs as go import plotly.io as pio @@ -48,7 +69,9 @@ def ensure_plotly_installed(self): self.prompt_for_plotly_installation() def prompt_for_plotly_installation(self): - """Prompts the user for permission to install Plotly and proceeds with installation if consented.""" + """ + Prompt the user for Plotly installation and install it upon agreement. + """ user_input = ( input( "Plotly is not installed. To proceed, we need to install plotly. (Y/n)? " @@ -64,7 +87,9 @@ def prompt_for_plotly_installation(self): sys.exit(1) # Exit if user cancels installation def install_plotly(self): - """Attempts to install the Plotly package using pip and exits if installation fails.""" + """ + Install the Plotly package using pip. Exit if installation fails. + """ try: subprocess.check_call([sys.executable, "-m", "pip", "install", "plotly"]) except subprocess.CalledProcessError as e: @@ -72,7 +97,9 @@ def install_plotly(self): sys.exit(1) # Exit if installation fails def post_install_setup(self): - """After successful installation, imports Plotly and sets the default renderer if necessary.""" + """ + Import Plotly modules and set the default renderer after installation. + """ import plotly.graph_objs as go import plotly.io as pio from plotly.subplots import make_subplots @@ -87,7 +114,9 @@ def post_install_setup(self): ) def check_renderer_settings(self): - """Checks if the Plotly renderer is set and provides information on how to set it if empty.""" + """ + Check and provide information on setting the Plotly renderer if it's not already set. + """ if self.pio and self.pio.renderers.default == "": print( "The Plotly renderer is an empty string. To set the renderer, use:\n" @@ -97,7 +126,9 @@ def check_renderer_settings(self): ) def check_browser_availability(self): - """Ensures a web browser is available for rendering plots with the 'browser' renderer and provides guidance if not.""" + """ + Confirm a web browser is available for Plotly's 'browser' renderer; provide guidance if not. + """ if self.pio and self.pio.renderers.default == "browser": try: webbrowser.get() diff --git a/pybop/plotting/quick_plot.py b/pybop/plotting/quick_plot.py index 8d9ef02b..95a5bfeb 100644 --- a/pybop/plotting/quick_plot.py +++ b/pybop/plotting/quick_plot.py @@ -5,43 +5,32 @@ class StandardPlot: """ - A class for creating and displaying a plotly figure that compares a target dataset against a simulated model output. + A class for creating and displaying Plotly figures for model output comparison. - This class provides an interface for generating interactive plots using Plotly, with the ability to include an - optional secondary dataset and visualize uncertainty if provided. + Generates interactive plots comparing simulated model output with an optional target dataset and visualizes uncertainty. - Attributes: - ----------- - x : list - The x-axis data points. + Parameters + ---------- + x : list or np.ndarray + X-axis data points. y : list or np.ndarray - The primary y-axis data points representing the simulated model output. - y2 : list or np.ndarray, optional - An optional secondary y-axis data points representing the target dataset against which the model output is compared. + Primary Y-axis data points for simulated model output. cost : float - The cost associated with the model output. + Cost associated with the model output. + y2 : list or np.ndarray, optional + Secondary Y-axis data points for the target dataset (default: None). title : str, optional - The title of the plot. + Title of the plot (default: None). xaxis_title : str, optional - The title for the x-axis. + Title for the x-axis (default: None). yaxis_title : str, optional - The title for the y-axis. + Title for the y-axis (default: None). trace_name : str, optional - The name of the primary trace representing the model output. Defaults to "Simulated". + Name for the primary trace (default: "Simulated"). width : int, optional - The width of the figure in pixels. Defaults to 720. + Width of the figure in pixels (default: 1024). height : int, optional - The height of the figure in pixels. Defaults to 540. - - Example: - ---------- - >>> x_data = [1, 2, 3, 4] - >>> y_simulated = [10, 15, 13, 17] - >>> y_target = [11, 14, 12, 16] - >>> plot = pybop.StandardPlot(x_data, y_simulated, cost=0.05, y2=y_target, - title="Model vs. Target", xaxis_title="X Axis", yaxis_title="Y Axis") - >>> fig = plot() # Generate the figure - >>> fig.show() # Display the figure in a browser + Height of the figure in pixels (default: 576). """ def __init__( @@ -57,6 +46,32 @@ def __init__( width=1024, height=576, ): + """ + Initialize the StandardPlot object with simulation and optional target data. + + Parameters + ---------- + x : list or np.ndarray + X-axis data points. + y : list or np.ndarray + Primary Y-axis data points for simulated model output. + cost : float + Cost associated with the model output. + y2 : list or np.ndarray, optional + Secondary Y-axis data points for target dataset (default: None). + title : str, optional + Plot title (default: None). + xaxis_title : str, optional + X-axis title (default: None). + yaxis_title : str, optional + Y-axis title (default: None). + trace_name : str, optional + Name for the primary trace (default: "Simulated"). + width : int, optional + Figure width in pixels (default: 1024). + height : int, optional + Figure height in pixels (default: 576). + """ self.x = x if isinstance(x, list) else x.tolist() self.y = y self.y2 = y2 @@ -79,26 +94,31 @@ def __init__( @staticmethod def wrap_text(text, width): """ - Wrap text to a specified width. - - Parameters: - ----------- - text: str - Text to be wrapped. - width: int - Width to wrap text to. + Wrap text to a specified width with HTML line breaks. - Returns: + Parameters ---------- + text : str + The text to wrap. + width : int + The width to wrap the text to. + + Returns + ------- str - Wrapped text with HTML line breaks. + The wrapped text. """ wrapped_text = textwrap.fill(text, width=width, break_long_words=False) return wrapped_text.replace("\n", "
") def create_layout(self): """ - Create the layout for the plot. + Create the layout for the Plotly figure. + + Returns + ------- + plotly.graph_objs.Layout + The layout for the Plotly figure. """ return self.go.Layout( title=self.title, @@ -115,7 +135,12 @@ def create_layout(self): def create_traces(self): """ - Create the traces for the plot. + Create traces for the Plotly figure. + + Returns + ------- + list + A list of plotly.graph_objs.Scatter objects to be used as traces. """ traces = [] @@ -149,7 +174,12 @@ def create_traces(self): def __call__(self): """ - Generate the plotly figure. + Generate the Plotly figure. + + Returns + ------- + plotly.graph_objs.Figure + The generated Plotly figure. """ layout = self.create_layout() traces = self.create_traces() @@ -159,24 +189,24 @@ def __call__(self): def quick_plot(params, cost, title="Scatter Plot", width=1024, height=576): """ - Plot the target dataset against the minimised model output. + Quickly plot the target dataset against minimized model output. - Parameters: - ----------- + Parameters + ---------- params : array-like - Optimised parameters. - cost : cost object - Cost object containing the problem, dataset, and signal. + Optimized parameters. + cost : object + Cost object with problem, dataset, and signal attributes. title : str, optional - Title of the plot (default is "Scatter Plot"). + Title of the plot (default: "Scatter Plot"). width : int, optional - Width of the figure in pixels (default is 720). + Width of the figure in pixels (default: 1024). height : int, optional - Height of the figure in pixels (default is 540). + Height of the figure in pixels (default: 576). - Returns: - ---------- - fig : plotly.graph_objs.Figure + Returns + ------- + plotly.graph_objs.Figure The Plotly figure object for the scatter plot. """ From cec7d6460ee946530a56bfc8b963b54157ac2a6d Mon Sep 17 00:00:00 2001 From: Brady Planden Date: Mon, 11 Dec 2023 14:48:34 +0000 Subject: [PATCH 11/22] Updts. changelog and contributing, reverts deployment workflow trigger to on release --- .github/workflows/deploy-docs.yaml | 5 ++--- CHANGELOG.md | 1 + CONTRIBUTING.md | 10 ++++++++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy-docs.yaml b/.github/workflows/deploy-docs.yaml index 390b12a9..bd8c9a87 100644 --- a/.github/workflows/deploy-docs.yaml +++ b/.github/workflows/deploy-docs.yaml @@ -1,10 +1,9 @@ name: Deploy Documentation on: - # release: - # types: [created] + release: + types: [created] workflow_dispatch: - push: permissions: contents: write # allow write access for docs deployment diff --git a/CHANGELOG.md b/CHANGELOG.md index 164050d0..478b61c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Features +- [#141](https://github.com/pybop-team/PyBOP/pull/141) - Adds documentation with Sphinx and PyData Sphinx Theme. Updates docstrings across package, relocates `costs` and `dataset` to top-level of package. Adds noxfile session and deployment workflow for docs. - [#131](https://github.com/pybop-team/PyBOP/issues/131) - Adds `SciPyDifferentialEvolution` optimiser, adds functionality for user-selectable maximum iteration limit to `SciPyMinimize`, `NLoptOptimize`, and `BaseOptimiser` classes. - [#107](https://github.com/pybop-team/PyBOP/issues/107) - Adds Equivalent Circuit Model (ECM) with examples, Import/Export parameter methods `ParameterSet.import_parameter` and `ParameterSet.export_parameters`, updates default FittingProblem.signal definition to `"Voltage [V]"`, and testing infrastructure - [#127](https://github.com/pybop-team/PyBOP/issues/127) - Adds Windows and macOS runners to the `test_on_push` action diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 95a6914f..8b83f204 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -126,6 +126,16 @@ def plot_great_things(self, x, y, z): This allows people to (1) use PyBOP without ever importing Matplotlib and (2) configure Matplotlib's back-end in their scripts, which _must_ be done before e.g. `pyplot` is first imported. +### Building documentation + +We use [Sphinx](http://www.sphinx-doc.org/en/stable/) to build our documentation. A nox session has been created to reduce the overhead when building the documentation locally. To run this session, type + +```bash +nox -s docs +``` + +This will build the docs using sphinx-autobuild and render them in your browser. + ## Testing All code requires testing. We use the [pytest](https://docs.pytest.org/en/) package for our tests. (These tests typically just check that the code runs without error, and so, are more _debugging_ than _testing_ in a strict sense. Nevertheless, they are very useful to have!) From 32d6766fd3d6913a1b6b71e2c23ee2e1af10e85c Mon Sep 17 00:00:00 2001 From: Brady Planden Date: Mon, 11 Dec 2023 16:54:28 +0000 Subject: [PATCH 12/22] Updt deployment to use nox session --- .github/workflows/deploy-docs.yaml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/.github/workflows/deploy-docs.yaml b/.github/workflows/deploy-docs.yaml index bd8c9a87..8d460734 100644 --- a/.github/workflows/deploy-docs.yaml +++ b/.github/workflows/deploy-docs.yaml @@ -27,16 +27,13 @@ jobs: - name: Install dependencies run: | - python -m pip install --upgrade pip - pip install -e .[docs] - - - name: Build documentation with sphinx-build - run: | - sphinx-build -b html docs/ docs/_build/html + python -m pip install --upgrade pip nox + - name: Using Python 3.11, build the docs + run: nox -s docs - name: Deploy to GitHub Pages uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./docs/_build/html + publish_dir: ./tmp/html publish_branch: gh-pages From 33ca4d0464a329812db355ed8a62a29e1fb88955 Mon Sep 17 00:00:00 2001 From: Brady Planden Date: Mon, 11 Dec 2023 17:01:09 +0000 Subject: [PATCH 13/22] restores on push deployment for testing --- .github/workflows/deploy-docs.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/deploy-docs.yaml b/.github/workflows/deploy-docs.yaml index 8d460734..75c2ab2d 100644 --- a/.github/workflows/deploy-docs.yaml +++ b/.github/workflows/deploy-docs.yaml @@ -4,6 +4,7 @@ on: release: types: [created] workflow_dispatch: + push: permissions: contents: write # allow write access for docs deployment From 32f5a2740c6218a680a2f9ab3a6752362857fcb8 Mon Sep 17 00:00:00 2001 From: Brady Planden Date: Mon, 11 Dec 2023 17:34:16 +0000 Subject: [PATCH 14/22] Remove duplicate docstrings, updt broken links in contributing.md --- CONTRIBUTING.md | 6 +++--- docs/_templates/autoapi/index.rst | 2 ++ docs/contributing.md | 2 ++ docs/user_guide/installation.rst | 2 ++ docs/user_guide/usage.rst | 9 ++------- pybop/models/base_model.py | 14 -------------- pybop/optimisers/base_optimiser.py | 9 --------- pybop/optimisers/nlopt_optimize.py | 9 --------- pybop/parameters/parameter.py | 9 --------- pybop/plotting/plot_convergence.py | 4 ++-- pybop/plotting/plotly_manager.py | 15 --------------- 11 files changed, 13 insertions(+), 68 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8b83f204..bc98f5ec 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,7 +2,7 @@ If you'd like to contribute to PyBOP, please have a look at the guidelines below. -## Installation +## Developer-Installation To install PyBOP for development purposes, which includes the testing and plotting dependencies, use the `[all]` flag as demonstrated below: @@ -30,7 +30,7 @@ pip install pre-commit pre-commit install ``` -This would run the checks every time a commit is created locally. The checks will only run on the files modified by that commit, but the checks can be triggered for all the files using - +This would run the checks every time a commit is created locally. The checks will only run on the files modified by that commit, but the checks can be triggered for all the files using, ```bash pre-commit run --all-files @@ -47,7 +47,7 @@ We use [GIT](https://en.wikipedia.org/wiki/Git) and [GitHub](https://en.wikipedi 1. Create an [issue](https://guides.github.com/features/issues/) where new proposals can be discussed before any coding is done. 2. Create a [branch](https://help.github.com/articles/creating-and-deleting-branches-within-your-repository/) of this repo (ideally on your own [fork](https://help.github.com/articles/fork-a-repo/)), where all changes will be made 3. Download the source code onto your local system, by [cloning](https://help.github.com/articles/cloning-a-repository/) the repository (or your fork of the repository). -4. [Install](Developer-Install) PyBOP with the developer options. +4. [Install](#developer-installation) PyBOP with the developer options. 5. [Test](#testing) if your installation worked: `$ pytest --unit -v`. You now have everything you need to start making changes! diff --git a/docs/_templates/autoapi/index.rst b/docs/_templates/autoapi/index.rst index 8cb56d2e..d6075995 100644 --- a/docs/_templates/autoapi/index.rst +++ b/docs/_templates/autoapi/index.rst @@ -1,3 +1,5 @@ +.. _api-reference: + API Reference ============= diff --git a/docs/contributing.md b/docs/contributing.md index 78caf34e..a7ea4b6f 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -1,2 +1,4 @@ +(contributing-guide) = + ```{include} ../CONTRIBUTING.md ``` diff --git a/docs/user_guide/installation.rst b/docs/user_guide/installation.rst index 1204d725..08f7ea00 100644 --- a/docs/user_guide/installation.rst +++ b/docs/user_guide/installation.rst @@ -1,3 +1,5 @@ +.. _installation: + Installation Guide for PyBOP ***************************** diff --git a/docs/user_guide/usage.rst b/docs/user_guide/usage.rst index 4e2b2418..14c7f678 100644 --- a/docs/user_guide/usage.rst +++ b/docs/user_guide/usage.rst @@ -46,16 +46,11 @@ These examples are also available on our `GitHub repository >> plotly_manager = PlotlyManager() From c34a9ea7b208fe6d723d05d0d32fce727b34136b Mon Sep 17 00:00:00 2001 From: Brady Planden Date: Mon, 11 Dec 2023 17:40:37 +0000 Subject: [PATCH 15/22] Remove treat warnings as errors --- noxfile.py | 1 - 1 file changed, 1 deletion(-) diff --git a/noxfile.py b/noxfile.py index fbb4912d..8116a3e0 100644 --- a/noxfile.py +++ b/noxfile.py @@ -60,7 +60,6 @@ def docs(session): "auto", "-b", "html", - "-W", "--keep-going", ".", f"{envbindir}/../tmp/html", From 3a0b2b4d5fab3261838428862b83b5ccd30e8f83 Mon Sep 17 00:00:00 2001 From: Brady Planden Date: Mon, 11 Dec 2023 17:57:07 +0000 Subject: [PATCH 16/22] relocate _build directory for deployable access --- .github/workflows/deploy-docs.yaml | 2 +- noxfile.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-docs.yaml b/.github/workflows/deploy-docs.yaml index 75c2ab2d..52d5b057 100644 --- a/.github/workflows/deploy-docs.yaml +++ b/.github/workflows/deploy-docs.yaml @@ -36,5 +36,5 @@ jobs: uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./tmp/html + publish_dir: ./docs/_build/html publish_branch: gh-pages diff --git a/noxfile.py b/noxfile.py index 8116a3e0..f21a4f13 100644 --- a/noxfile.py +++ b/noxfile.py @@ -62,5 +62,5 @@ def docs(session): "html", "--keep-going", ".", - f"{envbindir}/../tmp/html", + "_build/html", ) From a807a56dfee1ac62f63bbc9918ae51336aa9be4e Mon Sep 17 00:00:00 2001 From: Brady Planden Date: Tue, 12 Dec 2023 09:25:18 +0000 Subject: [PATCH 17/22] Tidy conf.py --- docs/conf.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 55f6b90c..c66713fd 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -27,12 +27,6 @@ "_extension.gallery_directive", # For extension examples and demos "myst_parser", - # "ablog", - # "jupyter_sphinx", - # "nbsphinx", - # "numpydoc", - # "sphinx_togglebutton", - # "jupyterlite_sphinx", "sphinx_favicon", ] From 7aaa4a84e1bbfb2a221ee67bdda0771107d1435f Mon Sep 17 00:00:00 2001 From: Brady Planden Date: Wed, 13 Dec 2023 09:22:52 +0000 Subject: [PATCH 18/22] Updt noxfile for notebooks, optimisation.py change to _optimisation.py, updt .gitignore, trigger deploy on release only --- .github/workflows/deploy-docs.yaml | 1 - .gitignore | 2 +- .../parameters/fit_ecm_parameters.json | 24 ------------------- noxfile.py | 2 +- pybop/__init__.py | 2 +- pybop/{optimisation.py => _optimisation.py} | 0 6 files changed, 3 insertions(+), 28 deletions(-) delete mode 100644 examples/scripts/parameters/fit_ecm_parameters.json rename pybop/{optimisation.py => _optimisation.py} (100%) diff --git a/.github/workflows/deploy-docs.yaml b/.github/workflows/deploy-docs.yaml index 52d5b057..bb64d714 100644 --- a/.github/workflows/deploy-docs.yaml +++ b/.github/workflows/deploy-docs.yaml @@ -4,7 +4,6 @@ on: release: types: [created] workflow_dispatch: - push: permissions: contents: write # allow write access for docs deployment diff --git a/.gitignore b/.gitignore index b6dae2f7..3fae572d 100644 --- a/.gitignore +++ b/.gitignore @@ -306,4 +306,4 @@ $RECYCLE.BIN/ .vscode/* # Output JSON files -*fit_ecm_parameters.json +**/fit_ecm_parameters.json diff --git a/examples/scripts/parameters/fit_ecm_parameters.json b/examples/scripts/parameters/fit_ecm_parameters.json deleted file mode 100644 index 63377470..00000000 --- a/examples/scripts/parameters/fit_ecm_parameters.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "chemistry": "ecm", - "Initial SoC": 0.5, - "Initial temperature [K]": 298.15, - "Cell capacity [A.h]": 5, - "Nominal cell capacity [A.h]": 5, - "Ambient temperature [K]": 298.15, - "Current function [A]": 5, - "Upper voltage cut-off [V]": 4.2, - "Lower voltage cut-off [V]": 3.0, - "Cell thermal mass [J/K]": 1000, - "Cell-jig heat transfer coefficient [W/K]": 10, - "Jig thermal mass [J/K]": 500, - "Jig-air heat transfer coefficient [W/K]": 10, - "Open-circuit voltage [V]": "Unable to write value to JSON file", - "R0 [Ohm]": 0.000944987987318333, - "Element-1 initial overpotential [V]": 0, - "Element-2 initial overpotential [V]": 0, - "R1 [Ohm]": 0.0002590935163068119, - "R2 [Ohm]": 0.0003, - "C1 [F]": 10000, - "C2 [F]": 5000, - "Entropic change [V/K]": 0.0004 -} diff --git a/noxfile.py b/noxfile.py index f21a4f13..ddb7bd19 100644 --- a/noxfile.py +++ b/noxfile.py @@ -29,7 +29,7 @@ def notebooks(session): """Run the examples tests for Jupyter notebooks.""" session.run_always("pip", "install", "-e", ".[all]") session.install("pytest", "nbmake") - session.run("pytest", "--nbmake", "examples/", external=True) + session.run("pytest", "--nbmake", "--examples", "examples/", external=True) @nox.session diff --git a/pybop/__init__.py b/pybop/__init__.py index 045a0fd5..9c9a23e1 100644 --- a/pybop/__init__.py +++ b/pybop/__init__.py @@ -43,7 +43,7 @@ # # Main optimisation class # -from .optimisation import Optimisation +from ._optimisation import Optimisation # # Optimiser class diff --git a/pybop/optimisation.py b/pybop/_optimisation.py similarity index 100% rename from pybop/optimisation.py rename to pybop/_optimisation.py From 6ac18801ef590ccfadf8d2ea0bbf918a13e113bc Mon Sep 17 00:00:00 2001 From: Brady Planden Date: Thu, 14 Dec 2023 10:07:15 +0000 Subject: [PATCH 19/22] Automate version linking --- .gitignore | 3 +++ docs/conf.py | 9 ++++++--- docs/index.md | 2 -- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 3fae572d..bc3caa2c 100644 --- a/.gitignore +++ b/.gitignore @@ -175,6 +175,9 @@ instance/ # Sphinx documentation docs/_build/ +docs/examples/generated/ +docs/api/ +warnings.txt # PyBuilder .pybuilder/ diff --git a/docs/conf.py b/docs/conf.py index c66713fd..9524d11f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -2,16 +2,19 @@ # -- Path setup -------------------------------------------------------------- +import os import sys -from pathlib import Path -sys.path.append(str(Path(".").resolve())) +root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) +sys.path.insert(0, root_path) + +from pybop.version import __version__ # noqa: E402 # -- Project information ----------------------------------------------------- project = "PyBOP" copyright = "2023, The PyBOP Team" author = "The PyBOP Team" -release = "v23.11" +release = f"v{__version__}" # -- General configuration --------------------------------------------------- extensions = [ diff --git a/docs/index.md b/docs/index.md index 622dd79d..d49d0a75 100644 --- a/docs/index.md +++ b/docs/index.md @@ -10,8 +10,6 @@ html_theme.sidebar_secondary.remove: true Welcome to PyBOP, a Python package dedicated to the optimization and parameterization of battery models. PyBOP is designed to streamline your workflow, whether you are conducting academic research, working in industry, or simply interested in battery technology and modelling. -**Version: v23.11** - ```{gallery-grid} :grid-columns: 1 2 2 2 From af10b312936d74101bbdb0b6ff0ff1cd552fb53a Mon Sep 17 00:00:00 2001 From: Brady Planden Date: Thu, 14 Dec 2023 11:44:11 +0000 Subject: [PATCH 20/22] Updt. landing page grid and header names, docstring typos, contributing render method --- CONTRIBUTING.md | 15 ++++++------- docs/Contributing.md | 8 +++++++ docs/contributing.md | 4 ---- docs/index.md | 21 +++++++++--------- docs/{user_guide => }/installation.rst | 6 ++--- .../{user_guide/usage.rst => quick_start.rst} | 6 +++-- docs/user_guide/index.md | 22 ------------------- examples/costs/standalone.py | 2 +- noxfile.py | 2 +- pybop/_optimisation.py | 20 ++++++++--------- pybop/optimisers/nlopt_optimize.py | 4 ++-- pybop/optimisers/pints_optimisers.py | 22 +++++++++---------- pybop/parameters/priors.py | 6 ++--- pybop/plotting/plot_convergence.py | 4 ++-- pybop/plotting/plot_cost2d.py | 4 ++-- 15 files changed, 65 insertions(+), 81 deletions(-) create mode 100644 docs/Contributing.md delete mode 100644 docs/contributing.md rename docs/{user_guide => }/installation.rst (95%) rename docs/{user_guide/usage.rst => quick_start.rst} (87%) delete mode 100644 docs/user_guide/index.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bc98f5ec..055221c9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -# Contributing to PyBOP +# Contributing If you'd like to contribute to PyBOP, please have a look at the guidelines below. @@ -82,7 +82,7 @@ python -m pip install pre-commit pre-commit run ruff ``` -ruff is configured inside the file `pre-commit-config.yaml`, allowing us to ignore some errors. If you think this should be added or removed, please submit an [issue](#issues) +ruff is configured inside the file `pre-commit-config.yaml`, allowing us to ignore some errors. If you think this should be added or removed, please submit an [issue](https://guides.github.com/features/issues/). When you commit your changes they will be checked against ruff automatically (see [Pre-commit checks](#pre-commit-checks)). @@ -293,7 +293,7 @@ Configuration files: setup.py ``` -Note that this file must be kept in sync with the version number in [pybop/**init**.py](pybop/__init__.py). +Note that this file must be kept in sync with the version number in [pybop/**init**.py](https://github.com/pybop-team/PyBOP/blob/develop/pybop/__init__.py). ### Continuous Integration using GitHub actions @@ -316,11 +316,10 @@ Code coverage (how much of our code is seen by the (Linux) unit tests) is tested GitHub does some magic with particular filenames. In particular: -- The first page people see when they go to [our GitHub page](https://github.com/pybop-team/PyBOP) displays the contents of [README.md](README.md), which is written in the [Markdown](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) format. Some guidelines can be found [here](https://help.github.com/articles/about-readmes/). -- The license for using PyBOP is stored in [LICENSE](LICENSE.txt), and [automatically](https://help.github.com/articles/adding-a-license-to-a-repository/) linked to by GitHub. -- This file, [CONTRIBUTING.md](CONTRIBUTING.md) is recognised as the contribution guidelines and a link is [automatically](https://github.com/blog/1184-contributing-guidelines) displayed when new issues or pull requests are created. +- The first page people see when they go to [our GitHub page](https://github.com/pybop-team/PyBOP) displays the contents of [README.md](https://github.com/pybop-team/PyBOP/blob/develop/README.md), which is written in the [Markdown](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) format. Some guidelines can be found [here](https://help.github.com/articles/about-readmes/). +- The license for using PyBOP is stored in [LICENSE](https://github.com/pybop-team/PyBOP/blob/develop/LICENSE), and [automatically](https://help.github.com/articles/adding-a-license-to-a-repository/) linked to by GitHub. +- This file, [CONTRIBUTING.md](https://github.com/pybop-team/PyBOP/blob/develop/CONTRIBUTING.md) is recognised as the contribution guidelines and a link is [automatically](https://github.com/blog/1184-contributing-guidelines) displayed when new issues or pull requests are created. ## Acknowledgements -This CONTRIBUTING.md file, along with large sections of the code infrastructure, -was copied from the excellent [Pints repo](https://github.com/pints-team/pints), and [PyBaMM repo](https://github.com/pybamm-team/PyBaMM) +This CONTRIBUTING.md file, along with large sections of the code infrastructure, was copied from the excellent [Pints repo](https://github.com/pints-team/pints), and [PyBaMM repo](https://github.com/pybamm-team/PyBaMM) diff --git a/docs/Contributing.md b/docs/Contributing.md new file mode 100644 index 00000000..ab90a2bb --- /dev/null +++ b/docs/Contributing.md @@ -0,0 +1,8 @@ +--- +myst: + html_meta: + "description lang=en": | + Contributing docs.. +--- + +```{include} ../CONTRIBUTING.md diff --git a/docs/contributing.md b/docs/contributing.md deleted file mode 100644 index a7ea4b6f..00000000 --- a/docs/contributing.md +++ /dev/null @@ -1,4 +0,0 @@ -(contributing-guide) = - -```{include} ../CONTRIBUTING.md -``` diff --git a/docs/index.md b/docs/index.md index d49d0a75..d45182ae 100644 --- a/docs/index.md +++ b/docs/index.md @@ -13,24 +13,25 @@ Welcome to PyBOP, a Python package dedicated to the optimization and parameteriz ```{gallery-grid} :grid-columns: 1 2 2 2 -- header: "{fab}`bootstrap;pst-color-primary` API Documentation" - content: "Get detailed information on functions, classes, and modules that allow you to fully leverage the power of PyBOP in your own projects." - link: "api/index.html" - header: "{fas}`bolt;pst-color-primary` Installation" content: "Setting up PyBOP is straightforward. Follow our step-by-step guide to install PyBOP on your system." - link: "user_guide/installation.html" -- header: "{fas}`circle-half-stroke;pst-color-primary` Usage" - content: "Discover how to use PyBOP effectively with our usage examples. From basic tasks to advanced features, learn how to solve real-world problems with PyBOP." - link: "user_guide/index.html" + link: "installation.html" +- header: "{fas}`circle-half-stroke;pst-color-primary` Quick Start" + content: "Discover how to use PyBOP effectively. From basic tasks to advanced features, learn how to solve real-world problems with PyBOP." + link: "quick_start.html" - header: "{fab}`python;pst-color-primary` Contributing" content: "Contribute to the PyBOP project and become a part of our growing community." - link: "contributing.html" + link: "Contributing.html" +- header: "{fab}`bootstrap;pst-color-primary` API Reference" + content: "Get detailed information on functions, classes, and modules that allow you to fully leverage the power of PyBOP in your own projects." + link: "api/index.html" ``` ```{toctree} :maxdepth: 2 :hidden: -user_guide/index -contributing +installation +quick_start +Contributing ``` diff --git a/docs/user_guide/installation.rst b/docs/installation.rst similarity index 95% rename from docs/user_guide/installation.rst rename to docs/installation.rst index 08f7ea00..8fa9cdd1 100644 --- a/docs/user_guide/installation.rst +++ b/docs/installation.rst @@ -1,6 +1,6 @@ .. _installation: -Installation Guide for PyBOP +Installation ***************************** PyBOP is a versatile Python package designed for optimization and parameterization of battery models. Follow the instructions below to install PyBOP and set up your environment to begin utilizing its capabilities. @@ -52,7 +52,7 @@ For Developers If you are installing PyBOP for development purposes, such as contributing to the project, please ensure that you follow the guidelines outlined in the contributing guide. It includes additional steps that might be necessary for setting up a development environment, including the installation of dependencies and setup of pre-commit hooks. -`Contributing Guide <../contributing.html>`_ +`Contributing Guide <../Contributing.html>`_ Further Assistance ------------------ @@ -64,5 +64,5 @@ Next Steps After installing PyBOP, you might want to: -* Explore the `Quick Start Guide `_ to begin using PyBOP. +* Explore the `Quick Start Guide `_ to begin using PyBOP. * Check out the `API Reference <../api/index.html>`_ for detailed information on PyBOP's programming interface. diff --git a/docs/user_guide/usage.rst b/docs/quick_start.rst similarity index 87% rename from docs/user_guide/usage.rst rename to docs/quick_start.rst index 14c7f678..e8ebbc0c 100644 --- a/docs/user_guide/usage.rst +++ b/docs/quick_start.rst @@ -1,4 +1,4 @@ -Quick Start Guide for PyBOP +Quick Start **************************** Welcome to the Quick Start Guide for PyBOP. This guide will help you get up and running with PyBOP. If you're new to PyBOP, we recommend you start here to learn the basics and get a feel for the package. @@ -53,4 +53,6 @@ Support and Contributions If you encounter any issues or have questions as you start using PyBOP, don't hesitate to reach out to our community: -- **Contributions**: Interested in contributing to PyBOP? Check out our [contributing-guide](contributing-guide) for guidelines on how to contribute. +- **GitHub Issues**: Report bugs or request new features by opening an `Issue `_ +- **GitHub Discussions**: Post your questions or feedback on our `GitHub Discussions `_ +- **Contributions**: Interested in contributing to PyBOP? Check out our `Contributing Guide <../Contributing.html>`_ for guidelines. diff --git a/docs/user_guide/index.md b/docs/user_guide/index.md deleted file mode 100644 index 0a5496f4..00000000 --- a/docs/user_guide/index.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -myst: - html_meta: - "description lang=en": | - Documentation for PyBOP users. ---- - -# User Guide - -```{toctree} -:caption: Installation - -installation - -``` - -```{toctree} -:caption: Usage - -usage - -``` diff --git a/examples/costs/standalone.py b/examples/costs/standalone.py index f4fa74f9..9836a7e7 100644 --- a/examples/costs/standalone.py +++ b/examples/costs/standalone.py @@ -6,7 +6,7 @@ class StandaloneCost(pybop.BaseCost): """ A standalone cost function example that inherits from pybop.BaseCost. - This class represents a simple cost function without a problem obkect, used for demonstration purposes. + This class represents a simple cost function without a problem object, used for demonstration purposes. It is a quadratic function of one variable with a constant term, defined by the formula: cost(x) = x^2 + 42. diff --git a/noxfile.py b/noxfile.py index ddb7bd19..9ab8a051 100644 --- a/noxfile.py +++ b/noxfile.py @@ -1,7 +1,7 @@ import nox # nox options -nox.options.reuse_existing_virtualenvs = True +nox.options.reuse_existing_virtualenvs = False @nox.session diff --git a/pybop/_optimisation.py b/pybop/_optimisation.py index d18c6a43..8052298d 100644 --- a/pybop/_optimisation.py +++ b/pybop/_optimisation.py @@ -5,16 +5,16 @@ class Optimisation: """ - A class for conducting optimization using PyBOP or PINTS optimizers. + A class for conducting optimization using PyBOP or PINTS optimisers. Parameters ---------- - cost : pints.ErrorMeasure or pints.LogPDF - An objective function to be optimized, which can be either a PINTS error measure or log PDF. - optimiser : pints.Optimiser or subclass of pybop.BaseOptimizer, optional - An optimizer from either the PINTS or PyBOP framework to perform the optimization (default: None). + cost : pybop.BaseCost or pints.ErrorMeasure + An objective function to be optimized, which can be either a pybop.Cost or PINTS error measure + optimiser : pybop.Optimiser or subclass of pybop.BaseOptimiser, optional + An optimiser from either the PINTS or PyBOP framework to perform the optimization (default: None). sigma0 : float or sequence, optional - Initial step size or standard deviation for the optimizer (default: None). + Initial step size or standard deviation for the optimiser (default: None). verbose : bool, optional If True, the optimization progress is printed (default: False). @@ -27,7 +27,7 @@ class Optimisation: n_parameters : int Number of parameters in the optimization problem. sigma0 : float or sequence - Initial step size or standard deviation for the optimizer. + Initial step size or standard deviation for the optimiser. log : list Log of the optimization process. """ @@ -146,7 +146,7 @@ def run(self): def _run_pybop(self): """ - Internal method to run the optimization using a PyBOP optimizer. + Internal method to run the optimization using a PyBOP optimiser. Returns ------- @@ -167,7 +167,7 @@ def _run_pybop(self): def _run_pints(self): """ - Internal method to run the optimization using a PINTS optimizer. + Internal method to run the optimization using a PINTS optimiser. Returns ------- @@ -362,7 +362,7 @@ def f_guessed_tracking(self): def set_f_guessed_tracking(self, use_f_guessed=False): """ - Set the method used to track the optimizer progress. + Set the method used to track the optimiser progress. Credit: PINTS Parameters diff --git a/pybop/optimisers/nlopt_optimize.py b/pybop/optimisers/nlopt_optimize.py index ae2235e2..d6b4df2b 100644 --- a/pybop/optimisers/nlopt_optimize.py +++ b/pybop/optimisers/nlopt_optimize.py @@ -83,7 +83,7 @@ def cost_wrapper(x, grad): def needs_sensitivities(self): """ - Indicates if the optimizer requires gradient information for the cost function. + Indicates if the optimiser requires gradient information for the cost function. Returns ------- @@ -94,7 +94,7 @@ def needs_sensitivities(self): def name(self): """ - Returns the name of this optimizer instance. + Returns the name of this optimiser instance. Returns ------- diff --git a/pybop/optimisers/pints_optimisers.py b/pybop/optimisers/pints_optimisers.py index 765b43c9..7b70e97f 100644 --- a/pybop/optimisers/pints_optimisers.py +++ b/pybop/optimisers/pints_optimisers.py @@ -5,8 +5,8 @@ class GradientDescent(pints.GradientDescent): """ Implements a simple gradient descent optimization algorithm. - This class extends the gradient descent optimizer from the PINTS library, designed - to minimize a scalar function of one or more variables. Note that this optimizer + This class extends the gradient descent optimiser from the PINTS library, designed + to minimize a scalar function of one or more variables. Note that this optimiser does not support boundary constraints. Parameters @@ -16,7 +16,7 @@ class GradientDescent(pints.GradientDescent): sigma0 : float, optional Initial step size (default is 0.1). bounds : sequence or ``Bounds``, optional - Ignored by this optimizer, provided for API consistency. + Ignored by this optimiser, provided for API consistency. See Also -------- @@ -35,9 +35,9 @@ class Adam(pints.Adam): """ Implements the Adam optimization algorithm. - This class extends the Adam optimizer from the PINTS library, which combines + This class extends the Adam optimiser from the PINTS library, which combines ideas from RMSProp and Stochastic Gradient Descent with momentum. Note that - this optimizer does not support boundary constraints. + this optimiser does not support boundary constraints. Parameters ---------- @@ -46,7 +46,7 @@ class Adam(pints.Adam): sigma0 : float, optional Initial step size (default is 0.1). bounds : sequence or ``Bounds``, optional - Ignored by this optimizer, provided for API consistency. + Ignored by this optimiser, provided for API consistency. See Also -------- @@ -65,7 +65,7 @@ class IRPropMin(pints.IRPropMin): """ Implements the iRpropMin optimization algorithm. - This class inherits from the PINTS IRPropMin class, which is an optimizer that + This class inherits from the PINTS IRPropMin class, which is an optimiser that uses resilient backpropagation with weight-backtracking. It is designed to handle problems with large plateaus, noisy gradients, and local minima. @@ -97,7 +97,7 @@ class PSO(pints.PSO): """ Implements a particle swarm optimization (PSO) algorithm. - This class extends the PSO optimizer from the PINTS library. PSO is a + This class extends the PSO optimiser from the PINTS library. PSO is a metaheuristic optimization method inspired by the social behavior of birds flocking or fish schooling, suitable for global optimization problems. @@ -129,7 +129,7 @@ class SNES(pints.SNES): """ Implements the stochastic natural evolution strategy (SNES) optimization algorithm. - Inheriting from the PINTS SNES class, this optimizer is an evolutionary algorithm + Inheriting from the PINTS SNES class, this optimiser is an evolutionary algorithm that evolves a probability distribution on the parameter space, guiding the search for the optimum based on the natural gradient of expected fitness. @@ -159,7 +159,7 @@ def __init__(self, x0, sigma0=0.1, bounds=None): class XNES(pints.XNES): """ - Implements the Exponential Natural Evolution Strategy (XNES) optimizer from PINTS. + Implements the Exponential Natural Evolution Strategy (XNES) optimiser from PINTS. XNES is an evolutionary algorithm that samples from a multivariate normal distribution, which is updated iteratively to fit the distribution of successful solutions. @@ -189,7 +189,7 @@ def __init__(self, x0, sigma0=0.1, bounds=None): class CMAES(pints.CMAES): """ - Adapter for the Covariance Matrix Adaptation Evolution Strategy (CMA-ES) optimizer in PINTS. + Adapter for the Covariance Matrix Adaptation Evolution Strategy (CMA-ES) optimiser in PINTS. CMA-ES is an evolutionary algorithm for difficult non-linear non-convex optimization problems. It adapts the covariance matrix of a multivariate normal distribution to capture the shape of the cost landscape. diff --git a/pybop/parameters/priors.py b/pybop/parameters/priors.py index 088e584d..482baff4 100644 --- a/pybop/parameters/priors.py +++ b/pybop/parameters/priors.py @@ -70,7 +70,7 @@ def rvs(self, size): Raises ------ ValueError - If the size parameter is not positive. + If the size parameter is negative. """ if size < 0: raise ValueError("size must be positive") @@ -153,7 +153,7 @@ def rvs(self, size): Raises ------ ValueError - If the size parameter is not positive. + If the size parameter is negative. """ if size < 0: raise ValueError("size must be positive") @@ -235,7 +235,7 @@ def rvs(self, size): Raises ------ ValueError - If the size parameter is not positive. + If the size parameter is negative. """ if size < 0: raise ValueError("size must be positive") diff --git a/pybop/plotting/plot_convergence.py b/pybop/plotting/plot_convergence.py index d1853ab4..81e9ef65 100644 --- a/pybop/plotting/plot_convergence.py +++ b/pybop/plotting/plot_convergence.py @@ -7,7 +7,7 @@ def plot_convergence( """ Plot the convergence of the optimisation algorithm. - Parameters: + Parameters ----------- optim : optimisation object Optimisation object containing the cost function and optimiser. @@ -18,7 +18,7 @@ def plot_convergence( title : str, optional Title of the plot (default is "Convergence"). - Returns: + Returns --------- fig : plotly.graph_objs.Figure The Plotly figure object for the convergence plot. diff --git a/pybop/plotting/plot_cost2d.py b/pybop/plotting/plot_cost2d.py index f8e7b187..ee43d9d0 100644 --- a/pybop/plotting/plot_cost2d.py +++ b/pybop/plotting/plot_cost2d.py @@ -15,7 +15,7 @@ def plot_cost2d(cost, bounds=None, optim=None, steps=10): bounds : numpy.ndarray, optional A 2x2 array specifying the [min, max] bounds for each parameter. If None, uses `get_param_bounds`. optim : object, optional - An optimizer instance which, if provided, overlays its specific trace on the plot. + An optimiser instance which, if provided, overlays its specific trace on the plot. steps : int, optional The number of intervals to divide the parameter space into along each dimension (default is 10). @@ -94,7 +94,7 @@ def create_figure(x, y, z, bounds, params, optim): params : iterable An iterable of parameter objects with 'name' attributes for axis labeling. optim : object - An optimizer instance with 'log' and 'x0' attributes for plotting traces. + An optimiser instance with 'log' and 'x0' attributes for plotting traces. Returns ------- From a51d720791afe31a5e87408000d70661d8d87be0 Mon Sep 17 00:00:00 2001 From: Brady Planden Date: Thu, 14 Dec 2023 12:07:59 +0000 Subject: [PATCH 21/22] Add readthedocs configuration --- pybop/readthedocs.yaml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 pybop/readthedocs.yaml diff --git a/pybop/readthedocs.yaml b/pybop/readthedocs.yaml new file mode 100644 index 00000000..aaeb9cfc --- /dev/null +++ b/pybop/readthedocs.yaml @@ -0,0 +1,20 @@ +version: 2 + +build: + os: ubuntu-20.04 + tools: + python: "3.11" + +# Build documentation in the "docs/" directory with Sphinx +sphinx: + configuration: docs/conf.py + +formats: + - htmlzip + - pdf + - epub + +python: + install: + - method: pip + path: .[docs] From a0d44e55e239a889a529245c831e9536e6bc533f Mon Sep 17 00:00:00 2001 From: Brady Planden Date: Thu, 14 Dec 2023 14:02:17 +0000 Subject: [PATCH 22/22] Add version switcher, updt header location, link rtd versions --- docs/conf.py | 17 +++++++++++++++++ noxfile.py | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 9524d11f..11588cda 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -45,6 +45,10 @@ autoapi_member_order = "groupwise" # -- Options for HTML output ------------------------------------------------- +# Define the json_url for our version switcher. +json_url = "http://pybop-docs.readthedocs.io/en/latest/_static/switcher.json" +version_match = os.environ.get("READTHEDOCS_VERSION") + html_theme = "pydata_sphinx_theme" html_show_sourcelink = False html_title = "PyBOP Documentation" @@ -66,7 +70,20 @@ ], "search_bar_text": "Search the docs...", "show_prev_next": False, + "navbar_align": "content", + "navbar_center": ["navbar-nav", "version-switcher"], + "show_version_warning_banner": True, + "switcher": { + "json_url": json_url, + "version_match": version_match, + }, + "footer_start": ["copyright"], + "footer_center": ["sphinx-version"], } html_static_path = ["_static"] html_js_files = ["custom-icon.js"] + +# -- Language ---------------------------------------------------------------- + +language = "en" diff --git a/noxfile.py b/noxfile.py index 9ab8a051..ddb7bd19 100644 --- a/noxfile.py +++ b/noxfile.py @@ -1,7 +1,7 @@ import nox # nox options -nox.options.reuse_existing_virtualenvs = False +nox.options.reuse_existing_virtualenvs = True @nox.session