4#ifndef TETL_COMPLEX_COMPLEX_HPP
5#define TETL_COMPLEX_COMPLEX_HPP
7#include <etl/_cmath/atan2.hpp>
8#include <etl/_cmath/cos.hpp>
9#include <etl/_cmath/cosh.hpp>
10#include <etl/_cmath/hypot.hpp>
11#include <etl/_cmath/log.hpp>
12#include <etl/_cmath/sin.hpp>
13#include <etl/_cmath/sinh.hpp>
14#include <etl/_concepts/floating_point.hpp>
15#include <etl/_concepts/integral.hpp>
16#include <etl/_cstddef/size_t.hpp>
17#include <etl/_tuple/is_tuple_like.hpp>
18#include <etl/_tuple/tuple_element.hpp>
19#include <etl/_tuple/tuple_size.hpp>
20#include <etl/_type_traits/integral_constant.hpp>
21#include <etl/_utility/move.hpp>
35 constexpr complex(T
const& re = T(), T
const& im = T());
46 constexpr auto real(T val) ->
void;
49 constexpr auto imag(T val) ->
void;
65 template <size_t I,
typename X>
66 friend constexpr auto get(
complex<X>&)
noexcept -> X&;
68 template <size_t I,
typename X>
69 friend constexpr auto get(
complex<X>&&)
noexcept -> X&&;
71 template <size_t I,
typename X>
72 friend constexpr auto get(
complex<X>
const&)
noexcept -> X
const&;
74 template <size_t I,
typename X>
75 friend constexpr auto get(
complex<X>
const&&)
noexcept -> X
const&&;
79 return lhs.real() == rhs.real()
and lhs.imag() == rhs.imag();
84 return lhs.real() == rhs
and lhs.imag() == T{};
93inline constexpr auto is_tuple_like<etl::complex<T>> =
true;
98template <size_t I,
typename T>
100 static_assert(I < 2,
"Index out of range for etl::complex");
104template <size_t I,
typename X>
107 static_assert(I < 2,
"Index out of range for etl::complex");
108 if constexpr (I == 0) {
115template <size_t I,
typename X>
118 static_assert(I < 2,
"Index out of range for etl::complex");
119 if constexpr (I == 0) {
120 return etl::move(z._real);
122 return etl::move(z._imag);
126template <size_t I,
typename X>
129 static_assert(I < 2,
"Index out of range for etl::complex");
130 if constexpr (I == 0) {
137template <size_t I,
typename X>
138constexpr auto get(
complex<X>
const&& z)
noexcept -> X
const&&
140 static_assert(I < 2,
"Index out of range for etl::complex");
141 if constexpr (I == 0) {
142 return etl::move(z._real);
144 return etl::move(z._imag);
158 : _real{
static_cast<T>(other.real())}
159 , _imag{
static_cast<T>(other.imag())}
170constexpr auto complex<T>::real(T
const val) ->
void
182constexpr auto complex<T>::imag(T
const val) ->
void
245 auto const r =
static_cast<T>((_real * val.real()) - (_imag * val.imag()));
246 _imag =
static_cast<T>(_real * val.imag() + _imag * val.real());
255 auto const norm = [](
auto const& c) {
256 auto const x = c.real();
257 auto const y = c.imag();
258 return static_cast<T>(x * x + y * y);
261 auto const r =
static_cast<T>(_real * val.real() + _imag * val.imag());
262 auto const n = norm(val);
263 _imag = (_imag * val.real() - _real * val.imag()) / n;
277 return {
static_cast<T>(-val.real()),
static_cast<T>(-val.imag())};
358 return {0.0L
, static_cast<
long double>(d)
};
363 return {0.0L
, static_cast<
long double>(d)
};
368 return {0.0
, static_cast<
double>(d)
};
373 return {0.0
, static_cast<
double>(d)
};
378 return {0.0F
, static_cast<
float>(d)
};
383 return {0.0F
, static_cast<
float>(d)
};
392 return hypot(z.real(), z.imag());
396[[nodiscard]]
constexpr auto arg(
complex<T>
const& z)
noexcept -> T
398 return etl::atan2(z.imag(), z.real());
401template <floating_point Float>
402[[nodiscard]]
constexpr auto arg(Float f)
noexcept ->
complex<Float>
407template <integral Integer>
408[[nodiscard]]
constexpr auto arg(Integer i)
noexcept ->
complex<
double>
416 return complex<T>(z.real(), -z.imag());
419template <floating_point Float>
420[[nodiscard]]
constexpr auto conj(Float f)
noexcept ->
complex<Float>
425template <integral Integer>
426[[nodiscard]]
constexpr auto conj(Integer i)
noexcept ->
complex<
double>
428 return complex<
double>(
static_cast<
double>(i));
434 auto const x = z.real();
435 auto const y = z.imag();
436 return {cos(x) * cosh(y), -sin(x) * sinh(y)};
442 auto const x = z.real();
443 auto const y = z.imag();
444 return {cosh(x) * cos(y), sinh(x) * sin(y)};
453template <floating_point Float>
454[[nodiscard]]
constexpr auto imag(Float )
noexcept -> Float
459template <integral Integer>
460[[nodiscard]]
constexpr auto imag(Integer )
noexcept ->
double
468 return {
etl::log(
etl::abs(z)),
etl::arg(z)};
474 return etl::log(z) /
etl::log(T(10));
478[[nodiscard]]
constexpr auto norm(
complex<T>
const& z)
noexcept -> T
480 auto const x = z.real();
481 auto const y = z.imag();
482 return x * x + y * y;
485template <floating_point Float>
486[[nodiscard]]
constexpr auto norm(Float f)
noexcept ->
complex<Float>
491template <integral Integer>
492[[nodiscard]]
constexpr auto norm(Integer i)
noexcept ->
complex<
double>
498[[nodiscard]]
constexpr auto polar(T
const& r, T
const& theta = T())
noexcept ->
etl::
complex<T>
509template <floating_point Float>
510[[nodiscard]]
constexpr auto real(Float f)
noexcept -> Float
515template <integral Integer>
516[[nodiscard]]
constexpr auto real(Integer i)
noexcept ->
double
518 return static_cast<
double>(i);
524 auto const x = z.real();
525 auto const y = z.imag();
527 etl::sin(x) *
etl::cosh(y),
528 etl::cos(x) *
etl::sinh(y),
535 auto const x = z.real();
536 auto const y = z.imag();
538 etl::sinh(x) *
etl::cos(y),
539 etl::cosh(x) *
etl::sin(y),
546 return etl::sin(z) /
etl::cos(z);
552 return etl::sinh(z) /
etl::cosh(z);
Definition complex.hpp:354
constexpr auto operator""_i(unsigned long long d) -> complex< double >
Definition complex.hpp:371
constexpr auto operator""_il(unsigned long long d) -> complex< long double >
Definition complex.hpp:361
constexpr auto operator""_if(long double d) -> complex< float >
Definition complex.hpp:376
constexpr auto operator""_il(long double d) -> complex< long double >
Definition complex.hpp:356
constexpr auto operator""_if(unsigned long long d) -> complex< float >
Definition complex.hpp:381
constexpr auto operator""_i(long double d) -> complex< double >
Definition complex.hpp:366
Definition adjacent_find.hpp:9
constexpr auto get(complex< X > const &z) noexcept -> X const &
Definition complex.hpp:127
constexpr auto log(complex< T > const &z) noexcept -> complex< T >
Definition complex.hpp:466
constexpr auto imag(Integer) noexcept -> double
Definition complex.hpp:460
constexpr auto arg(complex< T > const &z) noexcept -> T
Definition complex.hpp:396
constexpr auto arg(Float f) noexcept -> complex< Float >
Definition complex.hpp:402
constexpr auto sinh(complex< T > const &z) -> complex< T >
Definition complex.hpp:533
constexpr auto operator+(T const &lhs, complex< T > const &rhs) -> complex< T >
Definition complex.hpp:293
constexpr auto real(Integer i) noexcept -> double
Definition complex.hpp:516
constexpr auto operator-(complex< T > const &lhs, complex< T > const &rhs) -> complex< T >
Definition complex.hpp:299
constexpr auto tan(complex< T > const &z) -> complex< T >
Definition complex.hpp:544
constexpr auto get(complex< X > &z) noexcept -> X &
Definition complex.hpp:105
constexpr auto polar(T const &r, T const &theta=T()) noexcept -> etl::complex< T >
Definition complex.hpp:498
constexpr auto norm(complex< T > const &z) noexcept -> T
Definition complex.hpp:478
constexpr auto real(complex< T > const &z) noexcept(noexcept(z.real())) -> T
Definition complex.hpp:504
constexpr auto imag(Float) noexcept -> Float
Definition complex.hpp:454
constexpr auto operator+(complex< T > const &lhs, complex< T > const &rhs) -> complex< T >
Definition complex.hpp:281
constexpr auto sin(complex< T > const &z) -> complex< T >
Definition complex.hpp:522
constexpr auto norm(Integer i) noexcept -> complex< double >
Definition complex.hpp:492
constexpr auto operator-(complex< T > const &val) -> complex< T >
Definition complex.hpp:275
constexpr auto operator+(complex< T > const &val) -> complex< T >
Definition complex.hpp:269
constexpr auto operator/(T const &lhs, complex< T > const &rhs) -> complex< T >
Definition complex.hpp:347
constexpr auto real(Float f) noexcept -> Float
Definition complex.hpp:510
constexpr auto get(complex< X > const &&z) noexcept -> X const &&
Definition complex.hpp:138
constexpr auto operator-(T const &lhs, complex< T > const &rhs) -> complex< T >
Definition complex.hpp:311
constexpr auto imag(complex< T > const &z) noexcept(noexcept(z.imag())) -> T
Definition complex.hpp:448
constexpr auto operator/(complex< T > const &lhs, T const &rhs) -> complex< T >
Definition complex.hpp:341
constexpr auto abs(complex< T > const &z) -> T
Definition complex.hpp:390
constexpr auto operator/(complex< T > const &lhs, complex< T > const &rhs) -> complex< T >
Definition complex.hpp:335
constexpr auto cosh(complex< T > const &z) -> complex< T >
Definition complex.hpp:440
constexpr auto conj(Integer i) noexcept -> complex< double >
Definition complex.hpp:426
constexpr auto tanh(complex< T > const &z) -> complex< T >
Definition complex.hpp:550
constexpr auto cos(complex< T > const &z) -> complex< T >
Definition complex.hpp:432
constexpr auto conj(complex< T > const &z) noexcept -> complex< T >
Definition complex.hpp:414
constexpr auto operator*(T const &lhs, complex< T > const &rhs) -> complex< T >
Definition complex.hpp:329
constexpr auto norm(Float f) noexcept -> complex< Float >
Definition complex.hpp:486
constexpr auto conj(Float f) noexcept -> complex< Float >
Definition complex.hpp:420
constexpr auto operator*(complex< T > const &lhs, complex< T > const &rhs) -> complex< T >
Definition complex.hpp:317
constexpr auto log10(complex< T > const &z) noexcept -> complex< T >
Definition complex.hpp:472
constexpr auto arg(Integer i) noexcept -> complex< double >
Definition complex.hpp:408
constexpr auto get(complex< X > &&z) noexcept -> X &&
Definition complex.hpp:116
constexpr auto operator-(complex< T > const &lhs, T const &rhs) -> complex< T >
Definition complex.hpp:305
constexpr auto operator*(complex< T > const &lhs, T const &rhs) -> complex< T >
Definition complex.hpp:323
constexpr auto operator+(complex< T > const &lhs, T const &rhs) -> complex< T >
Definition complex.hpp:287
A complex number.
Definition complex.hpp:32
explicit(sizeof(X) > sizeof(T)) const expr complex(complex< X > const &other)
constexpr auto operator+=(complex< X > const &val) -> complex< T > &
Definition complex.hpp:225
constexpr auto operator*=(complex< X > const &val) -> complex< T > &
Definition complex.hpp:243
constexpr auto imag(T val) -> void
Definition complex.hpp:182
constexpr auto operator/=(T const &val) -> complex< T > &
Definition complex.hpp:217
constexpr auto operator/=(complex< X > const &val) -> complex< T > &
Definition complex.hpp:253
constexpr auto operator-=(T const &val) -> complex< T > &
Definition complex.hpp:203
constexpr auto imag() const -> T
Definition complex.hpp:176
constexpr complex(T const &re=T(), T const &im=T())
Definition complex.hpp:149
friend constexpr auto get(complex< X > &&) noexcept -> X &&
Definition complex.hpp:116
constexpr auto real(T val) -> void
Definition complex.hpp:170
friend constexpr auto operator==(complex const &lhs, T const &rhs) -> bool
Definition complex.hpp:82
friend constexpr auto get(complex< X > &) noexcept -> X &
Definition complex.hpp:105
constexpr auto operator=(complex< X > const &other) -> complex< T > &
friend constexpr auto operator==(complex const &lhs, complex const &rhs) -> bool
Definition complex.hpp:77
constexpr auto operator=(T const &val) -> complex< T > &
Definition complex.hpp:188
constexpr auto operator+=(T const &val) -> complex< T > &
Definition complex.hpp:196
friend constexpr auto get(complex< X > const &) noexcept -> X const &
Definition complex.hpp:127
constexpr auto real() const -> T
Definition complex.hpp:164
constexpr auto operator*=(T const &val) -> complex< T > &
Definition complex.hpp:210
friend constexpr auto get(complex< X > const &&) noexcept -> X const &&
Definition complex.hpp:138
constexpr auto operator-=(complex< X > const &val) -> complex< T > &
Definition complex.hpp:234
constexpr complex(complex const &other)=default
constexpr auto operator=(complex const &other) -> complex &=default
Definition integral_constant.hpp:11