Coverage for bilby/core/utils/samples.py: 59%
64 statements
« prev ^ index » next coverage.py v7.6.1, created at 2025-05-06 04:57 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2025-05-06 04:57 +0000
1import numpy as np
2from scipy.special import logsumexp
5class SamplesSummary(object):
6 """ Object to store a set of samples and calculate summary statistics
8 Parameters
9 ==========
10 samples: array_like
11 Array of samples
12 average: str {'median', 'mean'}
13 Use either a median average or mean average when calculating relative
14 uncertainties
15 level: float
16 The default confidence interval level, defaults t0 0.9
18 """
19 def __init__(self, samples, average='median', confidence_level=.9):
20 self.samples = samples
21 self.average = average
22 self.confidence_level = confidence_level
24 @property
25 def samples(self):
26 return self._samples
28 @samples.setter
29 def samples(self, samples):
30 self._samples = samples
32 @property
33 def confidence_level(self):
34 return self._confidence_level
36 @confidence_level.setter
37 def confidence_level(self, confidence_level):
38 if 0 < confidence_level and confidence_level < 1:
39 self._confidence_level = confidence_level
40 else:
41 raise ValueError("Confidence level must be between 0 and 1")
43 @property
44 def average(self):
45 if self._average == 'mean':
46 return self.mean
47 elif self._average == 'median':
48 return self.median
50 @average.setter
51 def average(self, average):
52 allowed_averages = ['mean', 'median']
53 if average in allowed_averages:
54 self._average = average
55 else:
56 raise ValueError("Average {} not in allowed averages".format(average))
58 @property
59 def median(self):
60 return np.median(self.samples, axis=0)
62 @property
63 def mean(self):
64 return np.mean(self.samples, axis=0)
66 @property
67 def _lower_level(self):
68 """ The credible interval lower quantile value """
69 return (1 - self.confidence_level) / 2.
71 @property
72 def _upper_level(self):
73 """ The credible interval upper quantile value """
74 return (1 + self.confidence_level) / 2.
76 @property
77 def lower_absolute_credible_interval(self):
78 """ Absolute lower value of the credible interval """
79 return np.quantile(self.samples, self._lower_level, axis=0)
81 @property
82 def upper_absolute_credible_interval(self):
83 """ Absolute upper value of the credible interval """
84 return np.quantile(self.samples, self._upper_level, axis=0)
86 @property
87 def lower_relative_credible_interval(self):
88 """ Relative (to average) lower value of the credible interval """
89 return self.lower_absolute_credible_interval - self.average
91 @property
92 def upper_relative_credible_interval(self):
93 """ Relative (to average) upper value of the credible interval """
94 return self.upper_absolute_credible_interval - self.average
97def kish_log_effective_sample_size(ln_weights):
98 """ Calculate the Kish effective sample size from the natural-log weights
100 See https://en.wikipedia.org/wiki/Effective_sample_size for details
102 Parameters
103 ==========
104 ln_weights: array
105 An array of the ln-weights
107 Returns
108 =======
109 ln_n_eff:
110 The natural-log of the effective sample size
112 """
113 return 2 * logsumexp(ln_weights) - logsumexp(2 * ln_weights)
116def reflect(u):
117 """
118 Iteratively reflect a number until it is contained in [0, 1].
120 This is for priors with a reflective boundary condition, all numbers in the
121 set `u = 2n +/- x` should be mapped to x.
123 For the `+` case we just take `u % 1`.
124 For the `-` case we take `1 - (u % 1)`.
126 E.g., -0.9, 1.1, and 2.9 should all map to 0.9.
128 Parameters
129 ==========
130 u: array-like
131 The array of points to map to the unit cube
133 Returns
134 =======
135 u: array-like
136 The input array, modified in place.
137 """
138 idxs_even = np.mod(u, 2) < 1
139 u[idxs_even] = np.mod(u[idxs_even], 1)
140 u[~idxs_even] = 1 - np.mod(u[~idxs_even], 1)
141 return u