You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

421 lines
12KB

  1. // TR1 complex -*- C++ -*-
  2. // Copyright (C) 2006-2020 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. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  30. namespace tr1
  31. {
  32. /**
  33. * @addtogroup complex_numbers
  34. * @{
  35. */
  36. #if __cplusplus >= 201103L
  37. using std::acos;
  38. using std::asin;
  39. using std::atan;
  40. using std::acosh;
  41. using std::asinh;
  42. using std::atanh;
  43. #else
  44. template<typename _Tp> std::complex<_Tp> acos(const std::complex<_Tp>&);
  45. template<typename _Tp> std::complex<_Tp> asin(const std::complex<_Tp>&);
  46. template<typename _Tp> std::complex<_Tp> atan(const std::complex<_Tp>&);
  47. template<typename _Tp> std::complex<_Tp> acosh(const std::complex<_Tp>&);
  48. template<typename _Tp> std::complex<_Tp> asinh(const std::complex<_Tp>&);
  49. template<typename _Tp> std::complex<_Tp> atanh(const std::complex<_Tp>&);
  50. #endif
  51. // The std::fabs return type in C++11 mode is different (just _Tp).
  52. template<typename _Tp> std::complex<_Tp> fabs(const std::complex<_Tp>&);
  53. #if __cplusplus < 201103L
  54. template<typename _Tp>
  55. inline std::complex<_Tp>
  56. __complex_acos(const std::complex<_Tp>& __z)
  57. {
  58. const std::complex<_Tp> __t = std::tr1::asin(__z);
  59. const _Tp __pi_2 = 1.5707963267948966192313216916397514L;
  60. return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag());
  61. }
  62. #if _GLIBCXX_USE_C99_COMPLEX_TR1
  63. inline __complex__ float
  64. __complex_acos(__complex__ float __z)
  65. { return __builtin_cacosf(__z); }
  66. inline __complex__ double
  67. __complex_acos(__complex__ double __z)
  68. { return __builtin_cacos(__z); }
  69. inline __complex__ long double
  70. __complex_acos(const __complex__ long double& __z)
  71. { return __builtin_cacosl(__z); }
  72. template<typename _Tp>
  73. inline std::complex<_Tp>
  74. acos(const std::complex<_Tp>& __z)
  75. { return __complex_acos(__z.__rep()); }
  76. #else
  77. /// acos(__z) [8.1.2].
  78. // Effects: Behaves the same as C99 function cacos, defined
  79. // in subclause 7.3.5.1.
  80. template<typename _Tp>
  81. inline std::complex<_Tp>
  82. acos(const std::complex<_Tp>& __z)
  83. { return __complex_acos(__z); }
  84. #endif
  85. template<typename _Tp>
  86. inline std::complex<_Tp>
  87. __complex_asin(const std::complex<_Tp>& __z)
  88. {
  89. std::complex<_Tp> __t(-__z.imag(), __z.real());
  90. __t = std::tr1::asinh(__t);
  91. return std::complex<_Tp>(__t.imag(), -__t.real());
  92. }
  93. #if _GLIBCXX_USE_C99_COMPLEX_TR1
  94. inline __complex__ float
  95. __complex_asin(__complex__ float __z)
  96. { return __builtin_casinf(__z); }
  97. inline __complex__ double
  98. __complex_asin(__complex__ double __z)
  99. { return __builtin_casin(__z); }
  100. inline __complex__ long double
  101. __complex_asin(const __complex__ long double& __z)
  102. { return __builtin_casinl(__z); }
  103. template<typename _Tp>
  104. inline std::complex<_Tp>
  105. asin(const std::complex<_Tp>& __z)
  106. { return __complex_asin(__z.__rep()); }
  107. #else
  108. /// asin(__z) [8.1.3].
  109. // Effects: Behaves the same as C99 function casin, defined
  110. // in subclause 7.3.5.2.
  111. template<typename _Tp>
  112. inline std::complex<_Tp>
  113. asin(const std::complex<_Tp>& __z)
  114. { return __complex_asin(__z); }
  115. #endif
  116. template<typename _Tp>
  117. std::complex<_Tp>
  118. __complex_atan(const std::complex<_Tp>& __z)
  119. {
  120. const _Tp __r2 = __z.real() * __z.real();
  121. const _Tp __x = _Tp(1.0) - __r2 - __z.imag() * __z.imag();
  122. _Tp __num = __z.imag() + _Tp(1.0);
  123. _Tp __den = __z.imag() - _Tp(1.0);
  124. __num = __r2 + __num * __num;
  125. __den = __r2 + __den * __den;
  126. return std::complex<_Tp>(_Tp(0.5) * atan2(_Tp(2.0) * __z.real(), __x),
  127. _Tp(0.25) * log(__num / __den));
  128. }
  129. #if _GLIBCXX_USE_C99_COMPLEX_TR1
  130. inline __complex__ float
  131. __complex_atan(__complex__ float __z)
  132. { return __builtin_catanf(__z); }
  133. inline __complex__ double
  134. __complex_atan(__complex__ double __z)
  135. { return __builtin_catan(__z); }
  136. inline __complex__ long double
  137. __complex_atan(const __complex__ long double& __z)
  138. { return __builtin_catanl(__z); }
  139. template<typename _Tp>
  140. inline std::complex<_Tp>
  141. atan(const std::complex<_Tp>& __z)
  142. { return __complex_atan(__z.__rep()); }
  143. #else
  144. /// atan(__z) [8.1.4].
  145. // Effects: Behaves the same as C99 function catan, defined
  146. // in subclause 7.3.5.3.
  147. template<typename _Tp>
  148. inline std::complex<_Tp>
  149. atan(const std::complex<_Tp>& __z)
  150. { return __complex_atan(__z); }
  151. #endif
  152. template<typename _Tp>
  153. std::complex<_Tp>
  154. __complex_acosh(const std::complex<_Tp>& __z)
  155. {
  156. // Kahan's formula.
  157. return _Tp(2.0) * std::log(std::sqrt(_Tp(0.5) * (__z + _Tp(1.0)))
  158. + std::sqrt(_Tp(0.5) * (__z - _Tp(1.0))));
  159. }
  160. #if _GLIBCXX_USE_C99_COMPLEX_TR1
  161. inline __complex__ float
  162. __complex_acosh(__complex__ float __z)
  163. { return __builtin_cacoshf(__z); }
  164. inline __complex__ double
  165. __complex_acosh(__complex__ double __z)
  166. { return __builtin_cacosh(__z); }
  167. inline __complex__ long double
  168. __complex_acosh(const __complex__ long double& __z)
  169. { return __builtin_cacoshl(__z); }
  170. template<typename _Tp>
  171. inline std::complex<_Tp>
  172. acosh(const std::complex<_Tp>& __z)
  173. { return __complex_acosh(__z.__rep()); }
  174. #else
  175. /// acosh(__z) [8.1.5].
  176. // Effects: Behaves the same as C99 function cacosh, defined
  177. // in subclause 7.3.6.1.
  178. template<typename _Tp>
  179. inline std::complex<_Tp>
  180. acosh(const std::complex<_Tp>& __z)
  181. { return __complex_acosh(__z); }
  182. #endif
  183. template<typename _Tp>
  184. std::complex<_Tp>
  185. __complex_asinh(const std::complex<_Tp>& __z)
  186. {
  187. std::complex<_Tp> __t((__z.real() - __z.imag())
  188. * (__z.real() + __z.imag()) + _Tp(1.0),
  189. _Tp(2.0) * __z.real() * __z.imag());
  190. __t = std::sqrt(__t);
  191. return std::log(__t + __z);
  192. }
  193. #if _GLIBCXX_USE_C99_COMPLEX_TR1
  194. inline __complex__ float
  195. __complex_asinh(__complex__ float __z)
  196. { return __builtin_casinhf(__z); }
  197. inline __complex__ double
  198. __complex_asinh(__complex__ double __z)
  199. { return __builtin_casinh(__z); }
  200. inline __complex__ long double
  201. __complex_asinh(const __complex__ long double& __z)
  202. { return __builtin_casinhl(__z); }
  203. template<typename _Tp>
  204. inline std::complex<_Tp>
  205. asinh(const std::complex<_Tp>& __z)
  206. { return __complex_asinh(__z.__rep()); }
  207. #else
  208. /// asinh(__z) [8.1.6].
  209. // Effects: Behaves the same as C99 function casin, defined
  210. // in subclause 7.3.6.2.
  211. template<typename _Tp>
  212. inline std::complex<_Tp>
  213. asinh(const std::complex<_Tp>& __z)
  214. { return __complex_asinh(__z); }
  215. #endif
  216. template<typename _Tp>
  217. std::complex<_Tp>
  218. __complex_atanh(const std::complex<_Tp>& __z)
  219. {
  220. const _Tp __i2 = __z.imag() * __z.imag();
  221. const _Tp __x = _Tp(1.0) - __i2 - __z.real() * __z.real();
  222. _Tp __num = _Tp(1.0) + __z.real();
  223. _Tp __den = _Tp(1.0) - __z.real();
  224. __num = __i2 + __num * __num;
  225. __den = __i2 + __den * __den;
  226. return std::complex<_Tp>(_Tp(0.25) * (log(__num) - log(__den)),
  227. _Tp(0.5) * atan2(_Tp(2.0) * __z.imag(), __x));
  228. }
  229. #if _GLIBCXX_USE_C99_COMPLEX_TR1
  230. inline __complex__ float
  231. __complex_atanh(__complex__ float __z)
  232. { return __builtin_catanhf(__z); }
  233. inline __complex__ double
  234. __complex_atanh(__complex__ double __z)
  235. { return __builtin_catanh(__z); }
  236. inline __complex__ long double
  237. __complex_atanh(const __complex__ long double& __z)
  238. { return __builtin_catanhl(__z); }
  239. template<typename _Tp>
  240. inline std::complex<_Tp>
  241. atanh(const std::complex<_Tp>& __z)
  242. { return __complex_atanh(__z.__rep()); }
  243. #else
  244. /// atanh(__z) [8.1.7].
  245. // Effects: Behaves the same as C99 function catanh, defined
  246. // in subclause 7.3.6.3.
  247. template<typename _Tp>
  248. inline std::complex<_Tp>
  249. atanh(const std::complex<_Tp>& __z)
  250. { return __complex_atanh(__z); }
  251. #endif
  252. #endif // C++11
  253. template<typename _Tp>
  254. inline std::complex<_Tp>
  255. /// fabs(__z) [8.1.8].
  256. // Effects: Behaves the same as C99 function cabs, defined
  257. // in subclause 7.3.8.1.
  258. fabs(const std::complex<_Tp>& __z)
  259. { return std::abs(__z); }
  260. /// Additional overloads [8.1.9].
  261. #if __cplusplus < 201103L
  262. template<typename _Tp>
  263. inline typename __gnu_cxx::__promote<_Tp>::__type
  264. arg(_Tp __x)
  265. {
  266. typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
  267. #if (_GLIBCXX_USE_C99_MATH && !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC)
  268. return std::signbit(__x) ? __type(3.1415926535897932384626433832795029L)
  269. : __type();
  270. #else
  271. return std::arg(std::complex<__type>(__x));
  272. #endif
  273. }
  274. template<typename _Tp>
  275. inline typename __gnu_cxx::__promote<_Tp>::__type
  276. imag(_Tp)
  277. { return _Tp(); }
  278. template<typename _Tp>
  279. inline typename __gnu_cxx::__promote<_Tp>::__type
  280. norm(_Tp __x)
  281. {
  282. typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
  283. return __type(__x) * __type(__x);
  284. }
  285. template<typename _Tp>
  286. inline typename __gnu_cxx::__promote<_Tp>::__type
  287. real(_Tp __x)
  288. { return __x; }
  289. #endif
  290. template<typename _Tp, typename _Up>
  291. inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
  292. pow(const std::complex<_Tp>& __x, const _Up& __y)
  293. {
  294. typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
  295. return std::pow(std::complex<__type>(__x), __type(__y));
  296. }
  297. template<typename _Tp, typename _Up>
  298. inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
  299. pow(const _Tp& __x, const std::complex<_Up>& __y)
  300. {
  301. typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
  302. return std::pow(__type(__x), std::complex<__type>(__y));
  303. }
  304. template<typename _Tp, typename _Up>
  305. inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
  306. pow(const std::complex<_Tp>& __x, const std::complex<_Up>& __y)
  307. {
  308. typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
  309. return std::pow(std::complex<__type>(__x),
  310. std::complex<__type>(__y));
  311. }
  312. using std::arg;
  313. template<typename _Tp>
  314. inline std::complex<_Tp>
  315. conj(const std::complex<_Tp>& __z)
  316. { return std::conj(__z); }
  317. template<typename _Tp>
  318. inline std::complex<typename __gnu_cxx::__promote<_Tp>::__type>
  319. conj(_Tp __x)
  320. { return __x; }
  321. using std::imag;
  322. using std::norm;
  323. using std::polar;
  324. template<typename _Tp, typename _Up>
  325. inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
  326. polar(const _Tp& __rho, const _Up& __theta)
  327. {
  328. typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
  329. return std::polar(__type(__rho), __type(__theta));
  330. }
  331. using std::real;
  332. template<typename _Tp>
  333. inline std::complex<_Tp>
  334. pow(const std::complex<_Tp>& __x, const _Tp& __y)
  335. { return std::pow(__x, __y); }
  336. template<typename _Tp>
  337. inline std::complex<_Tp>
  338. pow(const _Tp& __x, const std::complex<_Tp>& __y)
  339. { return std::pow(__x, __y); }
  340. template<typename _Tp>
  341. inline std::complex<_Tp>
  342. pow(const std::complex<_Tp>& __x, const std::complex<_Tp>& __y)
  343. { return std::pow(__x, __y); }
  344. // @} group complex_numbers
  345. }
  346. _GLIBCXX_END_NAMESPACE_VERSION
  347. }
  348. #endif // _GLIBCXX_TR1_COMPLEX