CensoPy 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
censopy-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jakob Cramer
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
censopy-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,98 @@
1
+ Metadata-Version: 2.4
2
+ Name: CensoPy
3
+ Version: 0.1.0
4
+ Summary: CensoPy - Statistical computations for exponentially distributed lifetimes under hybrid censoring
5
+ Author: Jakob Cramer, Erhard Cramer
6
+ Project-URL: Repository, https://gitlab.git.nrw/jakob/censopy
7
+ Requires-Python: >=3.13
8
+ Description-Content-Type: text/markdown
9
+ License-File: LICENSE
10
+ Requires-Dist: numpy>=2.3.5
11
+ Requires-Dist: mpmath>=1.3.0
12
+ Requires-Dist: scikit-learn>=1.7.2
13
+ Dynamic: license-file
14
+
15
+ # CensoPy
16
+ ---
17
+
18
+ ## Information
19
+ The source code for the paper **CensoPy - Statistical computations for exponentially distributed lifetimes under hybrid censoring** ([download](./Computation_of_distributions_under_hybrid_censoring.pdf)) and the Python 3 package `CensoPy` can be downloaded via **GitLab** from this website.
20
+ > **Note:** The program code was written in **Python 3** (version 3.13) and is an experimental version that will be developed further.
21
+
22
+ ---
23
+
24
+ ## Installation via pip
25
+ Installation via pip is not yet possible. The source code can therefore currently only be downloaded and integrated locally.
26
+
27
+ ---
28
+
29
+ ## Documentation and further information
30
+ Further information on the package can be found in the [documentation](./documentation_python.pdf).
31
+
32
+ ---
33
+
34
+ ## Source-Code Download
35
+ The code can be downloaded separately via the following link:
36
+
37
+ [code_version_0_1](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/CensoPy.py)
38
+
39
+ ---
40
+
41
+ ---
42
+
43
+ ## Examples
44
+ The code for some examples can be downloaded separately via the following links:
45
+
46
+ [Example-3-5-I](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-3-5-I.py)
47
+
48
+ [Example-3-6-I-HCS](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-3-6-I-HCS.py)
49
+
50
+ [Example-3-6-I](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-3-6-I.py)
51
+
52
+ [Example-3-7-I](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-3-7-I.py)
53
+
54
+ [Example-3-7-gen-I-HCS](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-3-7-gen-I-HCS.py)
55
+
56
+ [Example-3-7-gen-II-HCS](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-3-7-gen-II-HCS.py)
57
+
58
+ [Example-3-8-I-HCS](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-3-8-I-HCS.py)
59
+
60
+ [Example-3-8-I](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-3-8-I.py)
61
+
62
+ [Example-4-1-I-PCS](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-4-1-I-PCS.py)
63
+
64
+ [Example-4-1-II-PCS-extended-sample](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-4-1-II-PCS-extended-sample.py)
65
+
66
+ [Example-4-1-II-PCS-m8](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-4-1-II-PCS-m8.py)
67
+
68
+ [Example-4-1-II-PCS](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-4-1-II-PCS.py)
69
+
70
+ [HCS_plots-bivariate](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/Plots/HCS_plots-bivariate.py)
71
+
72
+ [HCS_plots-cdf](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/Plots/HCS_plots-cdf.py)
73
+
74
+ [HCS_plots-pdf](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/Plots/HCS_plots-pdf.py)
75
+
76
+ [R-interface-HCS_plots](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/R-interface/R-interface-HCS_plots.R)
77
+
78
+ ---
79
+
80
+ ## BibTeX Citation
81
+ ```
82
+ @Unpublished{Cramer2026a,
83
+ author = {Jakob I. Cramer and Erhard Cramer},
84
+ note = {submitted for publication},
85
+ title = {CensoPy – Statistical computations for exponentially distributed lifetimes under hybrid censoring},
86
+ year = {2026},
87
+ }
88
+ ```
89
+
90
+ ---
91
+
92
+ ## Errata and Contact</h1>
93
+ The author can be contacted regarding comments and corrections via [erhard.cramer@rwth-aachen.de](mailto:erhard.cramer@rwth-aachen.de)
94
+
95
+ ### Reported errata
96
+ ```
97
+
98
+ ```
@@ -0,0 +1,84 @@
1
+ # CensoPy
2
+ ---
3
+
4
+ ## Information
5
+ The source code for the paper **CensoPy - Statistical computations for exponentially distributed lifetimes under hybrid censoring** ([download](./Computation_of_distributions_under_hybrid_censoring.pdf)) and the Python 3 package `CensoPy` can be downloaded via **GitLab** from this website.
6
+ > **Note:** The program code was written in **Python 3** (version 3.13) and is an experimental version that will be developed further.
7
+
8
+ ---
9
+
10
+ ## Installation via pip
11
+ Installation via pip is not yet possible. The source code can therefore currently only be downloaded and integrated locally.
12
+
13
+ ---
14
+
15
+ ## Documentation and further information
16
+ Further information on the package can be found in the [documentation](./documentation_python.pdf).
17
+
18
+ ---
19
+
20
+ ## Source-Code Download
21
+ The code can be downloaded separately via the following link:
22
+
23
+ [code_version_0_1](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/CensoPy.py)
24
+
25
+ ---
26
+
27
+ ---
28
+
29
+ ## Examples
30
+ The code for some examples can be downloaded separately via the following links:
31
+
32
+ [Example-3-5-I](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-3-5-I.py)
33
+
34
+ [Example-3-6-I-HCS](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-3-6-I-HCS.py)
35
+
36
+ [Example-3-6-I](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-3-6-I.py)
37
+
38
+ [Example-3-7-I](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-3-7-I.py)
39
+
40
+ [Example-3-7-gen-I-HCS](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-3-7-gen-I-HCS.py)
41
+
42
+ [Example-3-7-gen-II-HCS](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-3-7-gen-II-HCS.py)
43
+
44
+ [Example-3-8-I-HCS](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-3-8-I-HCS.py)
45
+
46
+ [Example-3-8-I](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-3-8-I.py)
47
+
48
+ [Example-4-1-I-PCS](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-4-1-I-PCS.py)
49
+
50
+ [Example-4-1-II-PCS-extended-sample](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-4-1-II-PCS-extended-sample.py)
51
+
52
+ [Example-4-1-II-PCS-m8](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-4-1-II-PCS-m8.py)
53
+
54
+ [Example-4-1-II-PCS](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-4-1-II-PCS.py)
55
+
56
+ [HCS_plots-bivariate](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/Plots/HCS_plots-bivariate.py)
57
+
58
+ [HCS_plots-cdf](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/Plots/HCS_plots-cdf.py)
59
+
60
+ [HCS_plots-pdf](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/Plots/HCS_plots-pdf.py)
61
+
62
+ [R-interface-HCS_plots](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/R-interface/R-interface-HCS_plots.R)
63
+
64
+ ---
65
+
66
+ ## BibTeX Citation
67
+ ```
68
+ @Unpublished{Cramer2026a,
69
+ author = {Jakob I. Cramer and Erhard Cramer},
70
+ note = {submitted for publication},
71
+ title = {CensoPy – Statistical computations for exponentially distributed lifetimes under hybrid censoring},
72
+ year = {2026},
73
+ }
74
+ ```
75
+
76
+ ---
77
+
78
+ ## Errata and Contact</h1>
79
+ The author can be contacted regarding comments and corrections via [erhard.cramer@rwth-aachen.de](mailto:erhard.cramer@rwth-aachen.de)
80
+
81
+ ### Reported errata
82
+ ```
83
+
84
+ ```
@@ -0,0 +1,98 @@
1
+ Metadata-Version: 2.4
2
+ Name: CensoPy
3
+ Version: 0.1.0
4
+ Summary: CensoPy - Statistical computations for exponentially distributed lifetimes under hybrid censoring
5
+ Author: Jakob Cramer, Erhard Cramer
6
+ Project-URL: Repository, https://gitlab.git.nrw/jakob/censopy
7
+ Requires-Python: >=3.13
8
+ Description-Content-Type: text/markdown
9
+ License-File: LICENSE
10
+ Requires-Dist: numpy>=2.3.5
11
+ Requires-Dist: mpmath>=1.3.0
12
+ Requires-Dist: scikit-learn>=1.7.2
13
+ Dynamic: license-file
14
+
15
+ # CensoPy
16
+ ---
17
+
18
+ ## Information
19
+ The source code for the paper **CensoPy - Statistical computations for exponentially distributed lifetimes under hybrid censoring** ([download](./Computation_of_distributions_under_hybrid_censoring.pdf)) and the Python 3 package `CensoPy` can be downloaded via **GitLab** from this website.
20
+ > **Note:** The program code was written in **Python 3** (version 3.13) and is an experimental version that will be developed further.
21
+
22
+ ---
23
+
24
+ ## Installation via pip
25
+ Installation via pip is not yet possible. The source code can therefore currently only be downloaded and integrated locally.
26
+
27
+ ---
28
+
29
+ ## Documentation and further information
30
+ Further information on the package can be found in the [documentation](./documentation_python.pdf).
31
+
32
+ ---
33
+
34
+ ## Source-Code Download
35
+ The code can be downloaded separately via the following link:
36
+
37
+ [code_version_0_1](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/CensoPy.py)
38
+
39
+ ---
40
+
41
+ ---
42
+
43
+ ## Examples
44
+ The code for some examples can be downloaded separately via the following links:
45
+
46
+ [Example-3-5-I](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-3-5-I.py)
47
+
48
+ [Example-3-6-I-HCS](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-3-6-I-HCS.py)
49
+
50
+ [Example-3-6-I](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-3-6-I.py)
51
+
52
+ [Example-3-7-I](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-3-7-I.py)
53
+
54
+ [Example-3-7-gen-I-HCS](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-3-7-gen-I-HCS.py)
55
+
56
+ [Example-3-7-gen-II-HCS](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-3-7-gen-II-HCS.py)
57
+
58
+ [Example-3-8-I-HCS](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-3-8-I-HCS.py)
59
+
60
+ [Example-3-8-I](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-3-8-I.py)
61
+
62
+ [Example-4-1-I-PCS](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-4-1-I-PCS.py)
63
+
64
+ [Example-4-1-II-PCS-extended-sample](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-4-1-II-PCS-extended-sample.py)
65
+
66
+ [Example-4-1-II-PCS-m8](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-4-1-II-PCS-m8.py)
67
+
68
+ [Example-4-1-II-PCS](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/examples/Example-4-1-II-PCS.py)
69
+
70
+ [HCS_plots-bivariate](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/Plots/HCS_plots-bivariate.py)
71
+
72
+ [HCS_plots-cdf](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/Plots/HCS_plots-cdf.py)
73
+
74
+ [HCS_plots-pdf](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/Plots/HCS_plots-pdf.py)
75
+
76
+ [R-interface-HCS_plots](https://gitlab.git.nrw/jakob/censopy/-/blob/main/_Code/R-interface/R-interface-HCS_plots.R)
77
+
78
+ ---
79
+
80
+ ## BibTeX Citation
81
+ ```
82
+ @Unpublished{Cramer2026a,
83
+ author = {Jakob I. Cramer and Erhard Cramer},
84
+ note = {submitted for publication},
85
+ title = {CensoPy – Statistical computations for exponentially distributed lifetimes under hybrid censoring},
86
+ year = {2026},
87
+ }
88
+ ```
89
+
90
+ ---
91
+
92
+ ## Errata and Contact</h1>
93
+ The author can be contacted regarding comments and corrections via [erhard.cramer@rwth-aachen.de](mailto:erhard.cramer@rwth-aachen.de)
94
+
95
+ ### Reported errata
96
+ ```
97
+
98
+ ```
@@ -0,0 +1,9 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ _Code/CensoPy.py
5
+ _Code/CensoPy.egg-info/PKG-INFO
6
+ _Code/CensoPy.egg-info/SOURCES.txt
7
+ _Code/CensoPy.egg-info/dependency_links.txt
8
+ _Code/CensoPy.egg-info/requires.txt
9
+ _Code/CensoPy.egg-info/top_level.txt
@@ -0,0 +1,3 @@
1
+ numpy>=2.3.5
2
+ mpmath>=1.3.0
3
+ scikit-learn>=1.7.2
@@ -0,0 +1 @@
1
+ CensoPy
@@ -0,0 +1,823 @@
1
+ import mpmath as mp
2
+ from functools import lru_cache
3
+ import numpy as np
4
+ from sklearn.neighbors import KernelDensity
5
+
6
+ @lru_cache(maxsize=None)
7
+ def binom_cached(n, k):
8
+ return mp.binomial(n, k)
9
+
10
+ @lru_cache(maxsize=None)
11
+ def gamma_cached(k):
12
+ return mp.gamma(k)
13
+
14
+ @lru_cache(maxsize=None)
15
+ def factorial_cached(k):
16
+ return mp.factorial(k)
17
+
18
+ def calc_gammas(R):
19
+ n=len(R)
20
+ gammas=[]
21
+ for i in range(0,n):
22
+ gamma_i=mp.mpf(0)
23
+ for j in range(i,n):
24
+ gamma_i+=(mp.mpf(R[j])+1)
25
+ gammas.append(gamma_i)
26
+ gammas.append(0)
27
+ return gammas
28
+
29
+ def ker(X, x, kernel='gaussian', bandwidth=0.03):
30
+ X_2d = np.array(X).reshape(-1, 1)
31
+ kde = KernelDensity(kernel=kernel, bandwidth=bandwidth).fit(X_2d)
32
+ return np.exp(kde.score_samples([[x]]))
33
+
34
+ def gamma_pdf(x, k, theta):
35
+
36
+ #Parameter
37
+ x=mp.mpf(x)
38
+ k=mp.mpf(k)
39
+ theta=mp.mpf(theta)
40
+
41
+ if x < 0:
42
+ return mp.mpf("0")
43
+ return (x ** (k - 1)) * mp.exp(-x / theta) / (gamma_cached(k) * (theta ** k))
44
+
45
+ def gamma_cdf(x, k, theta):
46
+
47
+ #Parameter
48
+ x=mp.mpf(x)
49
+ k=mp.mpf(k)
50
+ theta=mp.mpf(theta)
51
+
52
+ if x < 0:
53
+ return mp.mpf("0")
54
+ sumb = mp.nsum(lambda b: mp.power(x/theta,b)/ factorial_cached(b), [0, k-1])
55
+ return 1 - mp.exp(-x/theta) * sumb
56
+
57
+ def bsplines_d_0(s, a, b):
58
+ if a <= s <= b:
59
+ return 1 / (b - a)
60
+ else:
61
+ return mp.mpf('0')
62
+
63
+ def bsplines_1(s, d, n, T):
64
+ if d == 1:
65
+ return bsplines_d_0(s, (n - d) * T, n * T)
66
+ else:
67
+ def term(i):
68
+ return mp.power(-1,i) * binom_cached(d, i) * mp.power(max((n - i) * T - s, 0), d - 1)
69
+ sumb = mp.nsum(lambda i: term(i), [0, d])
70
+ return sumb / (T**d * factorial_cached(d-1))
71
+
72
+ def bsplines_2(s, d, n, T):
73
+ if d == 1:
74
+ return bsplines_d_0(s, 0, n * T)
75
+ else:
76
+ def term(i):
77
+ return mp.power(-1,i)*binom_cached(d, i) * ((d - i) / (n - i)) * mp.power(max((n - i) * T - s, 0), d - 1)
78
+ sumb = mp.nsum(lambda i: term(i), [0, d-1])
79
+ main = sumb / (T**d * factorial_cached(d-1))
80
+ correction = mp.power(-1, d) * d * factorial_cached(n - d) / (factorial_cached(n) * T**d)* mp.power(max(-s, 0), d - 1)
81
+ return main + correction
82
+
83
+ def H(s, d, n, T, theta, i):
84
+ def term(k, t):
85
+ return mp.power(-1, d-1-k)*mp.power(t,k)/factorial_cached(k)
86
+ def summe(t):
87
+ return mp.exp(t)*factorial_cached(d-1)*mp.nsum(lambda k: term(k, t), [0, d-1])
88
+
89
+ return mp.power(theta, d)*mp.exp(-(n-i)*T/theta)*(summe((n-i)*T/theta) - summe(max((n-i)*T - s,0)/theta))
90
+
91
+ def int_bsplines_d_0(s, a, b, theta):
92
+ if a <= s <= b:
93
+ return theta / (b - a) * (mp.exp(-a / theta) - mp.exp(-s / theta))
94
+ elif s>b:
95
+ return theta / (b - a) * (mp.exp(-a / theta) - mp.exp(-b / theta))
96
+ else:
97
+ return mp.mpf('0')
98
+
99
+ def int_bsplines_1(s, d, n, T, theta):
100
+ if d == 1:
101
+ return int_bsplines_d_0(s, (n - 1) * T, n * T, theta)
102
+ else:
103
+ def term(i):
104
+ return mp.power(-1,i) * binom_cached(d, i) * H(s, d, n, T, theta, i)
105
+ sumb = mp.nsum(lambda i: term(i), [0, d])
106
+ return sumb / (T ** d * factorial_cached(d-1))
107
+
108
+ def int_bsplines_2(s, d, n, T, theta):
109
+ if d == 1:
110
+ return int_bsplines_d_0(s, 0, n * T, theta)
111
+ else:
112
+ def term(i):
113
+ return mp.power(-1,i)* binom_cached(d, i) * ((d - i) / (n - i)) * H(s, d, n, T, theta, i)
114
+ sumb = mp.nsum(lambda i: term(i), [0, d-1])
115
+ return sumb / (mp.power(T,d) * factorial_cached(d-1))
116
+
117
+ @lru_cache(maxsize=None)
118
+ def bsplines_de_boor(x, j, k, t):
119
+ if k == 0:
120
+ if t[j] <= x < t[j+1]:
121
+ return 1.0
122
+ else:
123
+ return 0.0
124
+
125
+ term1 = 0.0
126
+ term2 = 0.0
127
+
128
+ if t[j+k] - t[j] != 0:
129
+ term1 = ((x - t[j]) / (t[j+k] - t[j])) * bsplines_de_boor(x, j, k-1, t)
130
+
131
+ if t[j+k+1] - t[j+1] != 0:
132
+ term2 = ((t[j+k+1] - x) / (t[j+k+1] - t[j+1])) * bsplines_de_boor(x, j+1, k-1, t)
133
+
134
+ return term1 + term2
135
+
136
+ @lru_cache(maxsize=None)
137
+ def int_bsplines_de_boor(x, k, t, theta):
138
+ t=tuple(t)
139
+
140
+ if k == 0:
141
+ lower=max(t[0],mp.mpf(0))
142
+ upper=min(x,t[1])
143
+ if upper<=lower:
144
+ return mp.mpf(0)
145
+ return theta * (mp.exp(-lower / theta)-mp.exp(-upper/theta))
146
+
147
+ B0 = bsplines_de_boor(t[0], 0, k, t)
148
+ Bs = bsplines_de_boor(x, 0, k, t)
149
+
150
+ boundary = -theta * (Bs*mp.exp(-x/theta) - B0*mp.exp(-t[0]/theta))
151
+ I_lo = int_bsplines_de_boor(x, k-1, t[:-1], theta)
152
+ I_hi = int_bsplines_de_boor(x, k-1, t[1:], theta)
153
+ term = theta * k * (I_lo/(t[k]-t[0]) - I_hi/(t[k+1]-t[1]))
154
+ return boundary + term
155
+
156
+ def HCS_pdf_1_ana(s, d, n, T, theta):
157
+
158
+ #Parameter
159
+ s=mp.mpf(s)
160
+ T=mp.mpf(T)
161
+ theta=mp.mpf(theta)
162
+
163
+ return binom_cached(n, d)*mp.power(T/theta,d)*bsplines_1(s, d, n, T)*mp.exp(-s/theta)
164
+
165
+ def HCS_pdf_2_ana(s, m, n, T, theta):
166
+
167
+ #Parameter
168
+ s=mp.mpf(s)
169
+ T=mp.mpf(T)
170
+ theta=mp.mpf(theta)
171
+
172
+ return binom_cached(n, m)*mp.power(T/theta,m)*bsplines_2(s, m, n, T)*mp.exp(-s/theta)
173
+
174
+ def HCS_cdf_1_ana(s, d, n, T, theta):
175
+
176
+ #Parameter
177
+ s=mp.mpf(s)
178
+ T=mp.mpf(T)
179
+ theta=mp.mpf(theta)
180
+
181
+ return binom_cached(n, d)*mp.power(T/theta,d)*int_bsplines_1(s, d, n, T, theta)
182
+
183
+ def HCS_cdf_2_ana(s, m, n, T, theta):
184
+
185
+ #Parameter
186
+ s=mp.mpf(s)
187
+ T=mp.mpf(T)
188
+ theta=mp.mpf(theta)
189
+
190
+ return binom_cached(n, m)*mp.power(T/theta,m)*int_bsplines_2(s, m, n, T, theta)
191
+
192
+ def HCS_pdf_1_rec(s, d, n, T, theta):
193
+
194
+ #Parameter
195
+ s=mp.mpf(s)
196
+ T=mp.mpf(T)
197
+ theta=mp.mpf(theta)
198
+
199
+ t = tuple(mp.mpf((n - d + i) * T) for i in range(d + 1))
200
+
201
+ return binom_cached(n, d)*mp.power(T/theta,d)*(d * bsplines_de_boor(s, 0, d - 1, t)/ (t[d] - t[0]))*mp.exp(-s/theta)
202
+
203
+ def HCS_pdf_2_rec(s, m, n, T, theta):
204
+
205
+ #Parameter
206
+ s=mp.mpf(s)
207
+ T=mp.mpf(T)
208
+ theta=mp.mpf(theta)
209
+
210
+ t = (mp.mpf(0),) + tuple(mp.mpf((n - m + i) * T) for i in range(1, m + 1))
211
+
212
+ return binom_cached(n, m)*mp.power(T/theta,m)*(m * bsplines_de_boor(s, 0, m - 1, t)/ (t[m] - t[0]))*mp.exp(-s/theta)
213
+
214
+ def HCS_cdf_1_rec(s, d, n, T, theta):
215
+
216
+ #Parameter
217
+ s=mp.mpf(s)
218
+ T=mp.mpf(T)
219
+ theta=mp.mpf(theta)
220
+
221
+ t = tuple(mp.mpf((n - d + i) * T) for i in range(d + 1))
222
+
223
+ return binom_cached(n, d)*mp.power(T/theta,d)*(d * int_bsplines_de_boor(s, d-1, t, theta) / (t[d] - t[0]))
224
+
225
+ def HCS_cdf_2_rec(s, m, n, T, theta):
226
+
227
+ #Parameter
228
+ s=mp.mpf(s)
229
+ T=mp.mpf(T)
230
+ theta=mp.mpf(theta)
231
+
232
+ t = (mp.mpf(0),) + tuple(mp.mpf((n - m + i) * T) for i in range(1, m + 1))
233
+
234
+ return binom_cached(n, m)*mp.power(T/theta,m)*(m * int_bsplines_de_boor(s, m-1, t, theta) / (t[m] - t[0]))
235
+
236
+ def PCS_pdf_1_rec(s, d, R, T, theta):
237
+
238
+ #Parameter
239
+ s=mp.mpf(s)
240
+ T=mp.mpf(T)
241
+ theta=mp.mpf(theta)
242
+ gammas=calc_gammas(R)
243
+
244
+ t = tuple(mp.mpf(gammas[d-i] * T) for i in range(0, d+1))
245
+
246
+ product_gammas=gammas[:d]
247
+
248
+ return mp.power(T/theta,d)*mp.fprod(product_gammas)/factorial_cached(d)*(d * bsplines_de_boor(s, 0, d - 1, t)/ (t[d] - t[0]))*mp.exp(-s/theta)
249
+
250
+ def PCS_pdf_2_rec(s, n, R, T, theta):
251
+
252
+ #Parameter
253
+ s=mp.mpf(s)
254
+ T=mp.mpf(T)
255
+ theta=mp.mpf(theta)
256
+ gammas=calc_gammas(R)
257
+
258
+ t = (mp.mpf(0),) +tuple(mp.mpf(gammas[n - 1 - i] * T) for i in range(0, n))
259
+
260
+ product_gammas=gammas[:n]
261
+
262
+ return mp.power(T/theta,n)*mp.fprod(product_gammas)/factorial_cached(n)*(n * bsplines_de_boor(s, 0, n - 1, t)/ (t[n] - t[0]))*mp.exp(-s/theta)
263
+
264
+ def PCS_cdf_1_rec(s, d, R, T, theta):
265
+
266
+ #Parameter
267
+ s=mp.mpf(s)
268
+ T=mp.mpf(T)
269
+ theta=mp.mpf(theta)
270
+ gammas=calc_gammas(R)
271
+
272
+ t = tuple(mp.mpf(gammas[d-i] * T) for i in range(0, d+1))
273
+
274
+ product_gammas=gammas[:d]
275
+
276
+ return mp.power(T/theta,d)*mp.fprod(product_gammas)/factorial_cached(d)*(d * int_bsplines_de_boor(s, d-1, t, theta) / (t[d] - t[0]))
277
+
278
+ def PCS_cdf_2_rec(s, n, R, T, theta):
279
+
280
+ #Parameter
281
+ s=mp.mpf(s)
282
+ T=mp.mpf(T)
283
+ theta=mp.mpf(theta)
284
+ gammas=calc_gammas(R)
285
+
286
+ t = (mp.mpf(0),) +tuple(mp.mpf(gammas[n - 1 - i] * T) for i in range(0, n))
287
+
288
+ product_gammas=gammas[:n]
289
+
290
+ return mp.power(T/theta,n)*mp.fprod(product_gammas)/factorial_cached(n)*(n * int_bsplines_de_boor(s, n-1, t, theta) / (t[n] - t[0]))
291
+
292
+
293
+ class C_I_HCS:
294
+ def __init__(self, n, thresholds, censoring_numbers, Digits=200, Method="analytic"):
295
+
296
+ self.method=Method
297
+
298
+ method_catalog = {
299
+ "analytic": {"pdf_1": HCS_pdf_1_ana, "pdf_2": HCS_pdf_2_ana, "cdf_1": HCS_cdf_1_ana,"cdf_2": HCS_cdf_2_ana},
300
+ "recursive": {"pdf_1": HCS_pdf_1_rec, "pdf_2": HCS_pdf_2_rec, "cdf_1": HCS_cdf_1_rec,"cdf_2": HCS_cdf_2_rec}
301
+ }
302
+
303
+ method_clean = self.method.lower()
304
+
305
+ self.pdf_1 = method_catalog[method_clean]["pdf_1"]
306
+ self.pdf_2 = method_catalog[method_clean]["pdf_2"]
307
+ self.cdf_1 = method_catalog[method_clean]["cdf_1"]
308
+ self.cdf_2 = method_catalog[method_clean]["cdf_2"]
309
+
310
+ self.n=n
311
+ self.thresholds=thresholds
312
+ self.censoring_numbers=censoring_numbers
313
+ self.Digits=Digits
314
+ self.k=len(self.thresholds)
315
+
316
+ mp.mp.dps=Digits
317
+
318
+ def pdf_TTT(self,t, theta):
319
+ sum1=0
320
+ for j in range(1, self.k):
321
+ for d in range(self.censoring_numbers[j], self.censoring_numbers[j-1]):
322
+ sum1 +=self.pdf_1(t, d, self.n, self.thresholds[j-1], theta)
323
+ for d in range(1, self.censoring_numbers[self.k-1]):
324
+ sum1 +=self.pdf_1(t, d, self.n, self.thresholds[self.k-1], theta)
325
+ sum2=0
326
+ for j in range(1, self.k+1):
327
+ sum2+=self.pdf_2(t, self.censoring_numbers[j-1], self.n, self.thresholds[j-1], theta)
328
+ sum3=0
329
+ for j in range(2, self.k+1):
330
+ sum3+=self.pdf_2(t, self.censoring_numbers[j-1], self.n, self.thresholds[j-2], theta)
331
+ return float(sum1+sum2-sum3)
332
+
333
+ def cdf_TTT(self,t, theta):
334
+ sum1=0
335
+ for j in range(1, self.k):
336
+ for d in range(self.censoring_numbers[j], self.censoring_numbers[j-1]):
337
+ sum1 +=self.cdf_1(t, d, self.n, self.thresholds[j-1], theta)
338
+ for d in range(1, self.censoring_numbers[self.k-1]):
339
+ sum1 +=self.cdf_1(t, d, self.n, self.thresholds[self.k-1], theta)
340
+ sum2=0
341
+ for j in range(1, self.k+1):
342
+ sum2+=self.cdf_2(t, self.censoring_numbers[j-1], self.n, self.thresholds[j-1], theta)
343
+ sum3=0
344
+ for j in range(2, self.k+1):
345
+ sum3+=self.cdf_2(t, self.censoring_numbers[j-1], self.n, self.thresholds[j-2], theta)
346
+ return float(sum1+sum2-sum3)
347
+
348
+
349
+ def pdf_MLE(self,t,theta):
350
+ sum1=0
351
+ for j in range(1, self.k):
352
+ for d in range(self.censoring_numbers[j], self.censoring_numbers[j-1]):
353
+ sum1 +=d*self.pdf_1(d*t, d, self.n, self.thresholds[j-1], theta)
354
+ for d in range(1, self.censoring_numbers[self.k-1]):
355
+ sum1 +=d*self.pdf_1(d*t, d, self.n, self.thresholds[self.k-1], theta)
356
+ sum2=0
357
+ for j in range(1, self.k+1):
358
+ sum2+=self.censoring_numbers[j-1]*self.pdf_2(self.censoring_numbers[j-1]*t, self.censoring_numbers[j-1], self.n, self.thresholds[j-1], theta)
359
+ sum3=0
360
+ for j in range(2, self.k+1):
361
+ sum3+=self.censoring_numbers[j-1]*self.pdf_2(self.censoring_numbers[j-1]*t, self.censoring_numbers[j-1], self.n, self.thresholds[j-2], theta)
362
+ return float(1/(1-mp.exp(-self.n*self.thresholds[-1]/theta))*(sum1+sum2-sum3))
363
+
364
+ def cdf_MLE(self,t,theta):
365
+ sum1=0
366
+ for j in range(1, self.k):
367
+ for d in range(self.censoring_numbers[j], self.censoring_numbers[j-1]):
368
+ sum1 +=self.cdf_1(d*t, d, self.n, self.thresholds[j-1], theta)
369
+ for d in range(1, self.censoring_numbers[self.k-1]):
370
+ sum1 +=self.cdf_1(d*t, d, self.n, self.thresholds[self.k-1], theta)
371
+ sum2=0
372
+ for j in range(1, self.k+1):
373
+ sum2+=self.cdf_2(self.censoring_numbers[j-1]*t, self.censoring_numbers[j-1], self.n, self.thresholds[j-1], theta)
374
+ sum3=0
375
+ for j in range(2, self.k+1):
376
+ sum3+=self.cdf_2(self.censoring_numbers[j-1]*t, self.censoring_numbers[j-1], self.n, self.thresholds[j-2], theta)
377
+ return float(1/(1-mp.exp(-self.n*self.thresholds[-1]/theta))*(sum1+sum2-sum3))
378
+
379
+ def calc_MLE(self, data):
380
+ data=np.array(data)
381
+ thresholds_array=np.array(self.thresholds)
382
+ censoring_numbers_array=np.array(self.censoring_numbers)
383
+
384
+ D_array = np.searchsorted(data, thresholds_array, side="right")
385
+ X_mn_array = data[censoring_numbers_array - 1]
386
+
387
+ D_HCS=np.max(np.r_[np.minimum(censoring_numbers_array, D_array)])
388
+
389
+ if D_HCS==0:
390
+ return 0,0,0,0
391
+
392
+ W_HCS=np.max(np.r_[np.minimum(X_mn_array,thresholds_array)])
393
+
394
+
395
+ TTT_D_HCS=np.sum(data[:D_HCS])+(self.n-D_HCS)*W_HCS
396
+
397
+ theta_hat=TTT_D_HCS/D_HCS
398
+ return float(D_HCS), float(W_HCS), float(TTT_D_HCS), float(theta_hat)
399
+
400
+
401
+ def monte_carlo(self, theta, N):
402
+ q=0
403
+ D_HCS_array=[]
404
+ W_HCS_array=[]
405
+ TTT_D_HCS_array=[]
406
+ theta_array=[]
407
+ data=[]
408
+
409
+ for i in range(0, N):
410
+ data_i=np.random.exponential(size=self.n, scale=theta)
411
+ data_i=np.sort(data_i)
412
+
413
+ D_HCS_i, W_HCS_i, TTT_D_HCS_i, theta_hat_i = self.calc_MLE(data_i)
414
+
415
+ if D_HCS_i == 0:
416
+ q += 1
417
+ continue
418
+
419
+ D_HCS_array.append(D_HCS_i)
420
+ W_HCS_array.append(W_HCS_i)
421
+ TTT_D_HCS_array.append(TTT_D_HCS_i)
422
+ theta_array.append(theta_hat_i)
423
+ data.append(data_i)
424
+
425
+ return D_HCS_array, W_HCS_array, TTT_D_HCS_array, theta_array, q, data
426
+
427
+
428
+ class C_II_HCS:
429
+ def __init__(self, n, thresholds, censoring_numbers, Digits=200, Method="analytic"):
430
+ if Method == 'recursive':
431
+ thresholds = [mp.mpf('1e30') if x == "inf" else x for x in thresholds]
432
+ elif Method == 'analytic':
433
+ thresholds = [mp.inf if x == "inf" else x for x in thresholds]
434
+
435
+ self.method=Method
436
+
437
+ method_catalog = {
438
+ "analytic": {"pdf_1": HCS_pdf_1_ana, "pdf_2": HCS_pdf_2_ana, "cdf_1": HCS_cdf_1_ana,"cdf_2": HCS_cdf_2_ana},
439
+ "recursive": {"pdf_1": HCS_pdf_1_rec, "pdf_2": HCS_pdf_2_rec, "cdf_1": HCS_cdf_1_rec,"cdf_2": HCS_cdf_2_rec}
440
+ }
441
+
442
+ method_clean = self.method.lower()
443
+
444
+ self.pdf_1 = method_catalog[method_clean]["pdf_1"]
445
+ self.pdf_2 = method_catalog[method_clean]["pdf_2"]
446
+ self.cdf_1 = method_catalog[method_clean]["cdf_1"]
447
+ self.cdf_2 = method_catalog[method_clean]["cdf_2"]
448
+
449
+ self.n=n
450
+ self.thresholds=thresholds
451
+ self.censoring_numbers=censoring_numbers
452
+ self.Digits=Digits
453
+ self.k=len(self.thresholds)
454
+
455
+ mp.mp.dps=Digits
456
+
457
+ def pdf_TTT(self,t,theta):
458
+ sum1=0
459
+ for j in range(1, self.k):
460
+ for d in range(self.censoring_numbers[j], self.censoring_numbers[j-1]):
461
+ sum1 +=self.pdf_1(t, d, self.n, self.thresholds[j-1], theta)
462
+ sum2=0
463
+ for j in range(1, self.k):
464
+ sum2+=self.pdf_2(t, self.censoring_numbers[j-1], self.n, self.thresholds[j-1], theta)
465
+ sum3=0
466
+ for j in range(2, self.k+1):
467
+ sum3+=self.pdf_2(t, self.censoring_numbers[j-1], self.n, self.thresholds[j-2], theta)
468
+ return float(gamma_pdf(t, self.censoring_numbers[-1], theta)+sum1+sum2-sum3)
469
+
470
+ def cdf_TTT(self,t,theta):
471
+ sum1=0
472
+ for j in range(1, self.k):
473
+ for d in range(self.censoring_numbers[j], self.censoring_numbers[j-1]):
474
+ sum1 +=self.cdf_1(t, d, self.n, self.thresholds[j-1], theta)
475
+ sum2=0
476
+ for j in range(1, self.k):
477
+ sum2+=self.cdf_2(t, self.censoring_numbers[j-1], self.n, self.thresholds[j-1], theta)
478
+ sum3=0
479
+ for j in range(2, self.k+1):
480
+ sum3+=self.cdf_2(t, self.censoring_numbers[j-1], self.n, self.thresholds[j-2], theta)
481
+ return float(gamma_cdf(t, self.censoring_numbers[-1], theta)+sum1+sum2-sum3)
482
+
483
+ def pdf_MLE(self,t,theta):
484
+ sum1=0
485
+ for j in range(1, self.k):
486
+ for d in range(self.censoring_numbers[j], self.censoring_numbers[j-1]):
487
+ sum1 +=d*self.pdf_1(d*t, d, self.n, self.thresholds[j-1], theta)
488
+ sum2=0
489
+ for j in range(1, self.k):
490
+ sum2+=self.censoring_numbers[j-1]*self.pdf_2(self.censoring_numbers[j-1]*t, self.censoring_numbers[j-1], self.n, self.thresholds[j-1], theta)
491
+ sum3=0
492
+ for j in range(2, self.k+1):
493
+ sum3+=self.censoring_numbers[j-1]*self.pdf_2(self.censoring_numbers[j-1]*t, self.censoring_numbers[j-1], self.n, self.thresholds[j-2], theta)
494
+ return float(self.censoring_numbers[-1]*gamma_pdf(self.censoring_numbers[-1]*t, self.censoring_numbers[-1], theta)+sum1+sum2-sum3)
495
+
496
+ def cdf_MLE(self,t,theta):
497
+ sum1=0
498
+ for j in range(1, self.k):
499
+ for d in range(self.censoring_numbers[j], self.censoring_numbers[j-1]):
500
+ sum1 +=self.cdf_1(d*t, d, self.n, self.thresholds[j-1], theta)
501
+ sum2=0
502
+ for j in range(1, self.k):
503
+ sum2+=self.cdf_2(self.censoring_numbers[j-1]*t, self.censoring_numbers[j-1], self.n, self.thresholds[j-1], theta)
504
+ sum3=0
505
+ for j in range(2, self.k+1):
506
+ sum3+=self.cdf_2(self.censoring_numbers[j-1]*t, self.censoring_numbers[j-1], self.n, self.thresholds[j-2], theta)
507
+ return float(gamma_cdf(self.censoring_numbers[-1]*t, self.censoring_numbers[-1], theta)+sum1+sum2-sum3)
508
+
509
+ def calc_MLE(self, data):
510
+ data=np.array(data)
511
+
512
+ thresholds_array=np.array(self.thresholds)
513
+ censoring_numbers_array=np.array(self.censoring_numbers)
514
+
515
+ D_array = np.searchsorted(data, thresholds_array, side="right")
516
+ X_mn_array = data[censoring_numbers_array - 1]
517
+
518
+ D_HCS = np.max(np.r_[censoring_numbers_array[-1],np.minimum(censoring_numbers_array[:-1], D_array[:-1][::-1])])
519
+
520
+ W_HCS = np.max(np.r_[X_mn_array[-1],np.minimum(X_mn_array[:-1], thresholds_array[:-1][::-1])])
521
+
522
+ TTT_D_HCS=np.sum(data[:D_HCS])+(self.n-D_HCS)*W_HCS
523
+
524
+ theta_hat=TTT_D_HCS/D_HCS
525
+
526
+ return float(D_HCS), float(W_HCS), float(TTT_D_HCS), float(theta_hat)
527
+
528
+ def monte_carlo(self, theta, N):
529
+ q=0
530
+ D_HCS_array=[]
531
+ W_HCS_array=[]
532
+ TTT_D_HCS_array=[]
533
+ theta_array=[]
534
+ data=[]
535
+
536
+ for i in range(0, N):
537
+ data_i=np.random.exponential(size=self.n, scale=theta)
538
+ data_i=np.sort(data_i)
539
+
540
+ D_HCS_i, W_HCS_i, TTT_D_HCS_i, theta_hat_i = self.calc_MLE(data_i)
541
+
542
+ if D_HCS_i == 0:
543
+ q += 1
544
+ continue
545
+
546
+ D_HCS_array.append(D_HCS_i)
547
+ W_HCS_array.append(W_HCS_i)
548
+ TTT_D_HCS_array.append(TTT_D_HCS_i)
549
+ theta_array.append(theta_hat_i)
550
+ data.append(data_i)
551
+
552
+ return D_HCS_array, W_HCS_array, TTT_D_HCS_array, theta_array, q, data
553
+
554
+ class C_I_PCS:
555
+ def __init__(self, R, thresholds, censoring_numbers, Digits=200, Method='recursive'):
556
+
557
+ self.method=Method
558
+
559
+ method_catalog = {
560
+ "recursive": {"pdf_1": PCS_pdf_1_rec, "pdf_2": PCS_pdf_2_rec, "cdf_1": PCS_cdf_1_rec,"cdf_2": PCS_cdf_2_rec}
561
+ }
562
+
563
+ method_clean = self.method.lower()
564
+
565
+ self.pdf_1 = method_catalog[method_clean]["pdf_1"]
566
+ self.pdf_2 = method_catalog[method_clean]["pdf_2"]
567
+ self.cdf_1 = method_catalog[method_clean]["cdf_1"]
568
+ self.cdf_2 = method_catalog[method_clean]["cdf_2"]
569
+
570
+ self.R=R
571
+ self.thresholds=thresholds
572
+ self.censoring_numbers=censoring_numbers
573
+ self.Digits=Digits
574
+ self.k=len(self.thresholds)
575
+
576
+ mp.mp.dps=Digits
577
+
578
+ def pdf_TTT(self,t, theta):
579
+ sum1=0
580
+ for j in range(1, self.k):
581
+ for d in range(self.censoring_numbers[j], self.censoring_numbers[j-1]):
582
+ sum1 +=self.pdf_1(t, d, self.R, self.thresholds[j-1], theta)
583
+ for d in range(1, self.censoring_numbers[self.k-1]):
584
+ sum1 +=self.pdf_1(t, d, self.R, self.thresholds[self.k-1], theta)
585
+ sum2=0
586
+ for j in range(1, self.k+1):
587
+ sum2+=self.pdf_2(t, self.censoring_numbers[j-1], self.R, self.thresholds[j-1], theta)
588
+ sum3=0
589
+ for j in range(2, self.k+1):
590
+ sum3+=self.pdf_2(t, self.censoring_numbers[j-1], self.R, self.thresholds[j-2], theta)
591
+ return float(sum1+sum2-sum3)
592
+
593
+
594
+ def cdf_TTT(self,t, theta):
595
+ sum1=0
596
+ for j in range(1, self.k):
597
+ for d in range(self.censoring_numbers[j], self.censoring_numbers[j-1]):
598
+ sum1 +=self.cdf_1(t, d, self.R, self.thresholds[j-1], theta)
599
+ for d in range(1, self.censoring_numbers[self.k-1]):
600
+ sum1 +=self.cdf_1(t, d, self.R, self.thresholds[self.k-1], theta)
601
+ sum2=0
602
+ for j in range(1, self.k+1):
603
+ sum2+=self.cdf_2(t, self.censoring_numbers[j-1], self.R, self.thresholds[j-1], theta)
604
+ sum3=0
605
+ for j in range(2, self.k+1):
606
+ sum3+=self.cdf_2(t, self.censoring_numbers[j-1], self.R, self.thresholds[j-2], theta)
607
+ return float(sum1+sum2-sum3)
608
+
609
+ def pdf_MLE(self,t,theta):
610
+ sum1=0
611
+ for j in range(1, self.k):
612
+ for d in range(self.censoring_numbers[j], self.censoring_numbers[j-1]):
613
+ sum1 +=d*self.pdf_1(d*t, d, self.R, self.thresholds[j-1], theta)
614
+ for d in range(1, self.censoring_numbers[self.k-1]):
615
+ sum1 +=d*self.pdf_1(d*t, d, self.R, self.thresholds[self.k-1], theta)
616
+ sum2=0
617
+ for j in range(1, self.k+1):
618
+ sum2+=self.censoring_numbers[j-1]*self.pdf_2(self.censoring_numbers[j-1]*t, self.censoring_numbers[j-1], self.R, self.thresholds[j-1], theta)
619
+ sum3=0
620
+ for j in range(2, self.k+1):
621
+ sum3+=self.censoring_numbers[j-1]*self.pdf_2(self.censoring_numbers[j-1]*t, self.censoring_numbers[j-1], self.R, self.thresholds[j-2], theta)
622
+ return float(1/(1-mp.exp(-(sum(self.R)+len(self.R))*self.thresholds[-1]/theta))*(sum1+sum2-sum3))
623
+
624
+
625
+ def cdf_MLE(self,t,theta):
626
+ sum1=0
627
+ for j in range(1, self.k):
628
+ for d in range(self.censoring_numbers[j], self.censoring_numbers[j-1]):
629
+ sum1 +=self.cdf_1(d*t, d, self.R, self.thresholds[j-1], theta)
630
+ for d in range(1, self.censoring_numbers[self.k-1]):
631
+ sum1 +=self.cdf_1(d*t, d, self.R, self.thresholds[self.k-1], theta)
632
+ sum2=0
633
+ for j in range(1, self.k+1):
634
+ sum2+=self.cdf_2(self.censoring_numbers[j-1]*t, self.censoring_numbers[j-1], self.R, self.thresholds[j-1], theta)
635
+ sum3=0
636
+ for j in range(2, self.k+1):
637
+ sum3+=self.cdf_2(self.censoring_numbers[j-1]*t, self.censoring_numbers[j-1], self.R, self.thresholds[j-2], theta)
638
+ return float(1/(1-mp.exp(-(sum(self.R)+len(self.R))*self.thresholds[-1]/theta))*(sum1+sum2-sum3))
639
+
640
+ def calc_MLE(self, data):
641
+ data=np.array(data)
642
+ thresholds_array=np.array(self.thresholds)
643
+ censoring_numbers_array=np.array(self.censoring_numbers)
644
+
645
+ D_array = np.searchsorted(data, thresholds_array, side="right")
646
+ X_mn_array = data[censoring_numbers_array - 1]
647
+
648
+ D_HCS=np.max(np.r_[np.minimum(censoring_numbers_array, D_array)])
649
+
650
+ if D_HCS==0:
651
+ return 0,0,0,0
652
+
653
+ W_HCS=np.max(np.r_[np.minimum(X_mn_array,thresholds_array)])
654
+
655
+ R_array=np.array(self.R)
656
+ gammas= calc_gammas(self.R)
657
+ TTT_D_HCS=np.sum((R_array[:D_HCS]+1)*data[:D_HCS])+gammas[D_HCS]*W_HCS
658
+
659
+ theta_hat=TTT_D_HCS/D_HCS
660
+ return float(D_HCS), float(W_HCS), float(TTT_D_HCS), float(theta_hat)
661
+
662
+
663
+ def monte_carlo(self, theta, N):
664
+ q=0
665
+ D_HCS_array=[]
666
+ W_HCS_array=[]
667
+ TTT_D_HCS_array=[]
668
+ theta_array=[]
669
+ data=[]
670
+
671
+ for i in range(0, N):
672
+ v=np.random.exponential(size=len(self.R), scale=theta)
673
+ gamma=calc_gammas(self.R)
674
+ data_i=[0]
675
+ for j in range(0, len(self.R)):
676
+ data_i.append(v[j]/gamma[j]+data_i[j])
677
+ data_i.pop(0)
678
+
679
+ D_HCS_i, W_HCS_i, TTT_D_HCS_i, theta_hat_i = self.calc_MLE(data_i)
680
+
681
+ if D_HCS_i == 0:
682
+ q += 1
683
+ continue
684
+
685
+ D_HCS_array.append(D_HCS_i)
686
+ W_HCS_array.append(W_HCS_i)
687
+ TTT_D_HCS_array.append(TTT_D_HCS_i)
688
+ theta_array.append(theta_hat_i)
689
+ data.append(data_i)
690
+
691
+ return D_HCS_array, W_HCS_array, TTT_D_HCS_array, theta_array, q, data
692
+
693
+ class C_II_PCS:
694
+ def __init__(self, R, thresholds, censoring_numbers, Digits=200, Method='recursive'):
695
+ if Method == 'recursive':
696
+ thresholds = [mp.mpf('1e30') if x == "inf" else x for x in thresholds]
697
+
698
+ self.method=Method
699
+
700
+ method_catalog = {
701
+ "recursive": {"pdf_1": PCS_pdf_1_rec, "pdf_2": PCS_pdf_2_rec, "cdf_1": PCS_cdf_1_rec,"cdf_2": PCS_cdf_2_rec}
702
+ }
703
+
704
+ method_clean = self.method.lower()
705
+
706
+ self.pdf_1 = method_catalog[method_clean]["pdf_1"]
707
+ self.pdf_2 = method_catalog[method_clean]["pdf_2"]
708
+ self.cdf_1 = method_catalog[method_clean]["cdf_1"]
709
+ self.cdf_2 = method_catalog[method_clean]["cdf_2"]
710
+
711
+ self.R=R
712
+ self.thresholds=thresholds
713
+ self.censoring_numbers=censoring_numbers
714
+ self.Digits=Digits
715
+ self.k=len(self.thresholds)
716
+
717
+ mp.mp.dps=Digits
718
+
719
+ def pdf_TTT(self,t,theta):
720
+ sum1=0
721
+ for j in range(1, self.k):
722
+ for d in range(self.censoring_numbers[j], self.censoring_numbers[j-1]):
723
+ sum1 +=self.pdf_1(t, d, self.R, self.thresholds[j-1], theta)
724
+ sum2=0
725
+ for j in range(1, self.k):
726
+ sum2+=self.pdf_2(t, self.censoring_numbers[j-1], self.R, self.thresholds[j-1], theta)
727
+ sum3=0
728
+ for j in range(2, self.k+1):
729
+ sum3+=self.pdf_2(t, self.censoring_numbers[j-1], self.R, self.thresholds[j-2], theta)
730
+ return float(gamma_pdf(t, self.censoring_numbers[-1], theta)+sum1+sum2-sum3)
731
+
732
+
733
+ def cdf_TTT(self,t,theta):
734
+ sum1=0
735
+ for j in range(1, self.k):
736
+ for d in range(self.censoring_numbers[j], self.censoring_numbers[j-1]):
737
+ sum1 +=self.cdf_1(t, d, self.R, self.thresholds[j-1], theta)
738
+ sum2=0
739
+ for j in range(1, self.k):
740
+ sum2+=self.cdf_2(t, self.censoring_numbers[j-1], self.R, self.thresholds[j-1], theta)
741
+ sum3=0
742
+ for j in range(2, self.k+1):
743
+ sum3+=self.cdf_2(t, self.censoring_numbers[j-1], self.R, self.thresholds[j-2], theta)
744
+ return float(gamma_cdf(t, self.censoring_numbers[-1], theta)+sum1+sum2-sum3)
745
+
746
+ def pdf_MLE(self,t,theta):
747
+ sum1=0
748
+ for j in range(1, self.k):
749
+ for d in range(self.censoring_numbers[j], self.censoring_numbers[j-1]):
750
+ sum1 +=d*self.pdf_1(d*t, d, self.R, self.thresholds[j-1], theta)
751
+ sum2=0
752
+ for j in range(1, self.k):
753
+ sum2+=self.censoring_numbers[j-1]*self.pdf_2(self.censoring_numbers[j-1]*t, self.censoring_numbers[j-1], self.R, self.thresholds[j-1], theta)
754
+ sum3=0
755
+ for j in range(2, self.k+1):
756
+ sum3+=self.censoring_numbers[j-1]*self.pdf_2(self.censoring_numbers[j-1]*t, self.censoring_numbers[j-1], self.R, self.thresholds[j-2], theta)
757
+ return float(self.censoring_numbers[-1]*gamma_pdf(self.censoring_numbers[-1]*t, self.censoring_numbers[-1], theta)+sum1+sum2-sum3)
758
+
759
+
760
+ def cdf_MLE(self,t,theta):
761
+ sum1=0
762
+ for j in range(1, self.k):
763
+ for d in range(self.censoring_numbers[j], self.censoring_numbers[j-1]):
764
+ sum1 +=self.cdf_1(d*t, d, self.R, self.thresholds[j-1], theta)
765
+ sum2=0
766
+ for j in range(1, self.k):
767
+ sum2+=self.cdf_2(self.censoring_numbers[j-1]*t, self.censoring_numbers[j-1], self.R, self.thresholds[j-1], theta)
768
+ sum3=0
769
+ for j in range(2, self.k+1):
770
+ sum3+=self.cdf_2(self.censoring_numbers[j-1]*t, self.censoring_numbers[j-1], self.R, self.thresholds[j-2], theta)
771
+ return float(gamma_cdf(self.censoring_numbers[-1]*t, self.censoring_numbers[-1], theta)+sum1+sum2-sum3)
772
+
773
+ def calc_MLE(self, data):
774
+ data=np.array(data)
775
+
776
+ thresholds_array=np.array(self.thresholds)
777
+ censoring_numbers_array=np.array(self.censoring_numbers)
778
+
779
+ D_array = np.searchsorted(data, thresholds_array, side="right")
780
+ X_mn_array = data[censoring_numbers_array - 1]
781
+
782
+ D_HCS = np.max(np.r_[censoring_numbers_array[-1],np.minimum(censoring_numbers_array[:-1], D_array[:-1][::-1])])
783
+
784
+ W_HCS = np.max(np.r_[X_mn_array[-1],np.minimum(X_mn_array[:-1], thresholds_array[:-1][::-1])])
785
+
786
+ R_array=np.array(self.R)
787
+ gammas=calc_gammas(self.R)
788
+ TTT_D_HCS=np.sum((R_array[:D_HCS]+1)*data[:D_HCS])+gammas[D_HCS]*W_HCS
789
+
790
+ theta_hat=TTT_D_HCS/D_HCS
791
+
792
+ return float(D_HCS), float(W_HCS), float(TTT_D_HCS), float(theta_hat)
793
+
794
+ def monte_carlo(self, theta, N):
795
+ q=0
796
+ D_HCS_array=[]
797
+ W_HCS_array=[]
798
+ TTT_D_HCS_array=[]
799
+ theta_array=[]
800
+ data=[]
801
+
802
+ for i in range(0, N):
803
+ v=np.random.exponential(size=len(self.R), scale=theta)
804
+ gamma=calc_gammas(self.R)
805
+ data_i=[0]
806
+ for j in range(0, len(self.R)):
807
+ data_i.append(v[j]/gamma[j]+data_i[j])
808
+ data_i.pop(0)
809
+ data.append(data_i)
810
+
811
+ D_HCS_i, W_HCS_i, TTT_D_HCS_i, theta_hat_i = self.calc_MLE(data_i)
812
+
813
+ if D_HCS_i == 0:
814
+ q += 1
815
+ continue
816
+
817
+ D_HCS_array.append(D_HCS_i)
818
+ W_HCS_array.append(W_HCS_i)
819
+ TTT_D_HCS_array.append(TTT_D_HCS_i)
820
+ theta_array.append(theta_hat_i)
821
+ data.append(data_i)
822
+
823
+ return D_HCS_array, W_HCS_array, TTT_D_HCS_array, theta_array, q, data
@@ -0,0 +1,27 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "CensoPy"
7
+ version = "0.1.0"
8
+ description = "CensoPy - Statistical computations for exponentially distributed lifetimes under hybrid censoring"
9
+ readme = "README.md"
10
+ requires-python = ">=3.13"
11
+ license-files = ["LICENSE"]
12
+ authors = [
13
+ {name = "Jakob Cramer"},{name="Erhard Cramer"}
14
+ ]
15
+
16
+ dependencies = [
17
+ "numpy>=2.3.5",
18
+ "mpmath>=1.3.0",
19
+ "scikit-learn>=1.7.2",
20
+ ]
21
+
22
+ [project.urls]
23
+ Repository = "https://gitlab.git.nrw/jakob/censopy"
24
+
25
+ [tool.setuptools]
26
+ package-dir = { "" = "_Code" }
27
+ py-modules = ["CensoPy"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+