MLIR 23.0.0git
Complex.h
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file contains the declaration of the mlir::NonFloatComplex type and
11/// mlir::Complex type alias. The interface is intended to match the
12/// std::complex type, and the mlir::Complex alias defers to std::complex for
13/// builtin floating point types.
14///
15//===----------------------------------------------------------------------===//
16
17#ifndef MLIR_SUPPORT_COMPLEX_H
18#define MLIR_SUPPORT_COMPLEX_H
19
20#include <complex>
21#include <type_traits>
22
23namespace mlir {
24
25// The copy constructors should only be implicit iff the underlying constructors
26// are explicit and the conversion would not narrow. This is the case if the
27// underlying destination type is copy-list-initializeable from the source type,
28// so define a helper to determine if that is the case.
29namespace detail {
30// NOLINTBEGIN
31template <typename From, typename To>
33 -> decltype(void(std::declval<To &>() = {std::declval<From &>()}),
34 std::true_type{});
35
36template <typename, typename>
37auto test_copy_list_initializable(...) -> std::false_type;
38
39template <typename From, typename To>
41 : std::bool_constant<
42 decltype(detail::test_copy_list_initializable<From, To>(0))::value> {
43};
44
45template <typename From, typename To>
48// NOLINTEND
49} // namespace detail
50
51template <typename T>
53public:
54 using value_type = T;
55
56private:
57 T re;
58 T im;
59
60public:
61 constexpr NonFloatComplex(const T &re = T{}, const T &im = T{})
62 : re(re), im(im) {}
63
64 constexpr NonFloatComplex(const NonFloatComplex &other) = default;
65
66 template <typename U,
67 std::enable_if_t<detail::is_copy_list_initializable_v<U, T>>...>
68 constexpr NonFloatComplex(const NonFloatComplex<U> &other)
69 : re{other.re}, im{other.im} {}
70
71 template <typename U,
72 std::enable_if_t<!detail::is_copy_list_initializable_v<U, T>>...>
73 constexpr explicit NonFloatComplex(const NonFloatComplex<U> &other)
74 : re(other.re), im(other.im) {}
75
76 template <typename U,
77 std::enable_if_t<detail::is_copy_list_initializable_v<U, T>>...>
78 constexpr NonFloatComplex(const std::complex<U> &other)
79 : re{other.real()}, im{other.imag()} {}
80
81 template <typename U,
82 std::enable_if_t<!detail::is_copy_list_initializable_v<U, T>>...>
83 constexpr explicit NonFloatComplex(const std::complex<U> &other)
84 : re(other.real()), im(other.imag()) {}
85
86 [[nodiscard]] constexpr T real() const { return re; }
87 constexpr void real(T value) { re = value; }
88 [[nodiscard]] constexpr T imag() const { return im; }
89 constexpr void imag(T value) { im = value; }
90
91 constexpr NonFloatComplex &operator=(const NonFloatComplex &other) = default;
92
93 constexpr NonFloatComplex &operator=(const T &real) {
94 re = real;
95 im = T{};
96 return *this;
97 }
98
99 constexpr NonFloatComplex &operator+=(const T &real) {
100 re += real;
101 return *this;
102 }
103
104 constexpr NonFloatComplex &operator-=(const T &real) {
105 re -= real;
106 return *this;
107 }
108
109 constexpr NonFloatComplex &operator*=(const T &real) {
110 re *= real;
111 im *= real;
112 return *this;
113 }
114
115 constexpr NonFloatComplex &operator/=(const T &real) {
116 re /= real;
117 im /= real;
118 return *this;
119 }
120
121 constexpr NonFloatComplex &operator+=(const NonFloatComplex &other) {
122 re += other.re;
123 im += other.im;
124 return *this;
125 }
126
127 constexpr NonFloatComplex &operator-=(const NonFloatComplex &other) {
128 re -= other.re;
129 im -= other.im;
130 return *this;
131 }
132
133 constexpr NonFloatComplex &operator*=(const NonFloatComplex &other) {
134 *this = *this * NonFloatComplex{other.re, other.im};
135 return *this;
136 }
137
138 constexpr NonFloatComplex &operator/=(const NonFloatComplex &other) {
139 *this = *this / NonFloatComplex{other.re, other.im};
140 return *this;
141 }
142
143 template <typename U>
144 constexpr NonFloatComplex &operator=(const std::complex<U> &other) {
145 re = other.real();
146 im = other.imag();
147 return *this;
148 }
149};
150
151template <typename T, typename U>
152[[nodiscard]] constexpr NonFloatComplex<T>
153operator+(const NonFloatComplex<T> &x, const U &y) {
155 t += y;
156 return t;
157}
158
159template <typename T, typename U>
160[[nodiscard]] constexpr NonFloatComplex<T>
161operator-(const NonFloatComplex<T> &x, const U &y) {
163 t -= y;
164 return t;
165}
166
167template <typename T>
168[[nodiscard]] constexpr NonFloatComplex<T>
170 T a = x.real();
171 T b = x.imag();
172 T c = y.real();
173 T d = y.imag();
174
175 return {(a * c) - (b * d), (a * d) + (b * c)};
176}
177
178template <typename T, typename U>
179[[nodiscard]] constexpr NonFloatComplex<T>
180operator*(const NonFloatComplex<T> &x, const U &y) {
182 t *= y;
183 return t;
184}
185
186template <typename T>
187[[nodiscard]] constexpr NonFloatComplex<T>
189 T a = x.real();
190 T b = x.imag();
191 T c = y.real();
192 T d = y.imag();
193
194 T denom = c * c + d * d;
195 return {(a * c + b * d) / denom, (b * c - a * d) / denom};
196}
197
198template <typename T, typename U>
199[[nodiscard]] constexpr NonFloatComplex<T>
200operator/(const NonFloatComplex<T> &x, const U &y) {
202 t /= y;
203 return t;
204}
205
206template <typename T>
207[[nodiscard]] constexpr NonFloatComplex<T>
209 return x;
210}
211
212template <typename T>
213[[nodiscard]] constexpr NonFloatComplex<T>
215 return {-x.real(), -x.imag()};
216}
217
218template <typename T>
219[[nodiscard]] constexpr bool operator==(const NonFloatComplex<T> &x,
220 const NonFloatComplex<T> &y) {
221 return x.real() == y.real() && x.imag() == y.imag();
222}
223
224template <typename T, typename U>
225[[nodiscard]] constexpr bool operator==(const NonFloatComplex<T> &x,
226 const U &y) {
227 return x == NonFloatComplex<T>{y};
228}
229
230template <typename T, typename U>
231[[nodiscard]] constexpr bool operator==(const T &x,
232 const NonFloatComplex<U> &y) {
233 return NonFloatComplex<U>{x} == y;
234}
235
236template <typename T>
237[[nodiscard]] constexpr bool operator!=(const NonFloatComplex<T> &x,
238 const NonFloatComplex<T> &y) {
239 return !(x == y);
240}
241
242template <typename T, typename U>
243[[nodiscard]] constexpr bool operator!=(const NonFloatComplex<T> &x,
244 const U &y) {
245 return !(x == y);
246}
247
248template <typename T, typename U>
249[[nodiscard]] constexpr bool operator!=(const U &x,
250 const NonFloatComplex<T> &y) {
251 return !(y == x);
252}
253
254template <typename T>
255[[nodiscard]] constexpr T real(const NonFloatComplex<T> &x) {
256 return x.real();
257}
258
259template <typename T>
260[[nodiscard]] constexpr T imag(const NonFloatComplex<T> &x) {
261 return x.imag();
262}
263
264template <typename T>
265using Complex = std::conditional_t<std::is_floating_point_v<T>, std::complex<T>,
267} // namespace mlir
268
269#endif
b
Return true if permutation is a valid permutation of the outer_dims_perm (case OuterOrInnerPerm::Oute...
constexpr NonFloatComplex & operator-=(const T &real)
Definition Complex.h:104
constexpr NonFloatComplex(const NonFloatComplex &other)=default
constexpr NonFloatComplex(const std::complex< U > &other)
Definition Complex.h:78
constexpr NonFloatComplex & operator/=(const NonFloatComplex &other)
Definition Complex.h:138
constexpr T real() const
Definition Complex.h:86
constexpr NonFloatComplex & operator+=(const NonFloatComplex &other)
Definition Complex.h:121
constexpr NonFloatComplex & operator+=(const T &real)
Definition Complex.h:99
constexpr NonFloatComplex & operator=(const NonFloatComplex &other)=default
constexpr NonFloatComplex & operator*=(const NonFloatComplex &other)
Definition Complex.h:133
constexpr NonFloatComplex & operator/=(const T &real)
Definition Complex.h:115
constexpr NonFloatComplex & operator=(const T &real)
Definition Complex.h:93
constexpr NonFloatComplex(const T &re=T{}, const T &im=T{})
Definition Complex.h:61
constexpr NonFloatComplex & operator*=(const T &real)
Definition Complex.h:109
constexpr T imag() const
Definition Complex.h:88
constexpr NonFloatComplex(const NonFloatComplex< U > &other)
Definition Complex.h:68
constexpr NonFloatComplex & operator=(const std::complex< U > &other)
Definition Complex.h:144
constexpr void real(T value)
Definition Complex.h:87
constexpr NonFloatComplex & operator-=(const NonFloatComplex &other)
Definition Complex.h:127
constexpr void imag(T value)
Definition Complex.h:89
AttrTypeReplacer.
auto test_copy_list_initializable(int) -> decltype(void(std::declval< To & >()={std::declval< From & >()}), std::true_type{})
constexpr bool is_copy_list_initializable_v
Definition Complex.h:46
Include the generated interface declarations.
constexpr T real(const NonFloatComplex< T > &x)
Definition Complex.h:255
bool operator==(StringAttr lhs, std::nullptr_t)
Define comparisons for StringAttr against nullptr and itself to avoid the StringRef overloads from be...
bool operator!=(RegionBranchPoint lhs, RegionBranchPoint rhs)
constexpr NonFloatComplex< T > operator/(const NonFloatComplex< T > &x, const NonFloatComplex< T > &y)
Definition Complex.h:188
AffineExpr operator-(int64_t val, AffineExpr expr)
Definition AffineExpr.h:253
std::conditional_t< std::is_floating_point_v< T >, std::complex< T >, NonFloatComplex< T > > Complex
Definition Complex.h:265
AffineExpr operator+(int64_t val, AffineExpr expr)
Definition AffineExpr.h:251
AffineExpr operator*(int64_t val, AffineExpr expr)
Definition AffineExpr.h:252
constexpr T imag(const NonFloatComplex< T > &x)
Definition Complex.h:260