The Result class
The Result class stores the output of a Sampler run, namely a collection of samples. It contains several methods for operating on the samples, including for importance sampling, plotting, and density recovery:
See the Result API reference for the full list of methods.
Following a sampler run, a Result can be obtained using Sampler.to_result(). Since Result inherits from DingoDataset it also possesses to_file() and to_dictionary() methods for saving samples and associated metadata (including context data, namely event data and ASDs).
Density recovery
When sampling with GNPE, there is no direct access to the probability density \(q(\theta|d)\). This is because of the Gibbs iterations: one only has access to the probability density of the entire chain, not just the final samples. The probability density is, however, needed for importance sampling, since this is the proposal distribution.
The Result class contains methods to enable recovery of the probability density for a collection of samples. The approach is as follows:
- Start from the samples \(\{(\theta_i, \hat\theta_i)\}_{i=1}^N\) from the final Gibbs iteration, including parameters \(\theta\) and proxy parameters \(\hat\theta\). By default these are included in the
samplesattribute generated by theSampler. - Train an unconditional density estimator \(q(\hat\theta)\) to model the proxy parameters. This is done by (1) using
parameter_subset()to produce a newResultcontaining just the proxies, and (2) usingtrain_unconditional_flow()on this subset. - Generate new samples \((\theta, \hat\theta) \sim q(\theta, \hat\theta | d) = q(\theta | d, \hat\theta) q(\hat\theta)\). This can be accomplished using
GNPESampler.sample()withnum_iterations = 1and setting the initial sampler to be the unconditional flow trained in the previous step. Since this does not involve multiple iterations, the density is obtained as well, so importance sampling can be performed.
Density recovery can also be achieved using an unconditional density estimator for \(\theta\) (trained on samples \(\{\theta_i\}_{i=1}^N\) from GNPE). Since \(\theta\) typically comprises 14 parameters (versus 2 or 3 for \(\hat\theta\)) it is usually more straightforward to learn the proxies.
Synthetic phase
It is often challenging for Dingo to learn to model the phase parameter \(\phi_c\). For this reason, we usually marginalize over it in training by excluding it from the list of inference_parameters. The phase is, however, required for importance sampling unless using also a phase-marginalized likelihood (which is approximate except under special circumstances).
The Dingo gw.Result class includes a method sample_synthetic_phase() which produces a \(\phi_c\) sample from a \(\phi_c\)-marginalized sample. It does so by evaluating the likelihood on a \(\phi_c\)-grid and then sampling from the associated 1D distribution. The log_prob value for the sample is also corrected to reflect the sampled \(\phi_c\). Speed is ensured by caching waveform modes and evaluating the polarizations for different \(\phi_c\). For further details, see the Supplemental Material of (Dax et al. 2022).
This method should be run after recovering the density, since in particular it applies a correction to the density.
Configuration
The method sample_synthetic_phase() takes a kwargs argument. An example configuration is
approximation_22_mode: false
n_grid: 5001
uniform_weight: 0.01
num_processes: 100- approximation_22_mode
- Whether to make the approximation that only the \((l, m) = (2, 2)\) mode is present, i.e., waveforms transform as \(\exp{2\pi i \phi_c}\). This simplifies computations since it does not require caching of waveform modes.
- n_grid
- Specifies the phase grid on which the likelihoods are evaluated.
- uniform_weight
- Base probability level to add to ensure mass coverage.
- num_processes
- For parallelization of synthetic phase sampling. This is usually the most expensive part of importance sampling, so it is advantageous to perform calculations in parallel.
Importance sampling
Once samples are in the right form—including all relevant parameters and the log probability—importance sampling is carried out using the importance_sample() method. It allows to specify options for using a marginalized likelihood. (Time and phase marginalization are separately supported; see the documentation of dingo.gw.likelihood.StationaryGaussianGWLikelihood.)
As with the synthetic phase, importance sampling allows for parallelization.
Plotting
The plotting methods included here are intended for quick plots for evaluating results. They include
- corner plots comparing importance sampled and proposal results;
- weights plots to evaluate performance of importance sampling; and
- log probability plots comparing target and proposal log probability.