def prior_eval(self): """ Returns the prior evaluator class initialized with a set of pre-defined distributions for each parameters. """ parameters, values = zip(*self.parameters.items()) prior_dists = [] for param, val in zip(parameters, values): if param in ["mass1", "mass2"]: dist = distributions.Uniform(**{param: (6, 50)}) elif param in ["inclination", "dec"]: dist = distributions.SinAngle(**{param: None}) elif param in ["polarization", "ra", "coa_phase"]: dist = distributions.Uniform(**{param: (0, 2 * 3.1415)}) elif param in ["distance"]: dist = distributions.UniformRadius(distance=(val - 100, val + 300)) elif param in [ "spin1x", "spin1y", "spin1z", "spin2x", "spin2y", "spin2z" ]: dist = distributions.Uniform(**{param: (-0.1, 0.1)}) elif param in ["tc"]: dist = distributions.Uniform(tc=(val - 0.2, val + 0.2)) else: raise KeyError("Do not recognize parameter %s" % param) prior_dists.append(dist) return distributions.JointDistribution(parameters, *prior_dists)
def test_solid_angle(self): """ The uniform solid angle and uniform sky position distributions are two independent one-dimensional distributions. This tests checks that the two indepdent one-dimensional distributions agree by comparing the `rvs`, `pdf`, and `logpdf` functions' output. """ # set tolerance for comparing PDF and logPDF functions tolerance = 0.01 # set threshold for KL divergence test threshold = 0.1 # number of random draws for KL divergence test n_samples = int(1e6) # create generic angular distributions for test sin_dist = distributions.SinAngle(theta=(0, 1)) cos_dist = distributions.CosAngle(theta=(-0.5, 0.5)) ang_dist = distributions.UniformAngle(theta=(0, 2)) # step size for PDF calculation step = 0.1 # valid range of parameters polar_sin = numpy.arange(0, numpy.pi, step) polar_cos = numpy.arange(-numpy.pi, numpy.pi, step) azimuthal = numpy.arange(0, 2 * numpy.pi, step) # get Cartesian product to explore the two-dimensional space cart_sin = cartesian([polar_sin, azimuthal]) # loop over distributions for dist in self.dists: if dist.name == distributions.UniformSolidAngle.name: polar_vals = polar_sin polar_dist = sin_dist elif dist.name == distributions.UniformSky.name: polar_vals = polar_cos polar_dist = cos_dist else: continue # check PDF equilvalent pdf_1 = numpy.array([ dist.pdf(**{ dist.polar_angle: p, dist.azimuthal_angle: a }) for p, a in cart_sin ]) pdf_2 = numpy.array([ polar_dist.pdf(**{"theta": p}) * ang_dist.pdf(**{"theta": a}) for p, a in cart_sin ]) if not (numpy.all( numpy.nan_to_num(abs(1.0 - pdf_1 / pdf_2)) < tolerance)): raise ValueError("The {} distribution PDF does not match its " "component distriubtions.".format(dist.name)) # check logarithm of PDF equilvalent pdf_1 = numpy.array([ dist.logpdf(**{ dist.polar_angle: p, dist.azimuthal_angle: a }) for p, a in cart_sin ]) pdf_2 = numpy.array([ polar_dist.logpdf(**{"theta": p}) + ang_dist.logpdf(**{"theta": a}) for p, a in cart_sin ]) if not (numpy.all( numpy.nan_to_num(abs(1.0 - pdf_1 / pdf_2)) < tolerance)): raise ValueError("The {} distribution PDF does not match its " "component distriubtions.".format(dist.name)) # check random draws from polar angle equilvalent ang_1 = dist.rvs(n_samples)[dist.polar_angle] ang_2 = polar_dist.rvs(n_samples)["theta"] kl_val = entropy.kl(ang_1, ang_2, bins=polar_vals.size, hist_min=polar_vals.min(), hist_max=polar_vals.max()) if not (kl_val < threshold): raise ValueError("Class {} KL divergence is {} which is " "greater than the threshold for polar angle" "of {}".format(dist.name, kl_val, threshold)) # check random draws from azimuthal angle equilvalent ang_1 = dist.rvs(n_samples)[dist.azimuthal_angle] ang_2 = ang_dist.rvs(n_samples)["theta"] kl_val = entropy.kl(ang_1, ang_2, bins=azimuthal.size, hist_min=azimuthal.min(), hist_max=azimuthal.max()) if not (kl_val < threshold): raise ValueError( "Class {} KL divergence is {} which is " "greater than the threshold for azimuthal angle" "of {}".format(dist.name, kl_val, threshold))