DPC++ Runtime
Runtime libraries for oneAPI DPC++
complex.hpp
Go to the documentation of this file.
1 //===- complex.hpp --------------------------------------------------------===//
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 #pragma once
10 
11 #include "common.hpp"
12 
13 #include <sycl/stream.hpp>
14 
15 #include <complex>
16 
17 namespace sycl {
18 inline namespace _V1 {
19 
20 namespace ext {
21 namespace oneapi {
22 namespace experimental {
23 
24 template <class _Tp>
25 class complex<_Tp, typename std::enable_if_t<is_genfloat<_Tp>::value>> {
26 public:
27  typedef _Tp value_type;
28 
29 private:
30  value_type __re_;
31  value_type __im_;
32 
33 public:
35  value_type __re = value_type(), value_type __im = value_type())
36  : __re_(__re), __im_(__im) {}
37 
38  template <typename _Xp>
40  : __re_(__c.real()), __im_(__c.imag()) {}
41 
42  template <class _Xp, typename = std::enable_if_t<is_genfloat<_Xp>::value>>
44  const std::complex<_Xp> &__c)
45  : __re_(static_cast<value_type>(__c.real())),
46  __im_(static_cast<value_type>(__c.imag())) {}
47 
48  template <class _Xp, typename = std::enable_if_t<is_genfloat<_Xp>::value>>
50  operator std::complex<_Xp>() const {
51  return std::complex<_Xp>(static_cast<_Xp>(__re_), static_cast<_Xp>(__im_));
52  }
53 
55  return __re_;
56  }
58  return __im_;
59  }
60 
61  _SYCL_EXT_CPLX_INLINE_VISIBILITY void real(value_type __re) { __re_ = __re; }
62  _SYCL_EXT_CPLX_INLINE_VISIBILITY void imag(value_type __im) { __im_ = __im; }
63 
65  __re_ = __re;
66  __im_ = value_type();
67  return *this;
68  }
71  __c.__re_ += __re;
72  return __c;
73  }
76  __c.__re_ -= __re;
77  return __c;
78  }
81  __c.__re_ *= __re;
82  __c.__im_ *= __re;
83  return __c;
84  }
87  __c.__re_ /= __re;
88  __c.__im_ /= __re;
89  return __c;
90  }
91 
92  template <class _Xp>
94  __re_ = __c.real();
95  __im_ = __c.imag();
96  return *this;
97  }
98  template <class _Xp>
101  __x.__re_ += __y.real();
102  __x.__im_ += __y.imag();
103  return __x;
104  }
105  template <class _Xp>
108  __x.__re_ -= __y.real();
109  __x.__im_ -= __y.imag();
110  return __x;
111  }
112  template <class _Xp>
115  __x = __x * complex(__y.real(), __y.imag());
116  return __x;
117  }
118  template <class _Xp>
121  __x = __x / complex(__y.real(), __y.imag());
122  return __x;
123  }
124 
127  complex<value_type> __t(__x);
128  __t += __y;
129  return __t;
130  }
133  complex<value_type> __t(__x);
134  __t += __y;
135  return __t;
136  }
139  complex<value_type> __t(__y);
140  __t += __x;
141  return __t;
142  }
145  return __x;
146  }
147 
150  complex<value_type> __t(__x);
151  __t -= __y;
152  return __t;
153  }
156  complex<value_type> __t(__x);
157  __t -= __y;
158  return __t;
159  }
162  complex<value_type> __t(-__y);
163  __t += __x;
164  return __t;
165  }
168  return complex<value_type>(-__x.__re_, -__x.__im_);
169  }
170 
173  value_type __a = __z.__re_;
174  value_type __b = __z.__im_;
175  value_type __c = __w.__re_;
176  value_type __d = __w.__im_;
177  value_type __ac = __a * __c;
178  value_type __bd = __b * __d;
179  value_type __ad = __a * __d;
180  value_type __bc = __b * __c;
181  value_type __x = __ac - __bd;
182  value_type __y = __ad + __bc;
183  if (sycl::isnan(__x) && sycl::isnan(__y)) {
184  bool __recalc = false;
185  if (sycl::isinf(__a) || sycl::isinf(__b)) {
186  __a = sycl::copysign(sycl::isinf(__a) ? value_type(1) : value_type(0),
187  __a);
188  __b = sycl::copysign(sycl::isinf(__b) ? value_type(1) : value_type(0),
189  __b);
190  if (sycl::isnan(__c))
191  __c = sycl::copysign(value_type(0), __c);
192  if (sycl::isnan(__d))
193  __d = sycl::copysign(value_type(0), __d);
194  __recalc = true;
195  }
196  if (sycl::isinf(__c) || sycl::isinf(__d)) {
197  __c = sycl::copysign(sycl::isinf(__c) ? value_type(1) : value_type(0),
198  __c);
199  __d = sycl::copysign(sycl::isinf(__d) ? value_type(1) : value_type(0),
200  __d);
201  if (sycl::isnan(__a))
202  __a = sycl::copysign(value_type(0), __a);
203  if (sycl::isnan(__b))
204  __b = sycl::copysign(value_type(0), __b);
205  __recalc = true;
206  }
207  if (!__recalc && (sycl::isinf(__ac) || sycl::isinf(__bd) ||
208  sycl::isinf(__ad) || sycl::isinf(__bc))) {
209  if (sycl::isnan(__a))
210  __a = sycl::copysign(value_type(0), __a);
211  if (sycl::isnan(__b))
212  __b = sycl::copysign(value_type(0), __b);
213  if (sycl::isnan(__c))
214  __c = sycl::copysign(value_type(0), __c);
215  if (sycl::isnan(__d))
216  __d = sycl::copysign(value_type(0), __d);
217  __recalc = true;
218  }
219  if (__recalc) {
220  __x = value_type(INFINITY) * (__a * __c - __b * __d);
221  __y = value_type(INFINITY) * (__a * __d + __b * __c);
222  }
223  }
224  return complex<value_type>(__x, __y);
225  }
228  complex<value_type> __t(__x);
229  __t *= __y;
230  return __t;
231  }
234  complex<value_type> __t(__y);
235  __t *= __x;
236  return __t;
237  }
238 
241  int __ilogbw = 0;
242  value_type __a = __z.__re_;
243  value_type __b = __z.__im_;
244  value_type __c = __w.__re_;
245  value_type __d = __w.__im_;
246  value_type __logbw =
247  sycl::logb(sycl::fmax(sycl::fabs(__c), sycl::fabs(__d)));
248  if (sycl::isfinite(__logbw)) {
249  __ilogbw = static_cast<int>(__logbw);
250  __c = sycl::ldexp(__c, -__ilogbw);
251  __d = sycl::ldexp(__d, -__ilogbw);
252  }
253  value_type __denom = __c * __c + __d * __d;
254  value_type __x = sycl::ldexp((__a * __c + __b * __d) / __denom, -__ilogbw);
255  value_type __y = sycl::ldexp((__b * __c - __a * __d) / __denom, -__ilogbw);
256  if (sycl::isnan(__x) && sycl::isnan(__y)) {
257  if ((__denom == value_type(0)) &&
258  (!sycl::isnan(__a) || !sycl::isnan(__b))) {
259  __x = sycl::copysign(value_type(INFINITY), __c) * __a;
260  __y = sycl::copysign(value_type(INFINITY), __c) * __b;
261  } else if ((sycl::isinf(__a) || sycl::isinf(__b)) &&
262  sycl::isfinite(__c) && sycl::isfinite(__d)) {
263  __a = sycl::copysign(sycl::isinf(__a) ? value_type(1) : value_type(0),
264  __a);
265  __b = sycl::copysign(sycl::isinf(__b) ? value_type(1) : value_type(0),
266  __b);
267  __x = value_type(INFINITY) * (__a * __c + __b * __d);
268  __y = value_type(INFINITY) * (__b * __c - __a * __d);
269  } else if (sycl::isinf(__logbw) && __logbw > value_type(0) &&
270  sycl::isfinite(__a) && sycl::isfinite(__b)) {
271  __c = sycl::copysign(sycl::isinf(__c) ? value_type(1) : value_type(0),
272  __c);
273  __d = sycl::copysign(sycl::isinf(__d) ? value_type(1) : value_type(0),
274  __d);
275  __x = value_type(0) * (__a * __c + __b * __d);
276  __y = value_type(0) * (__b * __c - __a * __d);
277  }
278  }
279  return complex<value_type>(__x, __y);
280  }
283  return complex<value_type>(__x.__re_ / __y, __x.__im_ / __y);
284  }
287  complex<value_type> __t(__x);
288  __t /= __y;
289  return __t;
290  }
291 
292  _SYCL_EXT_CPLX_INLINE_VISIBILITY friend constexpr bool
294  return __x.__re_ == __y.__re_ && __x.__im_ == __y.__im_;
295  }
296  _SYCL_EXT_CPLX_INLINE_VISIBILITY friend constexpr bool
298  return __x.__re_ == __y && __x.__im_ == 0;
299  }
300  _SYCL_EXT_CPLX_INLINE_VISIBILITY friend constexpr bool
302  return __x == __y.__re_ && 0 == __y.__im_;
303  }
304 
305  _SYCL_EXT_CPLX_INLINE_VISIBILITY friend constexpr bool
307  return !(__x == __y);
308  }
309  _SYCL_EXT_CPLX_INLINE_VISIBILITY friend constexpr bool
311  return !(__x == __y);
312  }
313  _SYCL_EXT_CPLX_INLINE_VISIBILITY friend constexpr bool
315  return !(__x == __y);
316  }
317 
318  template <class _CharT, class _Traits>
319  _SYCL_EXT_CPLX_INLINE_VISIBILITY friend std::basic_istream<_CharT, _Traits> &
320  operator>>(std::basic_istream<_CharT, _Traits> &__is,
321  complex<value_type> &__x) {
322  if (__is.good()) {
323  ws(__is);
324  if (__is.peek() == _CharT('(')) {
325  __is.get();
326  value_type __r;
327  __is >> __r;
328  if (!__is.fail()) {
329  ws(__is);
330  _CharT __c = __is.peek();
331  if (__c == _CharT(',')) {
332  __is.get();
333  value_type __i;
334  __is >> __i;
335  if (!__is.fail()) {
336  ws(__is);
337  __c = __is.peek();
338  if (__c == _CharT(')')) {
339  __is.get();
340  __x = complex<value_type>(__r, __i);
341  } else
342  __is.setstate(__is.failbit);
343  } else
344  __is.setstate(__is.failbit);
345  } else if (__c == _CharT(')')) {
346  __is.get();
347  __x = complex<value_type>(__r, value_type(0));
348  } else
349  __is.setstate(__is.failbit);
350  } else
351  __is.setstate(__is.failbit);
352  } else {
353  value_type __r;
354  __is >> __r;
355  if (!__is.fail())
356  __x = complex<value_type>(__r, value_type(0));
357  else
358  __is.setstate(__is.failbit);
359  }
360  } else
361  __is.setstate(__is.failbit);
362  return __is;
363  }
364 
365  template <class _CharT, class _Traits>
366  _SYCL_EXT_CPLX_INLINE_VISIBILITY friend std::basic_ostream<_CharT, _Traits> &
367  operator<<(std::basic_ostream<_CharT, _Traits> &__os,
368  const complex<value_type> &__x) {
369  std::basic_ostringstream<_CharT, _Traits> __s;
370  __s.flags(__os.flags());
371  __s.imbue(__os.getloc());
372  __s.precision(__os.precision());
373  __s << '(' << __x.__re_ << ',' << __x.__im_ << ')';
374  return __os << __s.str();
375  }
376 
377  _SYCL_EXT_CPLX_INLINE_VISIBILITY friend const sycl::stream &
378  operator<<(const sycl::stream &__ss, const complex<value_type> &_x) {
379  return __ss << "(" << _x.__re_ << "," << _x.__im_ << ")";
380  }
381 };
382 
383 } // namespace experimental
384 } // namespace oneapi
385 } // namespace ext
386 
387 } // namespace _V1
388 } // namespace sycl
_SYCL_EXT_CPLX_INLINE_VISIBILITY friend complex< value_type > operator*(value_type __x, const complex< value_type > &__y)
Definition: complex.hpp:233
_SYCL_EXT_CPLX_INLINE_VISIBILITY friend complex & operator+=(complex< value_type > &__c, value_type __re)
Definition: complex.hpp:70
_SYCL_EXT_CPLX_INLINE_VISIBILITY friend complex & operator*=(complex< value_type > &__x, const complex< _Xp > &__y)
Definition: complex.hpp:114
_SYCL_EXT_CPLX_INLINE_VISIBILITY constexpr friend bool operator==(const complex< value_type > &__x, const complex< value_type > &__y)
Definition: complex.hpp:293
_SYCL_EXT_CPLX_INLINE_VISIBILITY friend complex< value_type > operator*(const complex< value_type > &__z, const complex< value_type > &__w)
Definition: complex.hpp:172
_SYCL_EXT_CPLX_INLINE_VISIBILITY friend complex< value_type > operator-(const complex< value_type > &__x)
Definition: complex.hpp:167
_SYCL_EXT_CPLX_INLINE_VISIBILITY friend complex & operator/=(complex< value_type > &__x, const complex< _Xp > &__y)
Definition: complex.hpp:120
constexpr _SYCL_EXT_CPLX_INLINE_VISIBILITY complex(value_type __re=value_type(), value_type __im=value_type())
Definition: complex.hpp:34
_SYCL_EXT_CPLX_INLINE_VISIBILITY constexpr friend bool operator==(const complex< value_type > &__x, value_type __y)
Definition: complex.hpp:297
_SYCL_EXT_CPLX_INLINE_VISIBILITY complex & operator=(const complex< _Xp > &__c)
Definition: complex.hpp:93
_SYCL_EXT_CPLX_INLINE_VISIBILITY friend complex & operator*=(complex< value_type > &__c, value_type __re)
Definition: complex.hpp:80
_SYCL_EXT_CPLX_INLINE_VISIBILITY constexpr friend bool operator!=(value_type __x, const complex< value_type > &__y)
Definition: complex.hpp:314
_SYCL_EXT_CPLX_INLINE_VISIBILITY friend complex< value_type > operator/(value_type __x, const complex< value_type > &__y)
Definition: complex.hpp:286
_SYCL_EXT_CPLX_INLINE_VISIBILITY friend complex< value_type > operator+(const complex< value_type > &__x, value_type __y)
Definition: complex.hpp:132
_SYCL_EXT_CPLX_INLINE_VISIBILITY friend complex< value_type > operator*(const complex< value_type > &__x, value_type __y)
Definition: complex.hpp:227
_SYCL_EXT_CPLX_INLINE_VISIBILITY friend complex & operator+=(complex< value_type > &__x, const complex< _Xp > &__y)
Definition: complex.hpp:100
constexpr _SYCL_EXT_CPLX_INLINE_VISIBILITY complex(const std::complex< _Xp > &__c)
Definition: complex.hpp:43
_SYCL_EXT_CPLX_INLINE_VISIBILITY friend complex< value_type > operator-(const complex< value_type > &__x, const complex< value_type > &__y)
Definition: complex.hpp:149
_SYCL_EXT_CPLX_INLINE_VISIBILITY friend complex< value_type > operator/(const complex< value_type > &__z, const complex< value_type > &__w)
Definition: complex.hpp:240
_SYCL_EXT_CPLX_INLINE_VISIBILITY friend complex & operator-=(complex< value_type > &__x, const complex< _Xp > &__y)
Definition: complex.hpp:107
_SYCL_EXT_CPLX_INLINE_VISIBILITY friend complex< value_type > operator/(const complex< value_type > &__x, value_type __y)
Definition: complex.hpp:282
_SYCL_EXT_CPLX_INLINE_VISIBILITY friend complex< value_type > operator+(const complex< value_type > &__x)
Definition: complex.hpp:144
_SYCL_EXT_CPLX_INLINE_VISIBILITY friend complex< value_type > operator-(value_type __x, const complex< value_type > &__y)
Definition: complex.hpp:161
_SYCL_EXT_CPLX_INLINE_VISIBILITY friend complex< value_type > operator+(const complex< value_type > &__x, const complex< value_type > &__y)
Definition: complex.hpp:126
_SYCL_EXT_CPLX_INLINE_VISIBILITY constexpr friend bool operator!=(const complex< value_type > &__x, value_type __y)
Definition: complex.hpp:310
constexpr _SYCL_EXT_CPLX_INLINE_VISIBILITY complex(const complex< _Xp > &__c)
Definition: complex.hpp:39
_SYCL_EXT_CPLX_INLINE_VISIBILITY friend complex< value_type > operator+(value_type __x, const complex< value_type > &__y)
Definition: complex.hpp:138
_SYCL_EXT_CPLX_INLINE_VISIBILITY friend std::basic_istream< _CharT, _Traits > & operator>>(std::basic_istream< _CharT, _Traits > &__is, complex< value_type > &__x)
Definition: complex.hpp:320
_SYCL_EXT_CPLX_INLINE_VISIBILITY constexpr friend bool operator!=(const complex< value_type > &__x, const complex< value_type > &__y)
Definition: complex.hpp:306
_SYCL_EXT_CPLX_INLINE_VISIBILITY friend complex< value_type > operator-(const complex< value_type > &__x, value_type __y)
Definition: complex.hpp:155
_SYCL_EXT_CPLX_INLINE_VISIBILITY friend complex & operator/=(complex< value_type > &__c, value_type __re)
Definition: complex.hpp:86
_SYCL_EXT_CPLX_INLINE_VISIBILITY friend complex & operator-=(complex< value_type > &__c, value_type __re)
Definition: complex.hpp:75
_SYCL_EXT_CPLX_INLINE_VISIBILITY constexpr friend bool operator==(value_type __x, const complex< value_type > &__y)
Definition: complex.hpp:301
#define _SYCL_EXT_CPLX_INLINE_VISIBILITY
DEFINES.
Definition: common.hpp:54
std::enable_if_t< std::is_same_v< Tp, float >, float > copysign(Tp x, Tp y)
Definition: math.hpp:77
__DPCPP_SYCL_EXTERNAL constexpr _SYCL_EXT_CPLX_INLINE_VISIBILITY std::enable_if_t< is_genfloat< _Tp >::value, _Tp > real(const complex< _Tp > &__c)
std::enable_if_t< std::is_same_v< T, bfloat16 >, bool > isnan(T x)
__DPCPP_SYCL_EXTERNAL constexpr _SYCL_EXT_CPLX_INLINE_VISIBILITY std::enable_if_t< is_genfloat< _Tp >::value, _Tp > imag(const complex< _Tp > &__c)
std::enable_if_t< detail::is_bf16_storage_type< T >::value, T > fabs(T x)
std::ostream & operator<<(std::ostream &Out, backend be)
const void value_type
Definition: multi_ptr.hpp:457
Definition: access.hpp:18