# Correlation Estimator Bugs

**URL:** <https://www.ruby-forum.com/t/correlation-estimator-bugs/242538>\
**Category:** GNU Radio\
**Created:** [July 1, 2015, 6:27am UTC](https://www.ruby-forum.com/t/correlation-estimator-bugs/242538 "2015-07-01T06:27:19Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![musicdenotation](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/ea666f/32.png) [@musicdenotation](https://www.ruby-forum.com/u/musicdenotation)\
**Post date:** [July 1, 2015, 6:27am UTC](https://www.ruby-forum.com/t/correlation-estimator-bugs/242538/1 "2015-07-01T06:27:19Z")

</div>

Hi all,

I was just looking through the code in corr\_est\_cc\_impl.cc because it is  
behaving unexpectedly and I think I have spotted a few bugs.

1. If you look at line 203 inside \_set\_threshold and line 240 inside  
work,  
the correlation output is being squared in both cases. The output of the  
correlation operation is already proportional to the voltage squared, so  
squaring it again makes it proportional to the fourth of voltage. These  
extra squares are likely a bug. I don’t think this has a big effect on  
function, but it’s not optimal and is extra calculations nonetheless. It  
is  
also the case that the phase\_est and time\_est values are being  
calculated  
on mag^4 data instead of mag^2 data. Because they are both monotonically  
increasing, again there is probably not a functional effect, but once  
again  
not optimal.

2. The peak value of the correlation peak is being reported as twice as  
big  
as they should be able to get, given a known input length with no noise  
added. For example, given a length 10 sequence which we correlate  
against,  
when they align perfect, you expect to see a peak value of 100 (1 or -1  
times itself summed 10 times = 10 and then squared because of the  
current  
code implementation is 100). Yet, the peak values reported by the  
corr\_start tag value are 200, which shouldn’t be achievable. I can’t  
figure  
out where this factor of two is being introduced in the code.

3. This may be intended, but doesn’t feel right. When you look at the  
correlation output port (port 1), the values of the y-axis seem to have  
been square rooted, so that they appear to be in the range you would  
expect, though the corr\_start tag shows the squared peak value that is  
proportional to the 4th of voltage. It’s confusing and the fact that  
these  
two values are being sent to the user makes me think this is  
unintentional.

4. I have noticed that when I start my receiver first, with a power  
squelch  
gate up front, and then start my transmitter, the correlator places  
thousands of tags on the initial output of the squelch. While the input  
data is very low, the values of the mag^2 being reported in the  
corr\_start  
tag value are very high, well above threshold. I don’t know how this  
could  
happen. It’s causing thousands of false tags to be placed in the stream  
that should not be there. I have not figured out anything concrete about  
this bug. It’s possible it could be my setup, but I don’t see how yet.  
This  
is an over the air test.

I’m hoping the original block designers can provide some feedback that  
might help me understand what the intentions were.

Thanks,  
Rich

---

<div class="post-metadata">

**Author:** ![reback](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/b5ac83/32.png) [@reback](https://www.ruby-forum.com/u/reback)\
**Post date:** [July 1, 2015, 4:03pm UTC](https://www.ruby-forum.com/t/correlation-estimator-bugs/242538/2 "2015-07-01T16:03:30Z")

</div>

Hi Richard,

I’m not the _original_ author, but hopefully I can enlighten little

> I was just looking through the code in corr\_est\_cc\_impl.cc because it  
> is behaving unexpectedly and I think I have spotted a few bugs.

> 1. If you look at line 203 inside \_set\_threshold and line 240 inside  
> work, the correlation output is being squared in both cases. The  
> output of the correlation operation is already proportional to the  
> voltage squared, so squaring it again makes it proportional to the  
> fourth of voltage. These extra squares are likely a bug. I don’t think  
> this has a big effect on function, but it’s not optimal and is extra  
> calculations nonetheless. It is also the case that the phase\_est and  
> time\_est values are being calculated on mag^4 data instead of mag^2  
> data. Because they are both monotonically increasing, again there is  
> probably not a functional effect, but once again not optimal.

Most of this is intentional and not a bug.

Consider:

a. the complex auto-correlation is guaranteed to be real and positive at  
its peak at lag time t=0; although not necessarily real and positive at  
any other lag

b. the complex _cross_-correlation, of a reference signal and an  
incoming noisy similar signal, is never guaranteed to to be real valued  
and positive at any lag value. So comparison of cross-correlation  
values with an auto-correlation peak requires comparison of complex  
number magnitudes, since only one of two complex numbers we know to be  
actually a real, positive number.

c. The sqrt() function has a non-zero computational cost. We wish to  
avoid computing n Msqrts/second if we can, to save CPU for other things.

d. Comparing the magnitude squared of complex numbers for “\<”, “==”, or  
“\>” is equivalent to comparing the magnitude of complex numbers and we  
avoid taking millions of square roots per second.

So no, the squaring is not extra and not a bug, it’s intentional. It’s  
not suboptimal, as finding the complex magnitude is a squaring (i.e.  
z\*z\_conj) followed by a square root, which is more expensive. The code  
is misleading in that has variables named d\_mag as opposed to d\_mag2  
for example.

I would encourage you to think of the cross-correlation as a joint  
property of two signals, and not some sort of power level. That way you  
can talk about things like “magnitude of the correlation peak” and leave  
the signal’s linear amplitude out of picture if it confuses things.

So there is a bug in the GUI and input arguments. If the user want a  
90% threshold, for example, the user needs to enter 0.9\*0.9 or 0.81 in  
the GUI. This is minor and easily worked-around and also can be easily  
fixed. (patch?)

> 1. The peak value of the correlation peak is being reported as twice  
> as big as they should be able to get, given a known input length with  
> no noise added. For example, given a length 10 sequence which we  
> correlate against, when they align perfect, you expect to see a peak  
> value of 100 (1 or -1 times itself summed 10 times = 10 and then  
> squared because of the current code implementation is 100). Yet, the  
> peak values reported by the corr\_start tag value are 200, which  
> shouldn’t be achievable. I can’t figure out where this factor of two  
> is being introduced in the code.

Hmm. Without seeing some matlab or octave code, I can’t really know for  
sure about the factor of two above what exactly.

After looking at this comment I threw in:

> <https://github.com/gnuradio/gnuradio/blob/master/gr-digital/lib/corr_est_cc_impl.cc#L280>

the 2\*A factor out front may hold your answer. I encourage you to look  
up the paper whence that expression came:

> <https://github.com/gnuradio/gnuradio/blob/master/gr-digital/include/gnuradio/digital/corr_est_cc.h#L78>

It may be specific to the modulated band-limited pulses used in that  
paper, but maybe it’s a general expression for complex  
cross-correlation.

> 1. This may be intended, but doesn’t feel right. When you look at the  
> correlation output port (port 1), the values of the y-axis seem to  
> have been square rooted, so that they appear to be in the range you  
> would expect, though the corr\_start tag shows the squared peak value  
> that is proportional to the 4th of voltage. It’s confusing and the  
> fact that these two values are being sent to the user makes me think  
> this is unintentional.

You are correct, that output is the complex cross-correlation without  
being ‘squared’ (i.e. z\*z\_conj). It is intentional. You can plot the  
real part and magnitude of the correlation output and grossly eyeball  
the phase at the correlation peak: if the they line up - the two input  
signals are in-phase; if they are flipped in sign - the two input  
signals are 180 degrees out of phase; if the one is 0 - the two input  
signals are +/-90 degrees out of phase; and everything in between.

The correlation value on the output tag being squared, yeah that’s  
probably a bug. But it was like that when I got here. 🙂 That could be  
easily worked-around or fixed as well.

> 1. I have noticed that when I start my receiver first, with a power  
> squelch gate up front, and then start my transmitter, the correlator  
> places thousands of tags on the initial output of the squelch. While  
> the input data is very low, the values of the mag^2 being reported in  
> the corr\_start tag value are very high, well above threshold. I don’t  
> know how this could happen. It’s causing thousands of false tags to be  
> placed in the stream that should not be there. I have not figured out  
> anything concrete about this bug. It’s possible it could be my setup,  
> but I don’t see how yet. This is an over the air test.

Without a flowgraph and maybe a data file, I’m at a loss on this one.

The tags should never be closer than the length of your preamble in  
samples though.

Is the squelch block before or after the corr\_est block?

> I’m hoping the original block designers can provide some feedback that  
> might help me understand what the intentions were.

Regards,  
Andy
