Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Given r^2, is there an efficient way to compute r^3?

double r2 = dx * dx + dy * dy;
double r3 = r2 * sqrt(r2);

Can the second line be replaced by something faster? Something that does not involve sqrt?

like image 396
fredoverflow Avatar asked Dec 09 '11 13:12

fredoverflow


People also ask

How do you calculate residuals from R Squared?

R 2 = 1 − sum squared regression (SSR) total sum of squares (SST) , = 1 − ∑ ( y i − y i ^ ) 2 ∑ ( y i − y ¯ ) 2 . The sum squared regression is the sum of the residuals squared, and the total sum of squares is the sum of the distance the data is away from the mean all squared.


2 Answers

How about

double r3 = pow(r2,1.5);

If sqrt is implemented as a special case of pow, that will save you a multiplication. Not much in the grand scheme of things mind!

If you are really looking for greater efficiency, consider whether you really need r^3. If, for example, you are only testing it (or something derived from it) to see whether it exceeds a certain threshold, then test r2 instead e.g.

const double r3_threshold = 9;

//don't do this
if (r3 > r3_threshold)
    ....

//do do this
const double r2_threshold = pow(r3_threshold,2./3.); 
if (r2 > r2_threshold)
    ....

That way pow will be called only once, maybe even at compile time.

EDIT If you do need to recompute the threshold each time, I think the answer concerning Q_rsqrt is worth a look and probably deserves to outrank this one

like image 109
Sideshow Bob Avatar answered Nov 10 '22 14:11

Sideshow Bob


Use fast inverse sqrt (take the Q_rsqrt function).

You have:

float r2;
// ... r2 gets a value
float invsqrt = Q_rsqrt(r2);
float r3 = r2*r2*invsqrt; // x*x/sqrt(x) = x*sqrt(x)

NOTE: For double types there is a constant like 0x5f3759df which can help you write a function that handles also double data types.

LATER EDIT: Seems like the method has been already discussed here.

LATER EDIT2: The constant for double was in the wikipedia link:

Lomont pointed out that the "magic number" for 64 bit IEEE754 size type double is 0x5fe6ec85e7de30da, but in fact it is close to 0x5fe6eb50c7aa19f9.

like image 43
INS Avatar answered Nov 10 '22 12:11

INS