File indexing completed on 2026-11-07 10:36:57
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef XSIMD_COMMON_COMPLEX_HPP
0013 #define XSIMD_COMMON_COMPLEX_HPP
0014
0015 #include "./xsimd_common_details.hpp"
0016
0017 #include <complex>
0018
0019 namespace xsimd
0020 {
0021
0022 namespace kernel
0023 {
0024
0025 using namespace types;
0026
0027
0028 template <class A, class T>
0029 XSIMD_INLINE batch<T, A> real(batch<T, A> const& self, requires_arch<common>) noexcept
0030 {
0031 return self;
0032 }
0033
0034 template <class A, class T>
0035 XSIMD_INLINE batch<T, A> real(batch<std::complex<T>, A> const& self, requires_arch<common>) noexcept
0036 {
0037 return self.real();
0038 }
0039
0040
0041 template <class A, class T>
0042 XSIMD_INLINE batch<T, A> imag(batch<T, A> const& , requires_arch<common>) noexcept
0043 {
0044 return batch<T, A>(T(0));
0045 }
0046
0047 template <class A, class T>
0048 XSIMD_INLINE batch<T, A> imag(batch<std::complex<T>, A> const& self, requires_arch<common>) noexcept
0049 {
0050 return self.imag();
0051 }
0052
0053
0054 template <class A, class T>
0055 XSIMD_INLINE real_batch_type_t<batch<T, A>> arg(batch<T, A> const& self, requires_arch<common>) noexcept
0056 {
0057 return atan2(imag(self), real(self));
0058 }
0059
0060
0061 template <class A, class T>
0062 XSIMD_INLINE complex_batch_type_t<batch<T, A>> conj(batch<T, A> const& self, requires_arch<common>) noexcept
0063 {
0064 return { real(self), -imag(self) };
0065 }
0066
0067
0068 template <class A, class T>
0069 XSIMD_INLINE real_batch_type_t<batch<T, A>> norm(batch<T, A> const& self, requires_arch<common>) noexcept
0070 {
0071 return { fma(real(self), real(self), imag(self) * imag(self)) };
0072 }
0073
0074
0075 template <class A, class T>
0076 XSIMD_INLINE complex_batch_type_t<batch<T, A>> proj(batch<T, A> const& self, requires_arch<common>) noexcept
0077 {
0078 using batch_type = complex_batch_type_t<batch<T, A>>;
0079 using real_batch = typename batch_type::real_batch;
0080 using real_value_type = typename real_batch::value_type;
0081 #ifdef __FAST_MATH__
0082 return { self };
0083 #else
0084 auto cond = xsimd::isinf(real(self)) || xsimd::isinf(imag(self));
0085 return select(cond,
0086 batch_type(constants::infinity<real_batch>(),
0087 copysign(real_batch(real_value_type(0)), imag(self))),
0088 batch_type(self));
0089 #endif
0090 }
0091
0092 template <class A, class T>
0093 XSIMD_INLINE batch_bool<T, A> isnan(batch<std::complex<T>, A> const& self, requires_arch<common>) noexcept
0094 {
0095 return batch_bool<T, A>(isnan(self.real()) || isnan(self.imag()));
0096 }
0097
0098 template <class A, class T>
0099 XSIMD_INLINE batch_bool<T, A> isinf(batch<std::complex<T>, A> const& self, requires_arch<common>) noexcept
0100 {
0101 return batch_bool<T, A>(isinf(self.real()) || isinf(self.imag()));
0102 }
0103
0104 template <class A, class T>
0105 XSIMD_INLINE batch_bool<T, A> isfinite(batch<std::complex<T>, A> const& self, requires_arch<common>) noexcept
0106 {
0107 return batch_bool<T, A>(isfinite(self.real()) && isfinite(self.imag()));
0108 }
0109 }
0110 }
0111
0112 #endif