Skip to content

Commit b425ab6

Browse files
authored
Add files via upload
1 parent 8c02d77 commit b425ab6

1 file changed

Lines changed: 276 additions & 0 deletions

File tree

rayleightolint.py

Lines changed: 276 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,276 @@
1+
import numpy as np
2+
from scipy.stats import rayleigh
3+
from scipy.optimize import brentq
4+
import pandas as pd
5+
import warnings
6+
warnings.filterwarnings('ignore')
7+
8+
def length(x):
9+
if type(x) == float or type(x) == int or type(x) == np.int32 or type(x) == np.float64 or type(x) == np.float32 or type(x) == np.int64:
10+
return 1
11+
return len(x)
12+
13+
#WORKS CITED:
14+
#On Construction of Two-Sided Tolerance Intervals and Confidence Intervals for Probability Content
15+
# Hoang-Nguyen-Thuy, Ngan.   University of Louisiana at Lafayette ProQuest Dissertations Publishing,  2020. 27959915.
16+
# https://www.proquest.com/openview/eaab2073101c1082445e2611c08c376e/1?pq-origsite=gscholar&cbl=18750&diss=y
17+
18+
def RaylMLEScens(xc, n):
19+
r = length(xc)
20+
x = list(xc.copy())
21+
x.extend([xc[-1],]*(n-r))
22+
x = np.array(x)
23+
xb = np.mean(xc)
24+
s = np.std(xc, ddof = 1)
25+
bhat = np.sqrt(2/(4-np.pi))*s
26+
def fn(a):
27+
ssq = sum((x-a)**2)
28+
y = 2*r*sum(x-a)/ssq-sum(1/(np.array(xc)-a))
29+
return y
30+
a0 = x[0]-15*bhat/np.sqrt(r)
31+
a1 = x[0]
32+
aMLE = brentq(fn, a = a0, b = a1, xtol = 1e-5, maxiter = 20)
33+
bMLE = np.sqrt(0.5*sum((x-aMLE)**2)/r)
34+
return [aMLE, bMLE]
35+
36+
def RaylMLESuncens(x):
37+
n = length(x)
38+
xmin = min(x)
39+
bh = np.sqrt(2/(4-np.pi))*np.std(x, ddof=1)
40+
a0 = xmin-15*bh/np.sqrt(n)
41+
a1 = xmin
42+
def ha(a):
43+
sxx = sum((np.array(x)-a)**2)
44+
hs = 2*n**2*(np.mean(x)-a)/sxx-sum(1/(np.array(x)-a))
45+
return (hs)
46+
aMLE = brentq(ha, a = a0, b = a1, xtol = 1e-5, maxiter = 30)
47+
bMLE = np.sqrt(sum((np.array(x)-aMLE)**2)/2/n)
48+
return [aMLE, bMLE]
49+
50+
def RaylMLES(x, n, censored):
51+
if censored:
52+
mles = RaylMLEScens(x, n)
53+
else:
54+
mles = RaylMLESuncens(x)
55+
return mles
56+
57+
def RayOneSidedFac(nr, n, r, P, alpha, censored):
58+
al = 1-alpha
59+
qupp = (np.sqrt(-2*np.log(1-P)))
60+
qlow = (np.sqrt(-2*np.log(P)))
61+
u = np.random.uniform(size = int(nr*n))
62+
#u = np.linspace(0.01,0.99, int(nr*n))
63+
xm = np.sqrt(-2*np.log(u)).reshape(n,nr).T
64+
xm = pd.DataFrame(np.array(list(map(np.sort,xm))))
65+
xc = xm.iloc[:,0:r]
66+
mles = []
67+
for i in range(length(xc.iloc[:,0])):
68+
mles.append(RaylMLES(xc.iloc[i].values, n, censored))
69+
mles = pd.DataFrame(mles).T
70+
ahs = mles.iloc[0].values
71+
bhs = mles.iloc[1].values
72+
pivL = np.sort((qlow-ahs)/bhs)
73+
pivU = np.sort((qupp-ahs)/bhs)
74+
if int(nr*al) == 0:
75+
return pivU[int(nr*(1-al))-1]
76+
else:
77+
Low = pivL[int(nr*al)-1]
78+
Upp = pivU[int(nr*(1-al))-1]
79+
return [Low, Upp]
80+
81+
def RaylTF(nr, n, r, P, alpha, censored, tails):
82+
p = (1+P)/2
83+
gam = (1+alpha)/2
84+
qupp = np.sqrt(-2*np.log(1-p))
85+
qlow = np.sqrt(-2*np.log(p))
86+
u = np.random.uniform(size = int(nr*n))
87+
#u = np.linspace(0.01,0.99, int(nr*n))
88+
xm = np.sqrt(-2*np.log(u)).reshape(n,nr).T
89+
xm = pd.DataFrame(np.array(list(map(np.sort,xm))))
90+
xc = xm.iloc[:,0:r]
91+
mles = []
92+
for i in range(length(xc.iloc[:,0])):
93+
mles.append(RaylMLES(xc.iloc[i].values, n, censored))
94+
mles = pd.DataFrame(mles).T
95+
ahs = mles.iloc[0].values
96+
bhs = mles.iloc[1].values
97+
pivL = np.sort((qlow-ahs)/bhs)
98+
pivU = np.sort((qupp-ahs)/bhs)
99+
def fn(x):
100+
if tails == 'equal-tailed':
101+
al = 1-(1+x)/2
102+
if int(nr*al) == 0:
103+
return "Number of Runs, nr, must be larger."
104+
Lfac = pivL[int(nr*al)-1]
105+
Ufac = pivU[int(nr*(1-al))-1]
106+
LowLim = ahs+Lfac*bhs
107+
UppLim = ahs+Ufac*bhs
108+
cont = (np.where(LowLim <= qlow) and np.where(qupp <= UppLim))[0]
109+
covr = np.mean(cont >= P)
110+
return(covr-alpha)
111+
elif tails == '1' or tails == '2':
112+
facL = np.percentile(pivL, (1-(1+x)/2)*100)
113+
facU = np.percentile(pivU, ((1+x)/2)*100)
114+
LowLim = ahs+facL*bhs
115+
UppLim = ahs+facU*bhs
116+
cont = rayleigh.cdf(UppLim,0,1) - rayleigh.cdf(LowLim,0,1)
117+
covr = np.mean(cont >= P)
118+
return covr-alpha
119+
xl = 0.3
120+
xr = alpha
121+
k = 1
122+
while True:
123+
fl = fn(xl)
124+
fr = fn(xr)
125+
xm = (xl+xr)/2
126+
fm = fn(xm)
127+
if abs(fm) < 1e-5 or k > 50:
128+
break
129+
if fl*fm > 0:
130+
xl = xm
131+
else:
132+
xr = xm
133+
k = k+1
134+
als = 1-(1+xm)/2
135+
if tails == 'equal-tailed':
136+
Lfac = pivL[int(nr*als)]
137+
Ufac = pivU[int(nr*(1-als))]
138+
else:
139+
Lfac = pivL[int(nr*als)-1]
140+
Ufac = pivU[int(nr*(1-als))-1]
141+
return (Lfac, Ufac)
142+
143+
def rayleightolint(x, alpha = 0.05, P= 0.99, side = 1, nr = 1000, censored = False, printMLES = False, printFactors = False):
144+
'''
145+
Description
146+
Rayleigh Tolerance Interval
147+
148+
Usage
149+
rayleightolint(x, alpha = 0.05, P= 0.99, side = 1, nr = 1000,
150+
censored = False, printMLES = False, printFactors = False):
151+
152+
Parameters
153+
----------
154+
x : list
155+
A vector of Rayleigh distributed data.
156+
157+
alpha : float, optional
158+
The level chosen such that 1-alpha is the confidence level. The
159+
default is 0.05.
160+
161+
P : float, optional
162+
The proportion of the population to be covered by this tolerance
163+
interval. The default is 0.99.
164+
165+
side : 1, 2, or 'equal-tailed', optional
166+
Whether a 1-sided, 2-sided, or equal-tailed tolerance interval is
167+
required (determined by side = 1 or side = 2, respectively). The
168+
default is 1.
169+
170+
nr : int, optional
171+
The number of simulations. The default is 1000.
172+
173+
censored : bool, optional
174+
If True, the the value of a measurement or observation is only
175+
partially known. The default is False.
176+
177+
printMLES : bool, optional
178+
Prints the Maximum Likelihood Estimators if True. The default is False.
179+
180+
printFactors : TYPE, optional
181+
Prints the tolerance factors if True. The default is False.
182+
183+
Returns
184+
-------
185+
rayleightolint returns a data frame with items:
186+
187+
alpha
188+
The specified significance level.
189+
190+
P
191+
The proportion of the population covered by this tolerance
192+
interval.
193+
194+
1-sided.lower
195+
The 1-sided lower tolerance bound. This is given only if side = 1.
196+
197+
1-sided.upper
198+
The 1-sided upper tolerance bound. This is given only if side = 1.
199+
200+
2-sided.lower
201+
The 2-sided lower tolerance bound. This is given only if side = 2.
202+
203+
2-sided.upper
204+
The 2-sided upper tolerance bound. This is given only if side = 2.
205+
206+
equal-tailed.lower
207+
The equal-tailed lower tolerance bound. This is given only if
208+
side = 'equal-tailed'.
209+
210+
equal-tailed.upper
211+
The equal-tailed upper tolerance bound. This is given only if
212+
side = 'equal-tailed'.
213+
214+
References
215+
----------
216+
On Construction of Two-Sided Tolerance Intervals and Confidence Intervals
217+
for Probability Content Hoang-Nguyen-Thuy, Ngan. University of
218+
Louisiana at Lafayette ProQuest Dissertations Publishing, 2020. 
219+
27959915.
220+
221+
Examples
222+
--------
223+
x = rayleigh.rvs(size = 100)
224+
225+
rayleightolint(x, alpha = 0.01, P = 0.99, side = 1)
226+
227+
rayleightolint(x, alpha = 0.05, P = 0.95, side = 2)
228+
229+
rayleightolint(x, alpha = 0.1, P = 0.9, side = 'equal-tailed')
230+
'''
231+
alpha = 1-alpha
232+
n = length(x)
233+
if censored:
234+
r = length(x)
235+
else:
236+
r = n
237+
mles = RaylMLES(x, n, censored)
238+
ah0 = mles[0]
239+
bh0 = mles[1]
240+
if printMLES:
241+
print(ah0,bh0)
242+
if side == 1:
243+
osfac = RayOneSidedFac(nr,n,r,P,alpha,censored)
244+
if printFactors:
245+
print(f'One-sided Factors are: {np.array(osfac)}')
246+
OSLow = ah0 + osfac[0]*bh0
247+
OSUpp = ah0 + osfac[1]*bh0
248+
return pd.DataFrame({'alpha': [1-alpha], 'P': [P], '1-sided.lower':OSLow, '1-sided.upper':OSUpp})
249+
elif side == 2:
250+
tsfac = RaylTF(nr,n,r,P,alpha,censored, tails = '2')
251+
if printFactors:
252+
print(f'Two-sided Factors are: {np.array(tsfac)}')
253+
TSLow = ah0 + tsfac[0]*bh0
254+
TSUpp = ah0 + tsfac[1]*bh0
255+
return pd.DataFrame({'alpha': [1-alpha], 'P': [P], '2-sided.lower':TSLow, '2-sided.upper':TSUpp})
256+
elif side == 'equal-tailed':
257+
eqfac = RaylTF(nr, n, r, P, alpha, censored, tails = 'equal-tailed')
258+
if printFactors:
259+
print(f'Equal-Tailed Factors are: {np.array(eqfac)}')
260+
EQLow = ah0 + eqfac[0]*bh0
261+
EQUpp = ah0 + eqfac[1]*bh0
262+
return pd.DataFrame({'alpha': [1-alpha], 'P': [P], 'equal-tailed.lower':EQLow, 'equal-tailed.upper':EQUpp})
263+
264+
## Tests
265+
# x = rayleigh.rvs(size = 1000)
266+
# print(rayleightolint(x,0.05,0.95, 1),'\n')
267+
# print(rayleightolint(x,0.05,0.95, 2),'\n')
268+
# print(rayleightolint(x,0.05,0.95, 'equal-tailed'))
269+
270+
## True Percentile Values
271+
#print(rayleigh.ppf(0.95))
272+
#print(rayleigh.ppf([0.025,0.975]))
273+
274+
## Notes
275+
## Rayl.cdf is equivalent to rayleigh.cdf()
276+
## Rayl.rand is equivalent to rayleigh.rvs()

0 commit comments

Comments
 (0)