1 /////////////////////////////////////////////////////////////////////////////// 2 // Copyright Christopher Kormanyos 2014. 3 // Copyright John Maddock 2014. 4 // Copyright Paul Bristow 2014. 5 // Distributed under the Boost Software License, 6 // Version 1.0. (See accompanying file LICENSE_1_0.txt 7 // or copy at http://www.boost.org/LICENSE_1_0.txt) 8 // 9 10 // Implement a specialization of std::complex<> for *anything* that 11 // is defined as BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE. 12 13 #ifndef BOOST_MATH_CSTDFLOAT_COMPLEX_STD_2014_02_15_HPP_ 14 #define BOOST_MATH_CSTDFLOAT_COMPLEX_STD_2014_02_15_HPP_ 15 16 #if defined(__GNUC__) 17 #pragma GCC system_header 18 #endif 19 20 #include <complex> 21 #include <boost/math/constants/constants.hpp> 22 #include <boost/math/tools/cxx03_warn.hpp> 23 24 namespace std 25 { 26 // Forward declarations. 27 template<class float_type> 28 class complex; 29 30 template<> 31 class complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>; 32 33 inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE real(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); 34 inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE imag(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); 35 36 inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE abs (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); 37 inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE arg (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); 38 inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE norm(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); 39 40 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> conj (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); 41 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> proj (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); 42 43 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> polar(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE&, 44 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& = 0); 45 46 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sqrt (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); 47 48 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sin (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); 49 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> cos (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); 50 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> tan (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); 51 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> asin (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); 52 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> acos (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); 53 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> atan (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); 54 55 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> exp (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); 56 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> log (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); 57 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> log10(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); 58 59 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&, 60 int); 61 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&, 62 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE&); 63 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&, 64 const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); 65 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow (const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE&, 66 const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); 67 68 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sinh (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); 69 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> cosh (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); 70 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> tanh (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); 71 72 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> asinh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); 73 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> acosh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); 74 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> atanh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); 75 76 template<class char_type, class traits_type> 77 inline std::basic_ostream<char_type, traits_type>& operator<<(std::basic_ostream<char_type, traits_type>&, const std::complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); 78 79 template<class char_type, class traits_type> 80 inline std::basic_istream<char_type, traits_type>& operator>>(std::basic_istream<char_type, traits_type>&, std::complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); 81 82 // Template specialization of the complex class. 83 template<> 84 class complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> 85 { 86 public: 87 typedef BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE value_type; 88 89 explicit complex(const complex<float>&); 90 explicit complex(const complex<double>&); 91 explicit complex(const complex<long double>&); 92 93 #if defined(BOOST_NO_CXX11_CONSTEXPR) complex(const value_type & r=value_type (),const value_type & i=value_type ())94 complex(const value_type& r = value_type(), 95 const value_type& i = value_type()) : re(r), 96 im(i) { } 97 98 template<typename X> complex(const complex<X> & x)99 complex(const complex<X>& x) : re(x.real()), 100 im(x.imag()) { } 101 real() const102 const value_type& real() const { return re; } imag() const103 const value_type& imag() const { return im; } 104 real()105 value_type& real() { return re; } imag()106 value_type& imag() { return im; } 107 #else complex(const value_type & r=value_type (),const value_type & i=value_type ())108 BOOST_CONSTEXPR complex(const value_type& r = value_type(), 109 const value_type& i = value_type()) : re(r), 110 im(i) { } 111 112 template<typename X> complex(const complex<X> & x)113 BOOST_CONSTEXPR complex(const complex<X>& x) : re(x.real()), 114 im(x.imag()) { } 115 real() const116 value_type real() const { return re; } imag() const117 value_type imag() const { return im; } 118 #endif 119 real(value_type r)120 void real(value_type r) { re = r; } imag(value_type i)121 void imag(value_type i) { im = i; } 122 operator =(const value_type & v)123 complex<value_type>& operator=(const value_type& v) 124 { 125 re = v; 126 im = value_type(0); 127 return *this; 128 } 129 operator +=(const value_type & v)130 complex<value_type>& operator+=(const value_type& v) 131 { 132 re += v; 133 return *this; 134 } 135 operator -=(const value_type & v)136 complex<value_type>& operator-=(const value_type& v) 137 { 138 re -= v; 139 return *this; 140 } 141 operator *=(const value_type & v)142 complex<value_type>& operator*=(const value_type& v) 143 { 144 re *= v; 145 im *= v; 146 return *this; 147 } 148 operator /=(const value_type & v)149 complex<value_type>& operator/=(const value_type& v) 150 { 151 re /= v; 152 im /= v; 153 return *this; 154 } 155 156 template<typename X> operator =(const complex<X> & x)157 complex<value_type>& operator=(const complex<X>& x) 158 { 159 re = x.real(); 160 im = x.imag(); 161 return *this; 162 } 163 164 template<typename X> operator +=(const complex<X> & x)165 complex<value_type>& operator+=(const complex<X>& x) 166 { 167 re += x.real(); 168 im += x.imag(); 169 return *this; 170 } 171 172 template<typename X> operator -=(const complex<X> & x)173 complex<value_type>& operator-=(const complex<X>& x) 174 { 175 re -= x.real(); 176 im -= x.imag(); 177 return *this; 178 } 179 180 template<typename X> operator *=(const complex<X> & x)181 complex<value_type>& operator*=(const complex<X>& x) 182 { 183 const value_type tmp_real = (re * x.real()) - (im * x.imag()); 184 im = (re * x.imag()) + (im * x.real()); 185 re = tmp_real; 186 return *this; 187 } 188 189 template<typename X> operator /=(const complex<X> & x)190 complex<value_type>& operator/=(const complex<X>& x) 191 { 192 const value_type tmp_real = (re * x.real()) + (im * x.imag()); 193 const value_type the_norm = std::norm(x); 194 im = ((im * x.real()) - (re * x.imag())) / the_norm; 195 re = tmp_real / the_norm; 196 return *this; 197 } 198 199 private: 200 value_type re; 201 value_type im; 202 }; 203 204 // Constructors from built-in complex representation of floating-point types. complex(const complex<float> & f)205 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::complex(const complex<float>& f) : re(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE( f.real())), im(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE( f.imag())) { } complex(const complex<double> & d)206 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::complex(const complex<double>& d) : re(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE( d.real())), im(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE( d.imag())) { } complex(const complex<long double> & ld)207 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::complex(const complex<long double>& ld) : re(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(ld.real())), im(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(ld.imag())) { } 208 } // namespace std 209 210 namespace boost { namespace math { namespace cstdfloat { namespace detail { multiply_by_i(const std::complex<float_type> & x)211 template<class float_type> inline std::complex<float_type> multiply_by_i(const std::complex<float_type>& x) 212 { 213 // Multiply x (in C) by I (the imaginary component), and return the result. 214 return std::complex<float_type>(-x.imag(), x.real()); 215 } 216 } } } } // boost::math::cstdfloat::detail 217 218 namespace std 219 { 220 // ISO/IEC 14882:2011, Section 26.4.7, specific values. real(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x)221 inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE real(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { return x.real(); } imag(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x)222 inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE imag(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { return x.imag(); } 223 abs(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x)224 inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE abs (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { using std::sqrt; return sqrt ((real(x) * real(x)) + (imag(x) * imag(x))); } arg(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x)225 inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE arg (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { using std::atan2; return atan2(x.imag(), x.real()); } norm(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x)226 inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE norm(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { return (real(x) * real(x)) + (imag(x) * imag(x)); } 227 conj(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x)228 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> conj (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(x.real(), -x.imag()); } 229 proj(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x)230 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> proj (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) 231 { 232 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE m = (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)(); 233 if ((x.real() > m) 234 || (x.real() < -m) 235 || (x.imag() > m) 236 || (x.imag() < -m)) 237 { 238 // We have an infinity, return a normalized infinity, respecting the sign of the imaginary part: 239 return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity(), x.imag() < 0 ? -0 : 0); 240 } 241 return x; 242 } 243 polar(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE & rho,const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE & theta)244 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> polar(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& rho, 245 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& theta) 246 { 247 using std::sin; 248 using std::cos; 249 250 return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(rho * cos(theta), rho * sin(theta)); 251 } 252 253 // Global add, sub, mul, div. operator +(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & u,const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & v)254 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator+(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u.real() + v.real(), u.imag() + v.imag()); } operator -(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & u,const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & v)255 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator-(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u.real() - v.real(), u.imag() - v.imag()); } 256 operator *(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & u,const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & v)257 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator*(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v) 258 { 259 return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>((u.real() * v.real()) - (u.imag() * v.imag()), 260 (u.real() * v.imag()) + (u.imag() * v.real())); 261 } 262 operator /(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & u,const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & v)263 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator/(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v) 264 { 265 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE the_norm = std::norm(v); 266 267 return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(((u.real() * v.real()) + (u.imag() * v.imag())) / the_norm, 268 ((u.imag() * v.real()) - (u.real() * v.imag())) / the_norm); 269 } 270 operator +(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & u,const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE & v)271 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator+(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u.real() + v, u.imag()); } operator -(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & u,const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE & v)272 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator-(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u.real() - v, u.imag()); } operator *(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & u,const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE & v)273 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator*(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u.real() * v, u.imag() * v); } operator /(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & u,const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE & v)274 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator/(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u.real() / v, u.imag() / v); } 275 operator +(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE & u,const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & v)276 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator+(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u + v.real(), v.imag()); } operator -(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE & u,const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & v)277 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator-(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u - v.real(), -v.imag()); } operator *(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE & u,const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & v)278 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator*(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u * v.real(), u * v.imag()); } operator /(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE & u,const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & v)279 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator/(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v) { const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE v_norm = norm(v); return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>((u * v.real()) / v_norm, (-u * v.imag()) / v_norm); } 280 281 // Unary plus / minus. operator +(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & u)282 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator+(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u) { return u; } operator -(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & u)283 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator-(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(-u.real(), -u.imag()); } 284 285 // Equality and inequality. operator ==(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x,const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & y)286 inline bool operator==(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& y) { return ((x.real() == y.real()) && (x.imag() == y.imag())); } operator ==(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x,const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE & y)287 inline bool operator==(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& y) { return ((x.real() == y) && (x.imag() == BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0))); } operator ==(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE & x,const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & y)288 inline bool operator==(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& y) { return ((x == y.real()) && (y.imag() == BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0))); } operator !=(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x,const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & y)289 inline bool operator!=(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& y) { return ((x.real() != y.real()) || (x.imag() != y.imag())); } operator !=(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x,const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE & y)290 inline bool operator!=(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& y) { return ((x.real() != y) || (x.imag() != BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0))); } operator !=(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE & x,const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & y)291 inline bool operator!=(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& y) { return ((x != y.real()) || (y.imag() != BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0))); } 292 293 // ISO/IEC 14882:2011, Section 26.4.8, transcendentals. sqrt(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x)294 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sqrt(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) 295 { 296 using std::fabs; 297 using std::sqrt; 298 299 // Compute sqrt(x) for x in C: 300 // sqrt(x) = (s , xi / 2s) : for xr > 0, 301 // (|xi| / 2s, +-s) : for xr < 0, 302 // (sqrt(xi), sqrt(xi) : for xr = 0, 303 // where s = sqrt{ [ |xr| + sqrt(xr^2 + xi^2) ] / 2 }, 304 // and the +- sign is the same as the sign of xi. 305 306 if(x.real() > 0) 307 { 308 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE s = sqrt((fabs(x.real()) + std::abs(x)) / 2); 309 310 return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(s, x.imag() / (s * 2)); 311 } 312 else if(x.real() < 0) 313 { 314 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE s = sqrt((fabs(x.real()) + std::abs(x)) / 2); 315 316 const bool imag_is_neg = (x.imag() < 0); 317 318 return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(fabs(x.imag()) / (s * 2), (imag_is_neg ? -s : s)); 319 } 320 else 321 { 322 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sqrt_xi_half = sqrt(x.imag() / 2); 323 324 return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(sqrt_xi_half, sqrt_xi_half); 325 } 326 } 327 sin(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x)328 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sin(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) 329 { 330 using std::sin; 331 using std::cos; 332 using std::exp; 333 334 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sin_x = sin (x.real()); 335 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cos_x = cos (x.real()); 336 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_yp = exp (x.imag()); 337 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_ym = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / exp_yp; 338 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sinh_y = (exp_yp - exp_ym) / 2; 339 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cosh_y = (exp_yp + exp_ym) / 2; 340 341 return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(sin_x * cosh_y, cos_x * sinh_y); 342 } 343 cos(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x)344 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> cos(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) 345 { 346 using std::sin; 347 using std::cos; 348 using std::exp; 349 350 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sin_x = sin (x.real()); 351 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cos_x = cos (x.real()); 352 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_yp = exp (x.imag()); 353 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_ym = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / exp_yp; 354 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sinh_y = (exp_yp - exp_ym) / 2; 355 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cosh_y = (exp_yp + exp_ym) / 2; 356 357 return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(cos_x * cosh_y, -(sin_x * sinh_y)); 358 } 359 tan(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x)360 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> tan(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) 361 { 362 using std::sin; 363 using std::cos; 364 using std::exp; 365 366 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sin_x = sin (x.real()); 367 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cos_x = cos (x.real()); 368 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_yp = exp (x.imag()); 369 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_ym = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / exp_yp; 370 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sinh_y = (exp_yp - exp_ym) / 2; 371 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cosh_y = (exp_yp + exp_ym) / 2; 372 373 return ( complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(sin_x * cosh_y, cos_x * sinh_y) 374 / complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(cos_x * cosh_y, -sin_x * sinh_y)); 375 } 376 asin(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x)377 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> asin(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) 378 { 379 return -boost::math::cstdfloat::detail::multiply_by_i(std::log(boost::math::cstdfloat::detail::multiply_by_i(x) + std::sqrt(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) - (x * x)))); 380 } 381 acos(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x)382 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> acos(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) 383 { 384 return boost::math::constants::half_pi<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>() - std::asin(x); 385 } 386 atan(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x)387 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> atan(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) 388 { 389 const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> izz = boost::math::cstdfloat::detail::multiply_by_i(x); 390 391 return boost::math::cstdfloat::detail::multiply_by_i(std::log(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) - izz) - std::log(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) + izz)) / 2; 392 } 393 exp(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x)394 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> exp(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) 395 { 396 using std::exp; 397 398 return std::polar(exp(x.real()), x.imag()); 399 } 400 log(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x)401 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> log(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) 402 { 403 using std::atan2; 404 using std::log; 405 406 return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(log(std::norm(x)) / 2, atan2(x.imag(), x.real())); 407 } 408 log10(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x)409 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> log10(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) 410 { 411 return std::log(x) / boost::math::constants::ln_ten<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(); 412 } 413 pow(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x,int p)414 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x, 415 int p) 416 { 417 const bool re_isneg = (x.real() < 0); 418 const bool re_isnan = (x.real() != x.real()); 419 const bool re_isinf = ((!re_isneg) ? bool(+x.real() > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)()) 420 : bool(-x.real() > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)())); 421 422 const bool im_isneg = (x.imag() < 0); 423 const bool im_isnan = (x.imag() != x.imag()); 424 const bool im_isinf = ((!im_isneg) ? bool(+x.imag() > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)()) 425 : bool(-x.imag() > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)())); 426 427 if(re_isnan || im_isnan) { return x; } 428 429 if(re_isinf || im_isinf) 430 { 431 return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::quiet_NaN(), 432 std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::quiet_NaN()); 433 } 434 435 if(p < 0) 436 { 437 if(std::abs(x) < (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::min)()) 438 { 439 return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity(), 440 std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity()); 441 } 442 else 443 { 444 return BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / std::pow(x, -p); 445 } 446 } 447 448 if(p == 0) 449 { 450 return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1)); 451 } 452 else 453 { 454 if(p == 1) { return x; } 455 456 if(std::abs(x) > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)()) 457 { 458 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE re = (re_isneg ? -std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity() 459 : +std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity()); 460 461 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE im = (im_isneg ? -std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity() 462 : +std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity()); 463 464 return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(re, im); 465 } 466 467 if (p == 2) { return (x * x); } 468 else if(p == 3) { return ((x * x) * x); } 469 else if(p == 4) { const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> x2 = (x * x); return (x2 * x2); } 470 else 471 { 472 // The variable xn stores the binary powers of x. 473 complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> result(((p % 2) != 0) ? x : complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1))); 474 complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> xn (x); 475 476 int p2 = p; 477 478 while((p2 /= 2) != 0) 479 { 480 // Square xn for each binary power. 481 xn *= xn; 482 483 const bool has_binary_power = ((p2 % 2) != 0); 484 485 if(has_binary_power) 486 { 487 // Multiply the result with each binary power contained in the exponent. 488 result *= xn; 489 } 490 } 491 492 return result; 493 } 494 } 495 } 496 pow(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x,const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE & a)497 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x, 498 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& a) 499 { 500 return std::exp(a * std::log(x)); 501 } 502 pow(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x,const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & a)503 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x, 504 const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a) 505 { 506 return std::exp(a * std::log(x)); 507 } 508 pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE & x,const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & a)509 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, 510 const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a) 511 { 512 return std::exp(a * std::log(x)); 513 } 514 sinh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x)515 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sinh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) 516 { 517 using std::sin; 518 using std::cos; 519 using std::exp; 520 521 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sin_y = sin (x.imag()); 522 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cos_y = cos (x.imag()); 523 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_xp = exp (x.real()); 524 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_xm = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / exp_xp; 525 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sinh_x = (exp_xp - exp_xm) / 2; 526 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cosh_x = (exp_xp + exp_xm) / 2; 527 528 return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(cos_y * sinh_x, cosh_x * sin_y); 529 } 530 cosh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x)531 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> cosh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) 532 { 533 using std::sin; 534 using std::cos; 535 using std::exp; 536 537 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sin_y = sin (x.imag()); 538 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cos_y = cos (x.imag()); 539 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_xp = exp (x.real()); 540 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_xm = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / exp_xp; 541 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sinh_x = (exp_xp - exp_xm) / 2; 542 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cosh_x = (exp_xp + exp_xm) / 2; 543 544 return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(cos_y * cosh_x, sin_y * sinh_x); 545 } 546 tanh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x)547 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> tanh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) 548 { 549 const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> ex_plus = std::exp(x); 550 const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> ex_minus = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / ex_plus; 551 552 return (ex_plus - ex_minus) / (ex_plus + ex_minus); 553 } 554 asinh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x)555 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> asinh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) 556 { 557 return std::log(x + std::sqrt((x * x) + BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1))); 558 } 559 acosh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x)560 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> acosh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) 561 { 562 const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE my_one(1); 563 564 const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> zp(x.real() + my_one, x.imag()); 565 const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> zm(x.real() - my_one, x.imag()); 566 567 return std::log(x + (zp * std::sqrt(zm / zp))); 568 } 569 atanh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x)570 inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> atanh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) 571 { 572 return (std::log(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) + x) - std::log(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) - x)) / 2.0; 573 } 574 575 template<class char_type, class traits_type> operator <<(std::basic_ostream<char_type,traits_type> & os,const std::complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x)576 inline std::basic_ostream<char_type, traits_type>& operator<<(std::basic_ostream<char_type, traits_type>& os, const std::complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) 577 { 578 std::basic_ostringstream<char_type, traits_type> ostr; 579 580 ostr.flags(os.flags()); 581 ostr.imbue(os.getloc()); 582 ostr.precision(os.precision()); 583 584 ostr << char_type('(') 585 << x.real() 586 << char_type(',') 587 << x.imag() 588 << char_type(')'); 589 590 return (os << ostr.str()); 591 } 592 593 template<class char_type, class traits_type> operator >>(std::basic_istream<char_type,traits_type> & is,std::complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> & x)594 inline std::basic_istream<char_type, traits_type>& operator>>(std::basic_istream<char_type, traits_type>& is, std::complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) 595 { 596 BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE rx; 597 BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE ix; 598 599 char_type the_char; 600 601 static_cast<void>(is >> the_char); 602 603 if(the_char == static_cast<char_type>('(')) 604 { 605 static_cast<void>(is >> rx >> the_char); 606 607 if(the_char == static_cast<char_type>(',')) 608 { 609 static_cast<void>(is >> ix >> the_char); 610 611 if(the_char == static_cast<char_type>(')')) 612 { 613 x = complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(rx, ix); 614 } 615 else 616 { 617 is.setstate(ios_base::failbit); 618 } 619 } 620 else if(the_char == static_cast<char_type>(')')) 621 { 622 x = rx; 623 } 624 else 625 { 626 is.setstate(ios_base::failbit); 627 } 628 } 629 else 630 { 631 static_cast<void>(is.putback(the_char)); 632 633 static_cast<void>(is >> rx); 634 635 x = rx; 636 } 637 638 return is; 639 } 640 } // namespace std 641 642 #endif // BOOST_MATH_CSTDFLOAT_COMPLEX_STD_2014_02_15_HPP_ 643