45 static_assert(std::is_floating_point_v<T>);
51 constexpr Complex(T
const& real = T{}, T
const& imag = T{}) : m_real(real), m_imag(imag)
56 constexpr Complex(Complex
const& other) =
default;
60 constexpr Complex(Complex<U>
const& other)
61 : m_real(
static_cast<T
>(other.real()))
62 , m_imag(
static_cast<T
>(other.imag()))
67 constexpr Complex(std::complex<T>
const& other) : m_real(other.real()), m_imag(other.imag())
72 constexpr operator std::complex<T>()
const
74 return std::complex<T>{m_real, m_imag};
78 Complex& operator=(Complex
const&) =
default;
81 constexpr T real()
const
87 constexpr void real(T value)
93 constexpr T imag()
const
99 constexpr void imag(T value)
105 constexpr Complex& operator+=(T
const& other)
113 constexpr Complex& operator+=(Complex<U>
const& other)
115 m_real +=
static_cast<T
>(other.real());
116 m_imag +=
static_cast<T
>(other.imag());
121 constexpr Complex& operator-=(T
const& other)
129 constexpr Complex& operator-=(Complex<U>
const& other)
131 m_real -=
static_cast<T
>(other.real());
132 m_imag -=
static_cast<T
>(other.imag());
137 constexpr Complex& operator*=(T
const& other)
146 constexpr Complex& operator*=(Complex<U>
const& other)
148 auto const newReal = m_real *
static_cast<T
>(other.real()) - m_imag *
static_cast<T
>(other.imag());
149 auto const newImag = m_imag *
static_cast<T
>(other.real()) + m_real *
static_cast<T
>(other.imag());
156 constexpr Complex& operator/=(T
const& other)
165 constexpr Complex& operator/=(Complex<U>
const& other)
167 return *
this *= Complex{
168 static_cast<T
>(other.real() / (other.real() * other.real() + other.imag() * other.imag())),
170 -other.imag() / (other.real() * other.real() + other.imag() * other.imag()))};
187 constexpr Complex<T>
operator+(Complex<T>
const& val)
194 constexpr Complex<T>
operator-(Complex<T>
const& val)
196 return Complex<T>{-val.real(), -val.imag()};
201 constexpr Complex<T> operator+(Complex<T>
const& lhs, Complex<T>
const& rhs)
203 return Complex<T>{lhs.real() + rhs.real(), lhs.imag() + rhs.imag()};
208 constexpr Complex<T> operator+(Complex<T>
const& lhs, T
const& rhs)
210 return Complex<T>{lhs.real() + rhs, lhs.imag()};
215 constexpr Complex<T> operator+(T
const& lhs, Complex<T>
const& rhs)
217 return Complex<T>{lhs + rhs.real(), rhs.imag()};
222 constexpr Complex<T> operator-(Complex<T>
const& lhs, Complex<T>
const& rhs)
224 return Complex<T>{lhs.real() - rhs.real(), lhs.imag() - rhs.imag()};
229 constexpr Complex<T> operator-(Complex<T>
const& lhs, T
const& rhs)
231 return Complex<T>{lhs.real() - rhs, lhs.imag()};
236 constexpr Complex<T> operator-(T
const& lhs, Complex<T>
const& rhs)
238 return Complex<T>{lhs - rhs.real(), -rhs.imag()};
243 constexpr Complex<T> operator*(Complex<T>
const& lhs, Complex<T>
const& rhs)
246 lhs.real() * rhs.real() - lhs.imag() * rhs.imag(),
247 lhs.imag() * rhs.real() + lhs.real() * rhs.imag()};
252 constexpr Complex<T> operator*(Complex<T>
const& lhs, T
const& rhs)
254 return Complex<T>{lhs.real() * rhs, lhs.imag() * rhs};
259 constexpr Complex<T> operator*(T
const& lhs, Complex<T>
const& rhs)
261 return Complex<T>{lhs * rhs.real(), lhs * rhs.imag()};
266 constexpr Complex<T> operator/(Complex<T>
const& lhs, Complex<T>
const& rhs)
269 (lhs.real() * rhs.real() + lhs.imag() * rhs.imag())
270 / (rhs.real() * rhs.real() + rhs.imag() * rhs.imag()),
271 (lhs.imag() * rhs.real() - lhs.real() * rhs.imag())
272 / (rhs.real() * rhs.real() + rhs.imag() * rhs.imag())};
277 constexpr Complex<T> operator/(Complex<T>
const& lhs, T
const& rhs)
279 return Complex<T>{lhs.real() / rhs, lhs.imag() / rhs};
284 constexpr Complex<T> operator/(T
const& lhs, Complex<T>
const& rhs)
287 lhs * rhs.real() / (rhs.real() * rhs.real() + rhs.imag() * rhs.imag()),
288 -lhs * rhs.imag() / (rhs.real() * rhs.real() + rhs.imag() * rhs.imag())};
293 constexpr bool operator==(Complex<T>
const& lhs, Complex<T>
const& rhs)
301 constexpr bool operator==(Complex<T>
const& lhs, T
const& rhs)
309 constexpr bool operator==(T
const& lhs, Complex<T>
const& rhs)
319 constexpr bool operator!=(Complex<T>
const& lhs, Complex<T>
const& rhs)
321 return !(lhs == rhs);
326 constexpr bool operator!=(Complex<T>
const& lhs, T
const& rhs)
334 constexpr bool operator!=(T
const& lhs, Complex<T>
const& rhs)
343 template<
typename T,
typename TChar,
typename TTraits>
344 std::basic_ostream<TChar, TTraits>& operator<<(std::basic_ostream<TChar, TTraits>& os, Complex<T>
const& x)
346 os << x.operator std::complex<T>();
351 template<
typename T,
typename TChar,
typename TTraits>
352 std::basic_istream<TChar, TTraits>& operator>>(std::basic_istream<TChar, TTraits>& is, Complex<T>
const& x)
378 constexpr T abs(Complex<T>
const& x)
380 return std::abs(std::complex<T>(x));
385 constexpr Complex<T> acos(Complex<T>
const& x)
387 return std::acos(std::complex<T>(x));
392 constexpr Complex<T> acosh(Complex<T>
const& x)
394 return std::acosh(std::complex<T>(x));
399 constexpr T arg(Complex<T>
const& x)
401 return std::arg(std::complex<T>(x));
406 constexpr Complex<T> asin(Complex<T>
const& x)
408 return std::asin(std::complex<T>(x));
413 constexpr Complex<T> asinh(Complex<T>
const& x)
415 return std::asinh(std::complex<T>(x));
420 constexpr Complex<T> atan(Complex<T>
const& x)
422 return std::atan(std::complex<T>(x));
427 constexpr Complex<T> atanh(Complex<T>
const& x)
429 return std::atanh(std::complex<T>(x));
434 constexpr Complex<T> conj(Complex<T>
const& x)
436 return std::conj(std::complex<T>(x));
441 constexpr Complex<T> cos(Complex<T>
const& x)
443 return std::cos(std::complex<T>(x));
448 constexpr Complex<T> cosh(Complex<T>
const& x)
450 return std::cosh(std::complex<T>(x));
455 constexpr Complex<T> exp(Complex<T>
const& x)
457 return std::exp(std::complex<T>(x));
462 constexpr Complex<T> log(Complex<T>
const& x)
464 return std::log(std::complex<T>(x));
469 constexpr Complex<T> log10(Complex<T>
const& x)
471 return std::log10(std::complex<T>(x));
476 constexpr T norm(Complex<T>
const& x)
478 return std::norm(std::complex<T>(x));
483 constexpr Complex<T> polar(T
const& r, T
const& theta = T())
485 return std::polar(r, theta);
489 template<
typename T,
typename U>
490 constexpr auto pow(Complex<T>
const& x, Complex<U>
const& y)
493 auto const result = std::pow(std::complex<T>(x), std::complex<U>(y));
494 using ValueType =
typename decltype(result)::value_type;
495 return Complex<ValueType>(result);
499 template<
typename T,
typename U>
500 constexpr auto pow(Complex<T>
const& x, U
const& y)
502 return pow(x, Complex<U>(y));
506 template<
typename T,
typename U>
507 constexpr auto pow(T
const& x, Complex<U>
const& y)
509 return pow(Complex<T>(x), y);
514 constexpr Complex<T> proj(Complex<T>
const& x)
516 return std::proj(std::complex<T>(x));
521 constexpr Complex<T> sin(Complex<T>
const& x)
523 return std::sin(std::complex<T>(x));
528 constexpr Complex<T> sinh(Complex<T>
const& x)
530 return std::sinh(std::complex<T>(x));
535 constexpr Complex<T> sqrt(Complex<T>
const& x)
537 return std::sqrt(std::complex<T>(x));
542 constexpr Complex<T> tan(Complex<T>
const& x)
544 return std::tan(std::complex<T>(x));
549 constexpr Complex<T> tanh(Complex<T>
const& x)
551 return std::tanh(std::complex<T>(x));
557 using internal::Complex;
559#if ALPAKA_LANG_CUDA || ALPAKA_LANG_HIP || ALPAKA_LANG_SYCL
563 template<
typename T_MathImpl,
typename T_Arg>
564 struct Abs::Op<T_MathImpl, Complex<T_Arg>>
566 constexpr auto operator()(T_MathImpl, Complex<T_Arg>
const& arg)
const
573 template<
typename T_MathImpl,
typename T>
574 struct Acos::Op<T_MathImpl, Complex<T>>
576 constexpr auto operator()(T_MathImpl, Complex<T>
const& arg)
const
579 return Complex<T>{
static_cast<T
>(0.0),
static_cast<T
>(-1.0)}
582 + Complex<T>{
static_cast<T
>(0.0),
static_cast<T
>(1.0)}
583 *
math::sqrt(
static_cast<T
>(1.0) - arg * arg));
588 template<
typename T_MathImpl,
typename T>
589 struct Acosh::Op<T_MathImpl, Complex<T>>
591 constexpr auto operator()(T_MathImpl, Complex<T>
const& arg)
const
599 template<
typename T_MathImpl,
typename T>
600 struct Arg::Op<T_MathImpl, Complex<T>>
602 constexpr auto operator()(T_MathImpl, Complex<T>
const& argument)
const
604 return math::atan2(argument.imag(), argument.real());
609 template<
typename T_MathImpl,
typename T>
610 struct Asin::Op<T_MathImpl, Complex<T>>
612 constexpr auto operator()(T_MathImpl, Complex<T>
const& arg)
const
615 return Complex<T>{
static_cast<T
>(0.0),
static_cast<T
>(1.0)}
618 - Complex<T>{
static_cast<T
>(0.0),
static_cast<T
>(1.0)} *
arg);
623 template<
typename T_MathImpl,
typename T>
624 struct Asinh::Op<T_MathImpl, Complex<T>>
626 constexpr auto operator()(T_MathImpl, Complex<T>
const& arg)
const
634 template<
typename T_MathImpl,
typename T>
635 struct Atan::Op<T_MathImpl, Complex<T>>
637 constexpr auto operator()(T_MathImpl, Complex<T>
const& arg)
const
640 return Complex<T>{
static_cast<T
>(0.0),
static_cast<T
>(-0.5)}
642 (Complex<T>{
static_cast<T
>(0.0),
static_cast<T
>(1.0)} -
arg)
643 / (Complex<T>{
static_cast<T
>(0.0),
static_cast<T
>(1.0)} +
arg));
648 template<
typename T_MathImpl,
typename T>
649 struct Atanh::Op<T_MathImpl, Complex<T>>
651 constexpr auto operator()(T_MathImpl, Complex<T>
const& arg)
const
654 return static_cast<T
>(0.5)
660 template<
typename T_MathImpl,
typename T>
661 struct Conj::Op<T_MathImpl, Complex<T>>
663 constexpr auto operator()(T_MathImpl
const& , Complex<T>
const& arg)
const
665 return Complex<T>{
arg.real(), -
arg.imag()};
670 template<
typename T_MathImpl,
typename T>
671 struct Cos::Op<T_MathImpl, Complex<T>>
673 constexpr auto operator()(T_MathImpl, Complex<T>
const& arg)
const
677 * (
math::exp(Complex<T>{
static_cast<T
>(0.0),
static_cast<T
>(1.0)} *
arg)
678 +
math::exp(Complex<T>{
static_cast<T
>(0.0),
static_cast<T
>(-1.0)} *
arg));
683 template<
typename T_MathImpl,
typename T>
684 struct Cosh::Op<T_MathImpl, Complex<T>>
686 constexpr auto operator()(T_MathImpl, Complex<T>
const& arg)
const
694 template<
typename T_MathImpl,
typename T>
695 struct Exp::Op<T_MathImpl, Complex<T>>
697 constexpr auto operator()(T_MathImpl, Complex<T>
const& arg)
const
700 auto re = T{}, im = T{};
707 template<
typename T_MathImpl,
typename T>
708 struct Log::Op<T_MathImpl, Complex<T>>
710 constexpr auto operator()(T_MathImpl, Complex<T>
const& argument)
const
715 + Complex<T>{
static_cast<T
>(0.0),
static_cast<T
>(1.0)} *
math::arg(argument);
720 template<
typename T_MathImpl,
typename T>
721 struct Log2::Op<T_MathImpl, Complex<T>>
723 constexpr auto operator()(T_MathImpl, Complex<T>
const& argument)
const
730 template<
typename T_MathImpl,
typename T>
731 struct Log10::Op<T_MathImpl, Complex<T>>
733 constexpr auto operator()(T_MathImpl, Complex<T>
const& argument)
const
740 template<
typename T_MathImpl,
typename T,
typename U>
741 struct Pow::Op<T_MathImpl, Complex<T>, Complex<U>>
743 constexpr auto operator()(T_MathImpl, Complex<T>
const& base, Complex<U>
const& exponent)
const
755 template<
typename T_MathImpl,
typename T,
typename U>
756 struct Pow::Op<T_MathImpl, Complex<T>, U>
758 constexpr auto operator()(T_MathImpl, Complex<T>
const& base, U
const& exponent)
const
760 return math::pow(base, Complex<U>{exponent});
765 template<
typename T_MathImpl,
typename T,
typename U>
766 struct Pow::Op<T_MathImpl, T, Complex<U>>
768 constexpr auto operator()(T_MathImpl, T
const& base, Complex<U>
const& exponent)
const
770 return math::pow(Complex<T>{base}, exponent);
775 template<
typename T_MathImpl,
typename T>
776 struct Rsqrt::Op<T_MathImpl, Complex<T>>
778 constexpr auto operator()(T_MathImpl, Complex<T>
const& arg)
const
785 template<
typename T_MathImpl,
typename T>
786 struct Sin::Op<T_MathImpl, Complex<T>>
788 constexpr auto operator()(T_MathImpl, Complex<T>
const& arg)
const
791 return (
math::exp(Complex<T>{
static_cast<T
>(0.0),
static_cast<T
>(1.0)} *
arg)
792 -
math::exp(Complex<T>{
static_cast<T
>(0.0),
static_cast<T
>(-1.0)} *
arg))
793 / Complex<T>{
static_cast<T
>(0.0),
static_cast<T
>(2.0)};
798 template<
typename T_MathImpl,
typename T>
799 struct Sinh::Op<T_MathImpl, Complex<T>>
801 constexpr auto operator()(T_MathImpl, Complex<T>
const& arg)
const
804 return (
math::exp(arg) -
math::exp(
static_cast<T
>(-1.0) * arg)) /
static_cast<T
>(2.0);
809 template<
typename T_MathImpl,
typename T>
810 struct SinCos::Op<T_MathImpl, Complex<T>>
812 constexpr auto operator()(
814 Complex<T>
const& arg,
815 Complex<T>& result_sin,
816 Complex<T>& result_cos)
const ->
void
824 template<
typename T_MathImpl,
typename T>
825 struct Sqrt::Op<T_MathImpl, Complex<T>>
827 constexpr auto operator()(T_MathImpl, Complex<T>
const& argument)
const
831 auto const halfArg = T(0.5) *
math::arg(argument);
832 auto re = T{}, im = T{};
839 template<
typename T_MathImpl,
typename T>
840 struct Tan::Op<T_MathImpl, Complex<T>>
842 constexpr auto operator()(T_MathImpl, Complex<T>
const& arg)
const
846 auto const expValue =
math::exp(Complex<T>{
static_cast<T
>(0.0),
static_cast<T
>(2.0)} *
arg);
847 return Complex<T>{
static_cast<T
>(0.0),
static_cast<T
>(1.0)} * (
static_cast<T
>(1.0) - expValue)
848 / (
static_cast<T
>(1.0) + expValue);
853 template<
typename T_MathImpl,
typename T>
854 struct Tanh::Op<T_MathImpl, Complex<T>>
856 constexpr auto operator()(T_MathImpl, Complex<T>
const& arg)
const
constexpr auto exp(auto const &arg)
constexpr auto sin(auto const &arg)
ALPAKA_FN_INLINE constexpr auto floatEqualExactNoWarning(T a, T b) -> bool
Compare two floating point numbers for exact equivalence.
constexpr auto abs(auto const &arg)
constexpr auto atan2(auto const &y, auto const &x)
constexpr auto arg(auto const &arg)
constexpr auto sincos(auto const &arg, auto &result_sin, auto &result_cos)
constexpr auto sqrt(auto const &arg)
constexpr auto cos(auto const &arg)
constexpr auto log(auto const &arg)
Computes the natural (base e) logarithm of arg.
constexpr auto pow(auto const &base, auto const &exp)
constexpr auto operator-(const Simd< T_Type, T_width, T_Storage > &lhs, const Simd< T_Type, T_width, T_OtherStorage > &rhs)
binary operators
constexpr auto operator+(const Simd< T_Type, T_width, T_Storage > &lhs, const Simd< T_Type, T_width, T_OtherStorage > &rhs)
binary operators
constexpr auto is_decayed_v
Provides a decaying wrapper around std::is_same. Example: is_decayed_v<volatile float,...
typename T::value_type type