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