Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-07 10:36:57

0001 /***************************************************************************
0002  * Copyright (c) Johan Mabille, Sylvain Corlay, Wolf Vollprecht and         *
0003  * Martin Renou                                                             *
0004  * Copyright (c) QuantStack                                                 *
0005  * Copyright (c) Serge Guelton                                              *
0006  *                                                                          *
0007  * Distributed under the terms of the BSD 3-Clause License.                 *
0008  *                                                                          *
0009  * The full license is in the file LICENSE, distributed with this software. *
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         // real
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         // imag
0041         template <class A, class T>
0042         XSIMD_INLINE batch<T, A> imag(batch<T, A> const& /*self*/, 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         // arg
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         // conj
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         // norm
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         // proj
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