Simple Magnitude Estimator

Those of us working in R&D can end up at odds with the chip designers who have to implement our so-called “pie-in-the-sky” algorithms.

You see, we like to use mathematical operations such as complex multiplies & divides, yn, y1/n, and logn( ). But the chip guys are under pressure to produce cheap, fast hardware and can have trouble doing anything more complicated than shifts and adds.

So it’s always nice to come across simpler versions of more complicated functions that work almost as well.

Matlab Users: There is a script that goes with this article. You can find it here.

In wireless communications, we often need to compute the magnitude of a complex number, I + jQ. In pie-in-the-sky world, this is:

mag_1

This could create headaches for the hardware guys if they need to do this quickly over hundreds or thousands of sub-carriers, as you might have to do for OFDM.

But as it turns out, we can replace the above equation with the following approximation:

mag_3

The equation is longer, but simpler.

The | |’s are easily implemented by just dropping sign bits. Both the max( ) and min( ) can be done with one compare.

But we have introduced two new multiplies with the α and β coefficients.

Now you can optimize α and β depending upon whether you’re interested in minimizing peak error, average error, etc.

But the bottom line is hardware guys don’t like multiplies.

As it turns out though, you get a very good approximation of magnitude if you just use α=1 and β=0.25. So our equation becomes:

mag_2

α has gone away and divide by 4 can be implemented as a bit shift by 2. Look ma, no multiplies. 😉 But how good is this approximation?

To simulate magnitudes that might be seen by a multicarrier receiver, I created 10,000 random complex numbers with a dynamic range of 70 dB. I saw an average estimation error of 0.3 dB and a max error of about 1.1 dB.

I could show you a plot of the results but they’re so similar you couldn’t tell the difference. If you have Matlab and want to try it for yourself, grab linear_mag_est.m

Final question. How does this approximation work?
(1) The | |’s re-map our complex coordingates from 0-360° to 0-90°.
(2) The max & min’s further re-map our coordinates from 0-90° to 0-45°.
(3) Once in the 0-45° range, magnitude can be approximated with a simple linear combination of I and Q (i.e. multiplying by α and β and summing).

An example?
(1) Let our complex number be -4-9i. It has an angle of 246°.
(2) The | |’s effectively map this to 4+9i. The angle is now 66°.
(3) The max( ) and min( ) swap this to 9+4i with an angle of 24°.

The ideal magnitude of our complex number was 9.8489.
Our approximation yields 9+4/4 = 10.0.

Pretty darn close – an SNR of 36 dB.

If you want an example Matlab implementation, download linear_mag_est.m.

If you want more of the details, further options for α and β, and example C code check out this link at DSPguru.com. After all, I learned this trick from them. 🙂

And if you found this article interesting, you might also like its evil twin concerning simple phase estimation.