Shouldn't xcorr(a, b) be same as conv(reverse(a), b)?


#1

When a=[1, 2, 3] and b=[1, 2, 3, 3, 2, 1], yc = conv(reverse(a), b) returns
[3, 8 14, 17, 15, 10, 4, 1],
and yx = xcorr(a, b) returns
[1, 4, 10, 15, 17, 14, 8, 3, 0, 0, 0].

Shouldn’t yx be same as yc?

yx1 = xcorr(b, a) returns
[0, 0, 0, 3, 8 14, 17, 15, 10, 4, 1]. yx1 seems to be right if it means cross-correlation (a, b) except the leading zeros. Where do these zeros come from?


#2

The choice of which signal to reverse is just a convention. Julia follows Matlab here, likewise for the zero padding.

The challenge is to document this properly without violating copyright.


#3

Thank you for your comment, Ralph.

Using * and ⦿ for convolution and cross-correlation respectively, I’ve found
xcorr(a, b) calculates b[p] ⦿ a[p] = b[-p] * a[p] instead of a[p] ⦿ b[p] = a[-p] * b[p]. Cross-correlation is not commutative, and b[p] ⦿ a[p] ≠ a[p] ⦿ b[p], of course.

I have to say that this xcorr’s “convention” is unnecessarily confusing, and one has to be very careful when applying this function as cross-correlation. It’d be kind, or almost necessary, to mention this in its manual/document, and I’m afraid I haven’t found such documents yet.

In Mathematica, there’s no such confusion when using ListCorrelate/ListConvolve. (I don’t have access to Matlab, I’m afraid.)

I still don’t understand the reason for the leading zeros…

I didn’t understand the issue on copyright, either… Because it’s just a matter of explaining the order of arguments in the xcorr function in Julia.

– Teru


#4

When I find that something is underdocumented or confusing, I usually try to find out the relevant details, then make a PR adding documentation.

In this case, since xcorr has been moved to DSP.jl, so you could make a PR there. Or at least open an issue.


#5

I agree that it’s confusing: that’s why I’ve had to look up the Matlab documentation enough times to worry about copyright. Someone without the Matlab background could write out the formula and explain the padding in a PR (as Tamas suggests), based on the current substitute for detailed documentation:

julia> less(xcorr)

#6

Thanks. Helpful :slight_smile:

julia> less(xcorr)
if su < sv
u = [u;zeros(eltype(u),sv-su)]
elseif sv < su
v = [v;zeros(eltype(v),su-sv)]
end
flipdim(conv(flipdim(u, 1), v), 1)
end

end # module

I now understand the arrays are zero-padded to be equal length, which caused the leading zeros in the result.

I don’t understand the last line, though… Why is conv(flipdim(u, 1), v) reversed? If the last line were conv(flipdim(u, 1), v), it’d be consistent with a regular definition of cross-correlation.

I’ve looked at a manual of Matlab’s xcorr here, and found that xcorr is not exactly a plain function for cross-correlation. It assumes the arrays are of equal length, and, if not, zero-pad to be equal. It isn’t required in cross-correlation usually. I noticed as well that the definition of cross-correlation written there is somehow a conjugate of a regular cross-correlation. Weird to me…

Even after reading the manual, I don’t see the reason for applying flipdim as mentioned above if the xcorr function in Julia is adopting that in Matlab.

I’m not a Matlab user, but now got curious of the issue and installed a trial version of Matlab… which ended up occupying 17GB of my disk space :open_mouth:

– Teru


#7

Thanks for your advice.

Because the issue seems to originate in Matlab rather than Julia, I may have to look for information in the Matlab community.

– Teru


#8

I tried xcorr in Matlab, and found the same result as in Julia’ xcorr.

– Teru