# Compare ifft in Matlab with Julia for complex input

**URL:** <https://discourse.julialang.org/t/compare-ifft-in-matlab-with-julia-for-complex-input/116002>\
**Category:** Signal and Image Processing\
**Created:** [June 22, 2024, 2:17am UTC](https://discourse.julialang.org/t/compare-ifft-in-matlab-with-julia-for-complex-input/116002 "2024-06-22T02:17:18Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jake](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jake/32/46007_2.png) [@Jake](https://discourse.julialang.org/u/Jake)\
**Post date:** [June 22, 2024, 2:17am UTC](https://discourse.julialang.org/t/compare-ifft-in-matlab-with-julia-for-complex-input/116002/1 "2024-06-22T02:17:18Z")

</div>

My use case is frequency demodulation using the method of [Coats and Randall](https://link.springer.com/chapter/10.1007/978-3-030-11220-2_30), with the link being one of many from a web search. They use the Hilbert transform for this purpose.

When I use ifft in MATLAB on a complex vector, the resulting vector is ~2x the length of the input vector.

In the MATLAB case the complex vector does not have the symmetry of having the positive and negative frequencies present. So what I think is happening is that MATLAB adds in the negative frequencies and then performs the ifft from the call to the FFTW library. Using this hypothesis I wrote the following code to do what I think MATLAB is doing:

```julia
# sf is the complex frequency vector obtained via rfft
# In this case it is assumed that the amplitude has been normalized by multiplying by 2 (except the DC component and the Nyquist frequency if the length is even.
nsf = length(sf)
if iseven(nsf) 
    sfd = Vector{ComplexF64}(undef, 2nsf-2)
    sfd[1] = sf[1]
    sfd[2:nsf-1] = sf[2:nsf-1] ./ 2
    sdf[nsf] = sf[nsf]
    sfd[nsf+1:end] = sfd[nsf-1:-1:2]
else
    sfd = Vector{ComplexF64}(undef, 2nsf-1)
    sfd[1] = sf[1]
    sfd[2:nsf] = sf[2:nsf] ./ 2
    sfd[nsf+1:end] = sfd[nsf:-1:2]
end
    
sc = ifft(sfd).*n # complex time from hilbert transform

```

Doing this I get a result that is different from Matlab. I am wondering if anyone has insight into this.

---

<div class="post-metadata">

**Author:** ![fatteneder](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fatteneder/32/33991_2.png) [@fatteneder](https://discourse.julialang.org/u/fatteneder)\
**Post date:** [June 22, 2024, 5:13am UTC](https://discourse.julialang.org/t/compare-ifft-in-matlab-with-julia-for-complex-input/116002/2 "2024-06-22T05:13:03Z")

</div>

Just guessing: If your input is computed with `rfft`, you will likely want to use `irfft` to compute the inverse. [API · AbstractFFTs.jl](https://juliamath.github.io/AbstractFFTs.jl/stable/api/#AbstractFFTs.irfft)

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [June 22, 2024, 6:21am UTC](https://discourse.julialang.org/t/compare-ifft-in-matlab-with-julia-for-complex-input/116002/3 "2024-06-22T06:21:15Z")

</div>

I don’t think Matlab’s and Julia’s `fft`/`ifft` behave differently, and I’m skeptical that the following is correct:

> [@Jake](#):
>
> When I use ifft in MATLAB on a complex vector, the resulting vector is ~2x the length of the input vector.

It seems to contradict the documentation of `ifft` here: [Inverse fast Fourier transform - MATLAB ifft - MathWorks Nordic](https://se.mathworks.com/help/matlab/ref/ifft.html)

Can you provide a minimal working example to show the difference you are seeing?

(And, as @fatteneder says, `rfft` is _not_ the same as `fft`, that is probably a crucial point here.)

---

<div class="post-metadata">

**Author:** ![Jake](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jake/32/46007_2.png) [@Jake](https://discourse.julialang.org/u/Jake)\
**Post date:** [June 22, 2024, 1:45pm UTC](https://discourse.julialang.org/t/compare-ifft-in-matlab-with-julia-for-complex-input/116002/4 "2024-06-22T13:45:18Z")

</div>

Thanks for the challenge of making a MWE. It turns out that some of my thinking was wrong. This is what I should have been doing:

- Transform to frequency domain
- Set negative frequency components to zero
- Multiply positive frequency components by 2 (do not change zero frequency component and take care with the Nyquist frequency component)
- Transform back to time domain
- Take real part of the analytic signal

Ergo, you have the original signal.

As an example

```julia
using FFTW

# Create signal
dt = 0.2
t = 0:dt:1
y = sin.(2*pi*t)
df = 1/t[end]
yf = fft(y)

# Make signal one sided like rfft
n = length(t)
np = div(n, 2) + 1
yf[np+1:end] = zeros(ComplexF64, n-np)

# Put energy lost from zeroing -ve frequency back in 
if iseven(n)
    yf[2:np-1] = 2*yf[2:np-1]
else
    yf[2:np] = 2*yf[2:np]
end

# Inverse FFT
ynew = ifft(yf)
[y ynew] # compare y with real part of ynew

```

MATLAB does the same thing
