def weigh_wigner_d(d, w):
    """
    The Wigner-d transform involves a sum where each term is a product of data, d-function, and quadrature weight.
     Since the d-functions and quadrature weights don't depend on the data, we can precompute their product.
    We have a quadrature weight for each value of beta and beta corresponds to the second axis of d,
    so the weights are broadcast over the other axes.

    :param d: a list of samples of the Wigner-d function, as returned by setup_d_transform
    :param w: an array of quadrature weights, as returned by S3.quadrature_weights
    :return: the weighted d function samples, with the same shape as d
    """
    return [d[l] * w[None, :, None] for l in range(len(d))]