Кросс-корреляция двух последовательностей разной длины с использованием свертки в Matlab - PullRequest
1 голос
/ 20 октября 2019

Предположим, что у нас есть две простые последовательности разной длины:

x = rand(3,1);
y = rand(2,1);

Я рассчитал взаимную корреляцию между ними и построил ее так:

r_1 = xcorr(x,(y));

tx = 1:length(x);
ty = 1:length(y);
tr = ceil(-(length(x)+length(y)-1)/2) :  floor((length(x)+length(y)-1)/2);

subplot(2,2,1); stem(tr,r_1); title('XC');

Я хотел вычислитьперекрестная корреляция с использованием свертки и показать, что ее результат равен результату при использовании xcorr (). Но когда я реализовал это так:

r_2 = conv(x,fliplr(y));

tx = 1:length(x);
ty = 1:length(y);
tr = ceil(-(length(x)+length(y)-1)/2) :  floor((length(x)+length(y)-1)/2);

subplot(2,2,1); stem(tr,r_2); title('XC');

длина r_1 и r_2 различна, и я получил эту ошибку :

Ошибка при использовании ствола (строка 43) X должна иметь ту же длину, что и Y.

Спасибо за помощь.

1 Ответ

2 голосов
/ 21 октября 2019

В вашем коде есть три проблемы:

  1. Вы применяете fliplr к y, но y - это вектор-столбец, поэтому - нетдействительно переворачивает это . Вам следует подать flipud;или flip, если вы хотите, чтобы он работал для любого вектора в целом.

  2. Из документации xcorr:

    C = xcorr(A,B) [...]> Если A и B имеют разную длину, самый короткий из них заполнен нулями .

    Итак, чтобы сделать результат conv равным результату xcorr, вам нужно с нулевой аппроксимацией более коротким вектором.

    ВВ общем случае для векторов столбцов x и y вы можете использовать [x; zeros(numel(y)-numel(x),1)] вместо x и [y; zeros(numel(x)-numel(y),1)] вместо y. Это расширит короткий вектор и оставит другой как есть. Обратите внимание, что это работает, потому что, согласно документации zeros,

    zeros(M,N,P,...) [...] Размер входных данных M, N, иP ... должны быть неотрицательными целыми числами. Отрицательные целые числа обрабатываются как 0.

  3. В корреляции применяется комплексный конъюгат ко второму входу . Вы должны сделать то же самое со сверткой. В вашем примере это не имеет значения, потому что входные данные реальны, но это должно быть сделано в целом.

Объединение трех пунктов выше:

r_1 = xcorr(x, y);
r_2 = conv([x; zeros(numel(y)-numel(x),1)], conj(flip([y; zeros(numel(x)-numel(y),1)])));

должно датьтот же результат.

Пример :

x = [3.1; -4.3; 5.6];
y = [2.6; -8.4];

дают

r_1 =
   0.000000000000004
 -26.040000000000006
  44.180000000000000
 -58.219999999999999
  14.559999999999999
r_2 =
                   0
 -26.040000000000003
  44.180000000000000
 -58.219999999999999
  14.559999999999999

, которые одинаковы с точностью до числовой погрешности.

...