Module pyangstrom.fitting_methods.metropolis_hastings
Expand source code
import logging
import abc
import random
import numpy as np
from pyangstrom.fit import (
Unknowns,
EquationPackage,
SignalProperties,
FitterOutput,
)
logger = logging.getLogger('fit')
class MetropolisHastingsEquations(EquationPackage):
@abc.abstractmethod
def propose(self, unknowns: Unknowns) -> Unknowns:
"""Proposes a new set of values for the unknowns based on the previous
set.
"""
...
@abc.abstractmethod
def log_posterior(
self,
unknowns: Unknowns,
observed_properties: SignalProperties,
) -> float:
"""Calculates the probability of the values for the unknowns, given the
experimental signal properties.
"""
...
def fit(
unknowns_guesses: Unknowns,
solution: MetropolisHastingsEquations,
observed_properties: SignalProperties,
target_num_accepted_samples,
) -> FitterOutput:
accepted_samples = []
current_unknowns = unknowns_guesses
current_log_posterior = solution.log_posterior(
current_unknowns,
observed_properties,
)
while len(accepted_samples) >= target_num_accepted_samples:
proposed_unknowns = solution.propose(current_unknowns)
new_log_posterior = solution.log_posterior(
proposed_unknowns,
observed_properties,
)
acceptance_ratio = np.exp(new_log_posterior - current_log_posterior)
if random.uniform(0, 1) <= acceptance_ratio:
accepted_samples.append(proposed_unknowns)
current_unknowns = proposed_unknowns
current_log_posterior = new_log_posterior
return FitterOutput(accepted_samples[-1])
Functions
def fit(unknowns_guesses: dict, solution: MetropolisHastingsEquations, observed_properties: SignalProperties, target_num_accepted_samples) ‑> FitterOutput
-
Expand source code
def fit( unknowns_guesses: Unknowns, solution: MetropolisHastingsEquations, observed_properties: SignalProperties, target_num_accepted_samples, ) -> FitterOutput: accepted_samples = [] current_unknowns = unknowns_guesses current_log_posterior = solution.log_posterior( current_unknowns, observed_properties, ) while len(accepted_samples) >= target_num_accepted_samples: proposed_unknowns = solution.propose(current_unknowns) new_log_posterior = solution.log_posterior( proposed_unknowns, observed_properties, ) acceptance_ratio = np.exp(new_log_posterior - current_log_posterior) if random.uniform(0, 1) <= acceptance_ratio: accepted_samples.append(proposed_unknowns) current_unknowns = proposed_unknowns current_log_posterior = new_log_posterior return FitterOutput(accepted_samples[-1])
Classes
class MetropolisHastingsEquations (margins: Margins, setup: ExperimentalSetup, **kwargs)
-
Declares methods required by the fitting method to calculate heat model properties.
EquationPackages are expected to be initialized with only margins, setup, and any constants relevant to its heat model.
Expand source code
class MetropolisHastingsEquations(EquationPackage): @abc.abstractmethod def propose(self, unknowns: Unknowns) -> Unknowns: """Proposes a new set of values for the unknowns based on the previous set. """ ... @abc.abstractmethod def log_posterior( self, unknowns: Unknowns, observed_properties: SignalProperties, ) -> float: """Calculates the probability of the values for the unknowns, given the experimental signal properties. """ ...
Ancestors
- EquationPackage
- abc.ABC
Subclasses
Methods
def log_posterior(self, unknowns: dict, observed_properties: SignalProperties) ‑> float
-
Calculates the probability of the values for the unknowns, given the experimental signal properties.
Expand source code
@abc.abstractmethod def log_posterior( self, unknowns: Unknowns, observed_properties: SignalProperties, ) -> float: """Calculates the probability of the values for the unknowns, given the experimental signal properties. """ ...
def propose(self, unknowns: dict) ‑> dict
-
Proposes a new set of values for the unknowns based on the previous set.
Expand source code
@abc.abstractmethod def propose(self, unknowns: Unknowns) -> Unknowns: """Proposes a new set of values for the unknowns based on the previous set. """ ...
Inherited members