@@ -129,5 +129,87 @@ namespace xt
129129 {
130130 return detail::complex_expression_helper<is_xexpression<std::decay_t <E>>::value>::imag (std::forward<E>(e));
131131 }
132+
133+ #define UNARY_COMPLEX_FUNCTOR (NAME )\
134+ template <class T >\
135+ struct NAME ##_fun {\
136+ using argument_type = T;\
137+ using result_type = decltype (std::NAME (std::declval<T>()));\
138+ constexpr result_type operator ()(const T& t) const {\
139+ using std::NAME ;\
140+ return NAME (t);\
141+ }\
142+ }
143+
144+ namespace math
145+ {
146+ UNARY_COMPLEX_FUNCTOR (conj);
147+ UNARY_COMPLEX_FUNCTOR (norm);
148+ UNARY_COMPLEX_FUNCTOR (arg);
149+ }
150+
151+ #undef UNARY_COMPLEX_FUNCTOR
152+
153+ /* *
154+ * @brief Returns an \ref xfunction evaluating to the complex conjugate of the given expression.
155+ *
156+ * @param e the \ref xexpression
157+ */
158+ template <class E >
159+ inline auto conj (E&& e) noexcept
160+ {
161+ using value_type = typename std::decay_t <E>::value_type;
162+ using functor = math::conj_fun<value_type>;
163+ using result_type = typename functor::result_type;
164+ using type = xfunction<functor, result_type, const_xclosure_t <E>>;
165+ return type (functor (), std::forward<E>(e));
166+ }
167+
168+ /* *
169+ * @brief Calculates the phase angle (in radians) elementwise for the complex numbers in e.
170+ * @param e the \ref xexpression
171+ */
172+ template <class E >
173+ inline auto arg (E&& e) noexcept
174+ {
175+ using value_type = typename std::decay_t <E>::value_type;
176+ using functor = math::arg_fun<value_type>;
177+ using result_type = typename functor::result_type;
178+ using type = xfunction<functor, result_type, const_xclosure_t <E>>;
179+ return type (functor (), std::forward<E>(e));
180+ }
181+
182+ /* *
183+ * @brief Calculates the phase angle elementwise for the complex numbers in e.
184+ * Note that this function might be slightly less perfomant than \ref arg.
185+ * @param e the \ref xexpression
186+ * @param deg calculate angle in degrees instead of radians
187+ */
188+ template <class E >
189+ inline auto angle (E&& e, bool deg = false ) noexcept
190+ {
191+ using value_type = complex_value_type_t <typename std::decay_t <E>::value_type>;
192+ value_type multiplier = 1.0 ;
193+ if (deg)
194+ {
195+ multiplier = value_type (180 ) / numeric_constants<value_type>::PI ;
196+ }
197+ return arg (std::forward<E>(e)) * std::move (multiplier);
198+ }
199+
200+ /* *
201+ * Calculates the squared magnitude elementwise for the complex numbers in e.
202+ * Equivalent to pow(real(e), 2) + pow(imag(e), 2).
203+ * @param e the \ref xexpression
204+ */
205+ template <class E >
206+ inline auto norm (E&& e) noexcept
207+ {
208+ using value_type = typename std::decay_t <E>::value_type;
209+ using functor = math::norm_fun<value_type>;
210+ using result_type = typename functor::result_type;
211+ using type = xfunction<functor, result_type, const_xclosure_t <E>>;
212+ return type (functor (), std::forward<E>(e));
213+ }
132214}
133215#endif
0 commit comments