Loading...
Searching...
No Matches
complex.h
Go to the documentation of this file.
1#ifndef _BBM_NATIVE_COMPLEX_H_
2#define _BBM_NATIVE_COMPLEX_H_
3
4#include <complex>
5#include "backbone/array.h"
6#include "backbone/vec.h"
7
8/************************************************************************/
9/*! \filename complex.h
10
11 \brief Complex numbers; built on top of array
12
13************************************************************************/
14
15namespace backbone {
16
17 /**********************************************************************/
18 /*! \brief Complex numbers
19 **********************************************************************/
20 template<typename T>
21 struct complex : public array<T, 2>
22 {
24 using base_type::operator=;
25
26 //! @{ \name Constructors
27 template<typename U=T> requires std::constructible_from<T,U>
28 constexpr complex(const T& r=0, const U& i=0) : base_type(r, i) {}
29
30 template<typename U> requires std::constructible_from<T,U>
31 constexpr complex(const array<U,2>& src) : base_type(src) {}
32
33 template<typename U> requires std::constructible_from<T, U>
34 constexpr complex(const std::complex<U>& src) : base_type( src.real(), src.imag() ) {}
35 //! @}
36
37 //! @{ \name Conversion to std::complex (with optimal float or double type based on T) -- not on 'U'!
38 inline constexpr auto std_complex(void) const -> decltype(std::complex(std::declval<T>(), std::declval<T>()))
39 {
40 return {real(*this), imag(*this)};
41 }
42
43 template<typename U>
44 static inline constexpr auto std_complex(complex<U> u) -> decltype(std::complex(std::declval<T>(), std::declval<T>()))
45 {
46 using type = typename decltype(std_complex())::value_type;
47 return {type(real(u)), type(imag(u))};
48 }
49 //! @}
50
51 //! \brief Specialized assignment operator
52 template<typename U> requires std::constructible_from<T, U>
53 complex& operator=(U&& r) { *this = complex(std::forward<U>(r),0); return *this; }
54
55
56 //! @{ \name Addition
57 inline constexpr complex operator+(T u) const { return *this + complex(u,0); }
58 template<typename U> inline constexpr complex operator+(complex<U> u) const { return std_complex() + complex<T>::std_complex(u); }
59 friend constexpr inline complex operator+(T u, complex& t) { return complex(u) + t; }
60
61 template<typename U> inline constexpr complex& operator+=(U u) { *this = *this + u; return *this; }
62 //! @}
63
64 //! @{ \name Subtraction
65 inline constexpr complex operator-(T u) const { return *this - complex(u,0); }
66 template<typename U> inline constexpr complex operator-(complex<U> u) const { return std_complex() + complex<T>::std_complex(u); }
67 friend constexpr inline complex operator-(T u, complex& t) { return complex(u) - t; }
68
69 template<typename U> inline constexpr complex& operator-=(U u) { *this = *this - u; return *this; }
70 //! @}
71
72 //! @{ \name Multiplication
73 inline constexpr complex operator*(T u) const { return std_complex() * u; }
74 template<typename U> inline constexpr complex operator*(complex<U> u) const { return std_complex() * complex<T>::std_complex(u); }
75 friend constexpr inline complex operator*(T u, complex& t) { return complex(u) * t; }
76
77 template<typename U> inline constexpr complex& operator*=(U u) { *this = *this * u; return *this; }
78 //! @}
79
80 //! @{ \name Division
81 inline constexpr complex operator/(T u) const { return std_complex() / u; }
82 template<typename U> inline constexpr complex operator/(complex<U> u) const { return std_complex() / complex<T>::std_complex(u); }
83 friend constexpr inline complex operator/(T u, complex& t) { return complex<T>::std_complex(u) / complex<T>::std_complex(t); }
84 template<typename U> inline constexpr complex& operator/=(U u) { *this = *this / u; return *this; }
85 //! @}
86 };
87
88 //! @{ \name Core Inspectors
89 template<typename T> inline constexpr T real(complex<T> z) { return z[0]; }
90 template<typename T> inline constexpr T imag(complex<T> z) { return z[1]; }
91 template<typename T> inline constexpr complex<T> conj(complex<T> z) { return std::conj(z.std_complex()); }
92 //! @}
93
94 //! \brief rcp
95 template<typename T> inline constexpr complex<T> rcp(complex<T> z)
96 {
97 auto l = squared_norm(z);
98 return conj(z) / l;
99 }
100
101 //! @{ \name std::complex -> complex Functions
102 #define BBM_DECL_COMPLEX_OP(op) template<typename T> inline constexpr complex<T> op (complex<T> z) { return std::op (z.std_complex()); }
103
120
121 #undef BBM_DECL_COMPLEX_OP
122 //! @}
123
124 //! \brief cossin method
125 template<typename T> inline constexpr vec2d<complex<T>> cossin(complex<T> z) { return vec2d<complex<T>>( cos(z), sin(z) ); }
126
127 //! @{ \name Horizontal methods
128 template<typename T> inline constexpr complex<T> reverse(complex<T> z) { return reverse(typename complex<T>::base_type(z)); }
129 template<typename T> inline constexpr complex<T> psum(complex<T> z) { return psum(typename complex<T>::base_type(z)); }
130 template<typename T> inline constexpr complex<T> normalize(complex<T> z) { return normalize(typename complex<T>::base_type(z)); }
131 //! @}
132
133 /*** Implementation Details for is_complex_impl ***/
134 namespace detail {
135
136 template<typename T> struct is_complex_impl : std::false_type {};
137 template<typename T> struct is_complex_impl<complex<T>> : std::true_type {};
138
139 } // end detail namespace
140
141
142 /*** Specializations for is_array and array_size ***/
143 namespace detail {
144 template<typename T> struct is_array<complex<T>> : std::true_type {};
145 template<typename T> struct array_size<complex<T>> { static constexpr size_t value = 2; };
146 }
147
148 /**********************************************************************/
149 /*! @{ \name type traits
150 **********************************************************************/
151 template<typename T>
152 using is_complex = detail::is_complex_impl<std::decay_t<T>>;
153
154 template<typename T>
155 inline constexpr bool is_complex_v = is_complex<T>::value;
156 //! @}
157
158} // end backbone namespace
159
160
161#endif /* _BBM_NATIVE_COMPLEX_H_ */
#define BBM_DECL_COMPLEX_OP(op)
Definition: complex.h:102
Random number generator; built on top of Drjit.
Definition: backbone.h:53
constexpr bool is_complex_v
Definition: complex.h:155
constexpr complex< T > psum(complex< T > z)
Definition: complex.h:129
constexpr complex< T > conj(complex< T > z)
Definition: complex.h:91
constexpr complex< T > reverse(complex< T > z)
Definition: complex.h:128
detail::is_complex_impl< std::decay_t< T > > is_complex
Definition: complex.h:152
drjit::Complex< T > complex
Alias drjit::Complex.
Definition: complex.h:20
vec2d< T > cossin(const T &a)
cossin
Definition: math.h:107
constexpr T real(complex< T > z)
Definition: complex.h:89
drjit::Array< T, 2 > vec2d
Definition: vec.h:13
constexpr complex< T > rcp(complex< T > z)
rcp
Definition: complex.h:95
constexpr T imag(complex< T > z)
Definition: complex.h:90
auto squared_norm(const T &a)
Definition: horizontal.h:31
auto normalize(const T &a)
Definition: horizontal.h:38
Definition: array.h:21
bbm::detail::is_array_impl< std::decay_t< T > > is_array
Definition: type_traits.h:163
decltype(auto) value(T &&t)
return the value of an attribute, or if not an attribute the object
Definition: attribute_value.h:20
Complex numbers.
Definition: complex.h:22
friend constexpr complex operator+(T u, complex &t)
Definition: complex.h:59
constexpr complex operator/(T u) const
Definition: complex.h:81
constexpr complex operator+(complex< U > u) const
Definition: complex.h:58
constexpr complex & operator+=(U u)
Definition: complex.h:61
constexpr complex operator*(T u) const
Definition: complex.h:73
constexpr complex operator*(complex< U > u) const
Definition: complex.h:74
constexpr complex(const std::complex< U > &src)
Definition: complex.h:34
constexpr complex operator+(T u) const
Definition: complex.h:57
constexpr complex & operator*=(U u)
Definition: complex.h:77
constexpr complex operator-(complex< U > u) const
Definition: complex.h:66
constexpr complex(const array< U, 2 > &src)
Definition: complex.h:31
friend constexpr complex operator-(T u, complex &t)
Definition: complex.h:67
complex & operator=(U &&r)
Specialized assignment operator.
Definition: complex.h:53
constexpr complex & operator-=(U u)
Definition: complex.h:69
constexpr auto std_complex(void) const -> decltype(std::complex(std::declval< T >(), std::declval< T >()))
Definition: complex.h:38
static constexpr auto std_complex(complex< U > u) -> decltype(std::complex(std::declval< T >(), std::declval< T >()))
Definition: complex.h:44
constexpr complex operator-(T u) const
Definition: complex.h:65
constexpr complex(const T &r=0, const U &i=0)
Definition: complex.h:28
constexpr complex operator/(complex< U > u) const
Definition: complex.h:82
constexpr complex & operator/=(U u)
Definition: complex.h:84
friend constexpr complex operator/(T u, complex &t)
Definition: complex.h:83
friend constexpr complex operator*(T u, complex &t)
Definition: complex.h:75