xcorr() - Signal Processing
exampler = xcorr(x,y) returns
the cross-correlation of two discrete-time sequences, x and y.
Cross-correlation measures the similarity between x and
shifted (lagged) copies of y as a function of
the lag. If x and y have
different lengths, the function appends zeros at the end of the shorter
vector so it has the same length, N, as the other.
exampler = xcorr(x) returns
the autocorrelation sequence of x. If x is
a matrix, then r is a matrix whose columns contain
the autocorrelation and cross-correlation sequences for all combinations
of the columns of x.
exampler = xcorr(___,maxlag) limits
the lag range from –maxlag to maxlag.
This syntax accepts one or two input sequences. maxlag defaults
to N – 1.
exampler = xcorr(___,scaleopt) additionally
specifies a normalization option for the cross-correlation or autocorrelation.
Any option other than 'none' (the default) requires x and y to
have the same length.
example[r,lags]
= xcorr(___) also returns a vector with the
lags at which the correlations are computed.
Syntax
r = xcorr(x,y) exampler = xcorr(x) exampler = xcorr(___,maxlag) exampler = xcorr(___,scaleopt) example[r,lags]
= xcorr(___) example
Example
Delay Between Two Correlated SignalsOpen This Example
Two sensors at different locations measure vibrations caused by a car as it crosses a bridge.
Load the signals and the sample rate,
. Create time vectors and plot the signals. The signal from Sensor 2 arrives at an earlier time than the signal from Sensor 1.load sensorData
t1 = (0:length(s1)-1)/Fs;
t2 = (0:length(s2)-1)/Fs;
subplot(2,1,1)
plot(t1,s1)
title('s_1')
subplot(2,1,2)
plot(t2,s2)
title('s_2')
xlabel('Time (s)')
The cross-correlation of the two measurements is maximum at a lag equal to the delay.Plot the cross-correlation. Express the delay as a number of samples and in seconds.[acor,lag] = xcorr(s2,s1);
[~,I] = max(abs(acor));
lagDiff = lag(I)
timeDiff = lagDiff/Fs
figure
plot(lag,acor)
a3 = gca;
a3.XTick = sort([-3000:1000:3000 lagDiff]);
lagDiff =
-350
timeDiff =
-0.0317
Align the two signals and replot them.s1al = s1(-lagDiff:end);
t1al = (0:length(s1al)-1)/Fs;
subplot(2,1,1)
plot(t1al,s1al)
title('s_1, aligned')
subplot(2,1,2)
plot(t2,s2)
title('s_2')
xlabel('Time (s)')
Echo CancelationOpen This Example
A speech recording includes an echo caused by reflection off a wall. Use autocorrelation to filter it out.
In the recording, a person says the word MATLAB®. Load the data and the sample rate,
.load mtlb
% To hear, type soundsc(mtlb,Fs)
Model the echo by adding to the recording a copy of the signal delayed by
samples and attenuated by a known factor
:
. Specify a time lag of 0.23 s and an attenuation factor of 0.5.timelag = 0.23;
delta = round(Fs*timelag);
alpha = 0.5;
orig = [mtlb;zeros(delta,1)];
echo = [zeros(delta,1);mtlb]*alpha;
mtEcho = orig + echo;
Plot the original, the echo, and the resulting signal.t = (0:length(mtEcho)-1)/Fs;
subplot(2,1,1)
plot(t,[orig echo])
legend('Original','Echo')
subplot(2,1,2)
plot(t,mtEcho)
legend('Total')
xlabel('Time (s)')
% To hear, type soundsc(mtEcho,Fs)
Compute an unbiased estimate of the signal autocorrelation. Select and plot the section that corresponds to lags greater than zero.[Rmm,lags] = xcorr(mtEcho,'unbiased');
Rmm = Rmm(lags>0);
lags = lags(lags>0);
figure
plot(lags/Fs,Rmm)
xlabel('Lag (s)')
The autocorrelation has a sharp peak at the lag at which the echo arrives. Cancel the echo by filtering the signal through an IIR system whose output,
, obeys
.[~,dl] = findpeaks(Rmm,lags,'MinPeakHeight',0.22);
mtNew = filter(1,[1 zeros(1,dl-1) alpha],mtEcho);
Plot the filtered signal and compare to the original.subplot(2,1,1)
plot(t,orig)
legend('Original')
subplot(2,1,2)
plot(t,mtNew)
legend('Filtered')
xlabel('Time (s)')
% To hear, type soundsc(mtNew,Fs)
Cross-Correlation with Multichannel InputOpen This Example
Generate three 11-sample exponential sequences given by
,
, and
, with
. Use stem3 to plot the sequences side by side.
N = 11;
n = (0:N-1)';
a = 0.4;
b = 0.7;
c = 0.999;
xabc = [a.^n b.^n c.^n];
stem3(n,1:3,xabc','filled')
ax = gca;
ax.YTick = 1:3;
view(37.5,30)
Compute the autocorrelations and mutual cross-correlations of the sequences. Output the lags so you do not have to keep track of them. Normalize the result so the autocorrelations have unit value at zero lag.[cr,lgs] = xcorr(xabc,'coeff');
for row = 1:3
for col = 1:3
nm = 3*(row-1)+col;
subplot(3,3,nm)
stem(lgs,cr(:,nm),'.')
title(sprintf('c_{%d%d}',row,col))
ylim([0 1])
end
end
Restrict the calculation to lags between
and
.[cr,lgs] = xcorr(xabc,5,'coeff');
for row = 1:3
for col = 1:3
nm = 3*(row-1)+col;
subplot(3,3,nm)
stem(lgs,cr(:,nm),'.')
title(sprintf('c_{%d%d}',row,col))
ylim([0 1])
end
end
Compute unbiased estimates of the autocorrelations and mutual cross-correlations. By default, the lags run between
and
.cu = xcorr(xabc,'unbiased');
for row = 1:3
for col = 1:3
nm = 3*(row-1)+col;
subplot(3,3,nm)
stem(-(N-1):(N-1),cu(:,nm),'.')
title(sprintf('c_{%d%d}',row,col))
end
end
Autocorrelation Function of Exponential SequenceOpen This Example
Compute the autocorrelation function of a 28-sample exponential sequence,
for
.
a = 0.95;
N = 28;
n = 0:N-1;
lags = -(N-1):(N-1);
x = a.^n;
c = xcorr(x);
Determine
analytically to check the correctness of the result. Use a larger sample rate to simulate a continuous situation. The autocorrelation function of the sequence
for
, with
, is
fs = 10;
nn = -(N-1):1/fs:(N-1);
cc = a.^abs(nn)/(1-a^2);
dd = (1-a.^(2*(N-abs(nn))))/(1-a^2).*a.^abs(nn);
Plot the sequences on the same figure.stem(lags,c);
hold on
plot(nn,dd)
xlabel('Lag')
legend('xcorr','Analytic')
hold off
Repeat the calculation, but now find an unbiased estimate of the autocorrelation. Verify that the unbiased estimate is given by
.cu = xcorr(x,'unbiased');
du = dd./(N-abs(nn));
stem(lags,cu);
hold on
plot(nn,du)
xlabel('Lag')
legend('xcorr','Analytic')
hold off
Repeat the calculation, but now find a biased estimate of the autocorrelation. Verify that the biased estimate is given by
.cb = xcorr(x,'biased');
db = dd/N;
stem(lags,cb);
hold on
plot(nn,db)
xlabel('Lag')
legend('xcorr','Analytic')
hold off
Find an estimate of the autocorrelation whose value at zero lag is unity.cz = xcorr(x,'coeff');
dz = dd/max(dd);
stem(lags,cz);
hold on
plot(nn,dz)
xlabel('Lag')
legend('xcorr','Analytic')
hold off
Cross-Correlation of Two Exponential SequencesOpen This ExampleCompute and plot the cross-correlation of two 16-sample exponential sequences,
and
, with
.N = 16;
n = 0:N-1;
a = 0.84;
b = 0.92;
xa = a.^n;
xb = b.^n;
r = xcorr(xa,xb);
stem(-(N-1):(N-1),r)
Determine
analytically to check the correctness of the result. Use a larger sample rate to simulate a continuous situation. The cross-correlation function of the sequences
and
for
, with
, is
fs = 10;
nn = -(N-1):1/fs:(N-1);
cn = (1 - (a*b).^(N-abs(nn)))/(1 - a*b) .* ...
(a.^nn.*(nn>0) + (nn==0) + b.^-(nn).*(nn<0));
Plot the sequences on the same figure.hold on
plot(nn,cn)
xlabel('Lag')
legend('xcorr','Analytic')
Verify that switching the order of the operands reverses the sequence.figure
stem(-(N-1):(N-1),xcorr(xb,xa))
hold on
stem(-(N-1):(N-1),fliplr(r),'--*')
xlabel('Lag')
legend('xcorr(x_b,x_a)','fliplr(xcorr(x_a,x_b))')
Generate the 20-sample exponential sequence
. Compute and plot its cross-correlations with
and
. Output the lags to make the plotting easier. xcorr appends zeros at the end of the shorter sequence to match the length of the longer one.xc = 0.77.^(0:20-1);
[xca,la] = xcorr(xa,xc);
[xcb,lb] = xcorr(xb,xc);
figure
subplot(2,1,1)
stem(la,xca)
subplot(2,1,2)
stem(lb,xcb)
xlabel('Lag')
GPU Acceleration for Autocorrelation Sequence Estimation
This example requires Parallel Computing Toolbox™ software
and a CUDA-enabled NVIDIA GPU with compute capability 1.3 or above.
See GPU
System Requirements for details.
Create a signal consisting of a 10 Hz sine wave in additive
noise, sampled at 1 kHz. Use gpuArray to create
a gpuArray object stored on your computer's
GPU.t = 0:0.001:10-0.001;
x = cos(2*pi*10*t) + randn(size(t));
X = gpuArray(x);Compute the normalized autocorrelation sequence to lag
200.[xc,lags] = xcorr(X,200,'coeff');The output, xc, is a gpuArray object.Use gather to transfer the data from the
GPU to the MATLAB® workspace as a double-precision vector.xc = gather(xc);Related ExamplesFind a Signal in a MeasurementAlign Two Simple SignalsMeasuring Signal SimilaritiesAccelerating Correlation with GPUs
Output / Return Value
Limitations
Alternatives / See Also
Reference