4
votes

I'm developing Python software for someone and they specifically requested that I use their DFT function, written in MATLAB, in my program. My translation is just plain not working, tested with sin(2*pi*r). The MATLAB function below:

function X=dft(t,x,f)
% Compute DFT (Discrete Fourier Transform) at frequencies given
%   in f, given samples x taken at times t:
%     X(f) = sum { x(k) * e**(2*pi*j*t(k)*f) }
%             k

shape = size(f);
t = t(:); % Format 't' into a column vector
x = x(:); % Format 'x' into a column vector
f = f(:); % Format 'f' into a column vector

W = exp(-2*pi*j * f*t');
X = W * x;
X = reshape(X,shape);

And my Python interpretation:

def dft(t, x, f):
    i = 1j  #might not have to set it to a variable but better safe than sorry!
    w1 = f * t
    w2 = -2 * math.pi * i
    W = exp(w1 * w2)
    newArr = W * x
    return newArr

Why am I having issues? The MATLAB code works fine but the Python translation outputs a weird increasing sine curve instead of a Fourier transform. I get the feeling Python is handling the calculations slightly differently but I don't know why or how to fix this.

2
In yout matlab code, you have a f*t' which I assume means t transposed. Calculate your w1 as the sum of what you have at the moment, and see whether that works. -- No, wait. That can't be it. - chw21
@chw21 is right, this is a kronecker produkt between f and the transposed t. Does Python possibly do an element-wise multiplication there? - hbaderts
Yes, multiplying two numpy arrays returns an array with each element being the product of the two corresponding elements. - chw21
Are those inputs numpy arrays or matrices? - Divakar
On the difference between numpy arrays and matrices: stackoverflow.com/questions/4151128/… - atomh33ls

2 Answers

1
votes

Here's your MATLAB code -

t = 0:0.005:10-0.005;
x = sin(2*pi*t);
f = 30*(rand(size(t))+0.225);

shape = size(f);
t = t(:); % Format 't' into a column vector
x = x(:); % Format 'x' into a column vector
f = f(:); % Format 'f' into a column vector

W = exp(-2*pi*1j * f*t');  %//'
X = W * x;
X = reshape(X,shape);

figure,plot(f,X,'ro')

And here's one version of numpy ported code might look like -

import numpy as np
from numpy import math
import matplotlib.pyplot as plt

t = np.arange(0, 10, 0.005) 
x = np.sin(2*np.pi*t) 
f = 30*(np.random.rand(t.size)+0.225)

N = t.size

i = 1j
W = np.exp((-2 * math.pi * i)*np.dot(f.reshape(N,1),t.reshape(1,N)))
X = np.dot(W,x.reshape(N,1))
out = X.reshape(f.shape).T

plt.plot(f, out, 'ro')

MATLAB Plot -

enter image description here

Numpy Plot -

enter image description here

1
votes

Numpy arrays do element wise multiplication with *.

You need np.dot(w1,w2) for matrix multiplication using numpy arrays (not the case for numpy matrices)

Make sure you are clear on the distinction between Numpy arrays and matrices. There is a good help page "Numpy for Matlab Users":

http://wiki.scipy.org/NumPy_for_Matlab_Users

Doesn't appear to be working at present so here is a temporary link.

Also, use t.T to transpose a numpy array called t.