Source code for dtaianomaly.windowing._fft

import math

import numpy as np

__all__ = ["dominant_fourier_frequency"]


[docs] def dominant_fourier_frequency( X: np.ndarray, lower_bound: int = 10, upper_bound: int = 1000 ) -> int: """ Compute the window size by selecting the dominant Fourier frequency. The Fourier transform decomposes a time series into a weighted sum of sine-waves. These weights are called the fourier coefficients and are related to a specific frequency or period length. The assumption is that the greatest coefficient corresponds to the dominant sine-wave which captures the time series characteristics best. The window size is therefore computed as the period of this dominant sine-wave. Parameters ---------- X : array-like of shape (n_samples,) Input time series. lower_bound : int, default=10 The lower bound on the automatically computed window size. upper_bound : int, default=1000 The lower bound on the automatically computed window size. Returns ------- int The computed window size. Warnings -------- Automatically computing the windwow size only works for univariate time series! Examples -------- >>> from dtaianomaly.data import demonstration_time_series >>> from dtaianomaly.windowing import dominant_fourier_frequency >>> X, _ = demonstration_time_series() >>> dominant_fourier_frequency(X) 107 """ # https://github.com/ermshaua/window-size-selection/blob/main/src/window_size/period.py#L10 fourier = np.fft.fft(X) freq = np.fft.fftfreq(X.shape[0], 1) magnitudes = [] window_sizes = [] for coef, freq in zip(fourier, freq): if coef and freq > 0: window_size = int(1 / freq) mag = math.sqrt(coef.real * coef.real + coef.imag * coef.imag) if lower_bound <= window_size <= upper_bound: window_sizes.append(window_size) magnitudes.append(mag) if len(window_sizes) == 0: return -1 return window_sizes[np.argmax(magnitudes)]