Context

I want to implement (real) cepstrum on stock data (for example MSFT stock) and achieve cepstral coefficients of this time series.

as noted in "Cepstral-based clustering of financial time series", "(real) cepstrum is defined as the inverse Fourier transform of the (real) logarithm of the Fourier transform of the time series".

so by this reference, these steps should be taken:

1. calculate Fourier transform of the time series
2. take (real) logarithm from step 1 result
3. finally calculate inverse Fourier transform of previous step

these are steps to calculate cepstrum of a time series.

Code

implementing such process in python shouldn't be much difficult:

# Import Packages
from scipy.fft import rfft , irfft
import numpy as np
from pandas_datareader import data as web

# ------------------------------------------

# read MSFT stock data and store it as pandas.DataFrame
df = pd.DataFrame(web.get_data_yahoo('MSFT' , start='01-03-2013' , end='12-06-2018')['Adj Close'])

# ------------------------------------------

# define a function to calculate cepstrum of time series
def cepstrum(x: np.array):
"""
This Function calculate cepstrum of a time series
"""
return irfft(np.log(rfft(x)))

# ------------------------------------------

# run cepstrum function


Output:

array([-0.86680682, -0.0558877 , -0.03134206, ..., -0.01719479, 0.01535661, -0.00099603])


As i said at first, I want to achieve cepsteral coefficients. I think cepsteral coefficients are the coefficients of inverse Fourier transform of the (real) logarithm of the Fourier transform of the time series. So how can i grab coefficients of this irfft(np.log(rfft(x))) process? for example i want to grab first 5 coefficient of this process. but i don't know how to access them! because scipy do things in backdrop!

as mentioned in "Cepstral-based clustering of financial time series":

Cepstral analysis is a non linear signal processing technique. The (real) cepstrum is defined as the inverse Fourier transform of the (real) logarithm of the Fourier transform of the time series. In order to define the cepstrum, we will first consider the autoregressive moving average (ARMA) processes. In particular an ARMA(p, q) process is defined as:

where $$\phi_r$$,r = 1, 2, . . . . p are the autoregressive (AR) parameters, $$\theta_r$$, r = 1, 2, . . . , q are the moving average (MA) parameters and $$\epsilon_t$$, is a white noise process. The spectral density of an ARMA(p, q) process is defined as:

where $$\sigma^2$$ is the variance of $$\epsilon_t$$. The logarithm of an estimated spectral density function can be approximated using an exponential form for the log spectral density function namely:

where 0 < $$\omega$$ < $$\pi$$, and where r2 and $$\psi_1$$, . . . , $$\psi_p$$ are unknown parameters. Savvides et al. (2008) introduce the following approximation of the log of the log spectral density function, namely, the spectrum of the log spectral density function, the cepstrum of $$X_t$$.

where $$\psi_0$$ = $$\int_0^1 log\lambda_x(\omega)d\omega$$ is the logarithm of the variance of the white noise process $$\epsilon_t$$. Under the absolute integrability on (0,1) of $$log\lambda_x(\omega)$$ , the Fourier coefficients of the expansion of $$log\lambda_x(\omega)$$ are defined by:

for k = 0, 1, 2, . . . and are referred to as the cepstral coefficients. Due to the convergence in mean square of $$log\lambda_x(\omega)$$ with increasing $$p$$, only a small number of cepstral coefficients can describe the second order characteristics of a time series.

I'm not familiar with signal processing knowledge. so it's possible that i inferred something wrong about the whole process. any help would be appreciated.

I think your code is mostly ok, but I don't get your problem. Just print them and you will grab the coefficients print(ifft(np.log(fft(x)))[:5]).
One thing to correct, you can't use rfft and irfft because $$\ln\mathcal{F}[x(n)]$$ will break the conjugate symmetry property, and thus the cepstrum is no longer a real sequence.
As for real cepstrum, it is given by $$c_r(n) = \mathcal{F}^{-1}\{ \ln |\mathcal{F}[x(n)]| \}$$ and you can get it by irfft(np.log(abs(rfft(x)))). In this case rfft and irfft is fine.
• Thanks for your explanation and correction! As mentioned in scipy.rfft (rfft) gives us "discrete Fourier Transform for real input"! nothing said about coefficients in documentation! I updated additional Note section, hope it help more to understand what I mean about cepsteral coefficients Nov 26, 2021 at 9:07
• @Shayan I don't understand what you mean by "grab coefficients of this process". You already have the cepstrum coefficients by ifft(np.log(fft(x))). Nov 26, 2021 at 9:12
• @Shayan fft and rfft return the DFT coefficients, ifft and irfft return the time sequences. You should keep in mind about the definition of cepstrum coefficient which is given by $c(n) = \mathcal{F}^{-1}\{ \ln \mathcal{F}[x(n)] \}$ and ifft(np.log(fft(x))) is exactly what you want. Nov 26, 2021 at 10:15
• Thanks a lot! Did you read additional notes section? Do you think i'm doing it in right way to achieve cepstral coefficients? Sorry I don't know much about cepstral coefficients. I fear if there's many kind of cepstral coefficients according to cepsteral context. And you mean ifft(np.log(abs(fft(x)))) is exactly what i want? Nov 26, 2021 at 10:52