简体   繁体   English

在频域中更改信号的相位(MatLab)

[英]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: 我在dsp.stackexchange上发布了这个问题,并被告知它与stackoverflow更相关,因为它主要是一个编程问题:

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. 举一个简单的例子,假设我们具有函数y = sin(2 * pi * t),并且想要实现-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); 我感觉到我的错误与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. real(y)实际上是一个余弦函数,您从正弦开始,但希望您能理解。 For pi/4 shift i got something like this (started with red, finished with black): 对于pi / 4 shift,我得到了这样的内容(从红色开始,以黑色结束):

这是图片描述,您好吗?

You made 3 major mistakes in your code design. 您在代码设计中犯了3个主要错误。

  1. The input vector of a FFT is interpreted as a period of a signal with is repeated infinitely. FFT的输入向量被解释为一个信号的周期,无限重复。 This means your input vector should contain an integer number of complete periods of your sine signal. 这意味着您的输入矢量应包含整数个正弦信号的完整周期。 You have an input vector of 64 samples and a sample rate of 10. This results in 6.4 periods of your sine wave, which leads to leakage. 您的输入向量为64个样本,采样率为10。这将导致6.4个正弦波周期,从而导致泄漏。 If you inspect the frequency spectrum after performing the FFT, you will see, that there are not two clean frequency lines, but a lot of frequency components around two places. 如果在执行FFT后检查频谱,您会发现没有两条干净的频率线,而是在两个地方周围有很多频率分量。
  2. After correcting your input vector, there should be only two single frequencies with values which are not close to zeros. 校正输入矢量后,应该只有两个单频率的值不能接近零。 62 frequency components will consist of numerical noise very close to zero. 62个频率分量将由非常接近零的数字噪声组成。 Calculating the phase of these values results in garbage data. 计算这些值的相位会导致垃圾数据。
  3. A phase shift of pi/2 in time domain is equivalent by a shift in time domain by N/4 if N is the number of input samples. 如果N是输入样本的数量,则时域中的pi / 2的相移等于时域中的N / 4的相移。

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. 使用变量M可以更改输入向量中正弦波的周期数。 In the example I have set M=3. 在示例中,我设置了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 具有三个正弦信号周期的输入信号

输入信号的频谱。频率线为-3和+3

Spectrum of input signal. 输入信号的频谱。 Frequency lines at -3 and +3 频率线为-3和+3

输入信号(蓝色)和相移信号(红色)

Input signal (blue) and phase shifted signal (red) 输入信号(蓝色)和相移信号(红色)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM