计算正弦波相位滞后时低频数据的互相关问题
Problems with cross correlation in low-frequency data when computing phase lag of sin wave
我正在尝试使用 matlab 中的互相关来计算简单正弦波的相位滞后。这是一些演示我看到的问题的代码。 (如果您没有并行计算工具箱,您可以相应地调整 k 和 n,并将 "parfor" 更改为 "for")。
clear all;
close all;
%%
knownLag = 1;
k = 100000;
n = k/1000;
lag = zeros(1, n);
percentError = zeros(1, n);
m = zeros(1, n);
parfor i = 1:n;
m(i) = i*2;
x = linspace(0, m(i)*pi, k);
y1 = sin(x);
y2 = sin(x+knownLag);
%%
[cc2, lags] = xcorr(y1, y2, 'coeff');
[mx, I] = max(cc2);
dx = (m(i)*pi)/(k-1);
lag(i) = (abs(k-I)*dx);
percentError(i) = (abs(lag(i)-knownLag)/knownLag)*100;
end
figure(1);
plot(m, percentError)
ylabel('Percent Error');
xlabel('m * pi');
%%
n = 1;
x1 = linspace(0, m(n)*pi, k);
y11 = sin(x1);
y21 = sin(x1+knownLag);
figure(2);
hold on;
plot(x1, y11);
plot(x1+lag(n), y21);
plot(x1, y21);
legend('Sin wave w/o phase shift', '"Corrected" Sin wave', '"Uncorrected" Sin wave');
xlabel('x');
ylabel('y');
title('Plot of "Corrected" Sin wave with period = 2*pi');
n = 5;
x1 = linspace(0, m(n)*pi, k);
y11 = sin(x1);
y21 = sin(x1+knownLag);
figure(3);
hold on;
plot(x1, y11);
plot(x1+lag(n), y21);
plot(x1, y21);
legend('Sin wave w/o phase shift', '"Corrected" Sin wave', '"Uncorrected" Sin wave');
xlabel('x');
ylabel('y');
title('Plot of "Corrected" Sin wave with period = 10*pi');
这是输出图:
如您所见,随着周期数的增加,预测相位滞后的误差会减少。最终数值取而代之,误差在一个非常低的值附近波动。我真的只对为什么误差从 2-60 pi 下降如此之大感兴趣。这是别名问题吗?我不明白这在互相关计算中是从哪里来的。
这不是别名问题。 xcorr 是两个信号之间相关性的估计。当您观察到更多信号时,您的估计会更好。对于 m*pi
的低值,周期数很低,您对信号的观察非常有限。对于更高的 m*pi
值,您可以更好地查看具有更多周期的信号模式,从而提供更好的估计。
想到一个周期的正弦波就很容易理解了。当您将这段时间恰好放在另一个时间段之上时,您将获得最大的相关性。但是当信号只有一个周期滞后时,这种具有完整周期的对齐不会发生,因为边缘总是用 0 填充。
我正在尝试使用 matlab 中的互相关来计算简单正弦波的相位滞后。这是一些演示我看到的问题的代码。 (如果您没有并行计算工具箱,您可以相应地调整 k 和 n,并将 "parfor" 更改为 "for")。
clear all;
close all;
%%
knownLag = 1;
k = 100000;
n = k/1000;
lag = zeros(1, n);
percentError = zeros(1, n);
m = zeros(1, n);
parfor i = 1:n;
m(i) = i*2;
x = linspace(0, m(i)*pi, k);
y1 = sin(x);
y2 = sin(x+knownLag);
%%
[cc2, lags] = xcorr(y1, y2, 'coeff');
[mx, I] = max(cc2);
dx = (m(i)*pi)/(k-1);
lag(i) = (abs(k-I)*dx);
percentError(i) = (abs(lag(i)-knownLag)/knownLag)*100;
end
figure(1);
plot(m, percentError)
ylabel('Percent Error');
xlabel('m * pi');
%%
n = 1;
x1 = linspace(0, m(n)*pi, k);
y11 = sin(x1);
y21 = sin(x1+knownLag);
figure(2);
hold on;
plot(x1, y11);
plot(x1+lag(n), y21);
plot(x1, y21);
legend('Sin wave w/o phase shift', '"Corrected" Sin wave', '"Uncorrected" Sin wave');
xlabel('x');
ylabel('y');
title('Plot of "Corrected" Sin wave with period = 2*pi');
n = 5;
x1 = linspace(0, m(n)*pi, k);
y11 = sin(x1);
y21 = sin(x1+knownLag);
figure(3);
hold on;
plot(x1, y11);
plot(x1+lag(n), y21);
plot(x1, y21);
legend('Sin wave w/o phase shift', '"Corrected" Sin wave', '"Uncorrected" Sin wave');
xlabel('x');
ylabel('y');
title('Plot of "Corrected" Sin wave with period = 10*pi');
这是输出图:
如您所见,随着周期数的增加,预测相位滞后的误差会减少。最终数值取而代之,误差在一个非常低的值附近波动。我真的只对为什么误差从 2-60 pi 下降如此之大感兴趣。这是别名问题吗?我不明白这在互相关计算中是从哪里来的。
这不是别名问题。 xcorr 是两个信号之间相关性的估计。当您观察到更多信号时,您的估计会更好。对于 m*pi
的低值,周期数很低,您对信号的观察非常有限。对于更高的 m*pi
值,您可以更好地查看具有更多周期的信号模式,从而提供更好的估计。
想到一个周期的正弦波就很容易理解了。当您将这段时间恰好放在另一个时间段之上时,您将获得最大的相关性。但是当信号只有一个周期滞后时,这种具有完整周期的对齐不会发生,因为边缘总是用 0 填充。