Logo ROOT   6.08/07
Reference Guide
inv.h
Go to the documentation of this file.
1 /*
2  * inv.h
3  * An experiment: implement division with the square fo the approximate
4  * inverse square root.
5  * In other words one transforms a shift, multiplications and sums into a
6  * sqrt.
7  *
8  * Created on: Jun 24, 2012
9  * Author: Danilo Piparo, Thomas Hauth, Vincenzo Innocente
10  *
11  * VDT is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser Public License as published by
13  * the Free Software Foundation, either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Lesser Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser Public License
22  * along with this program. If not, see <http://www.gnu.org/licenses/>.
23  */
24 
25 #ifndef INV_H_
26 #define INV_H_
27 
28 #include "vdtcore_common.h"
29 #include "sqrt.h"
30 #include <cmath>
31 #include <limits>
32 
33 namespace vdt{
34 
35 //------------------------------------------------------------------------------
36 
37 /// General implementation of the inversion
38 inline double fast_inv_general(double x, const uint32_t isqrt_iterations) {
39  const uint64_t sign_mask = details::getSignMask(x);
40  const double sqrt_one_over_x = fast_isqrt_general(std::fabs(x),
41  isqrt_iterations);
42  return sqrt_one_over_x*(details::dpORuint64(sqrt_one_over_x , sign_mask ));
43 }
44 
45 //------------------------------------------------------------------------------
46 
47 /// Four iterations inversion
48 inline double fast_inv(double x) {return fast_inv_general(x,4);}
49 
50 //------------------------------------------------------------------------------
51 
52 /// Three iterations
53 inline double fast_approx_inv(double x) {return fast_inv_general(x,3);}
54 
55 //------------------------------------------------------------------------------
56 
57 /// For comparisons
58 inline double inv (double x) {return 1./x;}
59 
60 //------------------------------------------------------------------------------
61 // Single precision
62 
63 
64 
65 /// General implementation of the inversion
66 inline float fast_invf_general(float x, const uint32_t isqrt_iterations) {
67  const uint32_t sign_mask = details::getSignMask(x);
68  const float sqrt_one_over_x = fast_isqrtf_general(std::fabs(x),
69  isqrt_iterations);
70  return sqrt_one_over_x*(details::spORuint32(sqrt_one_over_x , sign_mask ));
71 }
72 
73 //------------------------------------------------------------------------------
74 
75 /// Two iterations
76 inline float fast_invf(float x) {return fast_invf_general(x,2);}
77 
78 //------------------------------------------------------------------------------
79 
80 /// One iterations
81 inline float fast_approx_invf(float x) {return fast_invf_general(x,1);}
82 
83 //------------------------------------------------------------------------------
84 
85 /// For comparisons
86 inline float invf (float x) {return 1.f/x;}
87 
88 //------------------------------------------------------------------------------
89 
90 // void invv(const uint32_t size, double const * __restrict__ iarray, double* __restrict__ oarray);
91 // void fast_invv(const uint32_t size, double const * __restrict__ iarray, double* __restrict__ oarray);
92 // void fast_approx_invv(const uint32_t size, double const * __restrict__ iarray, double* __restrict__ oarray);
93 // void invfv(const uint32_t size, float const * __restrict__ iarray, float* __restrict__ oarray);
94 // void fast_invfv(const uint32_t size, float const * __restrict__ iarray, float* __restrict__ oarray);
95 // void fast_approx_invfv(const uint32_t size, float const * __restrict__ iarray, float* __restrict__ oarray);
96 
97 } // end namespace vdt
98 
99 #endif /* INV_H_ */
double fast_isqrt_general(double x, const uint32_t ISQRT_ITERATIONS)
Sqrt implmentation from Quake3.
Definition: sqrt.h:37
double inv(double x)
For comparisons.
Definition: inv.h:58
Double_t x[n]
Definition: legend1.C:17
float fast_invf(float x)
Two iterations.
Definition: inv.h:76
uint64_t getSignMask(const double x)
float fast_isqrtf_general(float x, const uint32_t ISQRT_ITERATIONS)
Sqrt implmentation from Quake3.
Definition: sqrt.h:68
VecExpr< UnaryOp< Fabs< T >, VecExpr< A, T, D >, T >, T, D > fabs(const VecExpr< A, T, D > &rhs)
float fast_invf_general(float x, const uint32_t isqrt_iterations)
General implementation of the inversion.
Definition: inv.h:66
float fast_approx_invf(float x)
One iterations.
Definition: inv.h:81
double fast_inv(double x)
Four iterations inversion.
Definition: inv.h:48
Definition: asin.h:32
float spORuint32(const float x, const uint32_t i)
Makes an OR of a float and a unsigned long.
double dpORuint64(const double x, const uint64_t i)
Makes an OR of a double and a unsigned long long.
double fast_approx_inv(double x)
Three iterations.
Definition: inv.h:53
double fast_inv_general(double x, const uint32_t isqrt_iterations)
General implementation of the inversion.
Definition: inv.h:38
float invf(float x)
For comparisons.
Definition: inv.h:86