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