alpaka
Abstraction Library for Parallel Kernel Acceleration
Complex.hpp
Go to the documentation of this file.
1 /* Copyright 2022 Sergei Bastrakov
2  * SPDX-License-Identifier: MPL-2.0
3  */
4 
5 #pragma once
6 
7 #include "alpaka/core/Common.hpp"
9 
10 #include <cmath>
11 #include <complex>
12 #include <iostream>
13 #include <type_traits>
14 
15 namespace alpaka
16 {
17  namespace internal
18  {
19  //! Implementation of a complex number useable on host and device.
20  //!
21  //! It follows the layout of std::complex and so array-oriented access.
22  //! The class template implements all methods and operators as std::complex<T>.
23  //! Additionally, it provides an implicit conversion to and from std::complex<T>.
24  //! All methods besides operators << and >> are host-device.
25  //! It does not provide non-member functions of std::complex besides the operators.
26  //! Those are provided the same way as alpaka math functions for real numbers.
27  //!
28  //! Note that unlike most of alpaka, this is a concrete type template, and not merely a concept.
29  //!
30  //! Naming and order of the methods match https://en.cppreference.com/w/cpp/numeric/complex in C++17.
31  //! Implementation chose to not extend it e.g. by adding constexpr to some places that would get it in C++20.
32  //! The motivation is that with internal conversion to std::complex<T> for CPU backends, it would define the
33  //! common interface for generic code anyways. So it is more clear to have alpaka's interface exactly matching
34  //! when possible, and not "improving".
35  //!
36  //! @tparam T type of the real and imaginary part: float, double, or long double.
37  template<typename T>
38  class Complex
39  {
40  public:
41  // Make sure the input type is floating-point
42  static_assert(std::is_floating_point_v<T>);
43 
44  //! Type of the real and imaginary parts
45  using value_type = T;
46 
47  //! Constructor from the given real and imaginary parts
48  constexpr ALPAKA_FN_HOST_ACC Complex(T const& real = T{}, T const& imag = T{}) : m_real(real), m_imag(imag)
49  {
50  }
51 
52  //! Copy constructor
53  constexpr Complex(Complex const& other) = default;
54 
55  //! Constructor from Complex of another type
56  template<typename U>
57  constexpr ALPAKA_FN_HOST_ACC Complex(Complex<U> const& other)
58  : m_real(static_cast<T>(other.real()))
59  , m_imag(static_cast<T>(other.imag()))
60  {
61  }
62 
63  //! Constructor from std::complex
64  constexpr ALPAKA_FN_HOST_ACC Complex(std::complex<T> const& other)
65  : m_real(other.real())
66  , m_imag(other.imag())
67  {
68  }
69 
70  //! Conversion to std::complex
71  constexpr ALPAKA_FN_HOST_ACC operator std::complex<T>() const
72  {
73  return std::complex<T>{m_real, m_imag};
74  }
75 
76  //! Assignment
77  Complex& operator=(Complex const&) = default;
78 
79  //! Get the real part
80  constexpr ALPAKA_FN_HOST_ACC T real() const
81  {
82  return m_real;
83  }
84 
85  //! Set the real part
86  constexpr ALPAKA_FN_HOST_ACC void real(T value)
87  {
88  m_real = value;
89  }
90 
91  //! Get the imaginary part
92  constexpr ALPAKA_FN_HOST_ACC T imag() const
93  {
94  return m_imag;
95  }
96 
97  //! Set the imaginary part
98  constexpr ALPAKA_FN_HOST_ACC void imag(T value)
99  {
100  m_imag = value;
101  }
102 
103  //! Addition assignment with a real number
105  {
106  m_real += other;
107  return *this;
108  }
109 
110  //! Addition assignment with a complex number
111  template<typename U>
113  {
114  m_real += static_cast<T>(other.real());
115  m_imag += static_cast<T>(other.imag());
116  return *this;
117  }
118 
119  //! Subtraction assignment with a real number
121  {
122  m_real -= other;
123  return *this;
124  }
125 
126  //! Subtraction assignment with a complex number
127  template<typename U>
129  {
130  m_real -= static_cast<T>(other.real());
131  m_imag -= static_cast<T>(other.imag());
132  return *this;
133  }
134 
135  //! Multiplication assignment with a real number
137  {
138  m_real *= other;
139  m_imag *= other;
140  return *this;
141  }
142 
143  //! Multiplication assignment with a complex number
144  template<typename U>
146  {
147  auto const newReal = m_real * static_cast<T>(other.real()) - m_imag * static_cast<T>(other.imag());
148  auto const newImag = m_imag * static_cast<T>(other.real()) + m_real * static_cast<T>(other.imag());
149  m_real = newReal;
150  m_imag = newImag;
151  return *this;
152  }
153 
154  //! Division assignment with a real number
156  {
157  m_real /= other;
158  m_imag /= other;
159  return *this;
160  }
161 
162  //! Division assignment with a complex number
163  template<typename U>
165  {
166  return *this *= Complex{
167  static_cast<T>(other.real() / (other.real() * other.real() + other.imag() * other.imag())),
168  static_cast<T>(
169  -other.imag() / (other.real() * other.real() + other.imag() * other.imag()))};
170  }
171 
172  private:
173  //! Real and imaginary parts, storage enables array-oriented access
174  T m_real, m_imag;
175  };
176 
177  //! Host-device arithmetic operations matching std::complex<T>.
178  //!
179  //! They take and return alpaka::Complex.
180  //!
181  //! @{
182  //!
183 
184  //! Unary plus (added for compatibility with std::complex)
185  template<typename T>
187  {
188  return val;
189  }
190 
191  //! Unary minus
192  template<typename T>
194  {
195  return Complex<T>{-val.real(), -val.imag()};
196  }
197 
198  //! Addition of two complex numbers
199  template<typename T>
201  {
202  return Complex<T>{lhs.real() + rhs.real(), lhs.imag() + rhs.imag()};
203  }
204 
205  //! Addition of a complex and a real number
206  template<typename T>
208  {
209  return Complex<T>{lhs.real() + rhs, lhs.imag()};
210  }
211 
212  //! Addition of a real and a complex number
213  template<typename T>
215  {
216  return Complex<T>{lhs + rhs.real(), rhs.imag()};
217  }
218 
219  //! Subtraction of two complex numbers
220  template<typename T>
222  {
223  return Complex<T>{lhs.real() - rhs.real(), lhs.imag() - rhs.imag()};
224  }
225 
226  //! Subtraction of a complex and a real number
227  template<typename T>
229  {
230  return Complex<T>{lhs.real() - rhs, lhs.imag()};
231  }
232 
233  //! Subtraction of a real and a complex number
234  template<typename T>
236  {
237  return Complex<T>{lhs - rhs.real(), -rhs.imag()};
238  }
239 
240  //! Muptiplication of two complex numbers
241  template<typename T>
243  {
244  return Complex<T>{
245  lhs.real() * rhs.real() - lhs.imag() * rhs.imag(),
246  lhs.imag() * rhs.real() + lhs.real() * rhs.imag()};
247  }
248 
249  //! Muptiplication of a complex and a real number
250  template<typename T>
252  {
253  return Complex<T>{lhs.real() * rhs, lhs.imag() * rhs};
254  }
255 
256  //! Muptiplication of a real and a complex number
257  template<typename T>
259  {
260  return Complex<T>{lhs * rhs.real(), lhs * rhs.imag()};
261  }
262 
263  //! Division of two complex numbers
264  template<typename T>
266  {
267  return Complex<T>{
268  (lhs.real() * rhs.real() + lhs.imag() * rhs.imag())
269  / (rhs.real() * rhs.real() + rhs.imag() * rhs.imag()),
270  (lhs.imag() * rhs.real() - lhs.real() * rhs.imag())
271  / (rhs.real() * rhs.real() + rhs.imag() * rhs.imag())};
272  }
273 
274  //! Division of complex and a real number
275  template<typename T>
277  {
278  return Complex<T>{lhs.real() / rhs, lhs.imag() / rhs};
279  }
280 
281  //! Division of a real and a complex number
282  template<typename T>
284  {
285  return Complex<T>{
286  lhs * rhs.real() / (rhs.real() * rhs.real() + rhs.imag() * rhs.imag()),
287  -lhs * rhs.imag() / (rhs.real() * rhs.real() + rhs.imag() * rhs.imag())};
288  }
289 
290  //! Equality of two complex numbers
291  template<typename T>
292  constexpr ALPAKA_FN_HOST_ACC bool operator==(Complex<T> const& lhs, Complex<T> const& rhs)
293  {
294  return math::floatEqualExactNoWarning(lhs.real(), rhs.real())
295  && math::floatEqualExactNoWarning(lhs.imag(), rhs.imag());
296  }
297 
298  //! Equality of a complex and a real number
299  template<typename T>
300  constexpr ALPAKA_FN_HOST_ACC bool operator==(Complex<T> const& lhs, T const& rhs)
301  {
302  return math::floatEqualExactNoWarning(lhs.real(), rhs)
303  && math::floatEqualExactNoWarning(lhs.imag(), static_cast<T>(0));
304  }
305 
306  //! Equality of a real and a complex number
307  template<typename T>
308  constexpr ALPAKA_FN_HOST_ACC bool operator==(T const& lhs, Complex<T> const& rhs)
309  {
310  return math::floatEqualExactNoWarning(lhs, rhs.real())
311  && math::floatEqualExactNoWarning(static_cast<T>(0), rhs.imag());
312  }
313 
314  //! Inequality of two complex numbers.
315  //!
316  //! @note this and other versions of operator != should be removed since C++20, as so does std::complex
317  template<typename T>
318  constexpr ALPAKA_FN_HOST_ACC bool operator!=(Complex<T> const& lhs, Complex<T> const& rhs)
319  {
320  return !(lhs == rhs);
321  }
322 
323  //! Inequality of a complex and a real number
324  template<typename T>
325  constexpr ALPAKA_FN_HOST_ACC bool operator!=(Complex<T> const& lhs, T const& rhs)
326  {
327  return !math::floatEqualExactNoWarning(lhs.real(), rhs)
328  || !math::floatEqualExactNoWarning(lhs.imag(), static_cast<T>(0));
329  }
330 
331  //! Inequality of a real and a complex number
332  template<typename T>
333  constexpr ALPAKA_FN_HOST_ACC bool operator!=(T const& lhs, Complex<T> const& rhs)
334  {
335  return !math::floatEqualExactNoWarning(lhs, rhs.real())
336  || !math::floatEqualExactNoWarning(static_cast<T>(0), rhs.imag());
337  }
338 
339  //! @}
340 
341  //! Host-only output of a complex number
342  template<typename T, typename TChar, typename TTraits>
343  std::basic_ostream<TChar, TTraits>& operator<<(std::basic_ostream<TChar, TTraits>& os, Complex<T> const& x)
344  {
345  os << x.operator std::complex<T>();
346  return os;
347  }
348 
349  //! Host-only input of a complex number
350  template<typename T, typename TChar, typename TTraits>
351  std::basic_istream<TChar, TTraits>& operator>>(std::basic_istream<TChar, TTraits>& is, Complex<T> const& x)
352  {
353  std::complex<T> z;
354  is >> z;
355  x = z;
356  return is;
357  }
358 
359  //! Host-only math functions matching std::complex<T>.
360  //!
361  //! Due to issue #1688, these functions are technically marked host-device and suppress related warnings.
362  //! However, they must be called for host only.
363  //!
364  //! They take and return alpaka::Complex (or a real number when appropriate).
365  //! Internally cast, fall back to std::complex implementation and cast back.
366  //! These functions can be used directly on the host side.
367  //! They are also picked up by ADL in math traits for CPU backends.
368  //!
369  //! On the device side, alpaka math traits must be used instead.
370  //! Note that the set of the traits is currently a bit smaller.
371  //!
372  //! @{
373  //!
374 
375  //! Absolute value
377  template<typename T>
378  constexpr ALPAKA_FN_HOST_ACC T abs(Complex<T> const& x)
379  {
380  return std::abs(std::complex<T>(x));
381  }
382 
383  //! Arc cosine
385  template<typename T>
387  {
388  return std::acos(std::complex<T>(x));
389  }
390 
391  //! Arc hyperbolic cosine
393  template<typename T>
395  {
396  return std::acosh(std::complex<T>(x));
397  }
398 
399  //! Argument
401  template<typename T>
402  constexpr ALPAKA_FN_HOST_ACC T arg(Complex<T> const& x)
403  {
404  return std::arg(std::complex<T>(x));
405  }
406 
407  //! Arc sine
409  template<typename T>
411  {
412  return std::asin(std::complex<T>(x));
413  }
414 
415  //! Arc hyperbolic sine
417  template<typename T>
419  {
420  return std::asinh(std::complex<T>(x));
421  }
422 
423  //! Arc tangent
425  template<typename T>
427  {
428  return std::atan(std::complex<T>(x));
429  }
430 
431  //! Arc hyperbolic tangent
433  template<typename T>
435  {
436  return std::atanh(std::complex<T>(x));
437  }
438 
439  //! Complex conjugate
441  template<typename T>
443  {
444  return std::conj(std::complex<T>(x));
445  }
446 
447  //! Cosine
449  template<typename T>
451  {
452  return std::cos(std::complex<T>(x));
453  }
454 
455  //! Hyperbolic cosine
457  template<typename T>
459  {
460  return std::cosh(std::complex<T>(x));
461  }
462 
463  //! Exponential
465  template<typename T>
467  {
468  return std::exp(std::complex<T>(x));
469  }
470 
471  //! Natural logarithm
473  template<typename T>
475  {
476  return std::log(std::complex<T>(x));
477  }
478 
479  //! Base 10 logarithm
481  template<typename T>
483  {
484  return std::log10(std::complex<T>(x));
485  }
486 
487  //! Squared magnitude
489  template<typename T>
490  constexpr ALPAKA_FN_HOST_ACC T norm(Complex<T> const& x)
491  {
492  return std::norm(std::complex<T>(x));
493  }
494 
495  //! Get a complex number with given magnitude and phase angle
497  template<typename T>
498  constexpr ALPAKA_FN_HOST_ACC Complex<T> polar(T const& r, T const& theta = T())
499  {
500  return std::polar(r, theta);
501  }
502 
503  //! Complex power of a complex number
505  template<typename T, typename U>
506  constexpr ALPAKA_FN_HOST_ACC auto pow(Complex<T> const& x, Complex<U> const& y)
507  {
508  // Use same type promotion as std::pow
509  auto const result = std::pow(std::complex<T>(x), std::complex<U>(y));
510  using ValueType = typename decltype(result)::value_type;
511  return Complex<ValueType>(result);
512  }
513 
514  //! Real power of a complex number
516  template<typename T, typename U>
517  constexpr ALPAKA_FN_HOST_ACC auto pow(Complex<T> const& x, U const& y)
518  {
519  return pow(x, Complex<U>(y));
520  }
521 
522  //! Complex power of a real number
524  template<typename T, typename U>
525  constexpr ALPAKA_FN_HOST_ACC auto pow(T const& x, Complex<U> const& y)
526  {
527  return pow(Complex<T>(x), y);
528  }
529 
530  //! Projection onto the Riemann sphere
532  template<typename T>
534  {
535  return std::proj(std::complex<T>(x));
536  }
537 
538  //! Sine
540  template<typename T>
542  {
543  return std::sin(std::complex<T>(x));
544  }
545 
546  //! Hyperbolic sine
548  template<typename T>
550  {
551  return std::sinh(std::complex<T>(x));
552  }
553 
554  //! Square root
556  template<typename T>
558  {
559  return std::sqrt(std::complex<T>(x));
560  }
561 
562  //! Tangent
564  template<typename T>
566  {
567  return std::tan(std::complex<T>(x));
568  }
569 
570  //! Hyperbolic tangent
572  template<typename T>
574  {
575  return std::tanh(std::complex<T>(x));
576  }
577 
578  //! @}
579  } // namespace internal
580 
581  using internal::Complex;
582 } // namespace alpaka
Implementation of a complex number useable on host and device.
Definition: Complex.hpp:39
constexpr ALPAKA_FN_HOST_ACC T imag() const
Get the imaginary part.
Definition: Complex.hpp:92
constexpr ALPAKA_FN_HOST_ACC T real() const
Get the real part.
Definition: Complex.hpp:80
ALPAKA_FN_HOST_ACC Complex & operator-=(Complex< U > const &other)
Subtraction assignment with a complex number.
Definition: Complex.hpp:128
ALPAKA_FN_HOST_ACC Complex & operator/=(Complex< U > const &other)
Division assignment with a complex number.
Definition: Complex.hpp:164
constexpr ALPAKA_FN_HOST_ACC void imag(T value)
Set the imaginary part.
Definition: Complex.hpp:98
constexpr Complex(Complex const &other)=default
Copy constructor.
ALPAKA_FN_HOST_ACC Complex & operator-=(T const &other)
Subtraction assignment with a real number.
Definition: Complex.hpp:120
constexpr ALPAKA_FN_HOST_ACC Complex(Complex< U > const &other)
Constructor from Complex of another type.
Definition: Complex.hpp:57
constexpr ALPAKA_FN_HOST_ACC void real(T value)
Set the real part.
Definition: Complex.hpp:86
constexpr ALPAKA_FN_HOST_ACC Complex(std::complex< T > const &other)
Constructor from std::complex.
Definition: Complex.hpp:64
ALPAKA_FN_HOST_ACC Complex & operator*=(T const &other)
Multiplication assignment with a real number.
Definition: Complex.hpp:136
ALPAKA_FN_HOST_ACC Complex & operator+=(T const &other)
Addition assignment with a real number.
Definition: Complex.hpp:104
constexpr ALPAKA_FN_HOST_ACC Complex(T const &real=T{}, T const &imag=T{})
Constructor from the given real and imaginary parts.
Definition: Complex.hpp:48
ALPAKA_FN_HOST_ACC Complex & operator/=(T const &other)
Division assignment with a real number.
Definition: Complex.hpp:155
ALPAKA_FN_HOST_ACC Complex & operator+=(Complex< U > const &other)
Addition assignment with a complex number.
Definition: Complex.hpp:112
Complex & operator=(Complex const &)=default
Assignment.
ALPAKA_FN_HOST_ACC Complex & operator*=(Complex< U > const &other)
Multiplication assignment with a complex number.
Definition: Complex.hpp:145
T value_type
Type of the real and imaginary parts.
Definition: Complex.hpp:45
#define ALPAKA_FN_HOST_ACC
Definition: Common.hpp:39
#define ALPAKA_NO_HOST_ACC_WARNING
Disable nvcc warning: 'calling a host function from host device function.' Usage: ALPAKA_NO_HOST_ACC_...
Definition: Common.hpp:82
constexpr ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC Complex< T > tan(Complex< T > const &x)
Tangent.
Definition: Complex.hpp:565
constexpr ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC Complex< T > acosh(Complex< T > const &x)
Arc hyperbolic cosine.
Definition: Complex.hpp:394
constexpr ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC Complex< T > proj(Complex< T > const &x)
Projection onto the Riemann sphere.
Definition: Complex.hpp:533
constexpr ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC Complex< T > atanh(Complex< T > const &x)
Arc hyperbolic tangent.
Definition: Complex.hpp:434
constexpr ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto pow(T const &x, Complex< U > const &y)
Complex power of a real number.
Definition: Complex.hpp:525
constexpr ALPAKA_FN_HOST_ACC bool operator==(Complex< T > const &lhs, Complex< T > const &rhs)
Equality of two complex numbers.
Definition: Complex.hpp:292
constexpr ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC Complex< T > cosh(Complex< T > const &x)
Hyperbolic cosine.
Definition: Complex.hpp:458
constexpr ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC Complex< T > atan(Complex< T > const &x)
Arc tangent.
Definition: Complex.hpp:426
constexpr ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC T abs(Complex< T > const &x)
Host-only math functions matching std::complex<T>.
Definition: Complex.hpp:378
ALPAKA_FN_HOST_ACC Complex< T > operator/(Complex< T > const &lhs, Complex< T > const &rhs)
Division of two complex numbers.
Definition: Complex.hpp:265
std::basic_ostream< TChar, TTraits > & operator<<(std::basic_ostream< TChar, TTraits > &os, Complex< T > const &x)
Host-only output of a complex number.
Definition: Complex.hpp:343
constexpr ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC Complex< T > log(Complex< T > const &x)
Natural logarithm.
Definition: Complex.hpp:474
constexpr ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC Complex< T > sinh(Complex< T > const &x)
Hyperbolic sine.
Definition: Complex.hpp:549
ALPAKA_FN_HOST_ACC Complex< T > operator*(Complex< T > const &lhs, Complex< T > const &rhs)
Muptiplication of two complex numbers.
Definition: Complex.hpp:242
constexpr ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC Complex< T > tanh(Complex< T > const &x)
Hyperbolic tangent.
Definition: Complex.hpp:573
constexpr ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC Complex< T > conj(Complex< T > const &x)
Complex conjugate.
Definition: Complex.hpp:442
ALPAKA_FN_HOST_ACC Complex< T > operator+(Complex< T > const &val)
Host-device arithmetic operations matching std::complex<T>.
Definition: Complex.hpp:186
constexpr ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC Complex< T > log10(Complex< T > const &x)
Base 10 logarithm.
Definition: Complex.hpp:482
constexpr ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC T arg(Complex< T > const &x)
Argument.
Definition: Complex.hpp:402
constexpr ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC Complex< T > polar(T const &r, T const &theta=T())
Get a complex number with given magnitude and phase angle.
Definition: Complex.hpp:498
constexpr ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC Complex< T > asinh(Complex< T > const &x)
Arc hyperbolic sine.
Definition: Complex.hpp:418
constexpr ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC Complex< T > cos(Complex< T > const &x)
Cosine.
Definition: Complex.hpp:450
constexpr ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC T norm(Complex< T > const &x)
Squared magnitude.
Definition: Complex.hpp:490
std::basic_istream< TChar, TTraits > & operator>>(std::basic_istream< TChar, TTraits > &is, Complex< T > const &x)
Host-only input of a complex number.
Definition: Complex.hpp:351
constexpr ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC Complex< T > asin(Complex< T > const &x)
Arc sine.
Definition: Complex.hpp:410
constexpr ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC Complex< T > exp(Complex< T > const &x)
Exponential.
Definition: Complex.hpp:466
constexpr ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto pow(Complex< T > const &x, Complex< U > const &y)
Complex power of a complex number.
Definition: Complex.hpp:506
constexpr ALPAKA_FN_HOST_ACC bool operator!=(Complex< T > const &lhs, Complex< T > const &rhs)
Inequality of two complex numbers.
Definition: Complex.hpp:318
constexpr ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC Complex< T > sqrt(Complex< T > const &x)
Square root.
Definition: Complex.hpp:557
constexpr ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC Complex< T > acos(Complex< T > const &x)
Arc cosine.
Definition: Complex.hpp:386
ALPAKA_FN_HOST_ACC Complex< T > operator-(Complex< T > const &val)
Unary minus.
Definition: Complex.hpp:193
constexpr ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC Complex< T > sin(Complex< T > const &x)
Sine.
Definition: Complex.hpp:541
ALPAKA_FN_INLINE ALPAKA_FN_HOST_ACC auto floatEqualExactNoWarning(T a, T b) -> bool
The alpaka accelerator library.