Rosetta
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
trig.functions.hh
Go to the documentation of this file.
1 // -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
2 // vi: set ts=2 noet:
3 //
4 // (c) Copyright Rosetta Commons Member Institutions.
5 // (c) This file is part of the Rosetta software suite and is made available under license.
6 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
7 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
8 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
9 
10 /// @file numeric/trig.functions.hh
11 /// @brief Trigonometric functions
12 /// @author Frank M. D'Ippolito (Objexx@objexx.com)
13 /// @author Stuart G. Mentzer (Stuart_Mentzer@objexx.com)
14 
15 
16 #ifndef INCLUDED_numeric_trig_functions_hh
17 #define INCLUDED_numeric_trig_functions_hh
18 
19 
20 // Package headers
22 
23 // Utility headers
24 #include <utility/exit.hh>
25 
26 // C++ headers
27 #include <utility/assert.hh>
28 #include <cmath>
29 #include <cstdlib>
30 #include <iomanip>
31 #include <iostream>
32 
33 //Exception for NaN in sin/cos
35 
36 
37 namespace numeric {
38 
39 
40 /// @brief Secant
41 template< typename T >
42 inline
43 T
44 sec( T const & x )
45 {
46  return ( T( 1.0 ) / std::cos( x ) );
47 }
48 
49 
50 /// @brief Cosecant
51 template< typename T >
52 inline
53 T
54 csc( T const & x )
55 {
56  return ( T( 1.0 ) / std::sin( x ) );
57 }
58 
59 
60 /// @brief Cotangent
61 template< typename T >
62 inline
63 T
64 cot( T const & x )
65 {
66  return ( T( 1.0 ) / std::tan( x ) );
67 }
68 
69 
70 /// @brief Is a sine or cosine value within a specified tolerance of the valid [-1,1] range?
71 template< typename T >
72 inline
73 bool
74 in_sin_cos_range( T const & x, T const & tol = T( .001 ) )
75 {
76  assert( tol >= T( 0.0 ) );
77  return ( ( x >= -( T( 1.0 ) + tol ) ) && ( x <= T( 1.0 ) + tol ) );
78 }
79 
80 
81 /// @brief Adjust a sine or cosine value to the valid [-1,1] range if within a specified
82 /// tolerance or exit with an error.
83 ///
84 /// @note The = on the first <= and >= else if conditions were added to work-around
85 /// optimization register passing bugs where x can be passed by a register
86 /// with a float value of +/-1.0f but where x has a full register precision
87 /// value slightly different from +/-1.0f/ The first else if cases were
88 /// failing but with the = added these if conditions will succeed.
89 /// The alternative fix of declaring "volatile float const x" is slower for
90 /// most calls.
91 /// DON'T REMOVE THESE = EVEN THOUGH THEY APPEAR TO BE SUPERFLUOUS!!!
92 template< typename T >
93 inline
94 T
95 sin_cos_range( T const & x, T const & tol = T( .001 ) )
96 {
97  using std::cout;
98  using std::cerr;
99  using std::endl;
100  using std::setprecision;
101  using std::showpoint;
102 
103  assert( tol >= T( 0.0 ) );
104  if ( ( x >= T( -1.0 ) ) && ( x <= T( 1.0 ) ) ) { // In valid [-1,+1] range
105  return x;
106  } else if ( ( x <= T( -1.0 ) ) && ( x >= -( T( 1.0 ) + tol ) ) ) { // Within tolerance
107  return T( -1.0 ); // Adjusted value
108  } else if ( ( x >= T( 1.0 ) ) && ( x <= T( 1.0 ) + tol ) ) { // Within tolerance
109  return T( 1.0 ); // Adjusted value
110  } else { // Out of range
111  cout << "sin_cos_range ERROR: " << setprecision( 8 ) << showpoint << x << " is outside of [-1,+1] sin and cos value legal range" << endl;
112  cerr << "sin_cos_range ERROR: " << setprecision( 8 ) << showpoint << x << " is outside of [-1,+1] sin and cos value legal range" << endl;
113 #ifdef BOINC
114  // There are enough sufficiently weird machines on BOINC that
115  // the error was getting triggered fairly often (~5% of jumping runs).
116  //SGM This deserves further investigation: Either there is a bug
117  // or we need a larger tolerance for some call sites on certain (which?) h/w
118  return ( x >= T( 0.0 ) ? T( 1.0 ) : T( -1.0 ) );
119 #endif
120 #ifdef USEMPI
121  std::string const warning( "NANs occured in sin_cos_range!" );
122  throw( utility::excn::EXCN_Msg_Exception( warning ) );
123 #endif
124  utility_exit();
125  return T( 0.0 ); // Keep compiler happy
126  }
127 }
128 
129 /// like std::acos but with range checking
130 template< typename T >
131 inline
132 T
133 arccos( T const x )
134 {
135  return std::acos( sin_cos_range( x ) );
136 }
137 
138 
139 } // namespace numeric
140 
141 
142 #endif // INCLUDED_numeric_trig_functions_HH
ocstream cerr(std::cerr)
Wrapper around std::cerr.
Definition: ocstream.hh:290
def x
T cot(T const &x)
Cotangent.
bool in_sin_cos_range(T const &x, T const &tol=T(.001))
Is a sine or cosine value within a specified tolerance of the valid [-1,1] range? ...
common derived classes for thrown exceptions
T sin_cos_range(T const &x, T const &tol=T(.001))
Adjust a sine or cosine value to the valid [-1,1] range if within a specified tolerance or exit with ...
Program exit functions and macros.
#define utility_exit()
Macro function wrappers for utility::exit.
Definition: exit.hh:41
T sec(T const &x)
Secant.
T csc(T const &x)
Cosecant.
ocstream cout(std::cout)
Wrapper around std::cout.
Definition: ocstream.hh:287
float tol
Definition: loops_kic.py:75
Numeric functions.
T arccos(T const x)
like std::acos but with range checking