Example #1
0
 def test_convolve_normal(self):
     p_1 = NormalDistribution(12.4, 0.346)
     p_2 = NormalDistribution(12.4, 2.463)
     p_x = NormalDistribution(12.3, 2.463)
     from flavio.statistics.probability import convolve_distributions
     # error if not the same central value:
     with self.assertRaises(AssertionError):
         convolve_distributions([p_1, p_x])
     p_comb = convolve_distributions([p_1, p_2])
     self.assertIsInstance(p_comb, NormalDistribution)
     self.assertEqual(p_comb.central_value, 12.4)
     self.assertEqual(p_comb.standard_deviation, sqrt(0.346**2+2.463**2))
 def test_convolve_delta(self):
     p_1 = DeltaDistribution(12.4)
     p_2 = NormalDistribution(12.4, 2.463)
     p_x = DeltaDistribution(12.3)
     from flavio.statistics.probability import convolve_distributions
     with self.assertRaises(NotImplementedError):
         convolve_distributions([p_1, p_x], central_values='sum')
     with self.assertRaises(AssertionError):
         convolve_distributions([p_x, p_2])
     p_comb = convolve_distributions([p_1, p_2])
     self.assertIsInstance(p_comb, NormalDistribution)
     self.assertEqual(p_comb.central_value, 12.4)
     self.assertEqual(p_comb.standard_deviation, 2.463)
Example #3
0
 def test_convolve_delta(self):
     p_1 = DeltaDistribution(12.4)
     p_2 = NormalDistribution(12.4, 2.463)
     p_x = DeltaDistribution(12.3)
     from flavio.statistics.probability import convolve_distributions
     with self.assertRaises(NotImplementedError):
         convolve_distributions([p_1, p_x], central_values='sum')
     with self.assertRaises(AssertionError):
         convolve_distributions([p_x, p_2])
     p_comb = convolve_distributions([p_1, p_2])
     self.assertIsInstance(p_comb, NormalDistribution)
     self.assertEqual(p_comb.central_value, 12.4)
     self.assertEqual(p_comb.standard_deviation, 2.463)
 def test_convolve_normal(self):
     p_1 = NormalDistribution(12.4, 0.346)
     p_2 = NormalDistribution(12.4, 2.463)
     p_x = NormalDistribution(12.3, 2.463)
     from flavio.statistics.probability import convolve_distributions
     # error if not the same central value:
     with self.assertRaises(AssertionError):
         convolve_distributions([p_1, p_x])
     p_comb = convolve_distributions([p_1, p_2])
     self.assertIsInstance(p_comb, NormalDistribution)
     self.assertEqual(p_comb.central_value, 12.4)
     self.assertEqual(p_comb.standard_deviation, sqrt(0.346**2 + 2.463**2))
     # check for addition of central values
     p_comb = convolve_distributions([p_1, p_x], central_values='sum')
     self.assertIsInstance(p_comb, NormalDistribution)
     self.assertAlmostEqual(p_comb.central_value, 24.7)
     self.assertEqual(p_comb.standard_deviation, sqrt(0.346**2 + 2.463**2))
Example #5
0
 def test_convolve_multivariate_gaussian(self):
     from flavio.statistics.probability import _convolve_multivariate_gaussians
     cov1 = np.array([[(0.2e-3)**2, 0.2e-3*0.5*0.3],[0.2e-3*0.5*0.3, 0.5**2]])
     cov2 = np.array([[0.2**2, 0.5*0.2*0.4], [0.5*0.2*0.4, 0.4**2]])
     cov12 = cov1 + cov2
     c1 = [2, 5]
     c2 = [-100, -250]
     p_11 = MultivariateNormalDistribution(c1, cov1)
     p_12 = MultivariateNormalDistribution(c1, cov2)
     p_22 = MultivariateNormalDistribution(c2, cov2)
     conv_11_12 = convolve_distributions([p_11, p_12])
     self.assertIsInstance(conv_11_12, MultivariateNormalDistribution)
     npt.assert_array_equal(conv_11_12.central_value, [2, 5])
     npt.assert_array_almost_equal(conv_11_12.covariance, cov12, decimal=15)
     with self.assertRaises(AssertionError):
         convolve_distributions([p_11, p_22])
     conv_11_22 = convolve_distributions([p_11, p_22], central_values='sum')
     self.assertIsInstance(conv_11_22, MultivariateNormalDistribution)
     npt.assert_array_almost_equal(conv_11_22.covariance, cov12, decimal=15)
     npt.assert_array_equal(conv_11_22.central_value, [-100+2, -250+5])
 def test_convolve_multivariate_gaussian(self):
     from flavio.statistics.probability import _convolve_multivariate_gaussians
     cov1 = np.array([[(0.2e-3)**2, 0.2e-3 * 0.5 * 0.3],
                      [0.2e-3 * 0.5 * 0.3, 0.5**2]])
     cov2 = np.array([[0.2**2, 0.5 * 0.2 * 0.4], [0.5 * 0.2 * 0.4, 0.4**2]])
     cov12 = cov1 + cov2
     c1 = [2, 5]
     c2 = [-100, -250]
     p_11 = MultivariateNormalDistribution(c1, cov1)
     p_12 = MultivariateNormalDistribution(c1, cov2)
     p_22 = MultivariateNormalDistribution(c2, cov2)
     conv_11_12 = convolve_distributions([p_11, p_12])
     self.assertIsInstance(conv_11_12, MultivariateNormalDistribution)
     npt.assert_array_equal(conv_11_12.central_value, [2, 5])
     npt.assert_array_almost_equal(conv_11_12.covariance, cov12, decimal=15)
     with self.assertRaises(AssertionError):
         convolve_distributions([p_11, p_22])
     conv_11_22 = convolve_distributions([p_11, p_22], central_values='sum')
     self.assertIsInstance(conv_11_22, MultivariateNormalDistribution)
     npt.assert_array_almost_equal(conv_11_22.covariance, cov12, decimal=15)
     npt.assert_array_equal(conv_11_22.central_value, [-100 + 2, -250 + 5])
Example #7
0
 def test_convolve_multivariate_gaussian_numerical(self):
     from flavio.statistics.probability import convolve_distributions
     cov1 = [[(0.1)**2, 0.1*0.5*0.3],[0.1*0.5*0.3, 0.5**2]]
     cov2 = [[0.2**2, 0.5*0.2*0.4], [0.5*0.2*0.4, 0.4**2]]
     c1 = [2, 5]
     c2 = [-100, -250]
     p_11 = MultivariateNormalDistribution(c1, cov1)
     p_12 = MultivariateNormalDistribution(c1, cov2)
     p_22 = MultivariateNormalDistribution(c2, cov2)
     n_11 = MultivariateNumericalDistribution.from_pd(p_11)
     n_12 = MultivariateNumericalDistribution.from_pd(p_12)
     n_22 = MultivariateNumericalDistribution.from_pd(p_22)
     conv_11_12_gauss = convolve_distributions([p_11, p_12])
     conv_11_12 = convolve_distributions([p_11, n_12])
     self.assertIsInstance(conv_11_12, MultivariateNumericalDistribution)
     npt.assert_array_almost_equal(conv_11_12.central_value, [2, 5], decimal=1)
     self.assertAlmostEqual(conv_11_12.logpdf([2.2, 4]),
                            conv_11_12_gauss.logpdf([2.2, 4]), delta=0.1)
     self.assertAlmostEqual(conv_11_12.logpdf([2.2, 6]),
                            conv_11_12_gauss.logpdf([2.2, 6]), delta=0.1)
     self.assertAlmostEqual(conv_11_12.logpdf([1.4, 4]),
                            conv_11_12_gauss.logpdf([1.4, 4]), delta=0.2)
     self.assertAlmostEqual(conv_11_12.logpdf([1.4, 6]),
                            conv_11_12_gauss.logpdf([1.4, 6]), delta=0.1)
     with self.assertRaises(AssertionError):
         convolve_distributions([p_11, n_22])
     conv_11_22 = convolve_distributions([p_11, n_22], central_values='sum')
     conv_11_22_gauss = convolve_distributions([p_11, p_22], central_values='sum')
     self.assertIsInstance(conv_11_22, MultivariateNumericalDistribution)
     npt.assert_array_almost_equal(conv_11_22.central_value, [-100+2, -250+5], decimal=1)
     self.assertAlmostEqual(conv_11_22.logpdf([2.2-100, 4-250]),
                            conv_11_22_gauss.logpdf([2.2-100, 4-250]), delta=0.1)
     self.assertAlmostEqual(conv_11_22.logpdf([1.6-100, 5.5-250]),
                            conv_11_22_gauss.logpdf([1.6-100, 5.5-250]), delta=0.1)
 def test_convolve_multivariate_gaussian_numerical(self):
     from flavio.statistics.probability import convolve_distributions
     cov1 = [[(0.1)**2, 0.1 * 0.5 * 0.3], [0.1 * 0.5 * 0.3, 0.5**2]]
     cov2 = [[0.2**2, 0.5 * 0.2 * 0.4], [0.5 * 0.2 * 0.4, 0.4**2]]
     c1 = [2, 5]
     c2 = [-100, -250]
     p_11 = MultivariateNormalDistribution(c1, cov1)
     p_12 = MultivariateNormalDistribution(c1, cov2)
     p_22 = MultivariateNormalDistribution(c2, cov2)
     n_11 = MultivariateNumericalDistribution.from_pd(p_11)
     n_12 = MultivariateNumericalDistribution.from_pd(p_12)
     n_22 = MultivariateNumericalDistribution.from_pd(p_22)
     conv_11_12_gauss = convolve_distributions([p_11, p_12])
     conv_11_12 = convolve_distributions([p_11, n_12])
     self.assertIsInstance(conv_11_12, MultivariateNumericalDistribution)
     npt.assert_array_almost_equal(conv_11_12.central_value, [2, 5],
                                   decimal=1)
     self.assertAlmostEqual(conv_11_12.logpdf([2.2, 4]),
                            conv_11_12_gauss.logpdf([2.2, 4]),
                            delta=0.1)
     self.assertAlmostEqual(conv_11_12.logpdf([2.2, 6]),
                            conv_11_12_gauss.logpdf([2.2, 6]),
                            delta=0.1)
     self.assertAlmostEqual(conv_11_12.logpdf([1.4, 4]),
                            conv_11_12_gauss.logpdf([1.4, 4]),
                            delta=0.2)
     self.assertAlmostEqual(conv_11_12.logpdf([1.4, 6]),
                            conv_11_12_gauss.logpdf([1.4, 6]),
                            delta=0.1)
     with self.assertRaises(AssertionError):
         convolve_distributions([p_11, n_22])
     conv_11_22 = convolve_distributions([p_11, n_22], central_values='sum')
     conv_11_22_gauss = convolve_distributions([p_11, p_22],
                                               central_values='sum')
     self.assertIsInstance(conv_11_22, MultivariateNumericalDistribution)
     npt.assert_array_almost_equal(conv_11_22.central_value,
                                   [-100 + 2, -250 + 5],
                                   decimal=1)
     self.assertAlmostEqual(conv_11_22.logpdf([2.2 - 100, 4 - 250]),
                            conv_11_22_gauss.logpdf([2.2 - 100, 4 - 250]),
                            delta=0.1)
     self.assertAlmostEqual(conv_11_22.logpdf([1.6 - 100, 5.5 - 250]),
                            conv_11_22_gauss.logpdf([1.6 - 100, 5.5 - 250]),
                            delta=0.1)
Example #9
0
def _load(obj):
    """Read measurements from a YAML stream or file."""
    measurements = yaml.load(obj)
    for m_name, m_data in measurements.items():
        m = Measurement(m_name)
        for arg in ['inspire', 'hepdata', 'experiment', 'url']:
            if arg in m_data:
                setattr(m, arg, m_data[arg])
        if 'observables' in m_data:
            # for multivariate constraints
            pd = probability.dict2dist(m_data['values'])
            pd = probability.convolve_distributions(pd)
            # for observables without arguments (i.e. strings), this is trivial;
            obs_list = [
                obs if isinstance(obs, str)
                # for obs. with arguments, need to convert dict of the form
                # {'name': myname, 'arg1': v1, ...} to a tuple of the form
                # (myname, v1, ...)
                else
                tuple([obs['name']] +
                      [obs[arg] for arg in Observable[obs['name']].arguments])
                for obs in m_data['observables']
            ]
            m.add_constraint(obs_list, pd)
        elif 'correlation' not in m_data:
            # for univariate constraints
            if isinstance(m_data['values'], list):
                for value_dict in m_data['values']:
                    args = Observable[value_dict['name']].arguments
                    # numerical values of arguments, e.g. [1, 6]
                    args_num = [value_dict[a] for a in args]
                    # insert string name in front of argument values and turn it
                    # into a tuple, e.g. ('FL(B0->K*mumu)', 1, 6)
                    args_num.insert(0, value_dict['name'])
                    obs_tuple = tuple(args_num)
                    if isinstance(value_dict['value'], dict):
                        m.set_constraint(obs_tuple,
                                         constraint_dict=value_dict['value'])
                    else:
                        m.set_constraint(obs_tuple, value_dict['value'])
            else:  # otherwise, 'values' is a dict just containing name: constraint_string
                for obs, value in m_data['values'].items():
                    if isinstance(value, dict) or isinstance(value, list):
                        m.set_constraint(obs, constraint_dict=value)
                    else:
                        m.set_constraint(obs, value)
        else:
            # for multivariate normal constraints
            observables = []
            central_values = []
            errors = []
            if isinstance(m_data['values'], list):
                for value_dict in m_data['values']:
                    # if "value" is a list, it contains the values of observable
                    # arguments (like q^2)
                    args = Observable[value_dict['name']].arguments
                    args_num = [value_dict[a] for a in args]
                    error_dict = errors_from_string(value_dict['value'])
                    args_num.insert(0, value_dict['name'])
                    obs_tuple = tuple(args_num)
                    observables.append(obs_tuple)
                    central_values.append(error_dict['central_value'])
                    squared_error = 0.
                    for sym_err in error_dict['symmetric_errors']:
                        squared_error += sym_err**2
                    for asym_err in error_dict['asymmetric_errors']:
                        squared_error += asym_err[0] * asym_err[1]
                    errors.append(sqrt(squared_error))
            else:  # otherwise, 'values' is a dict just containing name: constraint_string
                for obs, value in m_data['values'].items():
                    observables.append(obs)
                    error_dict = errors_from_string(value)
                    central_values.append(error_dict['central_value'])
                    squared_error = 0.
                    for sym_err in error_dict['symmetric_errors']:
                        squared_error += sym_err**2
                    for asym_err in error_dict['asymmetric_errors']:
                        squared_error += asym_err[0] * asym_err[1]
                    errors.append(sqrt(squared_error))
            correlation = _fix_correlation_matrix(m_data['correlation'],
                                                  len(observables))
            covariance = np.outer(np.asarray(errors),
                                  np.asarray(errors)) * correlation
            if not np.all(np.linalg.eigvals(covariance) > 0):
                # if the covariance matrix is not positive definite, try a dirty trick:
                # multiply all the correlations by 0.99.
                n_dim = len(correlation)
                correlation = (correlation -
                               np.eye(n_dim)) * 0.99 + np.eye(n_dim)
                covariance = np.outer(np.asarray(errors),
                                      np.asarray(errors)) * correlation
                # if it still isn't positive definite, give up.
                assert np.all(
                    np.linalg.eigvals(covariance) > 0
                ), "The covariance matrix is not positive definite!" + str(
                    covariance)
            m.add_constraint(
                observables,
                probability.MultivariateNormalDistribution(
                    central_values, covariance))
    return list(measurements.keys())
Example #10
0
def _load(obj):
    """Read measurements from a YAML stream or file."""
    measurements = yaml.load(obj)
    for m_name, m_data in measurements.items():
        m = Measurement(m_name)
        for arg in ['inspire', 'hepdata', 'experiment', 'url', 'description']:
            if arg in m_data:
                setattr(m, arg, m_data[arg])
        if 'observables' in m_data:
            # for multivariate constraints
            pd = probability.dict2dist(m_data['values'])
            pd = probability.convolve_distributions(pd)
            # for observables without arguments (i.e. strings), this is trivial;
            obs_list = [obs if isinstance(obs, str)
            # for obs. with arguments, need to convert dict of the form
            # {'name': myname, 'arg1': v1, ...} to a tuple of the form
            # (myname, v1, ...)
                        else tuple(
                                [obs['name']]
                              + [obs[arg] for arg in Observable[obs['name']].arguments])
                        for obs in m_data['observables']]
            m.add_constraint(obs_list, pd)
        elif 'correlation' not in m_data:
            # for univariate constraints
            if isinstance(m_data['values'], list):
                for value_dict in m_data['values']:
                    args = Observable[value_dict['name']].arguments
                    # numerical values of arguments, e.g. [1, 6]
                    args_num = [value_dict[a] for a in args]
                    # insert string name in front of argument values and turn it
                    # into a tuple, e.g. ('FL(B0->K*mumu)', 1, 6)
                    args_num.insert(0, value_dict['name'])
                    obs_tuple = tuple(args_num)
                    if isinstance(value_dict['value'], dict):
                        m.set_constraint(obs_tuple, constraint_dict=value_dict['value'])
                    else:
                        m.set_constraint(obs_tuple, value_dict['value'])
            else: # otherwise, 'values' is a dict just containing name: constraint_string
                for obs, value in m_data['values'].items():
                    if isinstance(value, dict) or isinstance(value, list):
                        m.set_constraint(obs, constraint_dict=value)
                    else:
                        m.set_constraint(obs, value)
        else:
            # for multivariate normal constraints
            observables = []
            central_values = []
            errors = []
            if isinstance(m_data['values'], list):
                for value_dict in m_data['values']:
                    # if "value" is a list, it contains the values of observable
                    # arguments (like q^2)
                    args = Observable[value_dict['name']].arguments
                    args_num = [value_dict[a] for a in args]
                    error_dict = errors_from_string(value_dict['value'])
                    args_num.insert(0, value_dict['name'])
                    obs_tuple = tuple(args_num)
                    observables.append(obs_tuple)
                    central_values.append(error_dict['central_value'])
                    squared_error = 0.
                    for sym_err in error_dict['symmetric_errors']:
                        squared_error += sym_err**2
                    for asym_err in error_dict['asymmetric_errors']:
                        squared_error += asym_err[0]*asym_err[1]
                    errors.append(sqrt(squared_error))
            else: # otherwise, 'values' is a dict just containing name: constraint_string
                for obs, value in m_data['values'].items():
                    observables.append(obs)
                    error_dict = errors_from_string(value)
                    central_values.append(error_dict['central_value'])
                    squared_error = 0.
                    for sym_err in error_dict['symmetric_errors']:
                        squared_error += sym_err**2
                    for asym_err in error_dict['asymmetric_errors']:
                        squared_error += asym_err[0]*asym_err[1]
                    errors.append(sqrt(squared_error))
            correlation = _fix_correlation_matrix(m_data['correlation'], len(observables))
            covariance = np.outer(np.asarray(errors), np.asarray(errors))*correlation
            m.add_constraint(observables, probability.MultivariateNormalDistribution(central_values, covariance))
    return list(measurements.keys())