ON 20090526@8:03:33 AM at page: On a web page you were interested in at: http://piclist.com/techref/microchip/math/vector/index.htm#39959.335787037 Nikolai Golovchenko[NG--944] Code:
There are several approximate methods for finding magnitude. They vary in their
complexity and accuracy. Here is a list of some options:

Method 1. Accurate up to -0..+8%. Requires a multiply by a constant.

 int magnitude_Robertson(int x, int y)
 {
   int mx;
   int mn;
   x = abs(x);
   y = abs(y);
   mx = max(x, y);
   mn = min(x, y);
   return mx + mn*k;
 }

The method is apparently due to:
Robertson, G.H., "A Fast Amplitude Approximation for Quadrature Pairs", Bell Sys. Tech. J., 
Vol. 50, Oct. 1971, pp.2849-2852.

The constant k is chosen to minimize error in one of different ways (average error, absolute error, 
peak-to-peak error, standard deviation, etc) and efficient to compute the multiply. 
A few examples:

1/2, 3/8, 1/4:          suggested by Robertson
sqrt(2)-1 ~= 106/256:   minimizes p-p error (also, zero error at multiples of 45 deg)


Method 2. Accurate to 2.8%. Requires three constant multiplies.

 int magnitude_Levitt(int x, int y)
 {
   int mx;
   int mn;
   x = abs(x);
   y = abs(y);
   mx = max(x, y);
   mn = min(x, y);

   if(mx >= 3*mn)
     return mx + mn/8;
   else
     return mx*7/8 + mn/2;
 }

See B.K Levitt, G.A. Morris, "An Improved Digital Algorithm for Fast Amplitude
Approximations of Quadrature Pairs", DSN Progress Report 42-40, May and June 1977, pp 97-101.
<a href="http://tmo.jpl.nasa.gov/progress_report2/42-40/40L.PDF">http://tmo.jpl.nasa.gov/progress_report2/42-40/40L.PDF</a>


Method 3. Accurate up to -1.5%...+0%. Requires a divide, multiply, and a constant multiply.

 int magnitude3(int x, int y)
 {
   int mx;
   int mn;
   x = abs(x);
   y = abs(y);
   mx = max(x, y);
   mn = min(x, y);
   if(mx == 0)
     return mx;

   return mx + mn*mn/mx*k;
 }

The constant k is chosen similarly to method 1. For example, k=sqrt(2)-1~=106/256 again 
minimizes the p-p error. The method is due to Nikolai Golovchenko. :)


Method 4. Accurate up to -0.5%..+0%. Requires a divide, multiply, and two constant multiplies.

This is a piecewise refinement of method 3. Vector (x,y) is assumed to be
rotated to the range of 0 to 45 deg (i.e. x=mx and y=mn as in examples above)

   b = y/x

   if b <= 0.5
     b += b * 0.14      // ~5/32
   else
     b += (1-b) * 0.14 

   r = x + y * b * 106/256

Method 5: Theoretically arbitrary accuracy. Requires a divide and two multiplies.

   r = x + y * lookup(y/x)

   lookup() - a function that represents a table with linear interpolation.


ON 20090526@9:48:06 AM at page: On a web page you were interested in at: http://piclist.com/techref/microchip/math/vector/index.htm#39959.4084027778 Nikolai Golovchenko[NG--944] Code:
Method 2B. Accurate to -1.2%..+0.8%. Requires up to four constant multiplies.

This method refines Levitt/Morris method.

 int magnitude2B(int x, int y)
 {
   int mx;
   int mn;
   x = abs(x);
   y = abs(y);
   mx = max(x, y);
   mn = min(x, y);

   if(mx >= 3*mn)
     return mx + mn/8;
   else if (mx >= 5/4*mn)
     return mx*7/8 + mn/2;
   else
     return mx*3/4 + mn*21/32;
 }