1 /*************************************************************************** 2 * Copyright (c) Johan Mabille, Sylvain Corlay, Wolf Vollprecht and * 3 * Martin Renou * 4 * Copyright (c) QuantStack * 5 * Copyright (c) Serge Guelton * 6 * * 7 * Distributed under the terms of the BSD 3-Clause License. * 8 * * 9 * The full license is in the file LICENSE, distributed with this software. * 10 ****************************************************************************/ 11 12 #ifndef XSIMD_GENERIC_COMPLEX_HPP 13 #define XSIMD_GENERIC_COMPLEX_HPP 14 15 #include <complex> 16 17 #include "./xsimd_generic_details.hpp" 18 19 namespace xsimd { 20 21 namespace kernel { 22 23 using namespace types; 24 25 // real 26 template <class A, class T> real(batch<T,A> const & self,requires_arch<generic>)27 batch<T, A> real(batch<T, A> const& self, requires_arch<generic>) { 28 return self; 29 } 30 31 template <class A, class T> real(batch<std::complex<T>,A> const & self,requires_arch<generic>)32 batch<T, A> real(batch<std::complex<T>, A> const& self, requires_arch<generic>) { 33 return self.real(); 34 } 35 36 // imag 37 template <class A, class T> imag(batch<T,A> const &,requires_arch<generic>)38 batch<T, A> imag(batch<T, A> const& /*self*/, requires_arch<generic>) { 39 return batch<T, A>(T(0)); 40 } 41 42 template <class A, class T> imag(batch<std::complex<T>,A> const & self,requires_arch<generic>)43 batch<T, A> imag(batch<std::complex<T>, A> const& self, requires_arch<generic>) { 44 return self.imag(); 45 } 46 47 // arg 48 template<class A, class T> arg(batch<T,A> const & self,requires_arch<generic>)49 real_batch_type_t<batch<T, A>> arg(batch<T, A> const& self, requires_arch<generic>) { 50 return atan2(imag(self), real(self)); 51 } 52 53 // conj 54 template<class A, class T> conj(batch<T,A> const & self,requires_arch<generic>)55 complex_batch_type_t<batch<T, A>> conj(batch<T, A> const& self, requires_arch<generic>) { 56 return {real(self), - imag(self)}; 57 } 58 59 // norm 60 template<class A, class T> norm(batch<T,A> const & self,requires_arch<generic>)61 real_batch_type_t<batch<T, A>> norm(batch<T, A> const& self, requires_arch<generic>) { 62 return {fma(real(self), real(self), imag(self) * imag(self))}; 63 } 64 65 // proj 66 template<class A, class T> proj(batch<T,A> const & self,requires_arch<generic>)67 complex_batch_type_t<batch<T, A>> proj(batch<T, A> const& self, requires_arch<generic>) { 68 using batch_type = complex_batch_type_t<batch<T, A>>; 69 using real_batch = typename batch_type::real_batch; 70 using real_value_type = typename real_batch::value_type; 71 auto cond = xsimd::isinf(real(self)) || xsimd::isinf(imag(self)); 72 return select(cond, 73 batch_type(constants::infinity<real_batch>(), 74 copysign(real_batch(real_value_type(0)), imag(self))), 75 batch_type(self)); 76 } 77 78 template <class A, class T> isnan(batch<std::complex<T>,A> const & self,requires_arch<generic>)79 batch_bool<T, A> isnan(batch<std::complex<T>, A> const& self, requires_arch<generic>) { 80 return batch_bool<T, A>(isnan(self.real()) || isnan(self.imag())); 81 } 82 } 83 } 84 85 #endif 86 87