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 | |
22 | namespace kernel |
23 | { |
24 | |
25 | using namespace types; |
26 | |
27 | // real |
28 | template <class A, class T> |
29 | inline batch<T, A> real(batch<T, A> const& self, requires_arch<generic>) noexcept |
30 | { |
31 | return self; |
32 | } |
33 | |
34 | template <class A, class T> |
35 | inline batch<T, A> real(batch<std::complex<T>, A> const& self, requires_arch<generic>) noexcept |
36 | { |
37 | return self.real(); |
38 | } |
39 | |
40 | // imag |
41 | template <class A, class T> |
42 | inline batch<T, A> imag(batch<T, A> const& /*self*/, requires_arch<generic>) noexcept |
43 | { |
44 | return batch<T, A>(T(0)); |
45 | } |
46 | |
47 | template <class A, class T> |
48 | inline batch<T, A> imag(batch<std::complex<T>, A> const& self, requires_arch<generic>) noexcept |
49 | { |
50 | return self.imag(); |
51 | } |
52 | |
53 | // arg |
54 | template <class A, class T> |
55 | inline real_batch_type_t<batch<T, A>> arg(batch<T, A> const& self, requires_arch<generic>) noexcept |
56 | { |
57 | return atan2(imag(self), real(self)); |
58 | } |
59 | |
60 | // conj |
61 | template <class A, class T> |
62 | inline complex_batch_type_t<batch<T, A>> conj(batch<T, A> const& self, requires_arch<generic>) noexcept |
63 | { |
64 | return { real(self), -imag(self) }; |
65 | } |
66 | |
67 | // norm |
68 | template <class A, class T> |
69 | inline real_batch_type_t<batch<T, A>> norm(batch<T, A> const& self, requires_arch<generic>) noexcept |
70 | { |
71 | return { fma(real(self), real(self), imag(self) * imag(self)) }; |
72 | } |
73 | |
74 | // proj |
75 | template <class A, class T> |
76 | inline complex_batch_type_t<batch<T, A>> proj(batch<T, A> const& self, requires_arch<generic>) noexcept |
77 | { |
78 | using batch_type = complex_batch_type_t<batch<T, A>>; |
79 | using real_batch = typename batch_type::real_batch; |
80 | using real_value_type = typename real_batch::value_type; |
81 | auto cond = xsimd::isinf(real(self)) || xsimd::isinf(imag(self)); |
82 | return select(cond, |
83 | batch_type(constants::infinity<real_batch>(), |
84 | copysign(real_batch(real_value_type(0)), imag(self))), |
85 | batch_type(self)); |
86 | } |
87 | |
88 | template <class A, class T> |
89 | inline batch_bool<T, A> isnan(batch<std::complex<T>, A> const& self, requires_arch<generic>) noexcept |
90 | { |
91 | return batch_bool<T, A>(isnan(self.real()) || isnan(self.imag())); |
92 | } |
93 | } |
94 | } |
95 | |
96 | #endif |
97 | |