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.


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

# Import Packages
from scipy.fft import rfft , irfft
import numpy as np
# pandas_datareader for reading MSFT stock data
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
cepstrum(df['Adj Close'].to_numpy())


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!

additional Note:

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:

enter image description here

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:

enter image description here

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:

enter image description here

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$.

enter image description here

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:

enter image description here

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.


1 Answer 1


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.

  • $\begingroup$ 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 $\endgroup$
    – Shayan
    Nov 26, 2021 at 9:07
  • $\begingroup$ @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))). $\endgroup$
    – ZR Han
    Nov 26, 2021 at 9:12
  • $\begingroup$ Yeah I exactly understand your point. But in scipy.rfft doc, they didn't say that this function gives you coefficients. by this, I concluded that scipy.rfft gives me just series (like Fourier series) and this series created by coefficients! by this I said "grab coefficients of this process". $\endgroup$
    – Shayan
    Nov 26, 2021 at 9:17
  • $\begingroup$ @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. $\endgroup$
    – ZR Han
    Nov 26, 2021 at 10:15
  • $\begingroup$ 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? $\endgroup$
    – Shayan
    Nov 26, 2021 at 10:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.