complex 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. // TR1 complex -*- C++ -*-
  2. // Copyright (C) 2006-2015 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file tr1/complex
  21. * This is a TR1 C++ Library header.
  22. */
  23. #ifndef _GLIBCXX_TR1_COMPLEX
  24. #define _GLIBCXX_TR1_COMPLEX 1
  25. #pragma GCC system_header
  26. #include <complex>
  27. namespace std _GLIBCXX_VISIBILITY(default)
  28. {
  29. namespace tr1
  30. {
  31. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  32. /**
  33. * @addtogroup complex_numbers
  34. * @{
  35. */
  36. #if __cplusplus >= 201103L
  37. using std::acos;
  38. using std::asin;
  39. using std::atan;
  40. #else
  41. template<typename _Tp> std::complex<_Tp> acos(const std::complex<_Tp>&);
  42. template<typename _Tp> std::complex<_Tp> asin(const std::complex<_Tp>&);
  43. template<typename _Tp> std::complex<_Tp> atan(const std::complex<_Tp>&);
  44. #endif
  45. template<typename _Tp> std::complex<_Tp> acosh(const std::complex<_Tp>&);
  46. template<typename _Tp> std::complex<_Tp> asinh(const std::complex<_Tp>&);
  47. template<typename _Tp> std::complex<_Tp> atanh(const std::complex<_Tp>&);
  48. // The std::fabs return type in C++0x mode is different (just _Tp).
  49. template<typename _Tp> std::complex<_Tp> fabs(const std::complex<_Tp>&);
  50. #if __cplusplus < 201103L
  51. template<typename _Tp>
  52. inline std::complex<_Tp>
  53. __complex_acos(const std::complex<_Tp>& __z)
  54. {
  55. const std::complex<_Tp> __t = std::tr1::asin(__z);
  56. const _Tp __pi_2 = 1.5707963267948966192313216916397514L;
  57. return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag());
  58. }
  59. #if _GLIBCXX_USE_C99_COMPLEX_TR1
  60. inline __complex__ float
  61. __complex_acos(__complex__ float __z)
  62. { return __builtin_cacosf(__z); }
  63. inline __complex__ double
  64. __complex_acos(__complex__ double __z)
  65. { return __builtin_cacos(__z); }
  66. inline __complex__ long double
  67. __complex_acos(const __complex__ long double& __z)
  68. { return __builtin_cacosl(__z); }
  69. template<typename _Tp>
  70. inline std::complex<_Tp>
  71. acos(const std::complex<_Tp>& __z)
  72. { return __complex_acos(__z.__rep()); }
  73. #else
  74. /// acos(__z) [8.1.2].
  75. // Effects: Behaves the same as C99 function cacos, defined
  76. // in subclause 7.3.5.1.
  77. template<typename _Tp>
  78. inline std::complex<_Tp>
  79. acos(const std::complex<_Tp>& __z)
  80. { return __complex_acos(__z); }
  81. #endif
  82. template<typename _Tp>
  83. inline std::complex<_Tp>
  84. __complex_asin(const std::complex<_Tp>& __z)
  85. {
  86. std::complex<_Tp> __t(-__z.imag(), __z.real());
  87. __t = std::tr1::asinh(__t);
  88. return std::complex<_Tp>(__t.imag(), -__t.real());
  89. }
  90. #if _GLIBCXX_USE_C99_COMPLEX_TR1
  91. inline __complex__ float
  92. __complex_asin(__complex__ float __z)
  93. { return __builtin_casinf(__z); }
  94. inline __complex__ double
  95. __complex_asin(__complex__ double __z)
  96. { return __builtin_casin(__z); }
  97. inline __complex__ long double
  98. __complex_asin(const __complex__ long double& __z)
  99. { return __builtin_casinl(__z); }
  100. template<typename _Tp>
  101. inline std::complex<_Tp>
  102. asin(const std::complex<_Tp>& __z)
  103. { return __complex_asin(__z.__rep()); }
  104. #else
  105. /// asin(__z) [8.1.3].
  106. // Effects: Behaves the same as C99 function casin, defined
  107. // in subclause 7.3.5.2.
  108. template<typename _Tp>
  109. inline std::complex<_Tp>
  110. asin(const std::complex<_Tp>& __z)
  111. { return __complex_asin(__z); }
  112. #endif
  113. template<typename _Tp>
  114. std::complex<_Tp>
  115. __complex_atan(const std::complex<_Tp>& __z)
  116. {
  117. const _Tp __r2 = __z.real() * __z.real();
  118. const _Tp __x = _Tp(1.0) - __r2 - __z.imag() * __z.imag();
  119. _Tp __num = __z.imag() + _Tp(1.0);
  120. _Tp __den = __z.imag() - _Tp(1.0);
  121. __num = __r2 + __num * __num;
  122. __den = __r2 + __den * __den;
  123. return std::complex<_Tp>(_Tp(0.5) * atan2(_Tp(2.0) * __z.real(), __x),
  124. _Tp(0.25) * log(__num / __den));
  125. }
  126. #if _GLIBCXX_USE_C99_COMPLEX_TR1
  127. inline __complex__ float
  128. __complex_atan(__complex__ float __z)
  129. { return __builtin_catanf(__z); }
  130. inline __complex__ double
  131. __complex_atan(__complex__ double __z)
  132. { return __builtin_catan(__z); }
  133. inline __complex__ long double
  134. __complex_atan(const __complex__ long double& __z)
  135. { return __builtin_catanl(__z); }
  136. template<typename _Tp>
  137. inline std::complex<_Tp>
  138. atan(const std::complex<_Tp>& __z)
  139. { return __complex_atan(__z.__rep()); }
  140. #else
  141. /// atan(__z) [8.1.4].
  142. // Effects: Behaves the same as C99 function catan, defined
  143. // in subclause 7.3.5.3.
  144. template<typename _Tp>
  145. inline std::complex<_Tp>
  146. atan(const std::complex<_Tp>& __z)
  147. { return __complex_atan(__z); }
  148. #endif
  149. #endif // C++11
  150. template<typename _Tp>
  151. std::complex<_Tp>
  152. __complex_acosh(const std::complex<_Tp>& __z)
  153. {
  154. // Kahan's formula.
  155. return _Tp(2.0) * std::log(std::sqrt(_Tp(0.5) * (__z + _Tp(1.0)))
  156. + std::sqrt(_Tp(0.5) * (__z - _Tp(1.0))));
  157. }
  158. #if _GLIBCXX_USE_C99_COMPLEX_TR1
  159. inline __complex__ float
  160. __complex_acosh(__complex__ float __z)
  161. { return __builtin_cacoshf(__z); }
  162. inline __complex__ double
  163. __complex_acosh(__complex__ double __z)
  164. { return __builtin_cacosh(__z); }
  165. inline __complex__ long double
  166. __complex_acosh(const __complex__ long double& __z)
  167. { return __builtin_cacoshl(__z); }
  168. template<typename _Tp>
  169. inline std::complex<_Tp>
  170. acosh(const std::complex<_Tp>& __z)
  171. { return __complex_acosh(__z.__rep()); }
  172. #else
  173. /// acosh(__z) [8.1.5].
  174. // Effects: Behaves the same as C99 function cacosh, defined
  175. // in subclause 7.3.6.1.
  176. template<typename _Tp>
  177. inline std::complex<_Tp>
  178. acosh(const std::complex<_Tp>& __z)
  179. { return __complex_acosh(__z); }
  180. #endif
  181. template<typename _Tp>
  182. std::complex<_Tp>
  183. __complex_asinh(const std::complex<_Tp>& __z)
  184. {
  185. std::complex<_Tp> __t((__z.real() - __z.imag())
  186. * (__z.real() + __z.imag()) + _Tp(1.0),
  187. _Tp(2.0) * __z.real() * __z.imag());
  188. __t = std::sqrt(__t);
  189. return std::log(__t + __z);
  190. }
  191. #if _GLIBCXX_USE_C99_COMPLEX_TR1
  192. inline __complex__ float
  193. __complex_asinh(__complex__ float __z)
  194. { return __builtin_casinhf(__z); }
  195. inline __complex__ double
  196. __complex_asinh(__complex__ double __z)
  197. { return __builtin_casinh(__z); }
  198. inline __complex__ long double
  199. __complex_asinh(const __complex__ long double& __z)
  200. { return __builtin_casinhl(__z); }
  201. template<typename _Tp>
  202. inline std::complex<_Tp>
  203. asinh(const std::complex<_Tp>& __z)
  204. { return __complex_asinh(__z.__rep()); }
  205. #else
  206. /// asinh(__z) [8.1.6].
  207. // Effects: Behaves the same as C99 function casin, defined
  208. // in subclause 7.3.6.2.
  209. template<typename _Tp>
  210. inline std::complex<_Tp>
  211. asinh(const std::complex<_Tp>& __z)
  212. { return __complex_asinh(__z); }
  213. #endif
  214. template<typename _Tp>
  215. std::complex<_Tp>
  216. __complex_atanh(const std::complex<_Tp>& __z)
  217. {
  218. const _Tp __i2 = __z.imag() * __z.imag();
  219. const _Tp __x = _Tp(1.0) - __i2 - __z.real() * __z.real();
  220. _Tp __num = _Tp(1.0) + __z.real();
  221. _Tp __den = _Tp(1.0) - __z.real();
  222. __num = __i2 + __num * __num;
  223. __den = __i2 + __den * __den;
  224. return std::complex<_Tp>(_Tp(0.25) * (log(__num) - log(__den)),
  225. _Tp(0.5) * atan2(_Tp(2.0) * __z.imag(), __x));
  226. }
  227. #if _GLIBCXX_USE_C99_COMPLEX_TR1
  228. inline __complex__ float
  229. __complex_atanh(__complex__ float __z)
  230. { return __builtin_catanhf(__z); }
  231. inline __complex__ double
  232. __complex_atanh(__complex__ double __z)
  233. { return __builtin_catanh(__z); }
  234. inline __complex__ long double
  235. __complex_atanh(const __complex__ long double& __z)
  236. { return __builtin_catanhl(__z); }
  237. template<typename _Tp>
  238. inline std::complex<_Tp>
  239. atanh(const std::complex<_Tp>& __z)
  240. { return __complex_atanh(__z.__rep()); }
  241. #else
  242. /// atanh(__z) [8.1.7].
  243. // Effects: Behaves the same as C99 function catanh, defined
  244. // in subclause 7.3.6.3.
  245. template<typename _Tp>
  246. inline std::complex<_Tp>
  247. atanh(const std::complex<_Tp>& __z)
  248. { return __complex_atanh(__z); }
  249. #endif
  250. template<typename _Tp>
  251. inline std::complex<_Tp>
  252. /// fabs(__z) [8.1.8].
  253. // Effects: Behaves the same as C99 function cabs, defined
  254. // in subclause 7.3.8.1.
  255. fabs(const std::complex<_Tp>& __z)
  256. { return std::abs(__z); }
  257. /// Additional overloads [8.1.9].
  258. #if __cplusplus < 201103L
  259. template<typename _Tp>
  260. inline typename __gnu_cxx::__promote<_Tp>::__type
  261. arg(_Tp __x)
  262. {
  263. typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
  264. #if (_GLIBCXX_USE_C99_MATH && !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC)
  265. return std::signbit(__x) ? __type(3.1415926535897932384626433832795029L)
  266. : __type();
  267. #else
  268. return std::arg(std::complex<__type>(__x));
  269. #endif
  270. }
  271. template<typename _Tp>
  272. inline typename __gnu_cxx::__promote<_Tp>::__type
  273. imag(_Tp)
  274. { return _Tp(); }
  275. template<typename _Tp>
  276. inline typename __gnu_cxx::__promote<_Tp>::__type
  277. norm(_Tp __x)
  278. {
  279. typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
  280. return __type(__x) * __type(__x);
  281. }
  282. template<typename _Tp>
  283. inline typename __gnu_cxx::__promote<_Tp>::__type
  284. real(_Tp __x)
  285. { return __x; }
  286. #endif
  287. template<typename _Tp, typename _Up>
  288. inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
  289. pow(const std::complex<_Tp>& __x, const _Up& __y)
  290. {
  291. typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
  292. return std::pow(std::complex<__type>(__x), __type(__y));
  293. }
  294. template<typename _Tp, typename _Up>
  295. inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
  296. pow(const _Tp& __x, const std::complex<_Up>& __y)
  297. {
  298. typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
  299. return std::pow(__type(__x), std::complex<__type>(__y));
  300. }
  301. template<typename _Tp, typename _Up>
  302. inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
  303. pow(const std::complex<_Tp>& __x, const std::complex<_Up>& __y)
  304. {
  305. typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
  306. return std::pow(std::complex<__type>(__x),
  307. std::complex<__type>(__y));
  308. }
  309. using std::arg;
  310. template<typename _Tp>
  311. inline std::complex<_Tp>
  312. conj(const std::complex<_Tp>& __z)
  313. { return std::conj(__z); }
  314. template<typename _Tp>
  315. inline std::complex<typename __gnu_cxx::__promote<_Tp>::__type>
  316. conj(_Tp __x)
  317. { return __x; }
  318. using std::imag;
  319. using std::norm;
  320. using std::polar;
  321. template<typename _Tp, typename _Up>
  322. inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
  323. polar(const _Tp& __rho, const _Up& __theta)
  324. {
  325. typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
  326. return std::polar(__type(__rho), __type(__theta));
  327. }
  328. using std::real;
  329. template<typename _Tp>
  330. inline std::complex<_Tp>
  331. pow(const std::complex<_Tp>& __x, const _Tp& __y)
  332. { return std::pow(__x, __y); }
  333. template<typename _Tp>
  334. inline std::complex<_Tp>
  335. pow(const _Tp& __x, const std::complex<_Tp>& __y)
  336. { return std::pow(__x, __y); }
  337. template<typename _Tp>
  338. inline std::complex<_Tp>
  339. pow(const std::complex<_Tp>& __x, const std::complex<_Tp>& __y)
  340. { return std::pow(__x, __y); }
  341. // @} group complex_numbers
  342. _GLIBCXX_END_NAMESPACE_VERSION
  343. }
  344. }
  345. #endif // _GLIBCXX_TR1_COMPLEX