Skip to content

Commit e68c422

Browse files
committed
Add x0 functionality to mcmc sampling.
1 parent 08d9b25 commit e68c422

2 files changed

Lines changed: 31 additions & 5 deletions

File tree

kinisi/fitting.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -201,17 +201,23 @@ def max_aposteriori(self) -> None:
201201
for i, name in enumerate(self.parameter_names):
202202
self.data_group[name] = result[i] * self.parameter_units[i]
203203

204-
def mcmc(self, n_samples: int = 1000, n_walkers: int = 32, n_burn: int = 500, n_thin=10) -> None:
204+
def mcmc(self, x0: tuple[sc.Variable] = None, n_samples: int = 1000, n_walkers: int = 32, n_burn: int = 500, n_thin=10) -> None:
205205
"""
206206
Perform MCMC sampling of the model parameters.
207207
208-
:param n_samples: Number of samples to generate
209-
:param n_walkers: Number of MCMC walkers
210-
:param n_burn: Number of burn-in samples
211-
:param n_thin: Thinning factor
208+
:param x0: Initial starting position for MCMC sampling. Optional, defaults to max likelihood/aposteriori or mean of samples.
209+
:param n_samples: Number of samples to generate. Optional, defaults to 1000.
210+
:param n_walkers: Number of MCMC walkers. Optional, defaults to 32.
211+
:param n_burn: Number of burn-in samples. Optional, defaults to 500.
212+
:param n_thin: Thinning factor. Optional, defaults to 10.
212213
"""
213214
if isinstance(self.data_group[self.parameter_names[0]], Samples):
214215
values = np.array([sc.mean(self.data_group[p]).value for p in self.parameter_names])
216+
elif x0 is not None:
217+
for i, x in enumerate(x0):
218+
if self.data_group[self.parameter_names[i]].unit != x.unit:
219+
raise TypeError("x0 input must have same unit as paramters")
220+
values = np.array([x.value for x in x0])
215221
else:
216222
values = np.array([self.data_group[p].value for p in self.parameter_names])
217223
pos = values + values * 1e-2 * np.random.randn(n_walkers, len(self.parameter_names))

kinisi/tests/test_fitting.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
# pylint: disable=R0201
1010

1111
import unittest
12+
import pytest
1213

1314
import numpy as np
1415
import scipp as sc
@@ -142,6 +143,25 @@ def test_mcmc(self):
142143
assert isinstance(td.data_group['c'], Samples)
143144
assert td.data_group['m'].shape == (32,)
144145
assert td.data_group['c'].shape == (32,)
146+
147+
def test_mcmc_x0(self):
148+
"""
149+
Test the MCMC sampling function with an x0 value.
150+
"""
151+
td = fitting.FittingBase(data, straight_line, ('m', 'c'), (sc.Unit('m/s'), sc.Unit('m')))
152+
td.mcmc(x0=(1 * sc.Unit('m/s'), 0.5 * sc.Unit('m')), n_samples=10, n_burn=5, n_walkers=32)
153+
assert isinstance(td.data_group['m'], Samples)
154+
assert isinstance(td.data_group['c'], Samples)
155+
assert td.data_group['m'].shape == (32,)
156+
assert td.data_group['c'].shape == (32,)
157+
158+
def test_mcmc_x0_wrong_unit(self):
159+
"""
160+
Test the MCMC sampling function with an x0 value.
161+
"""
162+
td = fitting.FittingBase(data, straight_line, ('m', 'c'), (sc.Unit('m/s'), sc.Unit('m')))
163+
with pytest.raises(TypeError):
164+
td.mcmc(x0=(1 * sc.Unit('m'), 0.5 * sc.Unit('m')), n_samples=10, n_burn=5, n_walkers=32)
145165

146166
def test_nested_sampling(self):
147167
"""

0 commit comments

Comments
 (0)