@@ -169,8 +169,10 @@ def cdf(self, val):
169169 _cdf = (np .log (val / self .minimum ) /
170170 np .log (self .maximum / self .minimum ))
171171 else :
172- _cdf = np .atleast_1d (val ** (self .alpha + 1 ) - self .minimum ** (self .alpha + 1 )) / \
173- (self .maximum ** (self .alpha + 1 ) - self .minimum ** (self .alpha + 1 ))
172+ _cdf = (
173+ (val ** (self .alpha + 1 ) - self .minimum ** (self .alpha + 1 ))
174+ / (self .maximum ** (self .alpha + 1 ) - self .minimum ** (self .alpha + 1 ))
175+ )
174176 _cdf = np .minimum (_cdf , 1 )
175177 _cdf = np .maximum (_cdf , 0 )
176178 return _cdf
@@ -367,16 +369,16 @@ def ln_prob(self, val):
367369 return np .nan_to_num (- np .log (2 * np .abs (val )) - np .log (np .log (self .maximum / self .minimum )))
368370
369371 def cdf (self , val ):
370- val = np .atleast_1d (val )
371372 norm = 0.5 / np .log (self .maximum / self .minimum )
372- cdf = np .zeros ((len (val )))
373- lower_indices = np .where (np .logical_and (- self .maximum <= val , val <= - self .minimum ))[0 ]
374- upper_indices = np .where (np .logical_and (self .minimum <= val , val <= self .maximum ))[0 ]
375- cdf [lower_indices ] = - norm * np .log (- val [lower_indices ] / self .maximum )
376- cdf [np .where (np .logical_and (- self .minimum < val , val < self .minimum ))] = 0.5
377- cdf [upper_indices ] = 0.5 + norm * np .log (val [upper_indices ] / self .minimum )
378- cdf [np .where (self .maximum < val )] = 1
379- return cdf
373+ _cdf = (
374+ - norm * np .log (abs (val ) / self .maximum )
375+ * (val <= - self .minimum ) * (val >= - self .maximum )
376+ + (0.5 + norm * np .log (abs (val ) / self .minimum ))
377+ * (val >= self .minimum ) * (val <= self .maximum )
378+ + 0.5 * (val > - self .minimum ) * (val < self .minimum )
379+ + 1 * (val > self .maximum )
380+ )
381+ return _cdf
380382
381383
382384class Cosine (Prior ):
@@ -426,10 +428,12 @@ def prob(self, val):
426428 return np .cos (val ) / 2 * self .is_in_prior_range (val )
427429
428430 def cdf (self , val ):
429- _cdf = np .atleast_1d ((np .sin (val ) - np .sin (self .minimum )) /
430- (np .sin (self .maximum ) - np .sin (self .minimum )))
431- _cdf [val > self .maximum ] = 1
432- _cdf [val < self .minimum ] = 0
431+ _cdf = (
432+ (np .sin (val ) - np .sin (self .minimum ))
433+ / (np .sin (self .maximum ) - np .sin (self .minimum ))
434+ * (val >= self .minimum ) * (val <= self .maximum )
435+ + 1 * (val > self .maximum )
436+ )
433437 return _cdf
434438
435439
@@ -480,10 +484,12 @@ def prob(self, val):
480484 return np .sin (val ) / 2 * self .is_in_prior_range (val )
481485
482486 def cdf (self , val ):
483- _cdf = np .atleast_1d ((np .cos (val ) - np .cos (self .minimum )) /
484- (np .cos (self .maximum ) - np .cos (self .minimum )))
485- _cdf [val > self .maximum ] = 1
486- _cdf [val < self .minimum ] = 0
487+ _cdf = (
488+ (np .cos (val ) - np .cos (self .minimum ))
489+ / (np .cos (self .maximum ) - np .cos (self .minimum ))
490+ * (val >= self .minimum ) * (val <= self .maximum )
491+ + 1 * (val > self .maximum )
492+ )
487493 return _cdf
488494
489495
@@ -625,11 +631,13 @@ def prob(self, val):
625631 / self .sigma / self .normalisation * self .is_in_prior_range (val )
626632
627633 def cdf (self , val ):
628- val = np .atleast_1d (val )
629- _cdf = (erf ((val - self .mu ) / 2 ** 0.5 / self .sigma ) - erf (
630- (self .minimum - self .mu ) / 2 ** 0.5 / self .sigma )) / 2 / self .normalisation
631- _cdf [val > self .maximum ] = 1
632- _cdf [val < self .minimum ] = 0
634+ _cdf = (
635+ (
636+ erf ((val - self .mu ) / 2 ** 0.5 / self .sigma )
637+ - erf ((self .minimum - self .mu ) / 2 ** 0.5 / self .sigma )
638+ ) / 2 / self .normalisation * (val >= self .minimum ) * (val <= self .maximum )
639+ + 1 * (val > self .maximum )
640+ )
633641 return _cdf
634642
635643
@@ -1367,6 +1375,8 @@ def __init__(self, sigma, mu=None, r=None, name=None, latex_label=None,
13671375 raise ValueError ("For the Fermi-Dirac prior the values of sigma and r "
13681376 "must be positive." )
13691377
1378+ self .expr = np .exp (self .r )
1379+
13701380 def rescale (self , val ):
13711381 """
13721382 'Rescale' a sample from the unit line element to the appropriate Fermi-Dirac prior.
@@ -1384,21 +1394,8 @@ def rescale(self, val):
13841394 .. [1] M. Pitkin, M. Isi, J. Veitch & G. Woan, `arXiv:1705.08978v1
13851395 <https:arxiv.org/abs/1705.08978v1>`_, 2017.
13861396 """
1387- inv = (- np .exp (- 1. * self .r ) + (1. + np .exp (self .r )) ** - val +
1388- np .exp (- 1. * self .r ) * (1. + np .exp (self .r )) ** - val )
1389-
1390- # if val is 1 this will cause inv to be negative (due to numerical
1391- # issues), so return np.inf
1392- if isinstance (val , (float , int )):
1393- if inv < 0 :
1394- return np .inf
1395- else :
1396- return - self .sigma * np .log (inv )
1397- else :
1398- idx = inv >= 0.
1399- tmpinv = np .inf * np .ones (len (np .atleast_1d (val )))
1400- tmpinv [idx ] = - self .sigma * np .log (inv [idx ])
1401- return tmpinv
1397+ inv = - 1 / self .expr + (1 + self .expr )** - val + (1 + self .expr )** - val / self .expr
1398+ return - self .sigma * np .log (np .maximum (inv , 0 ))
14021399
14031400 def prob (self , val ):
14041401 """Return the prior probability of val.
@@ -1411,7 +1408,11 @@ def prob(self, val):
14111408 =======
14121409 float: Prior probability of val
14131410 """
1414- return np .exp (self .ln_prob (val ))
1411+ return (
1412+ (np .exp ((val - self .mu ) / self .sigma ) + 1 )** - 1
1413+ / (self .sigma * np .log1p (self .expr ))
1414+ * (val >= self .minimum )
1415+ )
14151416
14161417 def ln_prob (self , val ):
14171418 """Return the log prior probability of val.
@@ -1424,19 +1425,34 @@ def ln_prob(self, val):
14241425 =======
14251426 Union[float, array_like]: Log prior probability of val
14261427 """
1428+ return np .log (self .prob (val ))
14271429
1428- norm = - np .log (self .sigma * np .log (1. + np .exp (self .r )))
1429- if isinstance (val , (float , int )):
1430- if val < self .minimum :
1431- return - np .inf
1432- else :
1433- return norm - np .logaddexp ((val / self .sigma ) - self .r , 0. )
1434- else :
1435- val = np .atleast_1d (val )
1436- lnp = - np .inf * np .ones (len (val ))
1437- idx = val >= self .minimum
1438- lnp [idx ] = norm - np .logaddexp ((val [idx ] / self .sigma ) - self .r , 0. )
1439- return lnp
1430+ def cdf (self , val ):
1431+ """
1432+ Evaluate the CDF of the Fermi-Dirac distribution using a slightly
1433+ modified form of Equation 23 of [1]_.
1434+
1435+ Parameters
1436+ ==========
1437+ val: Union[float, int, array_like]
1438+ The value(s) to evaluate the CDF at
1439+
1440+ Returns
1441+ =======
1442+ Union[float, array_like]:
1443+ The CDF value(s)
1444+
1445+ References
1446+ ==========
1447+
1448+ .. [1] M. Pitkin, M. Isi, J. Veitch & G. Woan, `arXiv:1705.08978v1
1449+ <https:arxiv.org/abs/1705.08978v1>`_, 2017.
1450+ """
1451+ result = (
1452+ (np .logaddexp (0 , - self .r ) - np .logaddexp (- val / self .sigma , - self .r ))
1453+ / np .logaddexp (0 , self .r )
1454+ )
1455+ return np .clip (result , 0 , 1 )
14401456
14411457
14421458class DiscreteValues (Prior ):
0 commit comments