Search code examples
matlabfiltersignal-processingphase

Change phase of a signal in frequency domain (MatLab)


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:

Plot of signal with phase change

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.


Solution

  • 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, i.e.:

    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):

    this is image description here, how are You?