如何直接计算所需的信号相移?

时间:2016-08-01 11:48:10

标签: matlab fft octave combinatorics algebraic-data-types

我将2个组合相移信号( x_phase_sig_comb )与给定信号( x_given )进行比较。 目前我正在使用for循环将每个组合相移信号( x_phase_sig_comb )加在一起,然后我计算RMSE(均方根误差)值相对于给定的信号( x_given )然后我将每个值放入一个数组,然后我排序最小的RMSE(均方根误差值)。

是否存在直接计算相移的代数方法,在该相移处,2个组合相移信号( x_phase_sig_comb )将具有最小,最大或选定范围的RMS(根)当与给定信号( x_given )相比时,均方误差)。我试图避免计算每个组合的相移信号( x_phase_sig_comb

我问的原因是我有非常大的信号,并且每个信号的循环都需要相当长的时间。使用某种类型的代数“形式”直接计算相对于( x_given )给出最小,最大或一系列RMSE值的相移将节省相当多的时间。我只是不知道如何约束相移信号的频率和幅度,或者如何代数地这样做。任何想法?

我在下面创建了一个动画,显示两个信号相对于( x_given )信号的相移以及RMSE值。 注意:顶部图中的两个信号是相同的,唯一的区别是一个信号向左移相移,另一个信号向右相移。

animated gif

Ps:我使用的是octave 4.0,类似于matlab 请参阅下面的示例代码

%test compare signals

Fs = 100;                    % Sampling frequency
T = 1/Fs;                     % Sample time
L = 100;                     % Length of signal
t = (0:L-1)*T;                % Time vector
t_plot=linspace(0,Fs,Fs);     %used just for plotting

x = .5*sin(2*pi*10*t)+0.7*sin(2*pi*12.3*t) +.4*sin(2*pi*16.5*t); %main signal
x_given=.4*sin(2*pi*15*t); %given signal to compare it to
data_array=[];

for rr=1:1:100
  x_sig_main_a = circshift(x(:),rr); %shift signal to the right
  x_sig_main_b = circshift(x(:),-rr); %shift signal to the left
  x_phase_sig_comb=x_sig_main_a+x_sig_main_b; %combine shifted signals together

  NFFT = 2^nextpow2(L); % Next power of 2 from length of siganl
  Y = fft(x_phase_sig_comb,NFFT)/L;
  freq = Fs/2*linspace(0,1,NFFT/2+1);

  %find maximum value, it should be the fundamental frequency (approximated)
  [maxidx,maxVal]=max(2*abs(Y(1:NFFT/2+1)));
  freq(maxVal); %max frequency value

  %RMSE
  dy = abs(x_phase_sig_comb(:)-x_given(:)); %absolute error
  MAE  = mean(dy); %mean-absolute-error
  MXE = max(dy); %maximum-absolute-error
  RMSE = sqrt(mean(dy.^2));  %   root-mean-sqare-error 

  %data_tmp=[rr,freq(maxVal)];
  data_tmp=[rr,RMSE];
  data_array=[data_array;data_tmp];

   % Plot .
  subplot(2,1,1);
  plot(t_plot,x_sig_main_a,'-r',t_plot,x_sig_main_b,'-b')
  s1 = strcat('Phase Shift of 2 signals',' - (',num2str(rr),' bits) shifted out of 100' );
  titletxt = {s1};

  title(titletxt,'FontSize',14);

  subplot(2,1,2); plot(data_array(rr,1),data_array(rr,2),'*-r') 
  axis([0 100 0 1.5])
  s1 = strcat('RMSE of 2 combined phase shifted signals to the given signal =',num2str(data_array(rr,2)));
  titletxt = {s1};
  hold on

  title(titletxt,'FontSize',14);
  xlabel('Phase shift of signals')
  ylabel('Root Mean Square Erro')

  pause(.01)
end
subplot(2,1,2); plot(data_array(:,1),data_array(:,2),'*-r'); %connect lines in plot 
data_array_sort = sortrows(data_array,2); %sort by least different 2 
data_array_sort(1:3,:) %Similar combined phase shifted signals to x_given signal

是否存在直接计算相移的代数方法,在该相移处,2个组合相移信号( x_phase_sig_comb )将具有最小,最大或选定范围的RMS(根均值)方波误差)与给定信号( x_given )的比较。我试图避免计算每个组合的相移信号( x_phase_sig_comb

我问的原因是我有非常大的信号,并且每个信号的循环都需要相当长的时间。使用某种类型的代数“形式”直接计算相对于( x_given )给出最小,最大或一系列RMSE值的相移将节省相当多的时间。我只是不知道如何约束相移信号的频率和幅度,或者如何代数地这样做。任何想法?

1 个答案:

答案 0 :(得分:0)

也许您可以使用相关性而不是RMS。

[Correlation,lag] = xcorr(x,x_given)
[~,index] = max(abs(Correlation))
timeshift = lag(index)

关于de function xcorr

的文档