aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/bits/complex_util.h
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3/include/bits/complex_util.h')
-rw-r--r--libstdc++-v3/include/bits/complex_util.h329
1 files changed, 329 insertions, 0 deletions
diff --git a/libstdc++-v3/include/bits/complex_util.h b/libstdc++-v3/include/bits/complex_util.h
new file mode 100644
index 00000000000..ca5503b0da5
--- /dev/null
+++ b/libstdc++-v3/include/bits/complex_util.h
@@ -0,0 +1,329 @@
+// TR29124 math special functions -*- C++ -*-
+
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/complex_util.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _GLIBCXX_BITS_COMPLEX_UTIL_H
+#define _GLIBCXX_BITS_COMPLEX_UTIL_H 1
+
+#pragma GCC system_header
+
+#include <complex>
+#include <ratio>
+#include <limits>
+#include <bits/specfun_util.h>
+#include <bits/numeric_limits.h>
+#include <ext/math_util.h>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+namespace __detail
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+//
+// The base definitions of __num_traits, __promote_fp,
+// and __isnan reside in ext/specfun_util.h
+//
+
+ /**
+ * A class to reach into compound numeric types to extract the
+ * value or element type - specialized for complex.
+ */
+ template<>
+ template<typename _Tp>
+ struct __num_traits<std::complex<_Tp>>
+ {
+ using __value_type = typename std::complex<_Tp>::value_type;
+ };
+
+ /**
+ * Create a complex number NaN.
+ */
+ template<>
+ template<typename _Tp>
+ struct __make_NaN<std::complex<_Tp>>
+ {
+ constexpr std::complex<_Tp>
+ operator()()
+ {
+ auto __NaN = std::numeric_limits<_Tp>::quiet_NaN();
+ return std::complex<_Tp>{__NaN, __NaN};
+ }
+ };
+
+ /**
+ * Return true if one component of a complex number is NaN.
+ */
+ template<typename _Tp>
+ inline bool
+ __isnan(const std::complex<_Tp>& __z)
+ { return __isnan(std::real(__z)) || __isnan(std::imag(__z)); }
+
+ /**
+ * Return true if one component of a complex number is inf.
+ */
+ template<typename _Tp>
+ inline bool
+ __isinf(const std::complex<_Tp>& __z)
+ { return __isinf(std::real(__z)) || __isinf(std::imag(__z)); }
+
+
+ /**
+ * Return the L1 norm modulus or the Manhattan metric distance of a complex number.
+ */
+ template<typename _Tp>
+ inline constexpr _Tp
+ __l1_norm(const std::complex<_Tp>& __z)
+ { return std::abs(std::real(__z)) + std::abs(std::imag(__z)); }
+
+ /**
+ * Return the L2 norm modulus or the Euclidean metric distance of a complex number.
+ */
+ template<typename _Tp>
+ inline constexpr _Tp
+ __l2_norm(const std::complex<_Tp>& __z)
+ { return std::norm(__z); }
+
+ /**
+ * Return the Linf norm modulus of a complex number.
+ */
+ template<typename _Tp>
+ inline constexpr _Tp
+ __linf_norm(const std::complex<_Tp>& __z)
+ { return std::max(std::abs(std::real(__z)), std::abs(std::imag(__z))); }
+
+
+ /**
+ * Return the L1 norm modulus or the Manhattan metric distance of a real number.
+ */
+ template<typename _Tp>
+ inline constexpr _Tp
+ __l1_norm(_Tp __x)
+ { return std::abs(__x); }
+
+ /**
+ * Return the L2 norm modulus or the Euclidean metric distance of a real number.
+ */
+ template<typename _Tp>
+ inline constexpr _Tp
+ __l2_norm(_Tp __x)
+ { return std::abs(__x); }
+
+ /**
+ * Return the Linf norm modulus of a real number.
+ */
+ template<typename _Tp>
+ inline constexpr _Tp
+ __linf_norm(_Tp __x)
+ { return std::abs(__x); }
+
+
+ /**
+ * Carefully compute @c z1/z2 avoiding overflow and destructive underflow.
+ * If the quotient is successfully computedit is returned.
+ * Otherwise, std::runtime_error is thrown.
+ */
+ template<typename _Tp>
+ std::complex<_Tp>
+ __safe_div(const std::complex<_Tp>& __z1, const std::complex<_Tp>& __z2);
+
+ /**
+ * Carefully compute @c s/z2 avoiding overflow and destructive underflow.
+ * If the quotient is successfully computed it is returned.
+ * Otherwise, @c false is returned and the quotient is not.
+ */
+ template<typename _Sp, typename _Tp>
+ inline std::complex<_Tp>
+ __safe_div(_Sp __s, const std::complex<_Tp>& __z)
+ { return __safe_div(std::complex<_Tp>(__s), __z); }
+
+ /**
+ * Carefully compute @c z1/s avoiding overflow and destructive underflow.
+ * If the quotient is successfully computed it is returned.
+ * Otherwise, @c false is returned and the quotient is not.
+ */
+ template<typename _Sp, typename _Tp>
+ inline std::complex<_Tp>
+ __safe_div(const std::complex<_Tp>& __z, _Sp __s)
+ { return __safe_div(__z, std::complex<_Tp>(__s)); }
+
+ /**
+ * @brief Carefully compute and return @c s1*s2 avoiding overflow.
+ * If the product can be successfully computed it is returned.
+ * Otherwise, std::runtime_error is thrown.
+ */
+ template<typename _Tp>
+ _Tp
+ __safe_mul(_Tp __s1, _Tp __s2);
+
+ /**
+ * Carefully compute @c z1*z2 avoiding overflow.
+ * If the product is successfully computed it is returned.
+ * Otherwise, std::runtime_error is thrown.
+ */
+ template<typename _Tp>
+ std::complex<_Tp>
+ __safe_mul(const std::complex<_Tp>& __z1, const std::complex<_Tp>& __z2);
+
+ /**
+ * Carefully compute @c s*z avoiding overflow.
+ * If the product is successfully computed it is returned.
+ * Otherwise, std::runtime_error is thrown.
+ */
+ template<typename _Sp, typename _Tp>
+ inline std::complex<_Tp>
+ __safe_mul(_Sp __s, const std::complex<_Tp>& __z)
+ { return __safe_mul(std::complex<_Tp>(__s), __z); }
+
+ /**
+ * Carefully compute @c z*s avoiding overflow.
+ * If the product is successfully computed it is returned.
+ * Otherwise, std::runtime_error is thrown.
+ */
+ template<typename _Sp, typename _Tp>
+ inline std::complex<_Tp>
+ __safe_mul(const std::complex<_Tp>& __z, _Sp __s)
+ { return __safe_mul(__z, std::complex<_Tp>(__s)); }
+
+ /**
+ * Carefully compute @c z*z avoiding overflow.
+ * If the square is successfully computed it is returned.
+ * Otherwise, std::runtime_error is thrown.
+ */
+ template<typename _Tp>
+ std::complex<_Tp>
+ __safe_sqr(const std::complex<_Tp>& __z);
+
+
+ /**
+ * A function to reliably test a complex number for realness.
+ *
+ * @param __w The complex argument
+ * @param __mul The multiplier for numeric epsilon for comparison tolerance
+ * @return @c true if @f$ Im(w) @f$ is zero within @f$ mul * epsilon @f$,
+ * @c false otherwize.
+ */
+ template<typename _Tp>
+ bool
+ __fpreal(const std::complex<_Tp>& __w, const _Tp __mul = _Tp{5})
+ { return __gnu_cxx::__fpequal(std::imag(__w), _Tp{0}, __mul); }
+
+ // Specialize for real numbers.
+ template<typename _Tp>
+ bool
+ __fpreal(const _Tp)
+ { return true; }
+
+
+ /**
+ * A function to reliably test a complex number for imaginaryness [?].
+ *
+ * @param __w The complex argument
+ * @param __mul The multiplier for numeric epsilon for comparison tolerance
+ * @return @c true if @f$ Re(w) @f$ is zero within @f$ mul * epsilon @f$,
+ * @c false otherwize.
+ */
+ template<typename _Tp>
+ bool
+ __fpimag(const std::complex<_Tp>& __w, const _Tp __mul = _Tp{5})
+ { return __gnu_cxx::__fpequal(std::real(__w), _Tp{0}, __mul); }
+
+ // Specialize for real numbers.
+ template<typename _Tp>
+ bool
+ __fpimag(const _Tp)
+ { return false; }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace std
+
+namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+#if __cplusplus >= 201103L
+
+ /**
+ * We need isnan to be extended to std::complex.
+ */
+ template<typename _Tp>
+ bool
+ isnan(const std::complex<_Tp>& __z)
+ { return std::__detail::__isnan(__z); }
+
+ /**
+ * This is a more modern version of __promote_N in ext/type_traits
+ * specialized for complex.
+ * This is used for numeric argument promotion of complex and cmath
+ */
+ template<>
+ template<typename _Tp>
+ struct __promote_fp_help<std::complex<_Tp>, false>
+ {
+ private:
+ using __vtype = typename std::complex<_Tp>::value_type;
+ public:
+ using __type = decltype(std::complex<__promote_fp_help_t<__vtype>>{});
+ };
+
+ /**
+ * Type introspection for complex.
+ */
+ template<typename _Tp>
+ struct is_complex : public std::false_type
+ { };
+
+ /**
+ * Type introspection for complex.
+ */
+ template<>
+ template<typename _Tp>
+ struct is_complex<std::complex<_Tp>> : public std::true_type
+ { };
+
+ /**
+ * Type introspection for complex.
+ */
+ template<typename _Tp>
+ using is_complex_t = typename is_complex<_Tp>::type;
+
+ /**
+ * Type introspection for complex.
+ */
+ template<typename _Tp>
+ constexpr bool is_complex_v = is_complex<_Tp>::value;
+
+#endif // __cplusplus >= 201103L
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __gnu_cxx
+
+#include <bits/complex_util.tcc>
+
+#endif // _GLIBCXX_BITS_COMPLEX_UTIL_H