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.
Files changed (93) hide show
  1. __init__.py +0 -0
  2. machinegnostics/__init__.py +24 -0
  3. machinegnostics/magcal/__init__.py +37 -0
  4. machinegnostics/magcal/characteristics.py +460 -0
  5. machinegnostics/magcal/criteria_eval.py +268 -0
  6. machinegnostics/magcal/criterion.py +140 -0
  7. machinegnostics/magcal/data_conversion.py +381 -0
  8. machinegnostics/magcal/gcor.py +64 -0
  9. machinegnostics/magcal/gdf/__init__.py +2 -0
  10. machinegnostics/magcal/gdf/base_df.py +39 -0
  11. machinegnostics/magcal/gdf/base_distfunc.py +1202 -0
  12. machinegnostics/magcal/gdf/base_egdf.py +823 -0
  13. machinegnostics/magcal/gdf/base_eldf.py +830 -0
  14. machinegnostics/magcal/gdf/base_qgdf.py +1234 -0
  15. machinegnostics/magcal/gdf/base_qldf.py +1019 -0
  16. machinegnostics/magcal/gdf/cluster_analysis.py +456 -0
  17. machinegnostics/magcal/gdf/data_cluster.py +975 -0
  18. machinegnostics/magcal/gdf/data_intervals.py +853 -0
  19. machinegnostics/magcal/gdf/data_membership.py +536 -0
  20. machinegnostics/magcal/gdf/der_egdf.py +243 -0
  21. machinegnostics/magcal/gdf/distfunc_engine.py +841 -0
  22. machinegnostics/magcal/gdf/egdf.py +324 -0
  23. machinegnostics/magcal/gdf/eldf.py +297 -0
  24. machinegnostics/magcal/gdf/eldf_intv.py +609 -0
  25. machinegnostics/magcal/gdf/eldf_ma.py +627 -0
  26. machinegnostics/magcal/gdf/homogeneity.py +1218 -0
  27. machinegnostics/magcal/gdf/intv_engine.py +1523 -0
  28. machinegnostics/magcal/gdf/marginal_intv_analysis.py +558 -0
  29. machinegnostics/magcal/gdf/qgdf.py +289 -0
  30. machinegnostics/magcal/gdf/qldf.py +296 -0
  31. machinegnostics/magcal/gdf/scedasticity.py +197 -0
  32. machinegnostics/magcal/gdf/wedf.py +181 -0
  33. machinegnostics/magcal/gdf/z0_estimator.py +1047 -0
  34. machinegnostics/magcal/layer_base.py +42 -0
  35. machinegnostics/magcal/layer_history_base.py +74 -0
  36. machinegnostics/magcal/layer_io_process_base.py +238 -0
  37. machinegnostics/magcal/layer_param_base.py +448 -0
  38. machinegnostics/magcal/mg_weights.py +36 -0
  39. machinegnostics/magcal/sample_characteristics.py +532 -0
  40. machinegnostics/magcal/scale_optimization.py +185 -0
  41. machinegnostics/magcal/scale_param.py +313 -0
  42. machinegnostics/magcal/util/__init__.py +0 -0
  43. machinegnostics/magcal/util/dis_docstring.py +18 -0
  44. machinegnostics/magcal/util/logging.py +24 -0
  45. machinegnostics/magcal/util/min_max_float.py +34 -0
  46. machinegnostics/magnet/__init__.py +0 -0
  47. machinegnostics/metrics/__init__.py +28 -0
  48. machinegnostics/metrics/accu.py +61 -0
  49. machinegnostics/metrics/accuracy.py +67 -0
  50. machinegnostics/metrics/auto_correlation.py +183 -0
  51. machinegnostics/metrics/auto_covariance.py +204 -0
  52. machinegnostics/metrics/cls_report.py +130 -0
  53. machinegnostics/metrics/conf_matrix.py +93 -0
  54. machinegnostics/metrics/correlation.py +178 -0
  55. machinegnostics/metrics/cross_variance.py +167 -0
  56. machinegnostics/metrics/divi.py +82 -0
  57. machinegnostics/metrics/evalmet.py +109 -0
  58. machinegnostics/metrics/f1_score.py +128 -0
  59. machinegnostics/metrics/gmmfe.py +108 -0
  60. machinegnostics/metrics/hc.py +141 -0
  61. machinegnostics/metrics/mae.py +72 -0
  62. machinegnostics/metrics/mean.py +117 -0
  63. machinegnostics/metrics/median.py +122 -0
  64. machinegnostics/metrics/mg_r2.py +167 -0
  65. machinegnostics/metrics/mse.py +78 -0
  66. machinegnostics/metrics/precision.py +119 -0
  67. machinegnostics/metrics/r2.py +122 -0
  68. machinegnostics/metrics/recall.py +108 -0
  69. machinegnostics/metrics/rmse.py +77 -0
  70. machinegnostics/metrics/robr2.py +119 -0
  71. machinegnostics/metrics/std.py +144 -0
  72. machinegnostics/metrics/variance.py +101 -0
  73. machinegnostics/models/__init__.py +2 -0
  74. machinegnostics/models/classification/__init__.py +1 -0
  75. machinegnostics/models/classification/layer_history_log_reg.py +121 -0
  76. machinegnostics/models/classification/layer_io_process_log_reg.py +98 -0
  77. machinegnostics/models/classification/layer_mlflow_log_reg.py +107 -0
  78. machinegnostics/models/classification/layer_param_log_reg.py +275 -0
  79. machinegnostics/models/classification/mg_log_reg.py +273 -0
  80. machinegnostics/models/cross_validation.py +118 -0
  81. machinegnostics/models/data_split.py +106 -0
  82. machinegnostics/models/regression/__init__.py +2 -0
  83. machinegnostics/models/regression/layer_histroy_rob_reg.py +139 -0
  84. machinegnostics/models/regression/layer_io_process_rob_rig.py +88 -0
  85. machinegnostics/models/regression/layer_mlflow_rob_reg.py +134 -0
  86. machinegnostics/models/regression/layer_param_rob_reg.py +212 -0
  87. machinegnostics/models/regression/mg_lin_reg.py +253 -0
  88. machinegnostics/models/regression/mg_poly_reg.py +258 -0
  89. machinegnostics-0.0.1.dist-info/METADATA +246 -0
  90. machinegnostics-0.0.1.dist-info/RECORD +93 -0
  91. machinegnostics-0.0.1.dist-info/WHEEL +5 -0
  92. machinegnostics-0.0.1.dist-info/licenses/LICENSE +674 -0
  93. 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
+ })