annotate DEPENDENCIES/generic/include/boost/math/cstdfloat/cstdfloat_complex_std.hpp @ 133:4acb5d8d80b6 tip

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