mbank.metric

This module implements the metric computation for cbc signals. It provides a class cbc_metric that, besides the metric computations, offers some functions to compute waveforms and the match between them.

The metric is a D dimensional square matrix that approximates the match between two waveforms. The metric M is defined such that:

\[<h(\theta) | h(\theta + \Delta\theta) > = 1 - M(\theta)_{ij} \Delta\theta_i \Delta\theta_j\]

The metric is a useful local approximation of the match and it is the physical input for the bank generation. The explicit expression for the metric is a complicated expression of the gradients of the waveform and it is a function of theta.

class cbc_metric(variable_format, PSD, approx, f_min=10.0, f_max=None)[source]

This class implements the metric on the space, defined for each point of the space. The metric corresponds to the hessian of the match function, when evaluated around a point. Besides the metric computation, this class allows for waveform (WF) generation and for match computation, both with and without metric.

Initialize the class.

Parameters:
  • variable_format (str) – How to handle the variables. Different options are possible and which option is set, will decide the dimensionality D of the parameter space (hence of the input). Variable format can be changed with set_variable_format() and can be accessed under name cbc_metric.variable_format. See mbank.handlers.variable_handler for more details.

  • PSD (tuple) – PSD for computing the scalar product. It is a tuple with a frequency grid array and a PSD array (both one dimensional and with the same size). PSD should be stored in an array which stores its value on a grid of evenly spaced positive frequencies (starting from f0 =0 Hz).

  • approx (str) – Which approximant to use. It can be any lal approx. The approximant can be changed with set_approximant() and can be accessed under name cbc_metric.approx

  • f_min (float) – Minimum frequency at which the scalar product is computed (and the WF is generated from)

  • f_max (float) – Cutoff for the high frequencies in the PSD. If not None, frequencies up to f_max will be removed from the computation If None, no cutoff is applied

WF_match(signal, template, overlap=False)[source]

Computes the match element by element between a set of signal WFs and template WFs. The WFs shall be evaluated on the custom grid. No checks will be perfomed on the inputs

Parameters:
  • signal (tuple) – ndarray (N,K) - Frequency domain WF for the signal to filter

  • template (tuple) – ndarray (N,K) - Complex frequency domain template to filter the signal with

  • overlap (bool) – Whether to compute the overlap between WFs (rather than the match) In this case, the time maximization is not performed

Returns:

match – Array containing the match of the given WFs

Return type:

ndarray (N,)

WF_symphony_match(signal, template_plus, template_cross, overlap=False)[source]

Computes the match element by element between two set of frequency domain WFs, using the symphony match. The symphony match is defined in eq (13) of 1709.09181 No checks will be perfomed on the inputs

To be computed, the symphony match requires the specification of antenna pattern functions. They are typically a function of sky location and a (conventional) polarization angle.

Parameters:
  • signal (tuple) – ndarray (N,K) - Frequency domain WF for the signal to filter

  • template_plus (tuple) – ndarray (N,K) - Plus polarization of the template to filter the signal with

  • template_cross (tuple) – ndarray (N,K) - Cross polarization of the template to filter the signal with

  • overlap (bool) – Whether to compute the overlap between WFs (rather than the match) In this case, the time maximization is not performed

  • F_p (float) – Value for the \(F_+\) antenna pattern function. Used to build the signal at ifo for the symphony match. See get_antenna_patterns()

  • F_c (float) – Value for the \(F_\times\) antenna pattern function. Used to build the signal at ifo for the symphony match. See get_antenna_patterns()

Returns:

sym_match – shape: (N,) - Array containing the symphony match of the given WFs

Return type:

ndarray

get_WF(theta, approx=None, plus_cross=False)[source]

Computes the WF with a given approximant with parameters theta. The WFs are in FD and are evaluated on the grid on which the PSD is evauated (self.f_grid) An any lal FD approximant.

Parameters:
  • theta (ndarray) – shape: (N,D) - Parameters of the BBHs. The dimensionality depends on self.variable_format

  • approx (str) – Which approximant to use. It can be FD lal approx If None, the default approximant will be used

  • plus_cross (bool) – Whether to return both polarizations. If False, only the plus polarization will be returned

Returns:

h – shape: (N,K) - Complex array holding the WFs evaluated on the default frequency/time grid

Return type:

ndarray

get_WF_grads(theta, approx=None, order=None, epsilon=1e-06, use_cross=False)[source]

Computes the gradient of the WF with a given lal FD approximant. The gradients are computed with finite difference methods.

Parameters:
  • theta (ndarray) – shape: (N,D) - parameters of the BBHs. The dimensionality depends on the variable format set for the metric

  • approx (str) – Which approximant to use. It can be any lal FD approximant If None, the default approximant will be used

  • order (int) – Order of the finite difference scheme for the gradient computation. If None, some defaults values will be set, depending on the total mass.

  • epsilon (list) – Size of the jump for the finite difference scheme for each dimension. If a float, the same jump will be used for all dimensions

  • use_cross (bool) – Whether to compute the gradients of the cross polarization, instead of the plus polarization.

Returns:

grad_h – shape: (N, K, D) - Complex array holding the gradient of the WFs evaluated on the default frequency/time grid

Return type:

ndarray

get_WF_lal(theta, approx=None, df=None)[source]

Returns the lal WF with a given approximant with parameters theta. The WFs are in FD and are evaluated on the grid set by lal

Parameters:
  • theta (ndarray) – shape: (D, ) - Parameters of the BBHs. The dimensionality depends on self.variable_format

  • approx (str) – Which approximant to use. It can be FD lal approx If None, the default approximant will be used

  • df (float) – The frequency step used for the WF generation. If None, the default, given by the PSD will be used

Returns:

hp, hc – shape: (N,K) - lal frequency series holding the polarizations

Return type:

ndarray

get_block_diagonal_hessian(theta, overlap=False, order=None, epsilon=1e-05)[source]

Computes the hessian with a block diagonal method

#WRITEME!!

get_fisher_matrix(theta, overlap=False, order=None, epsilon=0.001)[source]

Returns the Fisher matrix.

M_{ij} = 0.5 <d_i h | d_j h>

`##Check this!`

Parameters:
  • theta (ndarray) – shape: (N,D)/(D,) - Parameters of the BBHs. The dimensionality depends on self.variable_format

  • overlap (bool) – Whether to compute the metric based on the local expansion of the overlap rather than of the match In this context the match is the overlap maximized over time

  • order (int) – Order of the finite difference scheme for the gradient computation. If None, some defaults values will be set, depending on the total mass.

  • epsilon (list) – Size of the jump for the finite difference scheme for each dimension. If a float, the same jump will be used for all dimensions

Returns:

metric – shape: (N,D,D)/(D,D) - Array containing the metric Fisher matrix according to the given parameters

Return type:

ndarray

get_hessian(theta, overlap=False, order=None, epsilon=1e-05, time_comps=False)[source]

Returns the Hessian matrix.

Parameters:
  • theta (ndarray) – shape: (N,D)/(D,) - Parameters of the BBHs. The dimensionality depends on self.variable_format

  • overlap (bool) – Whether to compute the metric based on the local expansion of the overlap rather than of the match In this context the match is the overlap maximized over time

  • order (int) – Order of the finite difference scheme for the gradient computation. If None, some defaults values will be set, depending on the total mass.

  • epsilon (list) – Size of the jump for the finite difference scheme for each dimension. If a float, the same jump will be used for all dimensions

  • time_comps (bool) – Whether to return the time components \(H_{it}, H_{tt}\) of the hessian of the overlap.

Returns:

metric – shape: (N,D,D)/(D,D) - Array containing the metric Hessian in the given parameters

Return type:

ndarray

get_hessian_symphony(theta, overlap=False, order=None, epsilon=1e-06, time_comps=False)[source]

Returns the Hessian matrix of the symphony match.

Parameters:
  • theta (ndarray) – shape: (N,D)/(D,) - Parameters of the BBHs. The dimensionality depends on self.variable_format

  • overlap (bool) – Whether to compute the metric based on the local expansion of the overlap rather than of the match In this context the match is the overlap maximized over time

  • order (int) – Order of the finite difference scheme for the gradient computation. If None, some defaults values will be set, depending on the total mass.

  • epsilon (list) – Size of the jump for the finite difference scheme for each dimension. If a float, the same jump will be used for all dimensions

  • time_comps (bool) – Whether to return the time components \(H_{it}, H_{tt}\) of the hessian of the overlap.

Returns:

metric – shape: (N,D,D)/(D,D) - Array containing the metric Hessian in the given parameters

Return type:

ndarray

get_hpc(theta)[source]

Returns the real part of the overlap between plus and cross polarization:

\[h_{+\times} = \Re \int df \frac{\tilde{h}_+(f) \tilde{h}_\times^*(f)}{S_n(f)}\]

It is a good measurement of the amount of precession/HM present in a signal; for a non-precessing signal: \(h_{+\times} = 0\)

Parameters:

theta (ndarray) – shape: (N,D) - Parameters of the BBHs. The dimensionality depends on the variable format set for the metric

Returns:

h_pc – shape: (N,) - Overlap between plus and cross components

Return type:

ndarray

get_metric(theta, overlap=False, metric_type='symphony', **kwargs)[source]

Returns the metric. Depending on metric_type, it uses different approximations. It can accept any argument of the underlying function, specified by metric_type

Parameters:
  • theta (ndarray) – shape: (N,D)/(D,) - Parameters of the BBHs. The dimensionality depends on self.variable_format

  • overlap (bool) – Whether to compute the metric based on the local expansion of the overlap rather than of the match In this context the match is the overlap maximized over time

  • metric_type (str) –

    How to compute the metric. Available options are:
    • hessian: Computes the hessian of the standard match (calls get_hessian())

    • numerical_hessian: computes the numerical hessian with finite difference methods using the standard match (uses package numdifftools and calls get_numerical_hessian())

    • symphony: Computes the hessian of the symphony match (calls get_hessian_symphony())

    • numerical_symphony: computes the numerical hessian with finite difference methods using the symphony match (uses package numdifftools and calls get_numerical_hessian())

    • parabolic_fit_hessian: it updates the eigenvalues of the metric by doing a “parabolic fit” along each eigen-direction (calls get_parabolic_fit_hessian()) - This method experimental and not validated!

    There are a number of other methods but we don’t guarantee on their performance: you shouldn’t use, unless you really know what you’re doing.

Returns:

metric – shape: (N,D,D)/(D,D) - Array containing the metric in the given parameters

Return type:

ndarray

get_metric_determinant(theta, **kwargs)[source]

Returns the metric determinant

Parameters:
  • theta (ndarray) – shape: (N,D) - Parameters of the BBHs. The dimensionality depends on the variable format set for the metric

  • **kwargs – Any argument to pass to get_metric()

Returns:

det – shape: (N,) - Determinant of the metric for the given input

Return type:

ndarray

get_numerical_hessian(theta, overlap=False, symphony=False, epsilon=1e-06, target_match=0.97, antenna_patterns=None)[source]

Returns the Hessian matrix, obtained by finite difference differentiation. Within numerical erorrs, it should reproduce get_hessian() or get_hessian_symphony(), depending on the symphony option. This function is slower and most prone to numerical errors than its counterparts, based on waveform gradients. For this reason it is mostly intended as a check of the recommended function get_hessian() and get_hessian_symphony(). In particular the step size epsilon must be tuned carefully and the results are really sensible on this choice. Uses package numdifftools: it not among the dependencies, so it must be installed separately!

Parameters:
  • theta (ndarray) – shape: (N,D)/(D,) - Parameters of the BBHs. The dimensionality depends on self.variable_format

  • overlap (bool) – Whether to compute the metric based on the local expansion of the overlap rather than of the match In this context the match is the overlap maximized over time

  • symphony (bool) – Whether to compute the metric approximation for the symphony match

  • epsilon (float) – Size of the jump for the finite difference scheme. If None, it will be authomatically computed.

  • target_match (float) – Target match for the authomatic epsilon computation. Only applies is epsilon is None.

  • antenna_patterns (tuple) – Tuple of float/ndarray (\(F_+\), \(F_\times\)) for the two antenna patterns. If given, it is used to build the signal \(s\), starting from \(h(\theta_1)\); if None, \(s = h_+(\theta_\mathrm{template})\). See get_antenna_patterns().

Returns:

metric – shape: (N,D,D)/(D,D) - Array containing the metric Hessian in the given parameters

Return type:

ndarray

get_parabolic_fit_hessian(theta, overlap=False, symphony=False, target_match=0.9, N_epsilon_points=7, log_epsilon_range=(-4, 1), antenna_patterns=None, full_output=False, **kwargs)[source]

Returns the hessian with the adjusted eigenvalues. The eigenvalues are adjusted by fitting a parabola on the match along each direction.

Parameters:
  • theta (ndarray) – shape: (N,D)/(D,) - Parameters of the BBHs. The dimensionality depends on self.variable_format

  • overlap (bool) – Whether to compute the metric based on the local expansion of the overlap rather than of the match In this context the match is the overlap maximized over time

  • symphony (bool) – Whether to compute the metric approximation for the symphony match

  • target_match (float) – Target match for the eigenvalues fixing. Maximum range for the optimization problem

  • N_epsilon_points (int) – Number of points to evaluate the match along each dimension

  • log_epsilon_range (tuple) – Tuple of floats. They represent the range in the log10(epsilon) to explore

  • antenna_patterns (tuple) – Tuple of float/ndarray (\(F_+\), \(F_\times\)) for the two antenna patterns. If given, it is used to build the signal \(s\), starting from \(h(\theta_1)\); if None, \(s = h_+(\theta_\mathrm{template})\). See get_antenna_patterns().

  • full_output (bool) – Whether to return (together with the metric) a list of array, one for each dimension. The arrays have rows (step, match)

Returns:

  • metric (ndarray) – shape: (N,D,D)/(D,D) - Array containing the metric in the given parameters

  • parabolae (list) – List of array being used to compute the eigenvalues along each dimension.

  • original_metric (ndarray) – shape: (N,D,D)/(D,D) - The metric being used to compute the new eigenvalues.

get_points_at_match(N_points, theta, match, metric=None, overlap=False)[source]

Given a central theta point, it computes N_points couples of random points with constant metric match. The metric is evaluated at theta, hence the couple of points returned will be symmetric w.r.t. to theta and their distance from theta will be dist/2.

The match is related to the distance between templates in the metric as:

\[dist = sqrt(1-match)\]

The returned points points1, points2 will be such that

m_obj.metric_match(*m_obj.get_points_at_match(N_points, center, match = match))

is equal to match

Parameters:
  • N_points (int) – Number of random couples to be drawn

  • theta (ndarray) – shape: (D,) - Parameters of the central point. The dimensionality depends on self.variable_format

  • match (float) – Match between the randomly drawn points and the central point theta. The metric distance between such points and the center is d = sqrt(1-M)

  • metric (ndarray) – shape: (D,D) - Metric to use for the match (if None, it will be computed from scratch)

  • overlap (bool) – Whether to compute the overlap between WFs (rather than the match) In this case, the time maximization is not performed

Returns:

  • points1 (ndarray) – shape: (N,D) - N points close to the center. Each will have a constant metric distance from its counterpart in points2

  • points2 (ndarray) – shape: (N,D) - N points close to the center. Each will have a constant metric distance from its counterpart in points1

get_points_on_ellipse(N_points, theta, match, metric=None, inside=False, overlap=False)[source]

Given a central theta point, it computes N_points random point on the ellipse of constant match center in theta. The points returned will have approximately the the given metric match, although the actual metric match may differ as the metric is evaluated at theta and not at the baricenter of the points in question. If the option inside is set to True, the points will be inside the ellipse, i.e. they will have a metric match larger than the given match.

The match \(\mathcal{M}\) is related to the distance \(d\) between templates in the metric as:

\[d = \sqrt{(1-\mathcal{M})}\]
Parameters:
  • N_points (int) – Number of random points to be drawn

  • theta (ndarray) – shape: (D,) - Parameters of the central point the metric is evaluated at (i.e. the center of the ellipse). The dimensionality depends on the variable format

  • match (float) – Match between the randomly drawn points and the central point theta. The metric distance between such points and the center is d = sqrt(1-M)

  • metric (ndarray) – shape: (D,D) - Metric to use for the match (if None, it will be computed from scratch)

  • overlap (bool) – Whether to compute the overlap between WFs (rather than the match) In this case, the time maximization is not performed

Returns:

points – shape: (N,D) - Points with distance dist from the center

Return type:

ndarray

get_projected_hessian(theta, overlap=False, min_eig=0.001, order=None, epsilon=1e-05)[source]

Returns the projected Hessian matrix. The projections happens on the subspace spanned the eigenvectors with eigenvalues larger than min_eig.

See mbank.utils.get_projected_metric for more information.

The metric obtained with this procedure is a nicer accuracy but it is degenerate (i.e. very close to zero eigenvalues). Moreover, the volume element obtained by the metric is not representative of the actual volume element, since it makes sense in a lower dimensional space.

Parameters:
  • theta (ndarray) – shape: (N,D)/(D,) - Parameters of the BBHs. The dimensionality depends on self.variable_format

  • overlap (bool) – Whether to compute the metric based on the local expansion of the overlap rather than of the match In this context the match is the overlap maximized over time

  • min_eig (float) – Minimum tolerable eigenvalue for metric. The metric will be projected on the directions of smaller eigenvalues

  • order (int) – Order of the finite difference scheme for the gradient computation. If None, some defaults values will be set, depending on the total mass.

  • epsilon (list) – Size of the jump for the finite difference scheme for each dimension. If a float, the same jump will be used for all dimensions

Returns:

metric – shape: (N,D,D)/(D,D) - Array containing the metric Hessian in the given parameters

Return type:

ndarray

get_space_dimension()[source]

Returns the dimensionality D of the metric.

Returns:

D – The dimensionality of the metric

Return type:

float

get_volume_element(theta, **kwargs)[source]

Returns the volume element. It is equivalent to sqrt{|M(theta)|}

Parameters:
  • theta (ndarray) – shape: (N,D) - Parameters of the BBHs. The dimensionality depends on the variable format set for the metric

  • kwargs (bool) – Positional arguments for get_metric

Returns:

vol_element – shape: (N,) - Volume element of the metric for the given input

Return type:

ndarray

log_pdf(theta, boundaries=None, **kwargs)[source]

Returns the logarithm log(pdf) of the probability distribution function we want to sample from: .. math:

pdf = p(theta) ~ sqrt(|M(theta)|)

imposing the boundaries

Parameters:
  • theta (ndarray) – shape: (N,D) - parameters of the BBHs. The dimensionality depends on the variable format set for the metric

  • boundaries (ndarray) – shape: (2,D) An optional array with the boundaries for the model. If a point is asked below the limit, -10000000 is returned Lower limit is boundaries[0,:] while upper limits is boundaries[1,:] If None, no boundaries are implemented

  • **kwargs – Any argument to pass to get_metric()

Returns:

log_pdf – shape: (N,) - Logarithm of the pdf, ready to use for sampling

Return type:

ndarray

match(theta_signal, theta_template, symphony=False, overlap=False, antenna_patterns=None)[source]

Computes the elementwise match between a signal \(s\) and a template \(h\). The template is evaluated at point \(\theta_\mathrm{template}\) of the manifold, whereas the signal \(s\) is evaluated at point \(\theta_\mathrm{signal}\) of the manifold. The signal is constructed as

\[s = F_+ h_+(\theta_\mathrm{signal}) + F_\times h_\times(\theta_\mathrm{signal})\]

where \(F_+, F_\times\) are the antenna pattern functions (see get_antenna_patterns()), provided from the argument antenna_patterns. If the antenna_patterns is None, it is equivalent to \(s = h_+\) (i.e. \(F_+, F_\times = 0, 1\)). This option can be applied only in the case of standard match (symphony==False).

If symphony==False, the match is the standard non-precessing one

\[|<s|h_+>|^2\]

If symphony==True, it returns the symphony match (as in 1709.09181)

\[\frac{(s|h_+)^2+(s|h_\times)^2 - 2 (s|h_+)(s|h_\times)(h_+|h_\times)}{1-(h_+|h_\times)^2}\]

where \((\cdot|\cdot)\) is the real part of the standard complex scalar product \(<\cdot|\cdot>\). In the equations above, \(h_+, h_\times\) always refers to the polarizations of \(h(\theta_\mathrm{template})\).

The computation is done in batches, if the input array are too large to be stored in memory.

Parameters:
  • theta1 (ndarray) – shape: (N,D)/(D,) - Parameters of the first BBHs. The dimensionality depends on the variable format

  • theta2 (ndarray) – shape: (N,D) /(D,) - Parameters of the second BBHs. The dimensionality depends on the variable format

  • symphony (bool) – Whether to compute the symphony match (default False)

  • overlap (bool) – Whether to compute the overlap between WFs (rather than the match) In this case, the time maximization is not performed

  • antenna_patterns (tuple) – Tuple of float/ndarray (\(F_+\), \(F_\times\)) for the two antenna patterns. If given, it is used to build the signal \(s\), starting from \(h(\theta_1)\); if None, \(s = h_+(\theta_\mathrm{template})\). See get_antenna_patterns(). If symphony = True, the antenna patterns cannot be None.

Returns:

match – shape: (N,) - Array containing the match of the given WFs

Return type:

ndarray

metric_match(theta1, theta2, metric=None, overlap=False)[source]

Computes the match element by element between two sets of WFs, defined by theta1 and theta2. The match \(\mathcal{M}\) is approximated by the metric:

\[\mathcal{M}(\theta_1, \theta_2) \simeq 1 - M_{ij}\left(\frac{\theta_1+\theta_2}{2}\right) (\theta_1 - \theta_2)_i (\theta_1 - \theta_2)_j\]
Parameters:
  • theta1 (ndarray) – shape: (N,D) - Parameters of the first BBHs. The dimensionality depends on the variable format

  • theta2 (ndarray) – shape: (N,D) - Parameters of the second BBHs. The dimensionality depends on the variable format

  • metric (ndarray) – shape: (D,D) - metric to use for the match (if None, it will be computed from scratch)

  • overlap (bool) – Whether to compute the overlap between WFs (rather than the match) In this case, the time maximization is not performed

Returns:

match – shape: (N,) - Array containing the metric approximated match of the given WFs

Return type:

ndarray

set_approximant(approx)[source]

Change the lal approximant used to compute the WF

Parameters:

approx (str) – Which approximant to use. It can be any lal FD approximant.

set_variable_format(variable_format)[source]

Set the variable_format to be used. See mbank.handlers.variable_handler for more information.

The following snippet prints the allowed variable formats and to display some information about a given format.

from mbank import handlers
vh = handlers.variable_handler()
print(vh.valid_formats)
print(vh.format_info['Mq_s1xz_s2z_iota'])
Parameters:

variable_format (str) – A string to specify the variable format

sigmasq(template)[source]

Computes the template normalization sigmasq \(\sigma^2 = <h|h>\).

Parameters:

template (ndarray) – shape: (N,K) - First set of WFs

Returns:

sigmasq – Array containing the match of the given WFs

Return type:

ndarray (N,)