Python Inverse Fourier Transform of Imaginary Odd Function - python

I am trying to understand how the fft and ifft functions work in python. I made a simple example of an imaginary odd function to compute the inverse Fourier transform in the hopes of getting a real odd function (as should be the case). Below is my code:
v = np.array([-1,-2,0,2,1]) * 1j
t = [-2,-1,0,1,2]
V = ifft(fftshift(v))
Clearly, the function sampled by v is an odd imaginary function, so when I compute the inverse Fourier Transform and after shifting, I should get a real odd function. But this is not the case. What am I misunderstanding about the Fourier Transform? Thanks!

You need ifftshift where you use fftshift and fftshift at the very end:
>>> w = fftshift(ifft(ifftshift(v)))
>>>
>>> np.allclose(w, w.real)
True
>>> np.allclose(w, -w[::-1])
True

Related

From DFT to QFT python/qiskit

I have the following code
x = [1, -4, 5, -2] # Data points
N = len(x) # Number of samples
n = np.arange(N) # Current sample
k = n.reshape((N, 1)) # Current frequency
e = np.exp(-2j * np.pi * k * n / N) # Exponential part
DFT = np.dot(e, x)
How can I make this Classical Fourier Transform into the Quantum version, either via python or qiskit?
Ok, so I think you should first read about the quantum Fourier transform and see what it does, as the Quantum Fourier Transform is not a quantum algorithm for calculating the Fourier transform but rather a way to transform from one state basis to another called the Fourier basis, it does not convert a finite sequence of equally-spaced samples of a function into a same-length sequence of equally-spaced samples as the DFT does
That being said, if you simply want to implement the QFT then you can find examples here
https://qiskit.org/textbook/ch-algorithms/quantum-fourier-transform.html
as well as some intuition of what the transform does and how to use it. I don't know if the data points you have are those for a reason, but you may want to change them to use them in qiskit for strings of 0s and 1s or convert them to binary and use quite a few qubits

The Absolute Value of a Complex Number with Numpy

I have the following script in Python. I am calculating the Fourier Transform of an array. When I want to plot the results (Fourier transform) I am using the absolute value of that calculation.
However, I do not know how the absolute value of complex numbers is being produced.
Does anyone know how it calculates? I need this to reproduce in Java.
import numpy as np
import matplotlib.pyplot as plt
from numpy import fft
inp = [1,2,3,4]
res = fft.fft(inp)
print(res[1]) # returns (-2+2j) complex number
print(np.abs(res[1])) # returns 2.8284271247461903
np.abs gives magnitude of complex number i.e. sqrt(a^2 + b^2) in your case it's sqrt(8).
https://numpy.org/doc/stable/reference/generated/numpy.absolute.html
sqrt(Re(z)**2 + Im(z)**2)
for z = a + ib this becomes:
sqrt(a*a + b*b)
It's just the euclidean norm. You have to sum the square of real part and imaginary part (without the i) and do the sqrt of it.
https://www.varsitytutors.com/hotmath/hotmath_help/topics/absolute-value-complex-number
From numpy.absolute(arr, out = None, ufunc ‘absolute’) documentation:
This mathematical function helps user to calculate absolute value of each element.
For a complex number a+ib, the absolute value is sqrt(a^2 + b^2).
For complex valued pairs, a+ib, you can consider using the java Math static method hypot:
Math.hypot(a, b)
The method is an implementation of the Pythagorean theorem, sqrt(a*a + b*b) but additionally provides underflow and overflow protection.

Discrete Fourier Transform in Python

I need to use discrete Fourier transform (DFT) in Python (and inverse DFT) and the results I obtain are a bit weird, so I tried on a small example and I am not sure I understand the mistake (if it is math or coding). Here is my small version of the code:
from __future__ import division
import numpy as np
from pylab import *
pi = np.pi
def f(x):
return sin(x)
theta = np.arange(0,2*pi,2*pi/4)
k = np.arange(0,4,1)
x = f(theta)
y = np.fft.fft(x)
derivative = np.fft.ifft(1j*k*y)
print(derivative)
So what I do is to sample sin at 4 different points between 0 and 2pi and create with these numbers a vector x. Then I take the DFT of x to get y. What I want is to get the derivative of sin at the chosen points, so to do this I multiply y by k (the wave number, which in this case would be 0,1,2,3) and my the imaginary number 1j (this is because in the Fourier sum I have for each term something of the form e^{ikx}). So in the end I take the inverse DFT of 1jky and I am supposed to get the derivative of sin. But what I get is this.
[ -1.00000000e+00 -6.12323400e-17j -6.12323400e-17 +2.00000000e+00j
1.00000000e+00 +1.83697020e-16j 6.12323400e-17 -2.00000000e+00j]
when I was supposed to get this
[1,0,-1,0]
ignoring round-off errors. Can someone tell me what am I doing wrong? Thank you!
Manipulation of the spectrum must preserve this Hermitian symmetry if the inverse FFT is to yield result. Accordingly, the derivative operator in the frequency domain is defined over the lower half of the spectrum, and the upper half of the spectrum constructed from symmetry. Note that for spectrum of even sizes the value at exactly N/2 must be its own symmetry, hence must have a imaginary part which is 0. The following illustrate how to construct this derivative operator:
N = len(y)
if N%2:
derivative_operator = np.concatenate((np.arange(0,N/2,1),[0],np.arange(-N/2+1,0,1)))*1j
else:
derivative_operator = np.concatenate((np.arange(0,N/2,1),np.arange(-N//2+1,0,1)))*1j
You'd use this derivative_operator in the frequency-domain as follow:
derivative = np.fft.ifft(derivative_operator*y)
In your sample case you should then get the following result
[ 1.00000000e+00+0.j 6.12323400e-17+0.j
-1.00000000e+00+0.j -6.12323400e-17+0.j]
which is within roundoff errors of your expected [1,0,-1,0].

Translating an FFT function from Python 2.x to Python 3.x, and computing the IFFT from it

I have an Fast Fourier Transform function in Python for versions 2.x. I want to make it in Python 3.x, but I have some problems with "xrange" and list identifiers(as my compiler said). I also have no idea how to compute Inversed FFT from my FFT without using of any non-standard libraries. Code is below. Thanks in advance...
from cmath import exp,pi
def FFT(X):
n = len(X)
w = exp(-2*pi*1j/n)
if n > 1:
X = FFT(X[::2]) + FFT(X[1::2])
for k in xrange(n/2):
xk = X[k]
X[k] = xk + w**k*X[k+n/2]
X[k+n/2] = xk - w**k*X[k+n/2]
return X
UPD: Totally reconstructed ,my FFT and constructed IFFT due to your advices.
P.S. How to close post?
There are a couple ways to convert your FFT into an IFFT. The easiest is to get rid of the minus sign inside the parameter to your exp() function for w. The next is to take the complex conjugate of the FFT of the complex conjugate of the input.
If you don't scale your forward FFT, then common practice is to scale your IFFT computation by 1/N (the length), so that IFFT(FFT()) results in the same total sum magnitude. If you do scale your FFT by 1/N, then don't scale your IFFT computation. Or scale both by 1/sqrt(N).

(numpy) Wrong amplitude(?) of FFT'd array?

I'm using numpy and matplotlib to analyze data output form my simulations. There is one (apparent) inconsistency that I can't find the roots of. It's the following:
I have a signal that has a given energy a^2~1. When I use rfft to take the FFT and compute the energy in the Fourier space, it comes out to be significantly larger. To void giving the details of my data etc., here is an example with a simple sin wave:
from pylab import *
xx=np.linspace(0.,2*pi,128)
a=np.zeros(128)
for i in range(0,128):
a[i]=sin(xx[i])
aft=rfft(a)
print mean(abs(aft)**2),mean(a**2)
In principle both the numbers should be the same (at least in the numerical sense) but this is what I get out of this code:
62.523081632 0.49609375
I tried to go through numpy.fft documentation but could not find anything. A search here gave the following but I was not able to understand the explanations there:
Big FFT amplitude difference between the existing (synthesized) signal and the filtered signal
What am I missing/ misunderstanding? Any help/ pointer in this regard would be greatly appreciated.
Thanks!
Henry is right on the non-normalization part, but there is a little more to it, because you are using rfft, not fft. The following is consistent with his answer:
>>> x = np.linspace(0, 2 * np.pi, 128)
>>> y = 1 - np.sin(x)
>>> fft = np.fft.fft(y)
>>> np.mean((fft * fft.conj()).real)
191.49999999999991
>>> np.mean(y**2)
1.4960937500000004
>>> fft = fft / np.sqrt(len(fft))
>>> np.mean((fft * fft.conj()).real)
1.4960937499999991
But if you now try the same with rfft, things don't quite work out:
>>> rfft = np.fft.rfft(y)
>>> np.mean((rfft * rfft.conj()).real)
314.58462009358772
>>> rfft /= np.sqrt(len(rfft))
>>> np.mean((rfft * rfft.conj()).real)
4.8397633860551954
65
>>> np.mean((rfft * rfft.conj()).real) / len(rfft)
4.8397633860551954
The following does work properly, though:
>>> (rfft[0] * rfft[0].conj() +
... 2 * np.sum(rfft[1:] * rfft[1:].conj())).real / len(y)
1.4960937873636722
When you use rfft what you are getting is not properly the DFT of your data, but only the positive half of it, since the negative would be symmetric to it. To compute the mean, you need to consider every value other than the DC component twice, which is what the last line of code does.
In most FFT libraries, the various DFT flavours are not orthogonal. The numpy.fft library applies the necessary normalizations only during the inverse transform.
Consider the Wikipedia description of the DFT; the inverse DFT has the 1/N term that the DFT does not have (in which N is the length of the transform). To make an orthogonal version of the DFT, you need to scale the result of the un-normalised DFT by 1/sqrt(N). In this case, the transform is orthogonal (that is, if we define the orthogonal DFT as F, then the inverse DFT is the conjugate, or hermitian, transpose of F).
In your case, you can get the correct answer by simply scaling aft by 1.0/sqrt(len(a)) (note that N is found from the length of the transform; the real FFT just throws about half the values away, so it's the length of a that is important).
I suspect that the reason for leaving the normalization until the end is that in most situations, it doesn't matter and you therefore save the computational cost of doing the normalization twice. Indeed, the very quick FFTW library doesn't do any normalization in either direction, and leaves it entirely up to the user to deal with.
Edit: Just to be clear, the explanation above is not quite correct. The correct answer will not be arrived at with that simple scaling, as in your case the DC component will be added in twice, although 1.0/sqrt(len(a)) is still the correct scaling to produce the unitary transform.

Categories