I posted this question on dsp.stackexchange, and was informed that it was more relevant for stackoverflow as it is primarily a programming question:
I am attempting to write a code which allows me to change the phase of a signal in the frequency domain. However, my output isn't exactly correct, so something must be wrong. For a simple example assume that we have the function y = sin(2*pi*t) and want to implement a phase shift of -pi/2. My code looks as follows:
clear all
close all
N = 64; %number of samples
fs = 10; %sampling frequency
ts = 1/fs; %sample interval
tmax = (N-1)*ts;
t = 0:ts:tmax;
y = sin(2*pi*t);
figure
plot(t,y)
% We do the FT
f = -fs/2:fs/(N-1):fs/2;
Y = fftshift(fft(y));
% Magnitude spectrum
figure
plot(f,abs(Y));
phase = angle(Y);
% Phase spectrum
figure
plot(f,phase)
Y = ifftshift(Y)
% Attempt at phase shift
Y = Y.*exp(-i*2*pi*f*pi/2);
% Inverse FT
u = ifft(Y);
figure
plot(t,real(u))
All plots look OK except for the final plot which looks as follows:
This looks almost correct but not quite. If anyone can give me some pointers as to how my code can be corrected in order to fix this, I would greatly appreciate it! I have a feeling my mistake has something to do with the line Y = Y.*exp(-i*2*pi*f*pi/2);
, but I'm not sure how to fix it.
I can't really get into the Fourier analysis details (because I do not really know them), but I can offer a working solution with some hints:
First of all, You should express Your wave in imaginary terms, ie:
y = exp(1i*2*pi*t);
And what's even more crucial, You have to truly shift only the phase, without messing with the whole spectrum:
% Attempt at phase shift
Y = abs(Y).*exp(1i*angle(Y)-1i*pi/4); % -pi/4 shift
You should note that the shift isn't related to frequency anymore, which I guess makes sense. Finally You can plot the results:
figure
plot(t,real(u),'k')
hold on
plot(t,real(y),'r')
real(y)
is actually a cosine function, and You started with sine, but hopefully You get the idea. For pi/4 shift i got something like this (started with red, finished with black):
You made 3 major mistakes in your code design.
I modified your code. You will find it below. With the variable M you can change the number of periods of a sine wave in your input vector. In the example I have set M=3.
clear all;
close all;
T = 1; %length of sampling sequence in s
N = 64; %number of samples
M = 3; % number of periods per sequence
ts = T/N; %sample interval
fs = 1/ts %sampling frequency
tmax = (N-1)*ts;
t = 0:ts:tmax;
y = sin(2*pi*M*t);
fig01 = figure;
plot(t,y);
grid on;
%% We do the FT
Y = fft(y);
%% We create a frequency vector in natural order
% -fs/2, ..., 0, ... +fs/2
f =fftshift(( 0:(fs-1)) - fs/2);
%% Show Magnitude spectrum
% There shold be only two lines at -M and +M
figure;
plot(f,abs(Y),'o');
grid on;
%% Attempt at phase shift
% y/t) -> Y(w)
% y(t-t0) -> Y(w) * exp(-i*w*t0)
% Phase shift of pi/2 in frequncy domain is equavalent to as time shift
% of T/4 in time domain
Y = Y.*exp(-i*2*pi*f*T/4);
% Inverse FT
u = ifft(Y);
figure
hold on;
plot(t,real(u),'b-');
plot(t,real(y),'r-');
hold off;
grid;
Input signal with three periods of a sine signal
Spectrum of input signal. Frequency lines at -3 and +3
Input signal (blue) and phase shifted signal (red)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.