【问题标题】:Changing the phase of a signal in frequency domain在频域中改变信号的相位
【发布时间】:2015-09-15 11:05:32
【问题描述】:

我想改变频域中信号的相位。所以我生成了一个余弦测试信号来验证代码:

ycheck = cos(2*pi*t);

当我想将相位移动到大约 pi/4 时,我对信号执行 fft,将其拆分为幅度和相位,然后从中减去 pi/4。

Ycheck = abs(Ycheck).*exp(1i*angle(Ycheck)-1i*pi/4); % -pi/4 shift

绘制结果,看起来只有信号的幅度降低了,但没有发生相移。我在论坛上做了一些研究,发现了这个帖子 Change phase of a signal in frequency domain (MatLab)。所以我使用以下代码生成了另一个测试信号:

y = exp(1i*2*pi*t);

当我使用此信号进行相移时,它会给出所需的结果。遗憾的是我无法发布图片:(,所以我尝试描述(代码已附上,因此您可以执行它):只有想象项的 ifft 被正确移动。标准余弦的 ifft 仅在幅度上降低。我不太明白,这是什么问题。

我的问题是,为什么相移对以虚项表示的信号起作用,而不是对规则生成的余弦起作用?我的计划是将这种相移应用于真实信号 - 我可以将频域中的相移应用于例如音乐信号还是有另一种(可能更聪明)的方式?

我的代码在这里:

clear all;
close all;
clc;

N = 64; %number of samples
fs = 10; %sampling frequency
ts = 1/fs; %sample interval
tmax = (N-1)*ts;
t = 0:ts:tmax;
y = exp(1i*2*pi*t);
ycheck = cos(2*pi*t);

% plot test signals
figure
plot(t,y)
hold on
plot(t,ycheck,'r--')

% fft
Y = fft(y);
Ycheck = fft(ycheck);

% phase shift
Y = abs(Y).*exp(1i*angle(Y)-1i*pi/4); % -pi/4 shift
Ycheck = abs(Ycheck).*exp(1i*angle(Ycheck)-1i*pi/4); % -pi/4 shift

%ifft
u = ifft(Y);
ucheck = ifft(Ycheck);

% plot
figure
plot(t,real(u),'k')
hold on
plot(t,real(y),'r')
hold on
plot(t,real(ucheck),'g')
hold on
plot(t,ycheck,'b--')
legend('ifft(exp(1i*2*pi*t)) %-pi/4shift','real(cos(2*pi*t))','ifft(cos(2*pi*t)) %-pi/4 shift','cos(2*pi*t)')

【问题讨论】:

    标签: matlab signal-processing complex-numbers dft


    【解决方案1】:

    有趣的问题!

    如你所知,余弦可以表示为两个虚指数之和:

     cos(x) = ( exp(1i*x) + exp(-1i*x) ) / 2;
    

    更改余弦的相位意味着在余弦参数x 上添加一个数字,例如phi

     cos(x+phi) = ( exp(1i*(x+phi)) + exp(-1i*(x+phi)) ) / 2;
    

    也就是说,

     cos(x+phi) = ( exp(1i*x + 1i*phi) + exp(-1i*x - 1i*phi) ) / 2;
    

    因此,您需要在其中一个指数中添加1i*phi,在另一个指数中减去 1i*phi。在你的情况下phi = -pi/4。但是,您的线路

    Ycheck = abs(Ycheck).*exp(1i*angle(Ycheck)-1i*pi/4); % -pi/4 shift

    相同项添加到两个指数(实际上,添加到所有频率分量)。这就是问题所在。

    在普通的傅里叶变换中,第一个指数对应于变换域中的正频率,第二个指数对应于负频率。但是由于您正在执行 DFT (FFT),因此负频率会折叠并出现在上部。所以你需要在DFT的下半部分加上phi,在上半部分减去phi

    假设DFT的点数是偶数,如你的例子,你只需要将上面指示的行替换为

    phi = -pi//4; %/ desired phase shift
    ind = 1:numel(Ycheck)/2; %// lower half
    Ycheck(ind) = abs(Ycheck(ind)).*exp(1i*angle(Ycheck(ind))+1i*phi); %// add 1i*phi
    ind = numel(Ycheck)/2+1:numel(Ycheck); %// upper half
    Ycheck(ind) = abs(Ycheck(ind)).*exp(1i*angle(Ycheck(ind))-1i*phi); %// subtract 1i*phi
    

    【讨论】:

    • 哇,谢谢你的精彩回答,现在我明白了!我只想到了将复数描述为“absexp(iangle) 的公式,完全忘记了 dft 的基本事实。感谢你让我意识到偶数问题的事实点数。所以以防万一我需要归零。我也不会想到这一点。:)
    • @burgo 很高兴我能帮上忙 :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-07
    • 2023-03-24
    • 2016-04-25
    • 2019-07-17
    相关资源
    最近更新 更多