Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release v24.9.1 #502

Merged
merged 53 commits into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
f9446ed
Thermal parameters removed for non-thermal Thevenin example, example …
Dibyendu-IITKGP Aug 14, 2024
2dcad41
openpyxl package installation command added in notebook file
Dibyendu-IITKGP Aug 15, 2024
75d66b8
Merge branch 'develop' of https://github.com/pybop-team/PyBOP into 43…
Dibyendu-IITKGP Aug 15, 2024
cbce777
style: pre-commit fixes
pre-commit-ci[bot] Aug 15, 2024
0225270
results of notebooks updated
Dibyendu-IITKGP Aug 15, 2024
ec30ff7
Merge branch '437-add-thermal-thevenin-example-remove-params-from-oth…
Dibyendu-IITKGP Aug 15, 2024
cd4404d
pandas upgraded to remove openpyxl error
Dibyendu-IITKGP Aug 15, 2024
34f5520
import openpyxl added
Dibyendu-IITKGP Aug 15, 2024
6f226bd
style: pre-commit fixes
pre-commit-ci[bot] Aug 15, 2024
6a43506
fix: adds `openpyxl` to nox notebooks session
BradyPlanden Aug 19, 2024
ed4f6a0
Adds parameter specific sigma0, moves initial_state to model.build() …
BradyPlanden Aug 27, 2024
266d0a9
Updts to README.md
BradyPlanden Sep 9, 2024
1361e5c
Merge pull request #493 from pybop-team/main
BradyPlanden Sep 11, 2024
12b9883
removes optional [cite] dependency from pybamm
BradyPlanden Sep 11, 2024
c802e6e
fix: reapply transformation for joined parameters in GaussianLogLikel…
BradyPlanden Sep 11, 2024
6a0d838
fix: updates fail_gradient for GaussianLogLikelihood, fixes missed co…
BradyPlanden Sep 12, 2024
4ad8ffe
increment scheduled_tests.yaml to 3AM UTC
BradyPlanden Sep 12, 2024
7d07f4a
Merge pull request #496 from pybop-team/490-shift-scheduled-tests-to-…
BradyPlanden Sep 12, 2024
a3293ed
refactor: adds join_parameters() setter in BaseCost to replace direct…
BradyPlanden Sep 12, 2024
d5c7b3a
Merge pull request #501 from pybop-team/392-add-weppner-huggins-model…
BradyPlanden Sep 12, 2024
0ca7fa6
removes redundant commented-out code.
BradyPlanden Sep 12, 2024
bffce70
Merge branch 'refs/heads/develop' into 492-bug-fix-transformations-fo…
BradyPlanden Sep 12, 2024
7a9b049
Merge branch 'refs/heads/develop' into 437-add-thermal-thevenin-examp…
BradyPlanden Sep 13, 2024
a26d5ea
updt. noxfile.py with ipywidgets, updt. ecm notebook
BradyPlanden Sep 13, 2024
769734e
examples: update ecm hppc notebook.
BradyPlanden Sep 13, 2024
201451e
multipulse notebook example modified to get rid of test error
Dibyendu-IITKGP Sep 13, 2024
32cf455
style: pre-commit fixes
pre-commit-ci[bot] Sep 13, 2024
e978cda
tests: adds test_cost_transformations.py unit tests, adds `BaseCost.b…
BradyPlanden Sep 13, 2024
6569eaa
refactor: cost.parameters as private attribute -> cost._parameters
BradyPlanden Sep 14, 2024
2062c2f
Merge pull request #495 from pybop-team/492-bug-fix-transformations-f…
martinjrobins Sep 14, 2024
dafa3c8
Merge branch 'refs/heads/develop' into release-v24.9.1
BradyPlanden Sep 16, 2024
2adc629
update noxfile.py - remove installation dependencies
BradyPlanden Sep 16, 2024
edaa711
increment versions, add CHANGELOG.md entry for #495
BradyPlanden Sep 16, 2024
261271d
Merge branch 'develop' into 437-add-thermal-thevenin-example-remove-p…
BradyPlanden Sep 16, 2024
f88c5c9
1-single-pulse-circuit-model.ipynb file structure updated
Dibyendu-IITKGP Sep 16, 2024
a6429a3
fix: LogPosterior bugfixes for GaussianLogLikelihood.
BradyPlanden Sep 16, 2024
e256cbe
chore: update pre-commit hooks
pre-commit-ci[bot] Sep 16, 2024
017d926
tests: update posterior construction asserts
BradyPlanden Sep 16, 2024
e8c9fbe
Merge pull request #506 from pybop-team/pre-commit-ci-update-config
BradyPlanden Sep 17, 2024
a9ec9df
add changelog entry
BradyPlanden Sep 17, 2024
6f6a8fc
tests: small bug fix to clip initial parameters in optimisation test.
BradyPlanden Sep 17, 2024
412bc30
drive cycle current changed
Dibyendu-IITKGP Sep 17, 2024
522845c
style: pre-commit fixes
pre-commit-ci[bot] Sep 17, 2024
23b3731
Adds dependencies to nox notebook-overwrite session, overwrite single…
BradyPlanden Sep 17, 2024
ed457ff
examples: update state of thevenin fitting notebooks
BradyPlanden Sep 17, 2024
c8029e8
docs: update README.md [skip ci]
allcontributors[bot] Sep 17, 2024
78a4f47
docs: update .all-contributorsrc [skip ci]
allcontributors[bot] Sep 17, 2024
051e57e
Merge pull request #460 from pybop-team/437-add-thermal-thevenin-exam…
BradyPlanden Sep 17, 2024
dd0b889
Merge branch 'develop' into all-contributors/add-Dibyendu-IITKGP
BradyPlanden Sep 17, 2024
4f926ef
Merge branch 'develop' into bugfixes-for-logposterior-transformations
martinjrobins Sep 17, 2024
782b57f
Merge pull request #507 from pybop-team/all-contributors/add-Dibyendu…
BradyPlanden Sep 17, 2024
764bfb0
Merge pull request #505 from pybop-team/bugfixes-for-logposterior-tra…
BradyPlanden Sep 17, 2024
b8b8f45
Merge branch 'refs/heads/develop' into release-v24.9.1
BradyPlanden Sep 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/scheduled_tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ on:
branches:
- main

# runs every day at 09:00 UTC
# runs every day at 03:00 UTC
schedule:
- cron: '0 9 * * *'
- cron: '0 3 * * *'

# Check noxfile.py for associated environment variables
env:
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@

## Breaking Changes

# [v24.9.1](https://github.com/pybop-team/PyBOP/tree/v24.9.0) - 2024-09-16


## Features

## Bug Fixes

- [#495](https://github.com/pybop-team/PyBOP/pull/495) - Bugfixes for Transformation class, adds `apply_transform` optional arg to `BaseCost` for transformation functionality.

## Breaking Changes

# [v24.9.0](https://github.com/pybop-team/PyBOP/tree/v24.9.0) - 2024-09-10

## Features
Expand Down
2 changes: 1 addition & 1 deletion CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ authors:
family-names: Courtier
- given-names: David
family-names: Howey
version: "24.9.0" # Update this when you release a new version
version: "24.9.1" # Update this when you release a new version
repository-code: 'https://www.github.com/pybop-team/pybop'
60 changes: 35 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
[![Open Issues](https://img.shields.io/github/issues/pybop-team/PyBOP)](https://github.com/pybop-team/PyBOP/issues/)
[![License](https://img.shields.io/github/license/pybop-team/PyBOP?color=blue)](https://github.com/pybop-team/PyBOP/blob/develop/LICENSE)
[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/pybop-team/PyBOP/blob/develop/)
[![nbviewer](https://raw.githubusercontent.com/jupyter/design/master/logos/Badges/nbviewer_badge.svg)](https://nbviewer.org/github/pybop-team/PyBOP/tree/develop/examples/notebooks/)
[![Static Badge](https://img.shields.io/badge/https%3A%2F%2Fpybop-team.github.io%2Fpybop-bench%2F?label=Benchmarks)](https://pybop-team.github.io/pybop-bench/)
[![Releases](https://img.shields.io/github/v/release/pybop-team/PyBOP?color=gold)](https://github.com/pybop-team/PyBOP/releases)

</div>

## PyBOP
PyBOP provides a complete set of tools for parameterisation and optimisation of battery models, using both Bayesian and frequentist approaches, with [example workflows](https://github.com/pybop-team/PyBOP/tree/develop/examples/notebooks) to assist the user. PyBOP can be used to parameterise various battery models, including electrochemical and equivalent circuit models available in [PyBaMM](https://pybamm.org/). PyBOP prioritises clear and informative diagnostics for the user, while also allowing for advanced probabilistic methods.

The diagram below shows the conceptual framework of PyBOP. This package is currently under development, so users can expect the API to evolve with future releases.
Expand Down Expand Up @@ -54,44 +54,50 @@ To check that PyBOP is installed correctly, run one of the examples in the follo
## Using PyBOP
PyBOP has two intended uses:

1. Parameter estimation from battery test data.
1. Parameter inference from battery test data.

2. Design optimisation under battery manufacturing/use constraints.

These include a wide variety of optimisation problems that require careful consideration due to the choice of battery model, data availability and/or the choice of design parameters.

### Notebooks
PyBOP comes with a number of [example notebooks](https://github.com/pybop-team/PyBOP/blob/develop/examples), which can be found in the examples folder. A few noteworthy ones are listed below.
### Jupyter Notebooks

- [Gravimetric design optimisation of a single particle model](https://github.com/pybop-team/PyBOP/blob/develop/examples/notebooks/spm_electrode_design.ipynb)
- [Experimental GITT fitting of an ECM for an LG M50](https://github.com/pybop-team/PyBOP/blob/develop/examples/notebooks/LG_M50_ECM/1-single-pulse-circuit-model.ipynb)
- [Compare PyBOP optimisers for parameter identification](https://github.com/pybop-team/PyBOP/blob/develop/examples/notebooks/multi_optimiser_identification.ipynb)
- [Parameter identification for a spatial pouch cell model](https://github.com/pybop-team/PyBOP/blob/develop/examples/notebooks/pouch_cell_identification.ipynb)
Explore our [example notebooks](https://github.com/pybop-team/PyBOP/blob/develop/examples) for hands-on demonstrations:

### Scripts
Additional script-based examples can be found in the [examples directory](https://github.com/pybop-team/PyBOP/blob/develop/examples/scripts/). Some notable scripts are listed below.
- [Gravimetric design optimisation (SPM)](https://github.com/pybop-team/PyBOP/blob/develop/examples/notebooks/spm_electrode_design.ipynb)
- [GITT fitting of an ECM for an LG M50](https://github.com/pybop-team/PyBOP/blob/develop/examples/notebooks/LG_M50_ECM/1-single-pulse-circuit-model.ipynb)
- [Non-linear constrained ECM parameter identification](https://github.com/pybop-team/PyBOP/blob/develop/examples/notebooks/ecm_trust-constr.ipynb)
- [Optimiser comparison for parameter identification](https://github.com/pybop-team/PyBOP/blob/develop/examples/notebooks/multi_optimiser_identification.ipynb)
- [Parameter identification for spatial pouch cell model](https://github.com/pybop-team/PyBOP/blob/develop/examples/notebooks/pouch_cell_identification.ipynb)

### Python Scripts

Find additional script-based examples in the [examples directory](https://github.com/pybop-team/PyBOP/blob/develop/examples/scripts/):

- [UKF parameter identification (SPM)](https://github.com/pybop-team/PyBOP/blob/develop/examples/scripts/spm_UKF.py)
- [BPX format parameter import/export](https://github.com/pybop-team/PyBOP/blob/develop/examples/scripts/BPX_spm.py)
- [Electrochemical Impendence Spectroscopy (EIS) parameter identification](https://github.com/pybop-team/PyBOP/blob/develop/examples/scripts/eis_fitting.py)
- [Maximum a Posteriori parameter identification (SPM)](https://github.com/pybop-team/PyBOP/blob/develop/examples/scripts/BPX_spm.py)
- [Gradient-based parameter identification (SPM)](https://github.com/pybop-team/PyBOP/blob/develop/examples/scripts/spm_AdamW.py)

- [Unscented Kalman filter parameter identification of a SPM](https://github.com/pybop-team/PyBOP/blob/develop/examples/scripts/spm_UKF.py)
- [Import and export parameters using Faraday's BPX format](https://github.com/pybop-team/PyBOP/blob/develop/examples/scripts/BPX_spm.py)
- [Maximum a posteriori parameter identification of a SPM](https://github.com/pybop-team/PyBOP/blob/develop/examples/scripts/BPX_spm.py)
- [Gradient based parameter identification of a SPM](https://github.com/pybop-team/PyBOP/blob/develop/examples/scripts/spm_AdamW.py)

### Supported Methods
The table below lists the currently supported [models](https://github.com/pybop-team/PyBOP/tree/develop/pybop/models), [optimisers](https://github.com/pybop-team/PyBOP/tree/develop/pybop/optimisers), and [cost functions](https://github.com/pybop-team/PyBOP/tree/develop/pybop/costs) in PyBOP.

<p align="center">

| Battery Models | Optimization Algorithms | Cost Functions |
|-----------------------------------------------|-------------------------------------------------------------|------------------------------------------|
| Single Particle Model (SPM) | Covariance Matrix Adaptation Evolution Strategy (CMA-ES) | Sum of Squared Errors (SSE) <tr></tr> |
| Single Particle Model with Electrolyte (SPMe) | Particle Swarm Optimization (PSO) | Root Mean Squared Error (RMSE) <tr></tr> |
| Doyle-Fuller-Newman (DFN) | Exponential Natural Evolution Strategy (xNES) | Gaussian Log Likelihood <tr></tr> |
| Many Particle Model (MPM) | Separable Natural Evolution Strategy (sNES) | Gaussian Log Likelihood w/ known variance <tr></tr> |
| Multi-Species Multi-Reactants (MSMR) | Adaptive Moment Estimation with Weight Decay (AdamW) | Maximum a Posteriori (MAP) <tr></tr> |
| Equivalent Circuit Models (ECM) | Improved Resilient Backpropagation (iRProp-) | Unscented Kalman Filter (UKF) <tr></tr> |
| | SciPy Minimize & Differential Evolution | Gravimetric Energy Density <tr></tr> |
| | Gradient Descent| Volumetric Energy Density<tr></tr> |
| | Nelder-Mead | <tr></tr> |
| Battery Models | Optimization Algorithms | Cost Functions |
|-----------------------------------------------|----------------------------------------------------------|------------------------------------------|
| Single Particle Model (SPM) | Covariance Matrix Adaptation Evolution Strategy (CMA-ES) | Sum of Squared Errors (SSE) <tr></tr> |
| Single Particle Model with Electrolyte (SPMe) | Particle Swarm Optimization (PSO) | Root Mean Squared Error (RMSE) <tr></tr> |
| Doyle-Fuller-Newman (DFN) | Exponential Natural Evolution Strategy (xNES) | Minkowski <tr></tr> |
| Many Particle Model (MPM) | Separable Natural Evolution Strategy (sNES) | Sum of Power <tr></tr> |
| Multi-Species Multi-Reactants (MSMR) | Adaptive Moment Estimation with Weight Decay (AdamW) | Gaussian Log Likelihood <tr></tr> |
| Weppner-Huggins | Improved Resilient Backpropagation (iRProp-) | Log Posterior <tr></tr> |
| Equivalent Circuit Models (ECM) | SciPy Minimize & Differential Evolution | Unscented Kalman Filter (UKF) <tr></tr> |
| | Cuckoo Search | Gravimetric Energy Density <tr></tr> |
| | Gradient Descent | Volumetric Energy Density<tr></tr> |
| | Nelder-Mead | <tr></tr> |

</p>

Expand All @@ -106,6 +112,10 @@ PyBOP aims to foster a broad consortium of developers and users, building on and

- User-friendliness (putting user requirements first via user-assistance & workflows)

## License

PyBOP is released under the [BSD 3-Clause License](https://github.com/pybop-team/PyBOP/blob/develop/LICENSE).

## Contributors ✨

Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
Expand Down
6 changes: 3 additions & 3 deletions docs/_static/switcher.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
"url": "https://pybop-docs.readthedocs.io/en/latest/"
},
{
"name": "v24.9.0 (stable)",
"version": "v24.9.0",
"url": "https://pybop-docs.readthedocs.io/en/v24.9.0/",
"name": "v24.9 (stable)",
"version": "v24.9",
"url": "https://pybop-docs.readthedocs.io/en/v24.9.1/",
"preferred": true
},
{
Expand Down
6 changes: 3 additions & 3 deletions examples/standalone/cost.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ def __init__(self, problem=None):
"""
super().__init__(problem)

self.parameters = pybop.Parameters(
self._parameters = pybop.Parameters(
pybop.Parameter(
"x",
initial_value=4.2,
bounds=[-1, 10],
),
)
self.x0 = self.parameters.initial_value()
self.x0 = self._parameters.initial_value()

def compute(
self, y: dict = None, dy: np.ndarray = None, calculate_grad: bool = False
Expand All @@ -59,4 +59,4 @@ def compute(
float
The calculated cost value for the given parameter.
"""
return self.parameters["x"].value ** 2 + 42
return self._parameters["x"].value ** 2 + 42
12 changes: 0 additions & 12 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

@nox.session
def unit(session):
session.install("setuptools", "wheel")
session.install("-e", ".[all,dev]", silent=False)
if PYBOP_SCHEDULED:
session.run("pip", "install", f"pybamm=={PYBAMM_VERSION}", silent=False)
Expand All @@ -23,7 +22,6 @@ def unit(session):

@nox.session
def coverage(session):
session.install("setuptools", "wheel")
session.install("-e", ".[all,dev]", silent=False)
session.install("pip")
if PYBOP_SCHEDULED:
Expand All @@ -44,7 +42,6 @@ def coverage(session):
@nox.session
def plots(session):
"""Run the tests that generate plots."""
session.install("setuptools", "wheel")
session.install("-e", ".[plot,dev]", silent=False)
session.install("pip")
session.run("pytest", "--plots", "-n", "0")
Expand All @@ -53,15 +50,13 @@ def plots(session):
@nox.session
def integration(session):
"""Run the integration tests."""
session.install("setuptools", "wheel")
session.install("-e", ".[all,dev]", silent=False)
session.run("pytest", "--integration")


@nox.session
def examples(session):
"""Run the examples and notebooks"""
session.install("setuptools", "wheel")
session.install("-e", ".[all,dev]", silent=False)
session.run("pytest", "--examples")
notebooks(session)
Expand All @@ -70,7 +65,6 @@ def examples(session):
@nox.session
def notebooks(session):
"""Run the Jupyter notebooks."""
session.install("setuptools", "wheel")
session.install("-e", ".[all,dev]", silent=False)
if PYBOP_SCHEDULED:
session.run("pip", "install", f"pybamm=={PYBAMM_VERSION}", silent=False)
Expand All @@ -86,7 +80,6 @@ def notebooks(session):
@nox.session(name="notebooks-overwrite")
def notebooks_overwrite(session):
"""Run the Jupyter notebooks."""
session.install("setuptools", "wheel")
session.install("-e", ".[all,dev]", silent=False)
if PYBOP_SCHEDULED:
session.run("pip", "install", f"pybamm=={PYBAMM_VERSION}", silent=False)
Expand All @@ -103,7 +96,6 @@ def notebooks_overwrite(session):
@nox.session(name="tests")
def run_tests(session):
"""Run all the tests."""
session.install("setuptools", "wheel")
session.install("-e", ".[all,dev]", silent=False)
if PYBOP_SCHEDULED:
session.run("pip", "install", f"pybamm=={PYBAMM_VERSION}", silent=False)
Expand All @@ -118,7 +110,6 @@ def run_doc_tests(session):
Checks if the documentation can be built, runs any doctests (currently not
used).
"""
session.install("setuptools", "wheel")
session.install("-e", ".[plot,docs,dev]", silent=False)
session.run("pytest", "--docs", "-n", "0")

Expand All @@ -130,7 +121,6 @@ def lint(session):

Credit: PyBaMM Team
"""
session.install("setuptools", "wheel")
session.install("pre-commit", silent=False)
session.run("pre-commit", "run", "--all-files")

Expand All @@ -149,7 +139,6 @@ def run_quick(session):
@nox.session
def benchmarks(session):
"""Run the benchmarks."""
session.install("setuptools", "wheel")
session.install("-e", ".[all,dev]", silent=False)
session.install("asv[virtualenv]")
session.run("asv", "run", "--show-stderr", "--python=same")
Expand All @@ -161,7 +150,6 @@ def docs(session):
Build the documentation and load it in a browser tab, rebuilding on changes.
Credit: PyBaMM Team
"""
session.install("setuptools", "wheel")
envbindir = session.bin
session.install("-e", ".[all,docs]", silent=False)
session.chdir("docs")
Expand Down
18 changes: 10 additions & 8 deletions pybop/costs/_likelihoods.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,11 @@ def __init__(
self._dsigma_scale = dsigma_scale
self._logpi = -0.5 * self.n_data * np.log(2 * np.pi)

# Add sigma parameter, join with self.parameters, reapply transformations
self.sigma = Parameters()
self._add_sigma_parameters(sigma0)
self.parameters.join(self.sigma)
self.join_parameters(self.sigma)
self.transformation = self._parameters.construct_transformation()

def _add_sigma_parameters(self, sigma0):
sigma0 = [sigma0] if not isinstance(sigma0, list) else sigma0
Expand Down Expand Up @@ -235,11 +237,11 @@ def __init__(

# Store the likelihood and prior
self._log_likelihood = log_likelihood
self.parameters = self._log_likelihood.parameters
self._parameters = self._log_likelihood.parameters
self._has_separable_problem = self._log_likelihood.has_separable_problem

if log_prior is None:
self._prior = JointLogPrior(*self.parameters.priors())
self._prior = JointLogPrior(*self._parameters.priors())
else:
self._prior = log_prior

Expand Down Expand Up @@ -271,16 +273,16 @@ def compute(

if calculate_grad:
if isinstance(self._prior, BasePrior):
log_prior, dp = self._prior.logpdfS1(self.parameters.current_value())
log_prior, dp = self._prior.logpdfS1(self._parameters.current_value())
else:
# Compute log prior first
log_prior = self._prior.logpdf(self.parameters.current_value())
log_prior = self._prior.logpdf(self._parameters.current_value())

# Compute a finite difference approximation of the gradient of the log prior
delta = self.parameters.initial_value() * self.gradient_step
delta = self._parameters.initial_value() * self.gradient_step
dp = []

for parameter, step_size in zip(self.parameters, delta):
for parameter, step_size in zip(self._parameters, delta):
param_value = parameter.value
upper_value = param_value * (1 + step_size)
lower_value = param_value * (1 - step_size)
Expand All @@ -293,7 +295,7 @@ def compute(
)
dp.append(gradient)
else:
log_prior = self._prior.logpdf(self.parameters.current_value())
log_prior = self._prior.logpdf(self._parameters.current_value())

if not np.isfinite(log_prior).any():
return (-np.inf, -self.grad_fail) if calculate_grad else -np.inf
Expand Down
2 changes: 1 addition & 1 deletion pybop/costs/_weighted_cost.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def __init__(self, *costs, weights: Optional[list[float]] = None):
super().__init__()

for cost in self.costs:
self.parameters.join(cost.parameters)
self.join_parameters(cost.parameters)

# Weighted costs do not use this functionality
self._has_separable_problem = False
Expand Down
25 changes: 19 additions & 6 deletions pybop/costs/base_cost.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class BaseCost:
"""

def __init__(self, problem: Optional[BaseProblem] = None):
self.parameters = Parameters()
self._parameters = Parameters()
self.transformation = None
self.problem = problem
self.verbose = False
Expand All @@ -44,17 +44,17 @@ def __init__(self, problem: Optional[BaseProblem] = None):
self._de = 1.0
if isinstance(self.problem, BaseProblem):
self._target = self.problem.target
self.parameters.join(self.problem.parameters)
self._parameters.join(self.problem.parameters)
self.n_outputs = self.problem.n_outputs
self.signal = self.problem.signal
self.transformation = self.parameters.construct_transformation()
self.transformation = self._parameters.construct_transformation()
self._has_separable_problem = True
self.grad_fail = None
self.set_fail_gradient()

@property
def n_parameters(self):
return len(self.parameters)
return len(self._parameters)

@property
def has_separable_problem(self):
Expand Down Expand Up @@ -95,8 +95,8 @@ def __call__(
self.has_transform = self.transformation is not None and apply_transform
if self.has_transform:
inputs = self.transformation.to_model(inputs)
inputs = self.parameters.verify(inputs)
self.parameters.update(values=list(inputs.values()))
inputs = self._parameters.verify(inputs)
self._parameters.update(values=list(inputs.values()))

y, dy = None, None
if self._has_separable_problem:
Expand Down Expand Up @@ -183,3 +183,16 @@ def verify_args(self, dy: ndarray, calculate_grad: bool):
raise ValueError(
"Forward model sensitivities need to be provided alongside `calculate_grad=True` for `cost.compute`."
)

def join_parameters(self, parameters):
"""
Setter for joining parameters. This method sets the fail gradient if the join adds parameters.
"""
original_n_params = self.n_parameters
self._parameters.join(parameters)
if original_n_params != self.n_parameters:
self.set_fail_gradient()

@property
def parameters(self):
return self._parameters
Loading
Loading