14
14
import numpy as np
15
15
import matplotlib .pyplot as plt
16
16
import warnings
17
+ from math import erf
18
+
19
+ np_erf = np .vectorize (erf , doc = "Vectorized error function at x." ) # prevents need for SciPy dependency
17
20
18
21
class a_u :
19
22
"""
@@ -74,29 +77,33 @@ def _repr_latex_(self):
74
77
else :
75
78
return "$%f_{-%f}^{+%f}$" % (self .value ,self .minus ,self .plus )
76
79
77
- def pdf (self ,x ):
80
+ def pdf (self , x ):
78
81
"""
79
82
Computes and returns the values of the probability distribution function for the specified input.
80
83
"""
81
- return np .piecewise (x , [x < self .value , x >= self .value ],
82
- [lambda x : np .sqrt (2 )/ np .sqrt (np .pi )/ (self .plus + self .minus ) * np .exp (- 1 * (x - self .value )** 2 / (2 * self .minus ** 2 )),
83
- lambda x : np .sqrt (2 )/ np .sqrt (np .pi )/ (self .plus + self .minus ) * np .exp (- 1 * (x - self .value )** 2 / (2 * self .plus ** 2 ))])
84
+ x_arr = np .asanyarray (x ).astype (float )
85
+ pdf_arr = np .piecewise (x_arr , [x_arr < self .value , x_arr >= self .value ],
86
+ [lambda x : np .sqrt (2 )/ np .sqrt (np .pi )/ (self .plus + self .minus ) * np .exp (- 1 * (x - self .value )** 2 / (2 * self .minus ** 2 )),
87
+ lambda x : np .sqrt (2 )/ np .sqrt (np .pi )/ (self .plus + self .minus ) * np .exp (- 1 * (x - self .value )** 2 / (2 * self .plus ** 2 ))])
88
+ return pdf_arr .item () if np .isscalar (x ) else pdf_arr
84
89
85
- def cdf (self ,x ):
90
+ def cdf (self , x ):
86
91
"""
87
92
Computes and returns the values of the cumulative distribution function for the specified input.
88
93
"""
89
- return np .cumsum (self .pdf (x ))/ np .sum (self .pdf (x ))
90
-
94
+ x_arr = np .asanyarray (x ).astype (float )
95
+ cdf_arr = np .piecewise (x_arr , [x_arr < self .value , x_arr >= self .value ],
96
+ [lambda x : 0.5 * (1 + np_erf ((x - self .value )/ (self .minus * np .sqrt (2 )))),
97
+ lambda x : 0.5 * (1 + np_erf ((x - self .value )/ (self .plus * np .sqrt (2 ))))])
98
+ return cdf_arr .item () if np .isscalar (x ) else cdf_arr
99
+
91
100
def pdfplot (self ,num_sigma = 5 ,discretization = 100 ,** kwargs ):
92
101
"""
93
102
Plots the associated PDF over the specified number of sigma, using 2*`discretization` points.
94
103
`**kwargs` are passed on to `matplotlib` for configuration of the resulting plot.
95
104
"""
96
- neg_x = np .linspace (self .value - (num_sigma * self .minus ),self .value ,discretization )
97
- pos_x = np .linspace (self .value ,self .value + (num_sigma * self .minus ),discretization )
98
- p_neg = np .sqrt (2 )/ np .sqrt (np .pi )/ (self .plus + self .minus ) * np .exp (- 1 * (neg_x - self .value )** 2 / (2 * self .minus ** 2 ))
99
- p_pos = np .sqrt (2 )/ np .sqrt (np .pi )/ (self .plus + self .minus ) * np .exp (- 1 * (pos_x - self .value )** 2 / (2 * self .plus ** 2 ))
105
+ neg_x = np .linspace (self .value - (num_sigma * self .minus ), self .value , discretization )
106
+ pos_x = np .linspace (self .value , self .value + (num_sigma * self .plus ), discretization )
100
107
x = np .array (list (neg_x )+ list (pos_x ))
101
108
pdf = self .pdf (x )
102
109
plt .plot (x ,pdf ,** kwargs )
@@ -107,13 +114,10 @@ def cdfplot(self,num_sigma=5,discretization=100,**kwargs):
107
114
Plots the associated CDF over the specified number of sigma, using 2*`discretization` points.
108
115
`**kwargs` are passed on to `matplotlib` for configuration of the resulting plot.
109
116
"""
110
- neg_x = np .linspace (self .value - (num_sigma * self .minus ),self .value ,discretization )
111
- pos_x = np .linspace (self .value ,self .value + (num_sigma * self .minus ),discretization )
112
- p_neg = np .sqrt (2 )/ np .sqrt (np .pi )/ (self .plus + self .minus ) * np .exp (- 1 * (neg_x - self .value )** 2 / (2 * self .minus ** 2 ))
113
- p_pos = np .sqrt (2 )/ np .sqrt (np .pi )/ (self .plus + self .minus ) * np .exp (- 1 * (pos_x - self .value )** 2 / (2 * self .plus ** 2 ))
117
+ neg_x = np .linspace (self .value - (num_sigma * self .minus ), self .value , discretization )
118
+ pos_x = np .linspace (self .value , self .value + (num_sigma * self .plus ), discretization )
114
119
x = np .array (list (neg_x )+ list (pos_x ))
115
- pdf = self .pdf (x )
116
- cdf = np .cumsum (pdf )/ np .sum (pdf )
120
+ cdf = self .cdf (x )
117
121
plt .plot (x ,cdf ,** kwargs )
118
122
plt .show ()
119
123
@@ -426,4 +430,4 @@ def neg_errors(array):
426
430
Stand-alone function to return an array of the negative errors of an array of `a_u` objects.
427
431
Functional equivalent to `UncertaintyArray(array).minus`.
428
432
"""
429
- return [v .minus for v in array ]
433
+ return [v .minus for v in array ]
0 commit comments