How to calculate the real cepstrums of a time-series in Julia?

That being said, the real cepstrum of a time series can be calculated by

the inverse Fourier transform of the real logarithm of the Fourier transform of the time–series (K. Kalpakis et al., 2001).

Let’s assume that we have the following time series:

using YFinance
series = get_prices("MSFT", startdt="2021-01-01", enddt="2021-01-20")["adjclose"]
# 11-element Vector{Float64}:
#  211.99659729003906
#  212.20114135742188
#  206.69886779785156
#  212.5809326171875
#  213.87611389160156
#  211.80184936523438
#  209.30877685546875
#  210.6819305419922
#  207.44874572753906
#  207.0884246826172
#  210.779296875

Now, I want to calculate the real cepstrum of this time series. According to the definition brought earlier, the following steps should be taken:

  1. Calculate the Fourier transform of the time series.
  2. Calculate the real logarithm of the result of 1st step.
  3. Take the inverse Fourier transform of the result of 2nd step.

So, the process can be fused as follows:

using FFTW
series |> fft .|> real .|> log |> ifft
# ERROR: DomainError with -2.1316965395989245:
# log was called with a negative real argument but will only return a complex result if called with a complex argument. Try log(Complex(x)).

So, there is a mathematical problem that can be handled as mentioned in the description of the error:

  series |> fft .|> real .|> Complex .|> log |> ifft
  # 11-element Vector{ComplexF64}:
  #  2.1053213005396554 + 1.71359599286716im
  #  0.5250627554737464 - 0.4415937871666108im
  #  0.3054836751101531 + 0.6365173493037021im
  #  0.5006638565965567 + 0.025177272226508857im
  #  0.8459161100203939 - 0.6848321808959316im
  #   0.643679369835847 - 0.3920666499012487im
  #   0.643679369835847 - 0.3920666499012487im
  #  0.8459161100203939 - 0.6848321808959316im
  #  0.5006638565965567 + 0.025177272226508857im
  #  0.3054836751101531 + 0.6365173493037021im
  #  0.5250627554737464 - 0.4415937871666108im

However, I have a series of Complex values. Then, what are the real cepstrums? Are they the real part of the values? Although, these questions are valid if I have done the procedure correctly.

The function mfcc in GitHub - baggepinnen/LPVSpectral.jl: Least-squares (sparse) spectral estimation and (sparse) LPV spectral decomposition. ?

Hey, thank you for your reply.
Unfortunately, that’s not the case since it’s about Mel Frequency Cepstral Coefficients, a different concept.

It’s not that different, the mfcc computes the real cepstrum over time, scaled using the Mel frequency scaling. Using a single bin over time, you would essentially get the real cepstrum, apart from the frequency scaling.


Actually, mfcc computes the power spectrum rather than the real spectrum, so they are slightly more different than I first wrote.

1 Like

Yes Mr. @baggepinnen,
I wish we would have a specific library for this in Julia. I’m not a signal-processing expert. Otherwise, I would have tried to write a package in this field. I wonder why the Mel Frequency Cepstrum is that popular among the community, and people barely touch Real Cepstrum. I didn’t find any implementation in this regard. However, there are dozens of Mel… Implementations in various languages.

It’s useful for audio processing. The Mel frequency scaling is constructed to mimic how humans hear, making it particularly suitable for working with spoken language etc.

1 Like

I got it. I need:

series |> fft .|> abs .|> log |> ifft
# 11-element Vector{ComplexF64}:
#    2.513777018119395 + 0.0im
#   0.6631478310353252 + 0.0im
#   0.4305484020274489 + 0.0im
#  0.44641736254372333 + 0.0im
#     0.63729469653841 + 0.0im
#  0.43916962928751924 + 0.0im
#  0.43916962928751924 + 0.0im
#     0.63729469653841 + 0.0im
#  0.44641736254372333 + 0.0im
#   0.4305484020274489 + 0.0im
#   0.6631478310353252 + 0.0im

And they do not have imaginary parts, actually.