7#include <autodiff/common/numbertraits.hpp>
11#include <cuda/std/complex>
15 using ::cuda::std::atan2;
16 using ::cuda::std::complex;
17 using ::cuda::std::cos;
18 using ::cuda::std::cosh;
19 using ::cuda::std::imag;
20 using ::cuda::std::log;
21 using ::cuda::std::pow;
22 using ::cuda::std::real;
23 using ::cuda::std::sin;
24 using ::cuda::std::sinh;
25 using ::cuda::std::sqrt;
26 using ::cuda::std::tan;
27 using ::cuda::std::tanh;
28 template <
typename NT>
constexpr auto cot(
const NT x) {
return NT(1) / tan(x); }
50 template <
typename NT>
constexpr auto cot(
const NT x) {
return NT(1) / tan(x); }
60 using ::cuda::std::complex;
61 template <
typename T>
struct ArithmeticTraits<::cuda::std::__4::complex<T>> : ArithmeticTraits<T> {
71 template <
typename T>
struct ArithmeticTraits<::std::complex<T>> : ArithmeticTraits<T> {
80 template <
typename T1,
typename T2>
81 requires(!std::is_same_v<T1, T2>) && std::is_arithmetic_v<T1> && std::is_arithmetic_v<T2>
82 __host__ __device__
auto operator*(
const T1 x,
const complex<T2> y)
84 return complex<
decltype(T1(1.) * T2(1.))>(x * y.real(), x * y.imag());
86 template <
typename T1,
typename T2>
87 requires(!std::is_same_v<T1, T2>) && std::is_arithmetic_v<T1> && std::is_arithmetic_v<T2>
88 __host__ __device__
auto operator*(
const complex<T1> &x,
const T2 &y)
90 return complex<
decltype(T1(1.) * T2(1.))>(y * x.real(), y * x.imag());
93 template <
typename T1,
typename T2>
94 requires(!std::is_same_v<T1, T2>) && std::is_arithmetic_v<T1> && std::is_arithmetic_v<T2>
95 __host__ __device__
auto operator+(
const T1 &x,
const complex<T2> &y)
97 return complex<
decltype(T1(1.) + T2(1.))>(x + y.real(), y.imag());
99 template <
typename T1,
typename T2>
100 requires(!std::is_same_v<T1, T2>) && std::is_arithmetic_v<T1> && std::is_arithmetic_v<T2>
101 __host__ __device__
auto operator+(
const complex<T1> &x,
const T2 &y)
103 return complex<
decltype(T1(1.) + T2(1.))>(x.real() + y, x.imag());
106 template <
typename T1,
typename T2>
107 requires(!std::is_same_v<T1, T2>) && std::is_arithmetic_v<T1> && std::is_arithmetic_v<T2>
108 __host__ __device__
auto operator-(
const T1 &x,
const complex<T2> &y)
110 return complex<
decltype(T1(1.) - T2(1.))>(x - y.real(), -y.imag());
112 template <
typename T1,
typename T2>
113 requires(!std::is_same_v<T1, T2>) && std::is_arithmetic_v<T1> && std::is_arithmetic_v<T2>
114 __host__ __device__
auto operator-(
const complex<T1> &x,
const T2 &y)
116 return complex<
decltype(T1(1.) - T2(1.))>(x.real() - y, x.imag());
119 template <
typename T1,
typename T2>
120 requires(!std::is_same_v<T1, T2>) && std::is_arithmetic_v<T1> && std::is_arithmetic_v<T2>
121 __host__ __device__
auto operator/(
const T1 &x,
const complex<T2> &y)
123 return complex<
decltype(T1(1.) / T2(1.))>(x * y.real(), -x * y.imag()) / (powr<2>(y.real()) + powr<2>(y.imag()));
125 template <
typename T1,
typename T2>
126 requires(!std::is_same_v<T1, T2>) && std::is_arithmetic_v<T1> && std::is_arithmetic_v<T2>
127 __host__ __device__
auto operator/(
const complex<T1> x,
const T2 &y)
129 return complex<
decltype(T1(1.) / T2(1.))>(x.real() / y, x.imag() / y);
134#include <autodiff/forward/real.hpp>
138 template <
size_t N,
typename T>
using cxreal = autodiff::Real<N, complex<T>>;
139 using cxReal = autodiff::Real<1, complex<double>>;
141 template <
typename T>
struct is_complex :
public std::false_type {
143 template <
typename T>
struct is_complex<complex<T>> :
public std::true_type {
148 template <
size_t N,
typename T> AUTODIFF_DEVICE_FUNC
auto real(
const autodiff::Real<N, T> &a) {
return a; }
149 template <
size_t N,
typename T>
constexpr AUTODIFF_DEVICE_FUNC
auto imag(
const autodiff::Real<N, T> &) {
return 0.; }
153 autodiff::Real<N, T> res;
154 autodiff::detail::For<0, N + 1>([&](
auto i)
constexpr { res[i] =
real(x[i]); });
159 autodiff::Real<N, T> res;
160 autodiff::detail::For<0, N + 1>([&](
auto i)
constexpr { res[i] =
imag(x[i]); });
165 template <
size_t N,
typename T>
166 AUTODIFF_DEVICE_FUNC
auto operator*(
const autodiff::Real<N, T> &x,
const complex<double> &y)
169 autodiff::detail::For<0, N + 1>([&](
auto i)
constexpr { res[i] = x[i] * y; });
172 template <
size_t N,
typename T>
173 AUTODIFF_DEVICE_FUNC
auto operator*(
const complex<double> x,
const autodiff::Real<N, T> y)
176 autodiff::detail::For<0, N + 1>([&](
auto i)
constexpr { res[i] = x * y[i]; });
180 template <
size_t N,
typename T>
181 AUTODIFF_DEVICE_FUNC
auto operator+(
const autodiff::Real<N, T> &x,
const complex<double> &y)
185 autodiff::detail::For<1, N + 1>([&](
auto i)
constexpr { res[i] = x[i]; });
188 template <
size_t N,
typename T>
189 AUTODIFF_DEVICE_FUNC
auto operator+(
const complex<double> x,
const autodiff::Real<N, T> y)
193 autodiff::detail::For<1, N + 1>([&](
auto i)
constexpr { res[i] = y[i]; });
197 template <
size_t N,
typename T>
198 AUTODIFF_DEVICE_FUNC
auto operator-(
const autodiff::Real<N, T> &x,
const complex<double> &y)
202 autodiff::detail::For<1, N + 1>([&](
auto i)
constexpr { res[i] = x[i]; });
205 template <
size_t N,
typename T>
206 AUTODIFF_DEVICE_FUNC
auto operator-(
const complex<double> x,
const autodiff::Real<N, T> y)
210 autodiff::detail::For<1, N + 1>([&](
auto i)
constexpr { res[i] = -y[i]; });
214 template <
size_t N,
typename T>
215 AUTODIFF_DEVICE_FUNC
auto operator/(
const autodiff::Real<N, T> &x,
const complex<double> &y)
218 autodiff::detail::For<0, N + 1>([&](
auto i)
constexpr { res[i] = x[i] / y; });
221 template <
size_t N,
typename T>
222 AUTODIFF_DEVICE_FUNC
auto operator/(
const complex<double> x,
const autodiff::Real<N, T> y)
230 template <
size_t N,
typename T>
236 template <
size_t N,
typename T>
243 template <
size_t N,
typename T>
249 template <
size_t N,
typename T>
256 template <
size_t N,
typename T>
262 template <
size_t N,
typename T>
270 template <
size_t N,
typename T>
276 template <
size_t N,
typename T>
284 template <
size_t N,
typename T> AUTODIFF_DEVICE_FUNC
auto operator*(
const complex<double> &x,
const cxreal<N, T> &y)
287 autodiff::detail::For<0, N + 1>([&](
auto i)
constexpr { res[i] = y[i] * x; });
290 template <
size_t N,
typename T> AUTODIFF_DEVICE_FUNC
auto operator*(
const cxreal<N, T> &x,
const complex<double> &y)
293 autodiff::detail::For<0, N + 1>([&](
auto i)
constexpr { res[i] = x[i] * y; });
297 template <
size_t N,
typename T> AUTODIFF_DEVICE_FUNC
auto operator+(
const complex<double> &x,
const cxreal<N, T> &y)
303 template <
size_t N,
typename T> AUTODIFF_DEVICE_FUNC
auto operator+(
const cxreal<N, T> &x,
const complex<double> &y)
310 template <
size_t N,
typename T> AUTODIFF_DEVICE_FUNC
auto operator-(
const complex<double> &x,
const cxreal<N, T> &y)
315 template <
size_t N,
typename T> AUTODIFF_DEVICE_FUNC
auto operator-(
const cxreal<N, T> &x,
const complex<double> &y)
322 template <
size_t N,
typename T> AUTODIFF_DEVICE_FUNC
auto operator/(
const cxreal<N, T> &x,
const complex<double> &y)
325 autodiff::detail::For<0, N + 1>([&](
auto i)
constexpr { res[i] = x[i] / y; });
328 template <
size_t N,
typename T> AUTODIFF_DEVICE_FUNC
auto operator/(
const complex<double> &x,
const cxreal<N, T> &y)
340 autodiff::detail::For<N + 1>([&](
auto i)
constexpr {
341 res[i] -= autodiff::detail::Sum<0, i>([&](
auto j)
constexpr {
342 constexpr auto c = autodiff::detail::BinomialCoefficient<i.index, j.index>;
343 return c * res[j] * y[i - j];
355 template <
typename T1,
typename T2>
356 requires(!std::is_same_v<T1, T2>) && std::is_arithmetic_v<T1> && std::is_arithmetic_v<T2>
357 AUTODIFF_DEVICE_FUNC
auto operator*(
const T1 x,
const complex<T2> y)
359 return complex<
decltype(T1(1.) * T2(1.))>(x * y.real(), x * y.imag());
361 template <
typename T1,
typename T2>
362 requires(!std::is_same_v<T1, T2>) && std::is_arithmetic_v<T1> && std::is_arithmetic_v<T2>
363 AUTODIFF_DEVICE_FUNC
auto operator*(
const complex<T1> &x,
const T2 &y)
365 return complex<
decltype(T1(1.) * T2(1.))>(y * x.real(), y * x.imag());
368 template <
typename T1,
typename T2>
369 requires(!std::is_same_v<T1, T2>) && std::is_arithmetic_v<T1> && std::is_arithmetic_v<T2>
370 AUTODIFF_DEVICE_FUNC
auto operator+(
const T1 &x,
const complex<T2> &y)
372 return complex<
decltype(T1(1.) + T2(1.))>(x + y.real(), y.imag());
374 template <
typename T1,
typename T2>
375 requires(!std::is_same_v<T1, T2>) && std::is_arithmetic_v<T1> && std::is_arithmetic_v<T2>
376 AUTODIFF_DEVICE_FUNC
auto operator+(
const complex<T1> &x,
const T2 &y)
378 return complex<
decltype(T1(1.) + T2(1.))>(x.real() + y, x.imag());
381 template <
typename T1,
typename T2>
382 requires(!std::is_same_v<T1, T2>) && std::is_arithmetic_v<T1> && std::is_arithmetic_v<T2>
383 AUTODIFF_DEVICE_FUNC
auto operator-(
const T1 &x,
const complex<T2> &y)
385 return complex<
decltype(T1(1.) + T2(1.))>(x - y.real(), -y.imag());
387 template <
typename T1,
typename T2>
388 requires(!std::is_same_v<T1, T2>) && std::is_arithmetic_v<T1> && std::is_arithmetic_v<T2>
389 AUTODIFF_DEVICE_FUNC
auto operator-(
const complex<T1> &x,
const T2 &y)
391 return complex<
decltype(T1(1.) + T2(1.))>(x.real() - y, x.imag());
394 template <
typename T1,
typename T2>
395 requires(!std::is_same_v<T1, T2>) && std::is_arithmetic_v<T1> && std::is_arithmetic_v<T2>
396 AUTODIFF_DEVICE_FUNC
auto operator/(
const T1 &x,
const complex<T2> &y)
398 return complex<
decltype(T1(1.) + T2(1.))>(x * y.real(), -x * y.imag()) / (
powr<2>(y.real()) +
powr<2>(y.imag()));
400 template <
typename T1,
typename T2>
401 requires(!std::is_same_v<T1, T2>) && std::is_arithmetic_v<T1> && std::is_arithmetic_v<T2>
402 AUTODIFF_DEVICE_FUNC
auto operator/(
const complex<T1> x,
const T2 &y)
404 return complex<
decltype(T1(1.) + T2(1.))>(x.real() / y, x.imag() / y);
Definition complex_math.hh:14
AUTODIFF_DEVICE_FUNC auto operator/(const autodiff::Real< N, T > &x, const complex< double > &y)
Definition complex_math.hh:215
constexpr __forceinline__ __host__ __device__ NumberType powr(const NumberType x)
A compile-time evaluatable power function for whole number exponents.
Definition math.hh:45
constexpr auto cot(const NT x)
Definition complex_math.hh:28
AUTODIFF_DEVICE_FUNC auto operator+(const autodiff::Real< N, T > &x, const complex< double > &y)
Definition complex_math.hh:181
AUTODIFF_DEVICE_FUNC auto operator*(const autodiff::Real< N, T > &x, const complex< double > &y)
Definition complex_math.hh:166
AUTODIFF_DEVICE_FUNC auto real(const autodiff::Real< N, T > &a)
Definition complex_math.hh:148
autodiff::Real< 1, complex< double > > cxReal
Definition complex_math.hh:139
AUTODIFF_DEVICE_FUNC auto operator-(const autodiff::Real< N, T > &x, const complex< double > &y)
Definition complex_math.hh:198
autodiff::Real< N, complex< T > > cxreal
Definition complex_math.hh:138
constexpr AUTODIFF_DEVICE_FUNC auto imag(const autodiff::Real< N, T > &)
Definition complex_math.hh:149
Definition complex_math.hh:59
Definition complex_math.hh:141