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
19namespace 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