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_
|