Skip to content

Likelihood

jimgw.core.single_event.likelihood ¤

likelihood_presets = {'TransientLikelihoodFD': TransientLikelihoodFD, 'HeterodynedTransientLikelihoodFD': HeterodynedTransientLikelihoodFD} module-attribute ¤

SingleEventLikelihood ¤

Bases: LikelihoodBase

duration: Float property ¤

Duration of the data segment in seconds (taken from the first detector).

detector_names: list[str] property ¤

Names of the detectors used in this likelihood.

detectors: Sequence[Detector] = detectors instance-attribute ¤
waveform: Waveform = waveform instance-attribute ¤
fixed_parameters: dict[str, Float | Callable[[dict[str, Float]], Float | dict[str, Float]]] = fixed_parameters if fixed_parameters is not None else {} instance-attribute ¤
_model: object instance-attribute ¤
_data: object instance-attribute ¤
model: object property ¤

The model used by the likelihood.

data: object property ¤

The data used by the likelihood.

__init__(detectors: Sequence[Detector], waveform: Waveform, fixed_parameters: Optional[dict[str, Float | Callable[[dict[str, Float]], Float | dict[str, Float]]]] = None) -> None ¤

Parameters:

Name Type Description Default
detectors Sequence[Detector]

Detectors with initialized data and PSD.

required
waveform Waveform

Waveform model to evaluate.

required
fixed_parameters Optional[dict]

Parameters held constant during sampling. Values may be scalars or callables f(params) -> Float | dict; callables are applied in insertion order. Defaults to None (no fixed parameters).

None

Raises:

Type Description
ValueError

If any detector has uninitialized data or PSD.

evaluate(params: dict[str, Float], data: dict) -> Float ¤

Apply fixed_parameters overrides and evaluate the likelihood.

Constants are injected directly; callables receive the current params dict and may return a scalar or a dict (the matching key is extracted). Callables are applied in insertion order.

_likelihood(params: dict[str, Float], data: dict) -> Float abstractmethod ¤

Core likelihood evaluation method to be implemented by subclasses.

ZeroLikelihood ¤

Bases: LikelihoodBase

Trivial likelihood that always returns zero.

Useful for prior-only sampling or debugging.

_model: object instance-attribute ¤
_data: object instance-attribute ¤
model: object property ¤

The model used by the likelihood.

data: object property ¤

The data used by the likelihood.

__init__() -> None ¤
evaluate(params: dict[str, Float], data: dict) -> Float ¤

Return zero regardless of the parameters.

Parameters:

Name Type Description Default
params dict[str, Float]

Ignored.

required
data dict

Ignored.

required

Returns:

Name Type Description
Float Float

Always 0.0.

TransientLikelihoodFD ¤

Bases: SingleEventLikelihood

Frequency-domain transient gravitational wave likelihood.

Supports optional analytic marginalization over coalescence time, phase, and/or luminosity distance via boolean flags. All marginalization parameters are explicit __init__ arguments (no **kwargs).

Parameters:

Name Type Description Default
detectors Sequence[Detector]

List of detector objects containing data and metadata.

required
waveform Waveform

Waveform model to evaluate.

required
fixed_parameters Optional[dict[str, Float | Callable[[dict[str, Float]], Float | dict[str, Float]]]]

Parameters held constant during sampling. Values may be constants or callables f(params) -> Float | dict; callables are applied in insertion order. See the likelihood tutorial for details and examples.

None
f_min float | dict[str, float]

Minimum frequency for likelihood evaluation. Can be a single float or a per-detector dictionary.

0.0
f_max float | dict[str, float]

Maximum frequency for likelihood evaluation. Can be a single float or a per-detector dictionary.

inf
trigger_time Float

GPS time of the event trigger.

0
marginalize_time bool

If True, marginalize over coalescence time t_c.

False
marginalize_phase bool

If True, marginalize over coalescence phase phase_c.

False
marginalize_distance bool

If True, marginalize over luminosity distance d_L.

False
tc_range tuple[Float, Float]

Range of coalescence times to marginalize over (only used when marginalize_time=True).

(-0.12, 0.12)
dist_prior Optional[Prior]

1-D prior over d_L (required when marginalize_distance=True).

None
n_dist_points int

Number of grid points for distance quadrature.

10000
ref_dist Optional[float]

Reference distance in Mpc (defaults to midpoint of prior).

None
Example

likelihood = TransientLikelihoodFD( ... detectors, waveform, ... f_min=20, f_max=1024, trigger_time=1234567890, ... marginalize_phase=True, marginalize_time=True, ... ) logL = likelihood.evaluate(params, data)

df = _frequencies[0][1] - _frequencies[0][0] instance-attribute ¤
frequencies = jnp.unique(jnp.concatenate(_frequencies)) instance-attribute ¤
frequency_masks = [(jnp.isin(self.frequencies, detector.sliced_frequencies)) for detector in detectors] instance-attribute ¤
trigger_time = trigger_time instance-attribute ¤
gmst = compute_gmst(self.trigger_time) instance-attribute ¤
marginalize_time = marginalize_time instance-attribute ¤
marginalize_phase = marginalize_phase instance-attribute ¤
marginalize_distance = marginalize_distance instance-attribute ¤
_model: object instance-attribute ¤
_data: object instance-attribute ¤
model: object property ¤

The model used by the likelihood.

data: object property ¤

The data used by the likelihood.

detectors: Sequence[Detector] = detectors instance-attribute ¤
waveform: Waveform = waveform instance-attribute ¤
fixed_parameters: dict[str, Float | Callable[[dict[str, Float]], Float | dict[str, Float]]] = fixed_parameters if fixed_parameters is not None else {} instance-attribute ¤
duration: Float property ¤

Duration of the data segment in seconds (taken from the first detector).

detector_names: list[str] property ¤

Names of the detectors used in this likelihood.

__init__(detectors: Sequence[Detector], waveform: Waveform, fixed_parameters: Optional[dict[str, Float | Callable[[dict[str, Float]], Float | dict[str, Float]]]] = None, f_min: float | dict[str, float] = 0.0, f_max: float | dict[str, float] = jnp.inf, trigger_time: Float = 0, marginalize_time: bool = False, marginalize_phase: bool = False, marginalize_distance: bool = False, tc_range: tuple[Float, Float] = (-0.12, 0.12), dist_prior: Optional[Prior] = None, n_dist_points: int = 10000, ref_dist: Optional[float] = None) -> None ¤
evaluate(params: dict[str, Float], data: dict) -> Float ¤
_likelihood(params: dict[str, Float], data: dict) -> Float ¤
_init_time_marginalization(tc_range: tuple[Float, Float]) -> None ¤
_reduce_time(complex_d_inner_h: Float[Array, ' n_freq']) -> Float ¤

FFT-based time marginalization (real part).

_init_phase_marginalization() -> None ¤
_reduce_phase(complex_d_inner_h: complex, optimal_snr: Float) -> Float ¤

Phase marginalization via modified Bessel function (Thrane & Talbot 2019, Eq. 24).

_init_distance_marginalization(dist_prior: Optional[Prior], n_dist_points: int, ref_dist: Optional[float]) -> None ¤
_reduce_distance(match_filter_snr: Float, optimal_snr: Float) -> Float ¤

Distance marginalization using scaling + logsumexp.

_reduce_phase_time(complex_d_inner_h: Float[Array, ' n_freq']) -> Float ¤

FFT-based time + phase marginalization (Bessel-weighted FFT).

_reduce_phase_distance(complex_d_inner_h: complex, optimal_snr: Float) -> Float ¤

Phase + distance marginalization (Thrane & Talbot 2019, Eq. 79).

HeterodynedTransientLikelihoodFD ¤

Bases: SingleEventLikelihood

Frequency-domain likelihood using the relative-binning (heterodyne) scheme.

Optionally marginalizes over coalescence phase when marginalize_phase=True.

Parameters:

Name Type Description Default
detectors Sequence[Detector]

List of detector objects containing data and metadata.

required
waveform Waveform

Waveform model to evaluate.

required
fixed_parameters Optional[dict[str, Float | Callable[[dict[str, Float]], Float | dict[str, Float]]]]

Dictionary of fixed parameter values. Each value may be a constant Float, a callable returning a scalar, or a callable returning a dict (e.g. transform.backward). See :class:TransientLikelihoodFD for a detailed description and example.

None
f_min float | dict[str, float]

Minimum frequency for likelihood evaluation.

0.0
f_max float | dict[str, float]

Maximum frequency for likelihood evaluation.

inf
trigger_time float

GPS time of the event trigger.

0
n_bins int

Number of frequency bins for relative binning.

100
optimizer_popsize int

Population size for the CMA-ES optimizer used when finding reference parameters automatically. Defaults to 500.

500
optimizer_n_steps int

Maximum number of CMA-ES generations. Defaults to 1000.

1000
reference_parameters Optional[dict]

Pre-computed reference parameters (dict). If supplied, the optimizer is skipped entirely.

None
reference_waveform Optional[Waveform]

Optional :class:~ripplegw.interfaces.Waveform instance used to compute the reference waveform. Defaults to waveform when not provided.

None
prior Optional[Prior]

Prior distribution from which the initial CMA-ES mean is drawn. Required when reference_parameters is not provided.

None
likelihood_transforms Optional[list[NtoMTransform]]

Transforms mapping sampling parameters to likelihood parameters (e.g. mass-ratio → symmetric mass-ratio).

None
marginalize_phase bool

If True, marginalize over coalescence phase.

False
n_bins: int instance-attribute ¤
reference_parameters: dict instance-attribute ¤
df = _frequencies[0][1] - _frequencies[0][0] instance-attribute ¤
frequencies = jnp.unique(jnp.concatenate(_frequencies)) instance-attribute ¤
frequency_masks = [(jnp.isin(self.frequencies, detector.sliced_frequencies)) for detector in detectors] instance-attribute ¤
trigger_time = trigger_time instance-attribute ¤
gmst = compute_gmst(self.trigger_time) instance-attribute ¤
marginalize_phase = marginalize_phase instance-attribute ¤
waveform_low_ref: dict[str, Float[Array, ' n_bin']] = {} instance-attribute ¤
waveform_center_ref: dict[str, Float[Array, ' n_bin']] = {} instance-attribute ¤
A0_array: dict[str, Float[Array, ' n_bin']] = {} instance-attribute ¤
A1_array: dict[str, Float[Array, ' n_bin']] = {} instance-attribute ¤
B0_array: dict[str, Float[Array, ' n_bin']] = {} instance-attribute ¤
B1_array: dict[str, Float[Array, ' n_bin']] = {} instance-attribute ¤
freq_grid_center: Array = self.freq_grid_center[mask_heterodyne_center] instance-attribute ¤
freq_grid_low: Array = self.freq_grid_low[mask_heterodyne_center] instance-attribute ¤
_model: object instance-attribute ¤
_data: object instance-attribute ¤
model: object property ¤

The model used by the likelihood.

data: object property ¤

The data used by the likelihood.

detectors: Sequence[Detector] = detectors instance-attribute ¤
waveform: Waveform = waveform instance-attribute ¤
fixed_parameters: dict[str, Float | Callable[[dict[str, Float]], Float | dict[str, Float]]] = fixed_parameters if fixed_parameters is not None else {} instance-attribute ¤
duration: Float property ¤

Duration of the data segment in seconds (taken from the first detector).

detector_names: list[str] property ¤

Names of the detectors used in this likelihood.

__init__(detectors: Sequence[Detector], waveform: Waveform, fixed_parameters: Optional[dict[str, Float | Callable[[dict[str, Float]], Float | dict[str, Float]]]] = None, f_min: float | dict[str, float] = 0.0, f_max: float | dict[str, float] = jnp.inf, trigger_time: float = 0, n_bins: int = 100, optimizer_popsize: int = 500, optimizer_n_steps: int = 1000, reference_parameters: Optional[dict] = None, reference_waveform: Optional[Waveform] = None, prior: Optional[Prior] = None, likelihood_transforms: Optional[list[NtoMTransform]] = None, marginalize_phase: bool = False) ¤
evaluate(params: dict[str, Float], data: dict) -> Float ¤
_likelihood(params: dict[str, Float], data: dict) -> Float ¤
max_phase_diff(freqs: Float[Array, ' n_freq'], f_low: float, f_high: float, chi: float = 1.0) staticmethod ¤

Compute the maximum phase difference between the frequencies in the array.

See Eq.(7) in arXiv:2302.05333.

make_binning_scheme(freqs: Float[Array, ' n_freq'], n_bins: int, chi: float = 1) -> tuple[Float[Array, ' n_bins + 1'], Float[Array, ' n_bins']] ¤

Make a binning scheme based on the maximum phase difference between the frequencies in the array.

compute_coefficients(data, h_ref, psd, freqs, f_bins, f_bins_center) staticmethod ¤
maximize_likelihood(prior: Prior, likelihood_transforms: list[NtoMTransform], optimizer_popsize: int = 500, optimizer_n_steps: int = 1000) ¤

Find the maximum-likelihood parameters using CMA-ES.

Uses evosax.CMA_ES (Covariance Matrix Adaptation Evolution Strategy) to search the full parameter space. The initial mean is drawn from the prior and the entire ask/tell loop is compiled with jax.lax.scan for speed.

Parameters:

Name Type Description Default
prior Prior

Prior used to seed the initial CMA-ES mean.

required
likelihood_transforms list[NtoMTransform]

Transforms mapping sampling parameters to likelihood parameters.

required
optimizer_popsize int

Population size for CMA-ES. Defaults to 500.

500
optimizer_n_steps int

Number of CMA-ES generations. Defaults to 1000.

1000