<T>LAPACK 0.1.1
C++ Template Linear Algebra PACKage
Loading...
Searching...
No Matches
NaNPropagComplex.hpp
Go to the documentation of this file.
1
4//
5// Copyright (c) 2021-2023, University of Colorado Denver. All rights reserved.
6//
7// This file is part of <T>LAPACK.
8// <T>LAPACK is free software: you can redistribute it and/or modify it under
9// the terms of the BSD 3-Clause license. See the accompanying LICENSE file.
10
11#ifndef TLAPACK_TEST_COMPLEX_HH
12#define TLAPACK_TEST_COMPLEX_HH
13
15
16namespace tlapack {
17
18template <class T>
19struct NaNPropagComplex : public std::complex<T> {
20 constexpr NaNPropagComplex(const T& r = T(), const T& i = T())
21 : std::complex<T>(r, i)
22 {}
23
24 // operators:
25
26 template <typename U>
27 constexpr NaNPropagComplex& operator=(const std::complex<U>& x)
28 {
29 (std::complex<T>&)(*this) = x;
30 return *this;
31 }
32
33 template <typename U>
34 constexpr NaNPropagComplex& operator+=(const std::complex<U>& x)
35 {
36 if (isnan(x))
37 *this = std::numeric_limits<T>::quiet_NaN();
38 else if (isnan(*this))
39 *this = std::numeric_limits<T>::signaling_NaN();
40 else
41 (std::complex<T>&)(*this) += x;
42
43 return *this;
44 }
45
46 template <typename U>
47 constexpr NaNPropagComplex& operator-=(const std::complex<U>& x)
48 {
49 if (isnan(x))
50 *this = std::numeric_limits<T>::quiet_NaN();
51 else if (isnan(*this))
52 *this = std::numeric_limits<T>::signaling_NaN();
53 else
54 (std::complex<T>&)(*this) -= x;
55
56 return *this;
57 }
58
59 template <typename U>
60 constexpr NaNPropagComplex& operator*=(const std::complex<U>& x)
61 {
62 if (isnan(x))
63 *this = std::numeric_limits<T>::quiet_NaN();
64 else if (isnan(*this))
65 *this = std::numeric_limits<T>::signaling_NaN();
66 else
67 (std::complex<T>&)(*this) *= x;
68
69 return *this;
70 }
71
72 constexpr NaNPropagComplex& operator*=(const T& x)
73 {
74 (std::complex<T>&)(*this) *= x;
75 return *this;
76 }
77
78 template <typename U>
79 constexpr NaNPropagComplex& operator/=(const std::complex<U>& x)
80 {
81 if (isnan(x))
82 *this = std::numeric_limits<T>::quiet_NaN();
83 else if (isnan(*this))
84 *this = std::numeric_limits<T>::signaling_NaN();
85 else
86 (std::complex<T>&)(*this) /= x;
87
88 return *this;
89 }
90
91 constexpr NaNPropagComplex& operator/=(const T& x)
92 {
93 (std::complex<T>&)(*this) /= x;
94 return *this;
95 }
96
97 // wrappers:
98
99 friend constexpr NaNPropagComplex operator+(const NaNPropagComplex& x,
100 const NaNPropagComplex& y)
101 {
103 r += y;
104 return r;
105 }
106
107 friend constexpr NaNPropagComplex operator+(const T& x,
108 const NaNPropagComplex& y)
109 {
111 r += x;
112 return r;
113 }
114
115 friend constexpr NaNPropagComplex operator+(const NaNPropagComplex& x,
116 const T& y)
117 {
119 r += y;
120 return r;
121 }
122
123 friend constexpr NaNPropagComplex operator-(const NaNPropagComplex& x,
124 const NaNPropagComplex& y)
125 {
127 r -= y;
128 return r;
129 }
130
131 friend constexpr NaNPropagComplex operator-(const T& x,
132 const NaNPropagComplex& y)
133 {
135 r -= x;
136 return r;
137 }
138
139 friend constexpr NaNPropagComplex operator-(const NaNPropagComplex& x,
140 const T& y)
141 {
143 r -= y;
144 return r;
145 }
146
147 friend constexpr NaNPropagComplex operator*(const NaNPropagComplex& x,
148 const NaNPropagComplex& y)
149 {
151 r *= y;
152 return r;
153 }
154
155 friend constexpr NaNPropagComplex operator*(const T& x,
156 const NaNPropagComplex& y)
157 {
159 r *= x;
160 return r;
161 }
162
163 friend constexpr NaNPropagComplex operator*(const NaNPropagComplex& x,
164 const T& y)
165 {
167 r *= y;
168 return r;
169 }
170
171 friend constexpr NaNPropagComplex operator/(const NaNPropagComplex& x,
172 const NaNPropagComplex& y)
173 {
175 r /= y;
176 return r;
177 }
178
179 friend constexpr NaNPropagComplex operator/(const T& x,
180 const NaNPropagComplex& y)
181 {
183 r /= y;
184 return r;
185 }
186
187 friend constexpr NaNPropagComplex operator/(const NaNPropagComplex& x,
188 const T& y)
189 {
191 r /= y;
192 return r;
193 }
194
195 // Other math operations:
196
213 friend inline T abs(const NaNPropagComplex& x)
214 {
215 if (isnan(real(x)) || isnan(imag(x)))
216 return std::numeric_limits<T>::quiet_NaN();
217 else if (isinf(real(x)) || isinf(imag(x)))
218 return std::numeric_limits<T>::infinity();
219 else
220 return abs((const std::complex<T>&)x);
221 }
222
223 friend inline NaNPropagComplex conj(const NaNPropagComplex& x)
224 {
225 return conj((const std::complex<T>&)x);
226 }
227};
228
229namespace traits {
230 template <typename T>
232 : public real_type_traits<std::complex<T>, int> {};
233
234 template <typename T>
236 : public complex_type_traits<std::complex<T>, int> {};
237} // namespace traits
238
239} // namespace tlapack
240
241#endif // TLAPACK_TEST_COMPLEX_HH
constexpr bool isnan(const T &x) noexcept
Extends std::isnan() to complex numbers.
Definition utils.hpp:125
constexpr real_type< T > real(const T &x) noexcept
Extends std::real() to real datatypes.
Definition utils.hpp:71
constexpr real_type< T > imag(const T &x) noexcept
Extends std::imag() to real datatypes.
Definition utils.hpp:86
constexpr bool isinf(const T &x) noexcept
Extends std::isinf() to complex numbers.
Definition utils.hpp:117
typename traits::real_type_traits< Types..., int >::type real_type
The common real type of the list of types.
Definition scalar_type_traits.hpp:113
Definition NaNPropagComplex.hpp:19
friend T abs(const NaNPropagComplex &x)
2-norm absolute value, sqrt( |Re(x)|^2 + |Im(x)|^2 )
Definition NaNPropagComplex.hpp:213
Complex type traits for the list of types Types.
Definition scalar_type_traits.hpp:145
Real type traits for the list of types Types.
Definition scalar_type_traits.hpp:71