machinegnostics 0.0.1__py3-none-any.whl
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.
- __init__.py +0 -0
- machinegnostics/__init__.py +24 -0
- machinegnostics/magcal/__init__.py +37 -0
- machinegnostics/magcal/characteristics.py +460 -0
- machinegnostics/magcal/criteria_eval.py +268 -0
- machinegnostics/magcal/criterion.py +140 -0
- machinegnostics/magcal/data_conversion.py +381 -0
- machinegnostics/magcal/gcor.py +64 -0
- machinegnostics/magcal/gdf/__init__.py +2 -0
- machinegnostics/magcal/gdf/base_df.py +39 -0
- machinegnostics/magcal/gdf/base_distfunc.py +1202 -0
- machinegnostics/magcal/gdf/base_egdf.py +823 -0
- machinegnostics/magcal/gdf/base_eldf.py +830 -0
- machinegnostics/magcal/gdf/base_qgdf.py +1234 -0
- machinegnostics/magcal/gdf/base_qldf.py +1019 -0
- machinegnostics/magcal/gdf/cluster_analysis.py +456 -0
- machinegnostics/magcal/gdf/data_cluster.py +975 -0
- machinegnostics/magcal/gdf/data_intervals.py +853 -0
- machinegnostics/magcal/gdf/data_membership.py +536 -0
- machinegnostics/magcal/gdf/der_egdf.py +243 -0
- machinegnostics/magcal/gdf/distfunc_engine.py +841 -0
- machinegnostics/magcal/gdf/egdf.py +324 -0
- machinegnostics/magcal/gdf/eldf.py +297 -0
- machinegnostics/magcal/gdf/eldf_intv.py +609 -0
- machinegnostics/magcal/gdf/eldf_ma.py +627 -0
- machinegnostics/magcal/gdf/homogeneity.py +1218 -0
- machinegnostics/magcal/gdf/intv_engine.py +1523 -0
- machinegnostics/magcal/gdf/marginal_intv_analysis.py +558 -0
- machinegnostics/magcal/gdf/qgdf.py +289 -0
- machinegnostics/magcal/gdf/qldf.py +296 -0
- machinegnostics/magcal/gdf/scedasticity.py +197 -0
- machinegnostics/magcal/gdf/wedf.py +181 -0
- machinegnostics/magcal/gdf/z0_estimator.py +1047 -0
- machinegnostics/magcal/layer_base.py +42 -0
- machinegnostics/magcal/layer_history_base.py +74 -0
- machinegnostics/magcal/layer_io_process_base.py +238 -0
- machinegnostics/magcal/layer_param_base.py +448 -0
- machinegnostics/magcal/mg_weights.py +36 -0
- machinegnostics/magcal/sample_characteristics.py +532 -0
- machinegnostics/magcal/scale_optimization.py +185 -0
- machinegnostics/magcal/scale_param.py +313 -0
- machinegnostics/magcal/util/__init__.py +0 -0
- machinegnostics/magcal/util/dis_docstring.py +18 -0
- machinegnostics/magcal/util/logging.py +24 -0
- machinegnostics/magcal/util/min_max_float.py +34 -0
- machinegnostics/magnet/__init__.py +0 -0
- machinegnostics/metrics/__init__.py +28 -0
- machinegnostics/metrics/accu.py +61 -0
- machinegnostics/metrics/accuracy.py +67 -0
- machinegnostics/metrics/auto_correlation.py +183 -0
- machinegnostics/metrics/auto_covariance.py +204 -0
- machinegnostics/metrics/cls_report.py +130 -0
- machinegnostics/metrics/conf_matrix.py +93 -0
- machinegnostics/metrics/correlation.py +178 -0
- machinegnostics/metrics/cross_variance.py +167 -0
- machinegnostics/metrics/divi.py +82 -0
- machinegnostics/metrics/evalmet.py +109 -0
- machinegnostics/metrics/f1_score.py +128 -0
- machinegnostics/metrics/gmmfe.py +108 -0
- machinegnostics/metrics/hc.py +141 -0
- machinegnostics/metrics/mae.py +72 -0
- machinegnostics/metrics/mean.py +117 -0
- machinegnostics/metrics/median.py +122 -0
- machinegnostics/metrics/mg_r2.py +167 -0
- machinegnostics/metrics/mse.py +78 -0
- machinegnostics/metrics/precision.py +119 -0
- machinegnostics/metrics/r2.py +122 -0
- machinegnostics/metrics/recall.py +108 -0
- machinegnostics/metrics/rmse.py +77 -0
- machinegnostics/metrics/robr2.py +119 -0
- machinegnostics/metrics/std.py +144 -0
- machinegnostics/metrics/variance.py +101 -0
- machinegnostics/models/__init__.py +2 -0
- machinegnostics/models/classification/__init__.py +1 -0
- machinegnostics/models/classification/layer_history_log_reg.py +121 -0
- machinegnostics/models/classification/layer_io_process_log_reg.py +98 -0
- machinegnostics/models/classification/layer_mlflow_log_reg.py +107 -0
- machinegnostics/models/classification/layer_param_log_reg.py +275 -0
- machinegnostics/models/classification/mg_log_reg.py +273 -0
- machinegnostics/models/cross_validation.py +118 -0
- machinegnostics/models/data_split.py +106 -0
- machinegnostics/models/regression/__init__.py +2 -0
- machinegnostics/models/regression/layer_histroy_rob_reg.py +139 -0
- machinegnostics/models/regression/layer_io_process_rob_rig.py +88 -0
- machinegnostics/models/regression/layer_mlflow_rob_reg.py +134 -0
- machinegnostics/models/regression/layer_param_rob_reg.py +212 -0
- machinegnostics/models/regression/mg_lin_reg.py +253 -0
- machinegnostics/models/regression/mg_poly_reg.py +258 -0
- machinegnostics-0.0.1.dist-info/METADATA +246 -0
- machinegnostics-0.0.1.dist-info/RECORD +93 -0
- machinegnostics-0.0.1.dist-info/WHEEL +5 -0
- machinegnostics-0.0.1.dist-info/licenses/LICENSE +674 -0
- machinegnostics-0.0.1.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
'''
|
|
2
|
+
EGDF Derivative Module
|
|
3
|
+
|
|
4
|
+
Machine Gnostics
|
|
5
|
+
Author: Nirmal Parmar
|
|
6
|
+
'''
|
|
7
|
+
|
|
8
|
+
import numpy as np
|
|
9
|
+
import warnings
|
|
10
|
+
from machinegnostics.magcal.data_conversion import DataConversion
|
|
11
|
+
from machinegnostics.magcal.characteristics import GnosticsCharacteristics
|
|
12
|
+
from machinegnostics.magcal.gdf.egdf import EGDF
|
|
13
|
+
|
|
14
|
+
class DerivativesEGDF:
|
|
15
|
+
"""
|
|
16
|
+
Class for computing derivatives of the EGDF.
|
|
17
|
+
|
|
18
|
+
For internal use only, this class provides methods to calculate
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(self, egdf: EGDF):
|
|
22
|
+
self.fi = egdf.fi
|
|
23
|
+
self.hi = egdf.hi
|
|
24
|
+
self.weights = egdf.weights
|
|
25
|
+
self.S_opt = egdf.S_opt
|
|
26
|
+
self.z = egdf.z
|
|
27
|
+
self.di_points_n = egdf.di_points_n
|
|
28
|
+
self.catch = egdf.catch
|
|
29
|
+
self.LB_opt = egdf.LB_opt
|
|
30
|
+
self.UB_opt = egdf.UB_opt
|
|
31
|
+
|
|
32
|
+
def _get_egdf_first_derivative(self):
|
|
33
|
+
"""Calculate first derivative of EGDF (which is the PDF) from stored fidelities and irrelevances."""
|
|
34
|
+
if self.fi is None or self.hi is None:
|
|
35
|
+
raise ValueError("Fidelities and irrelevances must be calculated before first derivative estimation.")
|
|
36
|
+
|
|
37
|
+
weights = self.weights.reshape(-1, 1)
|
|
38
|
+
|
|
39
|
+
# First order moments
|
|
40
|
+
f1 = np.sum(weights * self.fi, axis=0) / np.sum(weights) # mean_fidelity
|
|
41
|
+
h1 = np.sum(weights * self.hi, axis=0) / np.sum(weights) # mean_irrelevance
|
|
42
|
+
|
|
43
|
+
# Second order moments (scaled by S as in MATLAB)
|
|
44
|
+
f2s = np.sum(weights * (self.fi**2 / self.S_opt), axis=0) / np.sum(weights)
|
|
45
|
+
fhs = np.sum(weights * (self.fi * self.hi / self.S_opt), axis=0) / np.sum(weights)
|
|
46
|
+
|
|
47
|
+
# Calculate denominator w = (f1^2 + h1^2)^(3/2)
|
|
48
|
+
w = (f1**2 + h1**2)**(3/2)
|
|
49
|
+
eps = np.finfo(float).eps
|
|
50
|
+
w = np.where(w == 0, eps, w)
|
|
51
|
+
|
|
52
|
+
# First derivative formula from MATLAB: y = (f1^2 * f2s + f1 * h1 * fhs) / w
|
|
53
|
+
numerator = f1**2 * f2s + f1 * h1 * fhs
|
|
54
|
+
first_derivative = numerator / w
|
|
55
|
+
# first_derivative = first_derivative / self.zi
|
|
56
|
+
|
|
57
|
+
if np.any(first_derivative < 0):
|
|
58
|
+
warnings.warn("EGDF first derivative (PDF) contains negative values", RuntimeWarning)
|
|
59
|
+
|
|
60
|
+
return first_derivative.flatten()
|
|
61
|
+
|
|
62
|
+
def _get_egdf_second_derivative(self):
|
|
63
|
+
"""Calculate second derivative of EGDF from stored fidelities and irrelevances."""
|
|
64
|
+
if self.fi is None or self.hi is None:
|
|
65
|
+
raise ValueError("Fidelities and irrelevances must be calculated before second derivative estimation.")
|
|
66
|
+
|
|
67
|
+
weights = self.weights.reshape(-1, 1)
|
|
68
|
+
|
|
69
|
+
# Moment calculations
|
|
70
|
+
f1 = np.sum(weights * self.fi, axis=0) / np.sum(weights)
|
|
71
|
+
h1 = np.sum(weights * self.hi, axis=0) / np.sum(weights)
|
|
72
|
+
f2 = np.sum(weights * self.fi**2, axis=0) / np.sum(weights)
|
|
73
|
+
f3 = np.sum(weights * self.fi**3, axis=0) / np.sum(weights)
|
|
74
|
+
fh = np.sum(weights * self.fi * self.hi, axis=0) / np.sum(weights)
|
|
75
|
+
fh2 = np.sum(weights * self.fi * self.hi**2, axis=0) / np.sum(weights)
|
|
76
|
+
f2h = np.sum(weights * self.fi**2 * self.hi, axis=0) / np.sum(weights)
|
|
77
|
+
|
|
78
|
+
# Calculate components
|
|
79
|
+
b = f1**2 * f2 + f1 * h1 * fh
|
|
80
|
+
d = f1**2 + h1**2
|
|
81
|
+
eps = np.finfo(float).eps
|
|
82
|
+
d = np.where(d == 0, eps, d)
|
|
83
|
+
|
|
84
|
+
# Following
|
|
85
|
+
term1 = f1 * (h1 * (f3 - fh2) - f2 * fh)
|
|
86
|
+
term2 = 2 * f1**2 * f2h + h1 * fh**2
|
|
87
|
+
term3 = (6 * b * (f1 * fh - h1 * f2)) / d
|
|
88
|
+
|
|
89
|
+
d2 = -1 / (d**(1.5)) * (2 * (term1 - term2) + term3)
|
|
90
|
+
second_derivative = d2 / (self.S_opt**2)
|
|
91
|
+
# second_derivative = second_derivative / self.zi**2
|
|
92
|
+
return second_derivative.flatten()
|
|
93
|
+
|
|
94
|
+
def _get_egdf_third_derivative(self):
|
|
95
|
+
"""Calculate third derivative of EGDF from stored fidelities and irrelevances."""
|
|
96
|
+
if self.fi is None or self.hi is None:
|
|
97
|
+
raise ValueError("Fidelities and irrelevances must be calculated before third derivative estimation.")
|
|
98
|
+
|
|
99
|
+
weights = self.weights.reshape(-1, 1)
|
|
100
|
+
|
|
101
|
+
# All required moments
|
|
102
|
+
f1 = np.sum(weights * self.fi, axis=0) / np.sum(weights)
|
|
103
|
+
h1 = np.sum(weights * self.hi, axis=0) / np.sum(weights)
|
|
104
|
+
f2 = np.sum(weights * self.fi**2, axis=0) / np.sum(weights)
|
|
105
|
+
f3 = np.sum(weights * self.fi**3, axis=0) / np.sum(weights)
|
|
106
|
+
f4 = np.sum(weights * self.fi**4, axis=0) / np.sum(weights)
|
|
107
|
+
fh = np.sum(weights * self.fi * self.hi, axis=0) / np.sum(weights)
|
|
108
|
+
h2 = np.sum(weights * self.hi**2, axis=0) / np.sum(weights)
|
|
109
|
+
fh2 = np.sum(weights * self.fi * self.hi**2, axis=0) / np.sum(weights)
|
|
110
|
+
f2h = np.sum(weights * self.fi**2 * self.hi, axis=0) / np.sum(weights)
|
|
111
|
+
f2h2 = np.sum(weights * self.fi**2 * self.hi**2, axis=0) / np.sum(weights)
|
|
112
|
+
f3h = np.sum(weights * self.fi**3 * self.hi, axis=0) / np.sum(weights)
|
|
113
|
+
fh3 = np.sum(weights * self.fi * self.hi**3, axis=0) / np.sum(weights)
|
|
114
|
+
|
|
115
|
+
# Following
|
|
116
|
+
# Derivative calculations
|
|
117
|
+
dh1 = -f2
|
|
118
|
+
df1 = fh
|
|
119
|
+
df2 = 2 * f2h
|
|
120
|
+
dfh = -f3 + fh2
|
|
121
|
+
dfh2 = -2 * f3h + fh3
|
|
122
|
+
df3 = 3 * f3h
|
|
123
|
+
df2h = -f4 + 2 * f2h2
|
|
124
|
+
|
|
125
|
+
# u4 and its derivative
|
|
126
|
+
u4 = h1 * f3 - h1 * fh2 - f2 * fh
|
|
127
|
+
du4 = dh1 * f3 + h1 * df3 - dh1 * fh2 - h1 * dfh2 - df2 * fh - f2 * dfh
|
|
128
|
+
|
|
129
|
+
# u and its derivative
|
|
130
|
+
u = f1 * u4
|
|
131
|
+
du = df1 * u4 + f1 * du4
|
|
132
|
+
|
|
133
|
+
# v components
|
|
134
|
+
v4a = (f1**2) * f2h
|
|
135
|
+
dv4a = 2 * f1 * df1 * f2h + (f1**2) * df2h
|
|
136
|
+
v4b = h1 * fh**2
|
|
137
|
+
dv4b = dh1 * (fh**2) + 2 * h1 * fh * dfh
|
|
138
|
+
|
|
139
|
+
v = 2 * v4a + v4b
|
|
140
|
+
dv = 2 * dv4a + dv4b
|
|
141
|
+
|
|
142
|
+
# x components
|
|
143
|
+
x4a = f1**2 * f2 + f1 * h1 * fh
|
|
144
|
+
dx4a = 2 * f1 * df1 * f2 + (f1**2) * df2 + df1 * h1 * fh + f1 * dh1 * fh + f1 * h1 * dfh
|
|
145
|
+
x4b = f1 * fh - h1 * f2
|
|
146
|
+
dx4b = df1 * fh + f1 * dfh - dh1 * f2 - h1 * df2
|
|
147
|
+
|
|
148
|
+
x = 6 * x4a * x4b
|
|
149
|
+
dx = 6 * (dx4a * x4b + x4a * dx4b)
|
|
150
|
+
|
|
151
|
+
# d components
|
|
152
|
+
d = f1**2 + h1**2
|
|
153
|
+
dd = 2 * (f1 * df1 + h1 * dh1)
|
|
154
|
+
eps = np.finfo(float).eps
|
|
155
|
+
d = np.where(d == 0, eps, d)
|
|
156
|
+
|
|
157
|
+
# Final calculation
|
|
158
|
+
term1 = (du - dv) / (d**1.5) - (1.5 * (u - v)) / (d**2.5) * dd
|
|
159
|
+
term2 = dx / (d**2.5) - (2.5 * x) / (d**3.5) * dd
|
|
160
|
+
|
|
161
|
+
d3p = -2 * term1 - term2
|
|
162
|
+
third_derivative = 2 * d3p / (self.S_opt**3)
|
|
163
|
+
# third_derivative = third_derivative / (self.zi**3)
|
|
164
|
+
return third_derivative.flatten()
|
|
165
|
+
|
|
166
|
+
def _get_egdf_fourth_derivative(self):
|
|
167
|
+
"""Calculate fourth derivative of EGDF using numerical differentiation."""
|
|
168
|
+
if self.fi is None or self.hi is None:
|
|
169
|
+
raise ValueError("Fidelities and irrelevances must be calculated before fourth derivative estimation.")
|
|
170
|
+
|
|
171
|
+
# For fourth derivative, use numerical differentiation as it's complex
|
|
172
|
+
dz = 1e-7
|
|
173
|
+
|
|
174
|
+
# Get third derivatives at slightly shifted points
|
|
175
|
+
zi_plus = self.zi + dz
|
|
176
|
+
zi_minus = self.zi - dz
|
|
177
|
+
|
|
178
|
+
# Store original zi
|
|
179
|
+
original_zi = self.zi.copy()
|
|
180
|
+
|
|
181
|
+
# Calculate third derivative at zi + dz
|
|
182
|
+
self.zi = zi_plus
|
|
183
|
+
self._calculate_fidelities_irrelevances_at_given_zi(self.zi)
|
|
184
|
+
third_plus = self._get_egdf_third_derivative()
|
|
185
|
+
|
|
186
|
+
# Calculate third derivative at zi - dz
|
|
187
|
+
self.zi = zi_minus
|
|
188
|
+
self._calculate_fidelities_irrelevances_at_given_zi(self.zi)
|
|
189
|
+
third_minus = self._get_egdf_third_derivative()
|
|
190
|
+
|
|
191
|
+
# Restore original zi and recalculate fi, hi
|
|
192
|
+
self.zi = original_zi
|
|
193
|
+
self._calculate_fidelities_irrelevances_at_given_zi(self.zi)
|
|
194
|
+
|
|
195
|
+
# Numerical derivative
|
|
196
|
+
fourth_derivative = (third_plus - third_minus) / (2 * dz) * self.zi
|
|
197
|
+
|
|
198
|
+
return fourth_derivative.flatten()
|
|
199
|
+
|
|
200
|
+
def _calculate_fidelities_irrelevances_at_given_zi(self, zi):
|
|
201
|
+
"""Helper method to recalculate fidelities and irrelevances for current zi."""
|
|
202
|
+
# Convert to infinite domain
|
|
203
|
+
zi_n = DataConversion._convert_fininf(self.z, self.LB_opt, self.UB_opt)
|
|
204
|
+
# is zi given then use it, else use self.zi
|
|
205
|
+
if zi is None:
|
|
206
|
+
zi_d = self.zi
|
|
207
|
+
else:
|
|
208
|
+
zi_d = zi
|
|
209
|
+
|
|
210
|
+
# Calculate R matrix
|
|
211
|
+
eps = np.finfo(float).eps
|
|
212
|
+
R = zi_n.reshape(-1, 1) / (zi_d + eps).reshape(1, -1)
|
|
213
|
+
|
|
214
|
+
# Get characteristics
|
|
215
|
+
gc = GnosticsCharacteristics(R=R)
|
|
216
|
+
q, q1 = gc._get_q_q1(S=self.S_opt)
|
|
217
|
+
|
|
218
|
+
# Store fidelities and irrelevances
|
|
219
|
+
self.fi = gc._fi(q=q, q1=q1)
|
|
220
|
+
self.hi = gc._hi(q=q, q1=q1)
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
def _get_pick_counts(self):
|
|
224
|
+
pass
|
|
225
|
+
|
|
226
|
+
def _get_derivatives(self):
|
|
227
|
+
"""Calculate all derivatives of EGDF."""
|
|
228
|
+
if self.fi is None or self.hi is None:
|
|
229
|
+
raise ValueError("Fidelities and irrelevances must be calculated before derivative estimation.")
|
|
230
|
+
# Calculate fidelities and irrelevances at current zi
|
|
231
|
+
# Calculate all derivatives
|
|
232
|
+
self.first_derivative = self._get_egdf_first_derivative()
|
|
233
|
+
self.second_derivative = self._get_egdf_second_derivative()
|
|
234
|
+
self.third_derivative = self._get_egdf_third_derivative()
|
|
235
|
+
self.fourth_derivative = np.gradient(self.third_derivative, self.di_points_n) # Numerical gradient for fourth derivative
|
|
236
|
+
|
|
237
|
+
if self.catch:
|
|
238
|
+
self.params.update({
|
|
239
|
+
'first_derivative': self.first_derivative,
|
|
240
|
+
'second_derivative': self.second_derivative,
|
|
241
|
+
'third_derivative': self.third_derivative,
|
|
242
|
+
'fourth_derivative': self.fourth_derivative
|
|
243
|
+
})
|