LALPulsar  6.1.0.1-89842e6
SinCosLUT.c
Go to the documentation of this file.
1 //
2 // Copyright (C) 2013 Karl Wette
3 // Copyright (C) 2009, 2010, 2011, 2012, 2013 Bernd Machenschalk
4 // Copyright (C) 2005, 2009 Reinhard Prix
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with with program; see the file COPYING. If not, write to the
18 // Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 // MA 02110-1301 USA
20 //
21 
22 #include <math.h>
23 
24 #include <lal/SinCosLUT.h>
25 
26 #define OOTWOPI (1.0 / LAL_TWOPI) // 1/2pi
27 
28 #ifdef __GNUC__
29 #define unlikely(x) __builtin_expect((x),0)
30 #else
31 #define unlikely(x) (x)
32 #endif
33 
34 // main definition of lookup table code
35 #include "SinCosLUT.i"
36 
37 static BOOLEAN haveLUT = 0;
38 
39 /* global VARIABLES to be used in (global) macros */
42 
43 /*
44  * LUT initialization. Normally not required for user, as will
45  * be called transparently by sincosLUT functions.
46  * Put here for certain specialized low-level usage in hotloops.
47 */
48 void
50 {
51  if ( haveLUT ) {
52  return;
53  }
54 
55  static const REAL8 step = LAL_TWOPI / ( REAL8 )SINCOS_LUT_RES;
56  static const REAL8 divide = 1.0 / ( 1 << SINCOS_SHIFT );
57  REAL8 start, end, true_mid, linear_mid;
58  int i;
59 
60  start = 0.0; /* sin(0 * step) */
61  for ( i = 0; i < SINCOS_LUT_RES + SINCOS_LUT_RES / 4; i++ ) {
62  true_mid = sin( ( i + 0.5 ) * step );
63  end = sin( ( i + 1 ) * step );
64  linear_mid = ( start + end ) * 0.5;
65  sincosLUTbase[i] = start + ( ( true_mid - linear_mid ) * 0.5 );
66  sincosLUTdiff[i] = ( end - start ) * divide;
67  start = end;
68  } // for i < LUT_RES
69 
70  haveLUT = 1;
71  return;
72 
73 } // XLALSinCosLUTInit()
74 
75 ///
76 /// Calculate sin(x) and cos(x) to roughly 1e-7 precision using a lookup-table and Taylor-expansion.
77 ///
78 /// \note This function will fail for arguments larger than |x| > INT4_MAX = 2147483647 ~ 2e9 !!!
79 ///
80 /// Returns XLAL_SUCCESS or XLAL_FAILURE.
81 ///
82 int
83 XLALSinCosLUT( REAL4 *sinx, REAL4 *cosx, REAL8 x )
84 {
85  return XLALSinCos2PiLUT( sinx, cosx, x * OOTWOPI );
86 } // XLALSinCosLUT
87 
88 ///
89 /// Calculate sin(2*pi*x) and cos(2*pi*x) to roughly 1e-7 precision using a lookup-table and
90 /// Taylor-expansion.
91 ///
92 /// \note This function will fail for arguments larger than |x| > INT4_MAX = 2147483647 ~ 2e9 !!!
93 ///
94 /// Returns XLAL_SUCCESS or XLAL_FAILURE.
95 ///
96 int
97 XLALSinCos2PiLUT( REAL4 *sin2pix, REAL4 *cos2pix, REAL8 x )
98 {
99  /* trim the value x to interval [0..2) */
100  REAL8 xt;
101  SINCOS_TRIM_X( xt, x );
102 
103  /* call lookup table to calculate sin(2*pi*xt) and cos(2*pi*xt) */
104  return XLALSinCos2PiLUTtrimmed( sin2pix, cos2pix, xt );
105 
106 } // XLALSinCos2PiLUT
107 
108 
109 /** A function that uses the lookup tables to evaluate sin and cos values
110  * of 2*Pi*x, but relies on x being already trimmed to the interval [0..2)
111  */
113 {
114  /* check range of input only in DEBUG mode */
115  if ( unlikely( x > SINCOS_ADDS || x < -SINCOS_ADDS ) ) {
116  if ( x > SINCOS_ADDS ) {
117  XLALPrintError( "%s: x too large: %22f > %f\n", __func__, x, SINCOS_ADDS );
118  return XLAL_FAILURE;
119  } else if ( x < -SINCOS_ADDS ) {
120  XLALPrintError( "%s: x too small: %22f < %f\n", __func__, x, -SINCOS_ADDS );
121  return XLAL_FAILURE;
122  }
123  }
124 
125  /* the first time we get called, we set up the lookup-table */
126  if ( ! haveLUT ) {
128  }
129 
130  /* use the macros defined above */
132  SINCOS_STEP1( x )
136  SINCOS_STEP5( s )
137  SINCOS_STEP6( c )
138  SINCOS_EPILOG( s, c, x )
139 
140  return XLAL_SUCCESS;
141 
142 } /* XLALSinCos2PiLUTtrimmed() */
#define __func__
log an I/O error, i.e.
#define c
static BOOLEAN haveLUT
Definition: SinCosLUT.c:37
UNUSED REAL4 sincosLUTbase[SINCOS_LUT_RES+SINCOS_LUT_RES/4]
Definition: SinCosLUT.c:40
#define unlikely(x)
Definition: SinCosLUT.c:29
UNUSED REAL4 sincosLUTdiff[SINCOS_LUT_RES+SINCOS_LUT_RES/4]
Definition: SinCosLUT.c:41
#define OOTWOPI
Definition: SinCosLUT.c:26
#define SINCOS_STEP1(x)
Definition: SinCosLUT.i:136
#define SINCOS_STEP5(s)
Definition: SinCosLUT.i:140
#define SINCOS_SHIFT
Definition: SinCosLUT.i:100
#define SINCOS_TRIM_X(y, x)
Definition: SinCosLUT.i:85
#define SINCOS_LUT_RES
Definition: SinCosLUT.i:101
#define SINCOS_STEP3
Definition: SinCosLUT.i:138
#define SINCOS_STEP6(c)
Definition: SinCosLUT.i:141
#define SINCOS_STEP4
Definition: SinCosLUT.i:139
#define SINCOS_EPILOG(s, c, x)
Definition: SinCosLUT.i:142
#define SINCOS_ADDS
Definition: SinCosLUT.i:97
#define SINCOS_PROLOG
Definition: SinCosLUT.i:135
#define SINCOS_STEP2
Definition: SinCosLUT.i:137
int s
#define LAL_TWOPI
unsigned char BOOLEAN
double REAL8
float REAL4
int XLALSinCosLUT(REAL4 *sinx, REAL4 *cosx, REAL8 x)
Calculate sin(x) and cos(x) to roughly 1e-7 precision using a lookup-table and Taylor-expansion.
Definition: SinCosLUT.c:83
int XLALSinCos2PiLUT(REAL4 *sin2pix, REAL4 *cos2pix, REAL8 x)
Calculate sin(2*pi*x) and cos(2*pi*x) to roughly 1e-7 precision using a lookup-table and Taylor-expan...
Definition: SinCosLUT.c:97
int XLALSinCos2PiLUTtrimmed(REAL4 *s, REAL4 *c, REAL8 x)
A function that uses the lookup tables to evaluate sin and cos values of 2*Pi*x, but relies on x bein...
Definition: SinCosLUT.c:112
void XLALSinCosLUTInit(void)
Definition: SinCosLUT.c:49
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
XLAL_SUCCESS
XLAL_FAILURE
end