Creating a DFT without built in function

Hello, I'm trying to create a discrete fourier transform and plot amplitude without the built in matlab function. I also need to make a shift so my axis shows half positive half negative. My code dosent work, it plots the square wave which it should but it dosent plot amplitude spectrum and generate dft. Does anybode know where my code is wrong? Here's the error message:
>> question3
Array indices must be positive integers or logical values.
Error in question3>dft (line 32)
p = p+xn(n)*exp(-2*pi*1j*k*n/N);
Error in question3 (line 17)
Y = dft(x);
Here's the code:
figure(1)
Fs = 100;
Ts = 1/Fs;
T = 5;
N = T/Ts;
t = (0:Ts:(N-1)*Ts);
x = square(2*pi*t);
plot(t,x);
xlim([0,5])
ylim([-1.5, 1.5]);
legend('Square Wave');
xlabel('t(s)');
ylabel('x(t)');
grid on;
figure(2)
Y = dft(x);
omega=2*pi*(-N(2:1:N/2-1))/T;
f_hz=omega/(2*pi);
P = abs(Y/N);
stem(f_hz,P);
title('Amplitude spectrum');
xlabel('f(hz)');
ylabel('pf');
function Xk = dft(xn)
N = length(xn);
Xk = zeros(1,N);
for n=0:1:N-1
p = 0;
for k=0:1:N-1
p = xn*exp(2*pi*-1i*n*k/N);
end
Xk(k+1) = p;
end
end

Answers (1)

Jan
Jan on 18 Oct 2022
Edited: Jan on 18 Oct 2022
p = 0;
for k = 0:1:N-1
p = xn * exp(2*pi*-1i*n*k/N);
end
This overwrites p N times. Should this be a sum?
If xn is a vector, p is also. Xk(k+1) = p tries to assign a vector to the scalar element of Xk.
"My code dosent work" - Then it is useful to post a copy of the complete error message, which tells you exactly, what I have written above.

5 Comments

Hey! That function should be a sum!
I added the error message as well, a plot with the amplitude should appear which it dosent
That does not look like the full error message. Please post all the text displayed in red in the Command Window when you run your code. There should be some red text above the "Error in question3>dft (line 32)" line.
I pasted the whole error message!
Thank you for adding that information. That does help determine the cause of the error. Let's look at your dft function
function Xk = dft(xn)
N = length(xn);
Xk = zeros(1,N);
for n=0:1:N-1
p = 0;
for k=0:1:N-1
p = p+xn(n)*exp(-2*pi*1j*k*n/N);
end
At the first iteration through the outer loop, n is 0. That means inside the loop you're trying to get element 0 of the array xn. Arrays in MATLAB don't have an element 0; the first element is element 1. That why MATLAB complains that the array index is neither a "positive integers or logical values" (emphasis added.)
Later in your dft function you accounted for this when you assigned to element k+1 (which in the case where k is 0 assigns to element 1, the first element) of Xk:
end
Xk(k+1) = p;
end
end
You need to do the same thing on the line where the error occurs.
Also FYI, you can simplify your expression inside the exp call a little bit. You can write complex numbers as a number followed by either i or j. So instead of computing -2*pi*1j you could use -pi*2j or -2j*pi.
I changed the first element to 1, now the errors are gone. Thanks so much! (Unfortunately I'm used to program in C)
You said that I needed to do that on the lines where it said error, Y = dft(x) also said error before. Not now tho, but I guess I don't need to change that?
Also thanks for the advice on writing complex number!

Sign in to comment.

Categories

Asked:

on 18 Oct 2022

Commented:

on 18 Oct 2022

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!