Skip to content
Snippets Groups Projects
Commit 368b3a20 authored by Moritz Huebner's avatar Moritz Huebner
Browse files

Add prior tests

parent b0382bfd
No related branches found
No related tags found
No related merge requests found
......@@ -19,6 +19,7 @@ Changes currently on master, but not under a tag.
- Adds plotting of the prior on 1D marginal distributions of corner plots
- Adds a method to plot time-domain GW data
- Hyperparameter estimation now enables the user to provide the single event evidences
- Prior and child classes now implement the \_\_eq\_\_ magic method for comparisons
### Changes
- Fix construct_cbc_derived_parameters
......@@ -27,6 +28,8 @@ Changes currently on master, but not under a tag.
- PowerSpectralDensity structure modified
- Fixed bug in get_open_data
- .prior files are no longer created. The prior is stored in the result object.
- Changed the way repr works for priors. The repr can now be used to
re-instantiate the Prior in most cases
- Users can now choose to overwrite existing result files, rather than creating
a .old file.
......
......@@ -12,11 +12,9 @@ class TestBBHPriorSet(unittest.TestCase):
self.base_directory =\
'/'.join(os.path.dirname(
os.path.abspath(sys.argv[0])).split('/')[:-1])
self.filename =\
self.base_directory + '/tupak/gw/prior_files/GW150914.prior'
self.filename = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'prior_files/binary_black_holes.prior')
self.default_prior = tupak.gw.prior.BBHPriorSet(
filename=self.base_directory\
+ '/tupak/gw/prior_files/binary_black_holes.prior')
filename=self.filename)
def tearDown(self):
del self.prior_dict
......
mass_1 = Uniform(name='mass_1', minimum=20, maximum=100)
mass_2 = Uniform(name='mass_2', minimum=20, maximum=100)
chirp_mass = Uniform(name='chirp_mass', minimum=25, maximum=100)
total_mass = Uniform(name='total_mass', minimum=10, maximum=200)
mass_ratio = Uniform(name='mass_ratio', minimum=0.125, maximum=1)
symmetric_mass_ratio = Uniform(name='symmetric_mass_ratio', minimum=8 / 81, maximum=0.25)
# These are the default priors we use for BBH systems.
# Note that you may wish to use more specific mass and distance parameters.
# These commands are all known to tupak.gw.prior.
# Lines beginning "#" are ignored.
mass_1 = Uniform(name='mass_1', minimum=5, maximum=100)
mass_2 = Uniform(name='mass_2', minimum=5, maximum=100)
# chirp_mass = Uniform(name='chirp_mass', minimum=25, maximum=100)
# total_mass = Uniform(name='total_mass', minimum=10, maximum=200)
# mass_ratio = Uniform(name='mass_ratio', minimum=0.125, maximum=1)
# symmetric_mass_ratio = Uniform(name='symmetric_mass_ratio', minimum=8 / 81, maximum=0.25)
a_1 = Uniform(name='a_1', minimum=0, maximum=0.8)
a_2 = Uniform(name='a_2', minimum=0, maximum=0.8)
tilt_1 = Sine(name='tilt_1')
tilt_2 = Sine(name='tilt_2')
cos_tilt_1 = Uniform(name='cos_tilt_1', minimum=-1, maximum=1)
cos_tilt_2 = Uniform(name='cos_tilt_2', minimum=-1, maximum=1)
# cos_tilt_1 = Uniform(name='cos_tilt_1', minimum=-1, maximum=1)
# cos_tilt_2 = Uniform(name='cos_tilt_2', minimum=-1, maximum=1)
phi_12 = Uniform(name='phi_12', minimum=0, maximum=2 * np.pi)
phi_jl = Uniform(name='phi_jl', minimum=0, maximum=2 * np.pi)
luminosity_distance = UniformComovingVolume(name='luminosity_distance', minimum=1e2, maximum=5e3)
luminosity_distance = tupak.gw.prior.UniformComovingVolume(name='luminosity_distance', minimum=1e2, maximum=5e3)
dec = Cosine(name='dec')
ra = Uniform(name='ra', minimum=0, maximum=2 * np.pi)
iota = Sine(name='iota')
cos_iota = Uniform(name='cos_iota', minimum=-1, maximum=1)
psi = Uniform(name='psi', minimum=0, maximum=2 * np.pi)
# cos_iota = Uniform(name='cos_iota', minimum=-1, maximum=1)
psi = Uniform(name='psi', minimum=0, maximum=np.pi)
phase = Uniform(name='phase', minimum=0, maximum=2 * np.pi)
......@@ -4,6 +4,8 @@ import unittest
from mock import Mock
import numpy as np
import os
import shutil
from collections import OrderedDict
class TestPriorInstantiationWithoutOptionalPriors(unittest.TestCase):
......@@ -38,6 +40,27 @@ class TestPriorInstantiationWithoutOptionalPriors(unittest.TestCase):
expected_string = "Prior(name='test_name', latex_label='test_label', unit=None, minimum=0, maximum=1)"
self.assertEqual(expected_string, self.prior.__repr__())
def test_base_prob(self):
self.assertTrue(np.isnan(self.prior.prob(5)))
def test_base_ln_prob(self):
self.prior.prob = lambda val: val
self.assertEqual(np.log(5), self.prior.ln_prob(5))
def test_is_in_prior(self):
self.prior.minimum = 0
self.prior.maximum = 1
val_below = self.prior.minimum - 0.1
val_at_minimum = self.prior.minimum
val_in_prior = (self.prior.minimum + self.prior.maximum)/2.
val_at_maximum = self.prior.maximum
val_above = self.prior.maximum + 0.1
self.assertTrue(self.prior.is_in_prior_range(val_at_minimum))
self.assertTrue(self.prior.is_in_prior_range(val_at_maximum))
self.assertTrue(self.prior.is_in_prior_range(val_in_prior))
self.assertFalse(self.prior.is_in_prior_range(val_below))
self.assertFalse(self.prior.is_in_prior_range(val_above))
class TestPriorName(unittest.TestCase):
......@@ -113,7 +136,8 @@ class TestPriorClasses(unittest.TestCase):
tupak.gw.prior.UniformComovingVolume(name='test', minimum=2e2, maximum=5e3),
tupak.core.prior.Sine(name='test', unit='unit'),
tupak.core.prior.Cosine(name='test', unit='unit'),
tupak.core.prior.Interped(name='test', unit='unit', xx=np.linspace(0, 10, 1000), yy=np.linspace(0, 10, 1000) ** 4,
tupak.core.prior.Interped(name='test', unit='unit', xx=np.linspace(0, 10, 1000),
yy=np.linspace(0, 10, 1000) ** 4,
minimum=3, maximum=5),
tupak.core.prior.TruncatedGaussian(name='test', unit='unit', mu=1, sigma=0.4, minimum=-1, maximum=1),
tupak.core.prior.TruncatedNormal(name='test', unit='unit', mu=1, sigma=0.4, minimum=-1, maximum=1),
......@@ -169,9 +193,6 @@ class TestPriorClasses(unittest.TestCase):
def test_probability_above_domain(self):
"""Test that the prior probability is non-negative in domain of validity and zero outside."""
for prior in self.priors:
# skip delta function prior in this case
if isinstance(prior, tupak.core.prior.DeltaFunction):
continue
if prior.maximum != np.inf:
outside_domain = np.linspace(prior.maximum + 1, prior.maximum + 1e4, 1000)
self.assertTrue(all(prior.prob(outside_domain) == 0))
......@@ -179,9 +200,6 @@ class TestPriorClasses(unittest.TestCase):
def test_probability_below_domain(self):
"""Test that the prior probability is non-negative in domain of validity and zero outside."""
for prior in self.priors:
# skip delta function prior in this case
if isinstance(prior, tupak.core.prior.DeltaFunction):
continue
if prior.minimum != -np.inf:
outside_domain = np.linspace(prior.minimum - 1e4, prior.minimum - 1, 1000)
self.assertTrue(all(prior.prob(outside_domain) == 0))
......@@ -189,9 +207,6 @@ class TestPriorClasses(unittest.TestCase):
def test_probability_in_domain(self):
"""Test that the prior probability is non-negative in domain of validity and zero outside."""
for prior in self.priors:
# skip delta function prior in this case
if isinstance(prior, tupak.core.prior.DeltaFunction):
continue
if prior.minimum == -np.inf:
prior.minimum = -1e5
if prior.maximum == np.inf:
......@@ -242,6 +257,201 @@ class TestPriorClasses(unittest.TestCase):
else:
self.assertEqual('unit', prior.unit)
def test_eq_different_classes(self):
for i in range(len(self.priors)):
for j in range(len(self.priors)):
if i == j:
self.assertEqual(self.priors[i], self.priors[j])
else:
self.assertNotEqual(self.priors[i], self.priors[j])
def test_eq_other_condition(self):
prior_1 = tupak.core.prior.PowerLaw(name='test', unit='unit', alpha=0, minimum=0, maximum=1)
prior_2 = tupak.core.prior.PowerLaw(name='test', unit='unit', alpha=0, minimum=0, maximum=1.5)
self.assertNotEqual(prior_1, prior_2)
def test_eq_different_keys(self):
prior_1 = tupak.core.prior.PowerLaw(name='test', unit='unit', alpha=0, minimum=0, maximum=1)
prior_2 = tupak.core.prior.PowerLaw(name='test', unit='unit', alpha=0, minimum=0, maximum=1)
prior_2.other_key = 5
self.assertNotEqual(prior_1, prior_2)
def test_np_array_eq(self):
prior_1 = tupak.core.prior.PowerLaw(name='test', unit='unit', alpha=0, minimum=0, maximum=1)
prior_2 = tupak.core.prior.PowerLaw(name='test', unit='unit', alpha=0, minimum=0, maximum=1)
prior_1.array_attribute = np.array([1, 2, 3])
prior_2.array_attribute = np.array([2, 2, 3])
self.assertNotEqual(prior_1, prior_2)
def test_repr(self):
for prior in self.priors:
if isinstance(prior, tupak.core.prior.Interped):
continue # we cannot test this because of the numpy arrays
elif isinstance(prior, tupak.gw.prior.UniformComovingVolume):
repr_prior_string = 'tupak.gw.prior.' + repr(prior)
else:
repr_prior_string = 'tupak.core.prior.' + repr(prior)
repr_prior = eval(repr_prior_string)
self.assertEqual(prior, repr_prior)
class TestPriorSet(unittest.TestCase):
def setUp(self):
self.first_prior = tupak.core.prior.Uniform(name='a', minimum=0, maximum=1, unit='kg')
self.second_prior = tupak.core.prior.PowerLaw(name='b', alpha=3, minimum=1, maximum=2, unit='m/s')
self.third_prior = tupak.core.prior.DeltaFunction(name='c', peak=42, unit='m')
self.prior_dict = dict(mass=self.first_prior,
speed=self.second_prior,
length=self.third_prior)
self.prior_set_from_dict = tupak.core.prior.PriorSet(dictionary=self.prior_dict)
self.default_prior_file = os.path.join(os.path.dirname(os.path.realpath(__file__)),
'prior_files/binary_black_holes.prior')
self.prior_set_from_file = tupak.core.prior.PriorSet(filename=self.default_prior_file)
def tearDown(self):
del self.first_prior
del self.second_prior
del self.third_prior
del self.prior_dict
del self.prior_set_from_dict
del self.default_prior_file
del self.prior_set_from_file
def test_prior_set_is_ordered_dict(self):
self.assertIsInstance(self.prior_set_from_dict, OrderedDict)
def test_prior_set_has_correct_length(self):
self.assertEqual(3, len(self.prior_set_from_dict))
def test_prior_set_has_expected_priors(self):
self.assertDictEqual(self.prior_dict, dict(self.prior_set_from_dict))
# Removed for now as it does not create the outdir in the Gitlab CI
# def test_write_to_file(self):
# outdir = 'prior_set_test_outdir'
# label = 'test_label'
# label_dot_prior = label + '.prior'
# current_dir_path = os.path.dirname(os.path.realpath(__file__))
# outdir_path = os.path.join(current_dir_path, outdir)
# outfile_path = os.path.join(outdir_path, label_dot_prior)
# self.prior_set_from_dict.write_to_file(outdir=outdir, label=label)
# self.assertTrue(os.path.isdir(outdir_path))
# self.assertTrue(os.listdir(outdir_path)[0] == label_dot_prior)
# with open(outfile_path, 'r') as f:
# expected_outfile = [
# 'speed = PowerLaw(alpha=3, minimum=1, maximum=2, name=\'b\', latex_label=\'b\', unit=\'m/s\')\n',
# 'mass = Uniform(minimum=0, maximum=1, name=\'a\', latex_label=\'a\', unit=\'kg\')\n',
# 'length = DeltaFunction(peak=42, name=\'c\', latex_label=\'c\', unit=\'m\')\n']
# self.assertListEqual(sorted(expected_outfile), sorted(f.readlines()))
# shutil.rmtree(outdir_path)
def test_read_from_file(self):
expected = dict(mass_1=tupak.core.prior.Uniform(name='mass_1', minimum=5, maximum=100),
mass_2=tupak.core.prior.Uniform(name='mass_2', minimum=5, maximum=100),
a_1=tupak.core.prior.Uniform(name='a_1', minimum=0, maximum=0.8),
a_2=tupak.core.prior.Uniform(name='a_2', minimum=0, maximum=0.8),
tilt_1=tupak.core.prior.Sine(name='tilt_1'),
tilt_2=tupak.core.prior.Sine(name='tilt_2'),
phi_12=tupak.core.prior.Uniform(name='phi_12', minimum=0, maximum=2 * np.pi),
phi_jl=tupak.core.prior.Uniform(name='phi_jl', minimum=0, maximum=2 * np.pi),
luminosity_distance=tupak.gw.prior.UniformComovingVolume(name='luminosity_distance',
minimum=1e2, maximum=5e3),
dec=tupak.core.prior.Cosine(name='dec'),
ra=tupak.core.prior.Uniform(name='ra', minimum=0, maximum=2 * np.pi),
iota=tupak.core.prior.Sine(name='iota'),
psi=tupak.core.prior.Uniform(name='psi', minimum=0, maximum=np.pi),
phase=tupak.core.prior.Uniform(name='phase', minimum=0, maximum=2 * np.pi)
)
self.assertDictEqual(expected, self.prior_set_from_file)
def test_convert_floats_to_delta_functions(self):
self.prior_set_from_dict['d'] = 5
self.prior_set_from_dict['e'] = 7.3
self.prior_set_from_dict['f'] = 'unconvertable'
self.prior_set_from_dict.convert_floats_to_delta_functions()
expected = dict(mass=tupak.core.prior.Uniform(name='a', minimum=0, maximum=1, unit='kg'),
speed=tupak.core.prior.PowerLaw(name='b', alpha=3, minimum=1, maximum=2, unit='m/s'),
length=tupak.core.prior.DeltaFunction(name='c', peak=42, unit='m'),
d=tupak.core.prior.DeltaFunction(peak=5),
e=tupak.core.prior.DeltaFunction(peak=7.3),
f='unconvertable')
self.assertDictEqual(expected, self.prior_set_from_dict)
def test_prior_set_from_dict_but_using_a_string(self):
prior_set = tupak.core.prior.PriorSet(dictionary=self.default_prior_file)
expected = dict(mass_1=tupak.core.prior.Uniform(name='mass_1', minimum=5, maximum=100),
mass_2=tupak.core.prior.Uniform(name='mass_2', minimum=5, maximum=100),
a_1=tupak.core.prior.Uniform(name='a_1', minimum=0, maximum=0.8),
a_2=tupak.core.prior.Uniform(name='a_2', minimum=0, maximum=0.8),
tilt_1=tupak.core.prior.Sine(name='tilt_1'),
tilt_2=tupak.core.prior.Sine(name='tilt_2'),
phi_12=tupak.core.prior.Uniform(name='phi_12', minimum=0, maximum=2 * np.pi),
phi_jl=tupak.core.prior.Uniform(name='phi_jl', minimum=0, maximum=2 * np.pi),
luminosity_distance=tupak.gw.prior.UniformComovingVolume(name='luminosity_distance',
minimum=1e2, maximum=5e3),
dec=tupak.core.prior.Cosine(name='dec'),
ra=tupak.core.prior.Uniform(name='ra', minimum=0, maximum=2 * np.pi),
iota=tupak.core.prior.Sine(name='iota'),
psi=tupak.core.prior.Uniform(name='psi', minimum=0, maximum=np.pi),
phase=tupak.core.prior.Uniform(name='phase', minimum=0, maximum=2 * np.pi)
)
self.assertDictEqual(expected, prior_set)
def test_dict_argument_is_not_string_or_dict(self):
with self.assertRaises(ValueError):
tupak.core.prior.PriorSet(dictionary=list())
def test_sample_subset_correct_size(self):
size = 7
samples = self.prior_set_from_dict.sample_subset(keys=self.prior_set_from_dict.keys(), size=size)
self.assertEqual(len(self.prior_set_from_dict), len(samples))
for key in samples:
self.assertEqual(size, len(samples[key]))
def test_sample_subset_correct_size_when_non_priors_in_dict(self):
self.prior_set_from_dict['asdf'] = 'not_a_prior'
samples = self.prior_set_from_dict.sample_subset(keys=self.prior_set_from_dict.keys())
self.assertEqual(len(self.prior_set_from_dict) - 1, len(samples))
def test_sample_subset_with_actual_subset(self):
size = 3
samples = self.prior_set_from_dict.sample_subset(keys=['length'], size=size)
expected = dict(length=np.array([42., 42., 42.]))
self.assertTrue(np.array_equal(expected['length'], samples['length']))
def test_sample(self):
size = 7
np.random.seed(42)
samples1 = self.prior_set_from_dict.sample_subset(keys=self.prior_set_from_dict.keys(), size=size)
np.random.seed(42)
samples2 = self.prior_set_from_dict.sample(size=size)
self.assertEqual(samples1.keys(), samples2.keys())
for key in samples1:
self.assertTrue(np.array_equal(samples1[key], samples2[key]))
def test_prob(self):
samples = self.prior_set_from_dict.sample_subset(keys=['mass', 'speed'])
expected = self.first_prior.prob(samples['mass']) * self.second_prior.prob(samples['speed'])
self.assertEqual(expected, self.prior_set_from_dict.prob(samples))
def test_ln_prob(self):
samples = self.prior_set_from_dict.sample_subset(keys=['mass', 'speed'])
expected = self.first_prior.ln_prob(samples['mass']) + self.second_prior.ln_prob(samples['speed'])
self.assertEqual(expected, self.prior_set_from_dict.ln_prob(samples))
def test_rescale(self):
theta = [0.5, 0.5, 0.5]
expected = [self.first_prior.rescale(0.5),
self.second_prior.rescale(0.5),
self.third_prior.rescale(0.5)]
self.assertListEqual(sorted(expected), sorted(self.prior_set_from_dict.rescale(
keys=self.prior_set_from_dict.keys(), theta=theta)))
def test_redundancy(self):
for key in self.prior_set_from_dict.keys():
self.assertFalse(self.prior_set_from_dict.test_redundancy(key=key))
class TestFillPrior(unittest.TestCase):
......@@ -250,9 +460,9 @@ class TestFillPrior(unittest.TestCase):
self.likelihood.parameters = dict(a=0, b=0, c=0, d=0, asdf=0, ra=1)
self.likelihood.non_standard_sampling_parameter_keys = dict(t=8)
self.priors = dict(a=1, b=1.1, c='string', d=tupak.core.prior.Uniform(0, 1))
self.priors = tupak.core.prior.PriorSet(self.priors)
self.default_prior_file = os.path.join('/'.join(os.path.dirname(__file__).split('/')[:-1]), 'tupak', 'gw',
'prior_files', 'binary_black_holes.prior')
self.priors = tupak.core.prior.PriorSet(dictionary=self.priors)
self.default_prior_file = os.path.join(os.path.dirname(os.path.realpath(__file__)),
'prior_files/binary_black_holes.prior')
self.priors.fill_priors(self.likelihood, self.default_prior_file)
def tearDown(self):
......@@ -282,5 +492,22 @@ class TestFillPrior(unittest.TestCase):
self.assertIsInstance(self.priors['ra'], tupak.core.prior.Uniform)
class TestCreateDefaultPrior(unittest.TestCase):
def test_none_behaviour(self):
self.assertIsNone(tupak.core.prior.create_default_prior(name='name', default_priors_file=None))
def test_bbh_params(self):
prior_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'prior_files/binary_black_holes.prior')
prior_set = tupak.core.prior.PriorSet(filename=prior_file)
for prior in prior_set:
self.assertEqual(prior_set[prior], tupak.core.prior.create_default_prior(name=prior,
default_priors_file=prior_file))
def test_unknown_prior(self):
prior_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'prior_files/binary_black_holes.prior')
self.assertIsNone(tupak.core.prior.create_default_prior(name='name', default_priors_file=prior_file))
if __name__ == '__main__':
unittest.main()
File moved
......@@ -12,6 +12,7 @@ from future.utils import iteritems
from tupak.core.utils import logger
from tupak.core import utils
import tupak # noqa
import inspect
class PriorSet(OrderedDict):
......@@ -277,7 +278,6 @@ def create_default_prior(name, default_priors_file=None):
class Prior(object):
_default_latex_labels = dict()
def __init__(self, name=None, latex_label=None, unit=None, minimum=-np.inf,
......@@ -313,6 +313,20 @@ class Prior(object):
"""
return self.sample()
def __eq__(self, other):
if self.__class__ != other.__class__:
return False
if sorted(self.__dict__.keys()) != sorted(other.__dict__.keys()):
return False
for key in self.__dict__:
if type(self.__dict__[key]) is np.ndarray:
if not np.array_equal(self.__dict__[key], other.__dict__[key]):
return False
else:
if not self.__dict__[key] == other.__dict__[key]:
return False
return True
def sample(self, size=None):
"""Draw a sample from the prior
......@@ -374,6 +388,20 @@ class Prior(object):
"""
return np.log(self.prob(val))
def is_in_prior_range(self, val):
"""Returns True if val is in the prior boundaries, zero otherwise
Parameters
----------
val: float
Returns
-------
np.nan
"""
return (val >= self.minimum) & (val <= self.maximum)
@staticmethod
def test_valid_for_rescaling(val):
"""Test if 0 < val < 1
......@@ -394,38 +422,23 @@ class Prior(object):
def __repr__(self):
"""Overrides the special method __repr__.
Should return a representation of this instance that resembles how it is instantiated
Returns a representation of this instance that resembles how it is instantiated.
Works correctly for all child classes
Returns
-------
str: A string representation of this instance
"""
return self._subclass_repr_helper()
def _subclass_repr_helper(self, subclass_args=iter([])):
"""Helps out subclass _repr__ methods by creating a common template
Parameters
----------
subclass_args: list, optional
List of attributes in the subclass instance
Returns
-------
str: A string representation for this subclass instance.
"""
subclass_args = inspect.getargspec(self.__init__).args
subclass_args.pop(0)
prior_name = self.__class__.__name__
args = ['name', 'latex_label', 'unit', 'minimum', 'maximum']
args.extend(subclass_args)
property_names = [p for p in dir(self.__class__) if isinstance(getattr(self.__class__, p), property)]
dict_with_properties = self.__dict__.copy()
for key in property_names:
dict_with_properties[key] = getattr(self, key)
args = ', '.join(['{}={}'.format(key, repr(dict_with_properties[key])) for key in args])
args = ', '.join(['{}={}'.format(key, repr(dict_with_properties[key])) for key in subclass_args])
return "{}({})".format(prior_name, args)
@property
......@@ -550,14 +563,8 @@ class DeltaFunction(Prior):
float: np.inf if val = peak, 0 otherwise
"""
if self.peak == val:
return np.inf
else:
return 0
def __repr__(self):
"""Call to helper method in the super class."""
return Prior._subclass_repr_helper(self, subclass_args=['peak'])
at_peak = (val == self.peak)
return np.nan_to_num(np.multiply(at_peak, np.inf))
class PowerLaw(Prior):
......@@ -618,13 +625,12 @@ class PowerLaw(Prior):
-------
float: Prior probability of val
"""
in_prior = (val >= self.minimum) & (val <= self.maximum)
if self.alpha == -1:
return np.nan_to_num(1 / val / np.log(self.maximum / self.minimum)) * in_prior
return np.nan_to_num(1 / val / np.log(self.maximum / self.minimum)) * self.is_in_prior_range(val)
else:
return np.nan_to_num(val ** self.alpha * (1 + self.alpha) /
(self.maximum ** (1 + self.alpha) -
self.minimum ** (1 + self.alpha))) * in_prior
self.minimum ** (1 + self.alpha))) * self.is_in_prior_range(val)
def ln_prob(self, val):
"""Return the logarithmic prior probability of val
......@@ -638,19 +644,13 @@ class PowerLaw(Prior):
float:
"""
in_prior = (val >= self.minimum) & (val <= self.maximum)
if self.alpha == -1:
normalising = 1. / np.log(self.maximum / self.minimum)
else:
normalising = (1 + self.alpha) / (self.maximum ** (1 + self.alpha) -
self.minimum ** (1 + self.alpha))
return (self.alpha * np.log(val) + np.log(normalising)) + np.log(1. * in_prior)
def __repr__(self):
"""Call to helper method in the super class."""
return Prior._subclass_repr_helper(self, subclass_args=['alpha'])
return (self.alpha * np.log(val) + np.log(normalising)) + np.log(1. * self.is_in_prior_range(val))
class Uniform(Prior):
......@@ -732,10 +732,6 @@ class LogUniform(PowerLaw):
if self.minimum <= 0:
logger.warning('You specified a uniform-in-log prior with minimum={}'.format(self.minimum))
def __repr__(self):
"""Call to helper method in the super class."""
return Prior._subclass_repr_helper(self)
class Cosine(Prior):
......@@ -779,8 +775,7 @@ class Cosine(Prior):
-------
float: Prior probability of val
"""
in_prior = (val >= self.minimum) & (val <= self.maximum)
return np.cos(val) / 2 * in_prior
return np.cos(val) / 2 * self.is_in_prior_range(val)
class Sine(Prior):
......@@ -825,11 +820,11 @@ class Sine(Prior):
-------
float: Prior probability of val
"""
in_prior = (val >= self.minimum) & (val <= self.maximum)
return np.sin(val) / 2 * in_prior
return np.sin(val) / 2 * self.is_in_prior_range(val)
class Gaussian(Prior):
def __init__(self, mu, sigma, name=None, latex_label=None, unit=None):
"""Gaussian prior with mean mu and width sigma
......@@ -875,10 +870,6 @@ class Gaussian(Prior):
def ln_prob(self, val):
return -0.5 * ((self.mu - val) ** 2 / self.sigma ** 2 + np.log(2 * np.pi * self.sigma ** 2))
def __repr__(self):
"""Call to helper method in the super class."""
return Prior._subclass_repr_helper(self, subclass_args=['mu', 'sigma'])
class Normal(Gaussian):
......@@ -964,13 +955,8 @@ class TruncatedGaussian(Prior):
-------
float: Prior probability of val
"""
in_prior = (val >= self.minimum) & (val <= self.maximum)
return np.exp(-(self.mu - val) ** 2 / (2 * self.sigma ** 2)) / (
2 * np.pi) ** 0.5 / self.sigma / self.normalisation * in_prior
def __repr__(self):
"""Call to helper method in the super class."""
return Prior._subclass_repr_helper(self, subclass_args=['mu', 'sigma'])
2 * np.pi) ** 0.5 / self.sigma / self.normalisation * self.is_in_prior_range(val)
class TruncatedNormal(TruncatedGaussian):
......@@ -1020,10 +1006,6 @@ class HalfGaussian(TruncatedGaussian):
name=name, latex_label=latex_label,
unit=unit)
def __repr__(self):
"""Call to helper method in the super class."""
return Prior._subclass_repr_helper(self, subclass_args=['sigma'])
class HalfNormal(HalfGaussian):
def __init__(self, sigma, name=None, latex_label=None, unit=None):
......@@ -1100,10 +1082,6 @@ class LogNormal(Prior):
def ln_prob(self, val):
return scipy.stats.lognorm.logpdf(val, self.sigma, scale=np.exp(self.mu))
def __repr__(self):
"""Call to helper method in the super class."""
return Prior._subclass_repr_helper(self, subclass_args=['mu', 'sigma'])
class LogGaussian(LogNormal):
def __init__(self, mu, sigma, name=None, latex_label=None, unit=None):
......@@ -1175,10 +1153,6 @@ class Exponential(Prior):
def ln_prob(self, val):
return scipy.stats.expon.logpdf(val, scale=self.mu)
def __repr__(self):
"""Call to helper method in the super class."""
return Prior._subclass_repr_helper(self, subclass_args=['mu'])
class StudentT(Prior):
def __init__(self, df, mu=0., scale=1., name=None, latex_label=None,
......@@ -1239,10 +1213,6 @@ class StudentT(Prior):
def ln_prob(self, val):
return scipy.stats.t.logpdf(val, self.df, loc=self.mu, scale=self.scale)
def __repr__(self):
"""Call to helper method in the super class."""
return Prior._subclass_repr_helper(self, subclass_args=['df', 'mu', 'scale'])
class Beta(Prior):
def __init__(self, alpha, beta, name=None, latex_label=None, unit=None):
......@@ -1320,10 +1290,6 @@ class Beta(Prior):
else:
return -np.inf
def __repr__(self):
"""Call to helper method in the super class."""
return Prior._subclass_repr_helper(self, subclass_args=['alpha', 'beta'])
class Logistic(Prior):
def __init__(self, mu, scale, name=None, latex_label=None, unit=None):
......@@ -1379,10 +1345,6 @@ class Logistic(Prior):
def ln_prob(self, val):
return scipy.stats.logistic.logpdf(val, loc=self.mu, scale=self.scale)
def __repr__(self):
"""Call to helper method in the super class."""
return Prior._subclass_repr_helper(self, subclass_args=['mu', 'scale'])
class Cauchy(Prior):
def __init__(self, alpha, beta, name=None, latex_label=None, unit=None):
......@@ -1438,10 +1400,6 @@ class Cauchy(Prior):
def ln_prob(self, val):
return scipy.stats.cauchy.logpdf(val, loc=self.alpha, scale=self.beta)
def __repr__(self):
"""Call to helper method in the super class."""
return Prior._subclass_repr_helper(self, subclass_args=['alpha', 'beta'])
class Lorentzian(Cauchy):
def __init__(self, alpha, beta, name=None, latex_label=None, unit=None):
......@@ -1522,10 +1480,6 @@ class Gamma(Prior):
def ln_prob(self, val):
return scipy.stats.gamma.logpdf(val, self.k, loc=0., scale=self.theta)
def __repr__(self):
"""Call to helper method in the super class."""
return Prior._subclass_repr_helper(self, subclass_args=['k', 'theta'])
class ChiSquared(Gamma):
def __init__(self, nu, name=None, latex_label=None, unit=None):
......@@ -1551,6 +1505,14 @@ class ChiSquared(Gamma):
Gamma.__init__(self, name=name, k=nu / 2., theta=2.,
latex_label=latex_label, unit=unit)
@property
def nu(self):
return int(self.k * 2)
@nu.setter
def nu(self, nu):
self.k = nu / 2.
class Interped(Prior):
......@@ -1595,6 +1557,13 @@ class Interped(Prior):
maximum=np.nanmin(np.array((max(xx), maximum))))
self.__initialize_attributes()
def __eq__(self, other):
if self.__class__ != other.__class__:
return False
if np.array_equal(self.xx, other.xx) and np.array_equal(self.yy, other.yy):
return True
return False
def prob(self, val):
"""Return the prior probability of val.
......@@ -1620,10 +1589,6 @@ class Interped(Prior):
rescaled = float(rescaled)
return rescaled
def __repr__(self):
"""Call to helper method in the super class."""
return Prior._subclass_repr_helper(self, subclass_args=['xx', 'yy'])
@property
def minimum(self):
"""Return minimum of the prior distribution.
......@@ -1716,7 +1681,3 @@ class FromFile(Interped):
logger.warning("Can't load {}.".format(self.id))
logger.warning("Format should be:")
logger.warning(r"x\tp(x)")
def __repr__(self):
"""Call to helper method in the super class."""
return Prior._subclass_repr_helper(self, subclass_args=['id'])
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment