diff --git a/clouddrift/signal.py b/clouddrift/signal.py index 6d54c5f8..3f344d13 100644 --- a/clouddrift/signal.py +++ b/clouddrift/signal.py @@ -13,16 +13,16 @@ def analytic_signal( time_axis: Optional[int] = -1, ) -> Union[np.ndarray, Tuple[np.ndarray, np.ndarray]]: """Return the analytic signal from a real-valued signal or the analytic and - anti-analytic signals from a complex-valued signal. + conjugate analytic signals from a complex-valued signal. If the input is a real-valued signal, the analytic signal is calculated as the inverse Fourier transform of the positive-frequency part of the Fourier - transform. If the input is a complex-valued signal, the anti-analytic signal - is additionally calculated as the inverse Fourier transform of the conjugate of - the negative-frequency part of the Fourier transform. + transform. If the input is a complex-valued signal, the conjugate analytic signal + is additionally calculated as the inverse Fourier transform of the positive-frequency + part of the Fourier transform of the complex conjugate of the input signal. For a complex-valued signal, the mean is evenly divided between the analytic and - anti-analytic signals. + conjugate analytic signal. The calculation is performed along the last axis of the input array by default. Alternatively, the user can specify the time axis of the input. The user can also @@ -44,7 +44,7 @@ def analytic_signal( xa : np.ndarray Analytic signal. It is a tuple if the input is a complex-valed signal with the first element being the analytic signal and the second element - being the anti-analytic signal. + being the conjugate analytic signal. Examples -------- @@ -54,7 +54,7 @@ def analytic_signal( >>> x = np.random.rand(99) >>> xa = analytic_signal(x) - To obtain the analytic and anti-analytic signals of a complex-valued signal: + To obtain the analytic and conjugate analytic signals of a complex-valued signal: >>> w = np.random.rand(99)+1j*np.random.rand(99) >>> wp, wn = analytic_signal(w) @@ -121,7 +121,7 @@ def analytic_signal( # analytic signal xap = np.fft.fft(xa) - # anti-analytic signal + # conjugate analytic signal xan = np.fft.fft(np.conj(xa)) # time dimension of extended time series @@ -142,7 +142,7 @@ def analytic_signal( xap = np.fft.ifft(xap) xan = np.fft.ifft(xan) - # return central part plus hlaf the mean + # return central part plus half the mean xap = xap[..., int(N + 1) - 1 : int(2 * N + 1) - 1] + 0.5 * mx_ xan = xan[..., int(N + 1) - 1 : int(2 * N + 1) - 1] + 0.5 * np.conj(mx_) diff --git a/clouddrift/wavelet.py b/clouddrift/wavelet.py index 8a2f18b2..d2fe6bec 100644 --- a/clouddrift/wavelet.py +++ b/clouddrift/wavelet.py @@ -64,7 +64,7 @@ def morse_wavelet_transform( ``radian_frequency``. However, if the optional argument ``complex=True`` is specified, the wavelets will be divided by 2 so that the total variance of the input complex signal is equal to the sum of the - variances of the returned analytic (positive) and anti-analiyic + variances of the returned analytic (positive) and conjugate analytic (negative) parts. See examples below. The other option is ``"energy"`` which uses the unit energy normalization. In this last case, the time-domain wavelet energies ``np.sum(np.abs(wave)**2)`` are always @@ -102,7 +102,7 @@ def morse_wavelet_transform( Apply a wavelet transform with a Morse wavelet with gamma parameter 3, beta parameter 4, for a complex input signal at radian frequency 0.2 cycles per unit time. This case returns the - analytic and anti-analytic components: + analytic and conjugate analytic components: >>> z = np.random.random(1024) + 1j*np.random.random(1024) >>> wtz_p, wtz_n = morse_wavelet_transform(z, 3, 4, np.array([2*np.pi*0.2]), complex=True) @@ -113,7 +113,7 @@ def morse_wavelet_transform( >>> wtz_imag = morse_wavelet_transform(np.imag(z)), 3, 4, np.array([2*np.pi*0.2])) >>> wtz_p, wtz_n = (wtz_real + 1j*wtz_imag) / 2, (wtz_real - 1j*wtz_imag) / 2 - For the "energy" normalization, the analytic and anti-analytic components are obtained as follows + For the "energy" normalization, the analytic and conjugate analytic components are obtained as follows with this alternative method: >>> wtz_real = morse_wavelet_transform(np.real(z)), 3, 4, np.array([2*np.pi*0.2])) >>> wtz_imag = morse_wavelet_transform(np.imag(z)), 3, 4, np.array([2*np.pi*0.2])) @@ -170,7 +170,7 @@ def morse_wavelet_transform( # apply the wavelet transform, distinguish complex and real cases if complex: - # imaginary case, divide by 2 the wavelet and return analytic and anti-analytic + # imaginary case, divide by 2 the wavelet and return analytic and conjugate analytic if normalization == "bandpass": wtx_p = wavelet_transform( 0.5 * x, wavelet, boundary="mirror", time_axis=time_axis