Skip to content

Commit bbe2ccc

Browse files
committed
Implement biweight midvariance variance estimation
1 parent bd90715 commit bbe2ccc

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed

pyriodicity/detectors/robustperiod.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ def detect(
164164
y = RobustPeriod._preprocess(x, lamb, c)
165165

166166
# TODO Decouple multiple periodicities
167+
RobustPeriod._decouple_periodicities(y)
167168

168169
# TODO Robust single periodicity detection
169170

@@ -218,6 +219,18 @@ def _preprocess(
218219
mad = np.mean(np.abs(y - mean))
219220
return RobustPeriod._huber((y - mean) / mad, c)
220221

222+
@staticmethod
223+
def _decouple_periodicities(x: ArrayLike, db_n: int, level: int):
224+
w_coeffs = RobustPeriod._modwt(x, db_n, level)
225+
bivar = np.array(
226+
[
227+
# Exclude the first Lj - 1 coefficients
228+
RobustPeriod._biweight_midvariance(w_coeffs[j][1][j:], 9)
229+
for j in range(level)
230+
]
231+
)
232+
pass
233+
221234
@staticmethod
222235
def _hpfilter(x: ArrayLike, lamb: float):
223236
"""
@@ -303,3 +316,23 @@ def _modwt(x: ArrayLike, db_n: int, level: int) -> NDArray:
303316

304317
# Compute the Maximal Overlap Discrete Wavelet Transform
305318
return pywt.swt(y, "db{}".format(db_n), level, norm=True)
319+
320+
@staticmethod
321+
def _biweight_midvariance(x: ArrayLike, c: float) -> float:
322+
# Ensure the correct data type
323+
x = np.asanyarray(x).astype(np.float64)
324+
325+
# Compute u
326+
med = np.median(x)
327+
mad = np.mean(np.abs(x - np.mean(x)))
328+
u = (x - med) / (c * mad)
329+
330+
# Indicator function
331+
indicator = np.abs(u) < 1
332+
333+
# Return the biweight midvariance estimation result
334+
return (
335+
len(x)
336+
* np.sum((x[indicator] - med) ** 2 * (1 - u[indicator] ** 2) ** 4)
337+
/ np.sum((1 - u[indicator] ** 2) * (1 - 5 * u[indicator] ** 2)) ** 2
338+
)

0 commit comments

Comments
 (0)