Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
21 changes: 21 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,27 @@ jobs:
- name: Run notebooks with pytest
run: python -m pytest examples

docs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: 'pip'

- name: Install docs dependencies
run: |
python -m pip install --upgrade pip setuptools wheel
python -m pip install -e '.[docs]'

- name: Build HTML docs
run: |
test -L docs/examples || ln -sf ../examples docs/examples
sphinx-build docs docs/_build/html -W --keep-going

build:
runs-on: ubuntu-latest

Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,4 @@
"scipy": ("https://docs.scipy.org/doc/scipy", None),
}

exclude_patterns = ["_build", "**.ipynb_checkpoints", "generated"]
exclude_patterns = ["_build", "**.ipynb_checkpoints"]
10 changes: 3 additions & 7 deletions examples/sampling_algos.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -267,9 +267,7 @@
"cell_type": "markdown",
"id": "de01662a-532d-40ae-b284-232a64e29f82",
"metadata": {},
"source": [
"### Sampling configurations for the model parameters"
]
"source": "## Sampling configurations for the model parameters"
},
{
"cell_type": "code",
Expand Down Expand Up @@ -311,9 +309,7 @@
"cell_type": "markdown",
"id": "f9852933-dad1-484e-89e8-b13e19e8d166",
"metadata": {},
"source": [
"### Sampling configurations for the likelihood parameters"
]
"source": "## Sampling configurations for the likelihood parameters"
},
{
"cell_type": "code",
Expand Down Expand Up @@ -888,4 +884,4 @@
},
"nbformat": 4,
"nbformat_minor": 5
}
}
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
scikit-learn>=1.0.0
numpy<=2.3
numpy>=2.2.6
pandas>=2.2
scipy>=1.15
pint>=0.2
Expand Down
4 changes: 2 additions & 2 deletions src/rxmc/adaptive_metropolis.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def adaptive_metropolis(
accepted = 0

x = x0.copy()
logp = log_posterior(x)
logp = float(np.squeeze(log_posterior(x)))
scale = 2.38**2 / dim

for i in range(start, start + n_steps):
Expand All @@ -95,7 +95,7 @@ def adaptive_metropolis(
chain[i, :] = x
logp_chain[i - start] = logp
continue
logp_new = log_posterior(x_new)
logp_new = float(np.squeeze(log_posterior(x_new)))

log_ratio = min(0, logp_new - logp)
if np.log(rng.random()) < log_ratio:
Expand Down
4 changes: 2 additions & 2 deletions src/rxmc/ias_pn_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ class IsobaricAnalogPNXSModel(PhysicalModel):
Each potential takes in an arbitrary tuple of params, which are
calculated from the model parameters via the `calculate_params` function.

The `calculate_params` function should have the signature:
(ws: jitr.xs.quasielastic_pn.Workspace, *params: tuple) -> tuple
The ``calculate_params`` function should have the signature:
``(ws: jitr.xs.quasielastic_pn.Workspace, *params: tuple) -> tuple``
and return a tuple of five elements, each being a tuple of parameters
to be passed to the corresponding potential function in the order listed above.
"""
Expand Down
2 changes: 1 addition & 1 deletion src/rxmc/ias_pn_observation.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def __init__(
"""
Initialize a Observation instance for the (p,n) IAS reaction.

Parameters:
Parameters
----------
x : np.ndarray
Measured angle grid in degrees.
Expand Down
140 changes: 80 additions & 60 deletions src/rxmc/likelihood_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,23 @@ class LikelihoodModel:
to a PhysicalModel.

The default behavior uses the following covariance matrix:
\[
\Sigma_{ij} = \sigma^2_{i}^{stat} \delta_{ij}
+ \Sigma_{ij}^{sys}
+ \gamma^2 y_m^2(x_i, \alpha)
\]

.. math::

\Sigma_{ij} = \sigma^2_{i}^{stat} \delta_{ij}
+ \Sigma_{ij}^{sys}
+ \gamma^2 y_m^2(x_i, \alpha)

where $sigma^2_{i}^{stat}$ is the statistical variance of the i-th
observation, (`observation.statistical_covariance`) and $\gamma$ is the
fractional uncorrelated error (`self.frac_err`).

Here, $Sigma_{ij}^{sys}$ is the systematic covariance matrix:
\[
\Sigma_{ij}^{sys} = \eta**2 y_m(x_i, \alpha) y_m(x_j, \alpha) + \omega,
\]

.. math::

\Sigma_{ij}^{sys} = \eta**2 y_m(x_i, \alpha) y_m(x_j, \alpha) + \omega,

where $\eta$ is the uncertainty in the overall normalization of the
observation (`observation.y_sys_err_normalization`) and $\omega$ is the
uncertainty in the additive normalization to the observation
Expand Down Expand Up @@ -87,19 +91,23 @@ def covariance(self, observation: Observation, ym: np.ndarray):
override this.

Returns the following covariance matrix:
\[
\Sigma_{ij} = \sigma^2_{i}^{stat} \delta_{ij}
+ \Sigma_{ij}^{sys}
+ \gamma^2 y_m^2(x_i, \alpha)
\]

.. math::

\Sigma_{ij} = \sigma^2_{i}^{stat} \delta_{ij}
+ \Sigma_{ij}^{sys}
+ \gamma^2 y_m^2(x_i, \alpha)

where $sigma^2_{i}^{stat}$ is the statistical variance of the i-th
observation, (`observation.statistical_covariance`) and $\gamma$ is the
fractional uncorrelated error (`self.frac_err`).

Here, $Sigma_{ij}^{sys}$ is the systematic covariance matrix:
\[
\Sigma_{ij}^{sys} = \eta**2 y_m(x_i, \alpha) y_m(x_j, \alpha) + \omega,
\]

.. math::

\Sigma_{ij}^{sys} = \eta**2 y_m(x_i, \alpha) y_m(x_j, \alpha) + \omega,

where $\eta$ is the uncertainty in the overall normalization of the
observation (`observation.y_sys_err_normalization`) and $\omega$ is the
uncertainty in the additive normalization to the observation
Expand Down Expand Up @@ -396,9 +404,9 @@ class UnknownNoiseErrorModel(ParametricLikelihoodModel):
No matter the Observation, the statistical contribution to the covariance
thus always takes the form:

\[
.. math::

\Sigma_{ij}^{stat} = \epsilon^2 \delta_{ij}
\]

where $\epsilon$ is the statistical `noise` parameter.
"""
Expand All @@ -416,18 +424,20 @@ def __init__(self):
def covariance(self, observation: Observation, ym: np.ndarray, log_epsilon: float):
r"""
Returns the following covariance matrix:
\[
\Sigma_{ij} = \sigma^2_{i}^{stat} \delta_{ij}
+ \Sigma_{ij}^{sys}
+ \gamma^2 y_m^2(x_i, \alpha)
\]

.. math::

\Sigma_{ij} = \sigma^2_{i}^{stat} \delta_{ij}
+ \Sigma_{ij}^{sys}
+ \gamma^2 y_m^2(x_i, \alpha)

where sigma^2_{i}^{stat} is the statistical variance of the i-th
observation, which is dependent on the parameter $\epsilon$, which
is the statistical `noise`:

\[
.. math::

\sigma^2_{i}^{stat} = \epsilon^2 \delta_{ij}
\]

(note this class ignores `observation.statistical_covariance`,
replacing it with $\epsilon$).
Expand Down Expand Up @@ -463,9 +473,9 @@ class UnknownNoiseFractionErrorModel(ParametricLikelihoodModel):

This implies the statistical contribution to the covariance takes the form:

\[
.. math::

\Sigma_{ij}^{stat} = \epsilon^2 y(x_i)^2 \delta_{ij}
\]


"""
Expand All @@ -484,18 +494,20 @@ def __init__(self):
def covariance(self, observation: Observation, ym: np.ndarray, log_epsilon: float):
r"""
Returns the following covariance matrix:
\[
\Sigma_{ij} = \sigma^2_{i}^{stat} \delta_{ij}
+ \Sigma_{ij}^{sys}
+ \gamma^2 y_m^2(x_i, \alpha)
\]

.. math::

\Sigma_{ij} = \sigma^2_{i}^{stat} \delta_{ij}
+ \Sigma_{ij}^{sys}
+ \gamma^2 y_m^2(x_i, \alpha)

where sigma^2_{i}^{stat} is the statistical variance of the i-th
observation, which is dependent on the parameter $\epsilon$, which
is the statistical `noise_fraction`:

\[
.. math::

\Sigma_{ij}^{stat} = \epsilon^2 y(x_i)^2 \delta_{ij}
\]

(note this class ignores `observation.statistical_covariance`, substituting it with
the variable `noise_fraction` multiplied by `ym`) and $\gamma$ is the
Expand Down Expand Up @@ -532,9 +544,10 @@ class UnknownNormalizationModel(ParametricLikelihoodModel):
the normalization, as the data are explicitly re-normalized.

This corresponds to a statistical model:
\[
y_i + \epsilon_i = \rho y_m(x_i, \alpha) + \epsilon_i + \dots
\]

.. math::

y_i + \epsilon_i = \rho y_m(x_i, \alpha) + \epsilon_i + \dots

where $\rho$ is a free parameter corresponding to the multiplicative
normalization factor. This corresponds to the Kennedy & O'Hagan
Expand Down Expand Up @@ -564,9 +577,11 @@ def __init__(self):
def covariance(self, observation: Observation, ym: np.ndarray, log_rho: float):
r"""
Returns the statistical covariance matrix:
\[
\Sigma_{ij}^{stat} = \sigma^2_{i}^{stat} \delta_{ij}
\]

.. math::

\Sigma_{ij}^{stat} = \sigma^2_{i}^{stat} \delta_{ij}

where $\sigma^2_{i}^{stat}$ is the statistical variance of the i-th
observation, (`observation.statistical_covariance`).

Expand All @@ -590,7 +605,7 @@ def residual(self, observation: Observation, ym: np.ndarray, log_rho: float):
Returns the residual between the renormalized model prediction ym and
observation.y

Parameters:
Parameters
----------
observation : Observation
The observation object containing the observed data.
Expand Down Expand Up @@ -665,9 +680,9 @@ class UnknownNormalizationErrorModel(ParametricLikelihoodModel):
This implies the systematic normalization contribution to the
covariance takes the form:

\[
\Sigma_{ij}^{sys norm} = \eta**2 y_m(x_i, \alpha) y_m(x_j, \alpha)
\]
.. math::

\Sigma_{ij}^{sys norm} = \eta**2 y_m(x_i, \alpha) y_m(x_j, \alpha)

where $\eta$ is a free parameter.
"""
Expand All @@ -686,19 +701,23 @@ def __init__(self):
def covariance(self, observation: Observation, ym: np.ndarray, log_eta: float):
r"""
Returns the following covariance matrix:
\[
\Sigma_{ij} = \sigma^2_{i}^{stat} \delta_{ij}
+ \Sigma_{ij}^{sys}
+ \gamma^2 y_m^2(x_i, \alpha)
\]

.. math::

\Sigma_{ij} = \sigma^2_{i}^{stat} \delta_{ij}
+ \Sigma_{ij}^{sys}
+ \gamma^2 y_m^2(x_i, \alpha)

where $sigma^2_{i}^{stat}$ is the statistical variance of the i-th
observation, (`observation.statistical_covariance`) and $\gamma$ is the
fractional uncorrelated error (`self.frac_err`).

Here, $Sigma_{ij}^{sys}$ is the systematic covariance matrix:
\[
\Sigma_{ij}^{sys} = \eta**2 y_m(x_i, \alpha) y_m(x_j, \alpha) + \omega,
\]

.. math::

\Sigma_{ij}^{sys} = \eta**2 y_m(x_i, \alpha) y_m(x_j, \alpha) + \omega,

where $\eta$ is the uncertainty in the overall normalization of the
observation (`y_sys_err_normalization` - in this case, this value is a parameter,
and corresponding value in `observation` is ignored) and $\omega$ is
Expand Down Expand Up @@ -737,9 +756,9 @@ class UnknownModelError(ParametricLikelihoodModel):
is a free parameter $\gamma$, such that the covariance due to the
uncorrelated model error takes the form:

\[
.. math::

\Sigma_{ij}^{uncorrelated} = \gamma^2 y_m(x_i, \alpha)^2 \delta_{ij}
\]

where $\gamma$ is a free parameter.

Expand All @@ -750,7 +769,6 @@ def __init__(self, averaging=True):
"""
Initializes the UnknownModelError instance.

Parameters
Parameters
----------
averaging : bool, optional
Expand All @@ -777,11 +795,13 @@ def covariance(
override this.

Returns the following covariance matrix:
\[
\Sigma_{ij} = \sigma^2_{i}^{stat} \delta_{ij}
+ \Sigma_{ij}^{sys}
+ \gamma^2 y_m^2(x_i, \alpha)
\]

.. math::

\Sigma_{ij} = \sigma^2_{i}^{stat} \delta_{ij}
+ \Sigma_{ij}^{sys}
+ \gamma^2 y_m^2(x_i, \alpha)

where $\gamma$ is the fractional uncorrelated error
(`frac_err`), treated here as a free parameter, and
all other definitions are the same as `LikelihoodModel.covariance`
Expand Down
4 changes: 2 additions & 2 deletions src/rxmc/metropolis_hastings.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def metropolis_hastings(
"""
chain = np.zeros((n_steps, x0.size))
logp_chain = np.zeros((n_steps,))
logp = log_posterior(x0)
logp = float(np.squeeze(log_posterior(x0)))
accepted = 0
x = x0
for i in range(n_steps):
Expand All @@ -59,7 +59,7 @@ def metropolis_hastings(
chain[i, ...] = x
logp_chain[i] = logp
continue
logp_new = log_posterior(x_new)
logp_new = float(np.squeeze(log_posterior(x_new)))
log_ratio = min(0, logp_new - logp)
xi = np.log(rng.random())
if xi < log_ratio:
Expand Down
Loading
Loading