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;
}