File indexing completed on 2025-08-28 09:11:27
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef XSIMD_GENERIC_COMPLEX_HPP
0013 #define XSIMD_GENERIC_COMPLEX_HPP
0014
0015 #include <complex>
0016
0017 #include "./xsimd_generic_details.hpp"
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<generic>) 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<generic>) 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<generic>) 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<generic>) 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<generic>) 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<generic>) 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<generic>) 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<generic>) 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 auto cond = xsimd::isinf(real(self)) || xsimd::isinf(imag(self));
0082 return select(cond,
0083 batch_type(constants::infinity<real_batch>(),
0084 copysign(real_batch(real_value_type(0)), imag(self))),
0085 batch_type(self));
0086 }
0087
0088 template <class A, class T>
0089 XSIMD_INLINE batch_bool<T, A> isnan(batch<std::complex<T>, A> const& self, requires_arch<generic>) noexcept
0090 {
0091 return batch_bool<T, A>(isnan(self.real()) || isnan(self.imag()));
0092 }
0093
0094 template <class A, class T>
0095 XSIMD_INLINE batch_bool<T, A> isinf(batch<std::complex<T>, A> const& self, requires_arch<generic>) noexcept
0096 {
0097 return batch_bool<T, A>(isinf(self.real()) || isinf(self.imag()));
0098 }
0099
0100 template <class A, class T>
0101 XSIMD_INLINE batch_bool<T, A> isfinite(batch<std::complex<T>, A> const& self, requires_arch<generic>) noexcept
0102 {
0103 return batch_bool<T, A>(isfinite(self.real()) && isfinite(self.imag()));
0104 }
0105 }
0106 }
0107
0108 #endif