Quadruple-precision complex numbers

Contents

Quadruple-precision complex numbers#

Note

The functionality described in this section is available only if mp++ was configured with the MPPP_WITH_QUADMATH option enabled (see the installation instructions).

Added in version 0.20.

#include <mp++/complex128.hpp>

The complex128 class#

class mppp::complex128#

Quadruple-precision complex floating-point class.

This class represents complex numbers as pairs of quadruple-precision IEEE 754 floating-point values. The class is a thin wrapper around the __complex128 type and the quadmath library, available on GCC, Clang and the Intel compiler on most modern platforms, on top of which it provides the following additions:

  • interoperability with other mp++ classes,

  • consistent behaviour with respect to the conventions followed elsewhere in mp++ (e.g., values are default-initialised to zero rather than to indefinite values, conversions must be explicit, etc.),

  • enhanced compile-time (constexpr) capabilities,

  • a generic C++ API.

Most of the functionality is exposed via plain functions, with the general convention that the functions are named after the corresponding quadmath functions minus the leading c prefix and the trailing q suffix. For instance, the quadmath code

__complex128 a{1, 2};
auto b = ::csinq(a);

that computes the sine of \(1+2\imath\) in quadruple precision, storing the result in b, becomes in mp++

complex128 a{1, 2};
auto b = sin(a);

where the sin() function is resolved via argument-dependent lookup.

Various overloaded operators are provided.

The complex128 class is a literal type, and, whenever possible, operations involving complex128 are marked as constexpr. Some functions which are not constexpr in the quadmath library have been reimplemented as constexpr functions via compiler builtins.

A tutorial showcasing various features of complex128 is available.

__complex128 m_value#

The internal value.

This class member gives direct access to the __complex128 instance stored inside a complex128.

using value_type = real128#

Alias to mimick the interface of std::complex.

constexpr complex128()#

Default constructor.

The default constructor will set this to zero.

complex128(const complex128&) = default#
complex128(complex128&&) = default#

complex128 is trivially copy and move constructible.

explicit constexpr complex128(const __complex128 &c)#

Constructor from a __complex128.

This constructor will initialise the internal __complex128 value to c.

Parameters:

c – the __complex128 that will be assigned to the internal value.

template<complex128_interoperable T>
constexpr complex128(const T &x)#

Constructor from real-valued interoperable types.

Note

This constructor is explicit if T is real.

This constructor will initialise the internal value to x. Depending on the value and type of x, this may not be exactly equal to x after initialisation (e.g., if x is a very large integer).

Parameters:

x – the value that will be used for the initialisation.

Throws:

unspecified – any exception raised by casting T to real128.

template<complex128_interoperable T, complex128_interoperable U>
explicit constexpr complex128(const T &x, const U &y)#

Constructor from real and imaginary parts.

This constructor will initialise the internal value to \(x+\imath y\). Depending on the value and type of x and y, this may not be exactly equal to \(x+\imath y\) after initialisation (e.g., if x and y are very large integer values).

Parameters:
  • x – the real part of the value that will be used for the initialisation.

  • y – the imaginary part of the value that will be used for the initialisation.

Throws:

unspecified – any exception raised by casting T to real128.

template<real128_cpp_complex T>
constexpr complex128(const T &c)#

Note

This constructor is constexpr only if at least C++14 is being used.

Constructor from std::complex.

Parameters:

x – the complex value that will be used for the initialisation.

template<string_type T>
explicit complex128(const T &s)#

Constructor from string.

This constructor will initialise this from the string_type s. The accepted string formats are:

  • a single floating-point number (e.g., 1.234),

  • a single floating-point number surrounded by round brackets (e.g., (1.234)),

  • a pair of floating-point numbers, surrounded by round brackets and separated by a comma (e.g., (1.234, 4.567)).

The allowed floating-point representations (for both the real and imaginary part) are described in the documentation of the constructor from string of real128.

Parameters:

s – the string that will be used to initialise this.

Throws:
  • std::invalid_argument – if s does not represent a valid quadruple-precision complex floating-point value.

  • unspecified – any exception thrown by memory errors in standard containers.

explicit complex128(const char *begin, const char *end)#

Constructor from a range of characters.

This constructor will initialise this from the content of the input half-open range, which is interpreted as the string representation of a complex value.

Internally, the constructor will copy the content of the range to a local buffer, add a string terminator, and invoke the constructor from string.

Parameters:
  • begin – the begin of the input range.

  • end – the end of the input range.

Throws:

unspecified – any exception thrown by the constructor from string or by memory errors in standard containers.

complex128 &operator=(const complex128&) = default#
complex128 &operator=(complex128&&) = default#

complex128 is trivially copy and move assignable.

constexpr complex128 &operator=(const __complex128 &c)#

Note

This operator is constexpr only if at least C++14 is being used.

Assignment operator from __complex128.

Parameters:

c – the assignment argument.

Returns:

a reference to this.

template<complex128_interoperable T>
constexpr complex128 &operator=(const T &x)#

Note

This operator is constexpr only if at least C++14 is being used.

Assignment from interoperable types.

Parameters:

x – the assignment argument.

Returns:

a reference to this.

Throws:

unspecified – any exception thrown by the construction of a complex128 from x.

template<real128_cpp_complex T>
constexpr complex128 &operator=(const T &c)#

Note

This operator is constexpr only if at least C++14 is being used.

Assignment from complex C++ types.

Parameters:

c – the assignment argument.

Returns:

a reference to this.

complex128 &operator=(const complex &c)#

Note

This operator is available only if mp++ was configured with the MPPP_WITH_MPC option enabled.

Added in version 0.20.

Assignment operator from complex.

This operator is formally equivalent to converting c to complex128 and then move-assigning the result to this.

Parameters:

c – the assignment argument.

Returns:

a reference to this.

template<string_type T>
complex128 &operator=(const T &s)#

Assignment from string.

The accepted string formats are the same explained in the constructor from string.

Parameters:

s – the assignment argument.

Returns:

a reference to this.

Throws:

unspecified – any exception thrown by the constructor from string.

constexpr real128 real() const#
constexpr real128 imag() const#

Getters for the real and imaginary parts.

Returns:

a copy of the real or imaginary part of this.

constexpr complex128 &set_real(const real128 &x)#
constexpr complex128 &set_imag(const real128 &x)#

Note

These functions are constexpr only if at least C++14 is being used.

Setters for the real and imaginary parts.

Parameters:

x – the desired value for the real or imaginary part of this.

Returns:

a reference to this.

explicit constexpr operator __complex128() const#

Conversion to __complex128.

Returns:

a copy of m_value.

template<complex128_interoperable T>
explicit constexpr operator T() const#

Conversion to real-valued interoperable types.

Conversion to non-real types uses the cast operator of real128. Conversion to real invokes the real constructor from real128, and thus produces a return value with a precision of 113 bits.

Returns:

this converted to the type T.

Throws:
  • std::domain_error – if the imaginary part of this is not zero.

  • unspecified – any exception thrown by the conversion operator of real128.

template<real128_cpp_complex T>
explicit constexpr operator T() const#

Note

This operator is constexpr only if at least C++14 is being used.

Conversion to complex C++ types.

Returns:

this converted to the type T.

template<complex128_interoperable T>
constexpr bool get(T &rop) const#
template<real128_cpp_complex T>
constexpr bool get(T &rop) const#

Note

The first overload is constexpr only if at least C++14 is being used. The second overload is constexpr only if at least C++20 is being used.

Conversion member functions to interoperable and complex C++ types.

These member functions, similarly to the conversion operator, will convert this to T, storing the result of the conversion into rop. Differently from the conversion operator, these functions do not raise any exception: if the conversion is successful, the functions will return true, otherwise the functions will return false. If the conversion fails, rop will not be altered.

The conversion can fail only in the first overload, if either:

  • the imaginary part of this is not zero, or

  • the conversion of the real part of this to T (where T is neither real128 nor real) via mppp::real128::get() returns false.

Parameters:

rop – the variable which will store the result of the conversion.

Returns:

true if the conversion succeeds, false otherwise.

std::string to_string() const#

Convert to string.

This member function will convert this to a decimal string representation in scientific format. The number of significant digits in the output (36) guarantees that a complex128 constructed from the returned string will have a value identical to the value of this.

The string format consists of the real and imaginary parts of this (as returned by mppp::real128::to_string()), separated by a comma and enclosed by round brackets.

Returns:

a decimal string representation of this.

Throws:

unspecified – any exception thrown by mppp::real128::to_string() or by the public interface of output streams.

complex128 &abs()#
complex128 &arg()#
constexpr complex128 &conj()#
complex128 &proj()#

Note

conj() is constexpr only if at least C++14 is being used.

In-place absolute value, argument, complex conjugate and projection into Riemann sphere.

These member functions will set this to, respectively:

  • \(\left| z \right|\),

  • \(\arg z\),

  • \(\overline{z}\),

  • the projection of \(z\) into Riemann sphere,

where \(z\) is the current value of this.

Returns:

a reference to this.

complex128 &sqrt()#

Square root.

This member function will set this to \(\sqrt{z}\), where \(z\) is the current value of this.

Returns:

a reference to this.

complex128 &sin()#
complex128 &cos()#
complex128 &tan()#

In-place trigonometric functions.

These member functions will set this to, respectively:

  • \(\sin z\),

  • \(\cos z\),

  • \(\tan z\),

where \(z\) is the current value of this.

Returns:

a reference to this.

complex128 &asin()#
complex128 &acos()#
complex128 &atan()#

In-place inverse trigonometric functions.

These member functions will set this to, respectively:

  • \(\arcsin z\),

  • \(\arccos z\),

  • \(\arctan z\),

where \(z\) is the current value of this.

Returns:

a reference to this.

complex128 &sinh()#
complex128 &cosh()#
complex128 &tanh()#

In-place hyperbolic functions.

These member functions will set this to, respectively:

  • \(\sinh z\),

  • \(\cosh z\),

  • \(\tanh z\),

where \(z\) is the current value of this.

Returns:

a reference to this.

complex128 &asinh()#
complex128 &acosh()#
complex128 &atanh()#

In-place inverse hyperbolic functions.

These member functions will set this to, respectively:

  • \(\operatorname{arcsinh} z\),

  • \(\operatorname{arccosh} z\),

  • \(\operatorname{arctanh} z\),

where \(z\) is the current value of this.

Returns:

a reference to this.

complex128 &exp()#
complex128 &log()#
complex128 &log10()#

Exponentials and logarithms.

These member functions will set this to, respectively:

  • \(e^z\),

  • \(\log z\),

  • \(\log_{10} z\),

where \(z\) is the current value of this.

Returns:

a reference to this.

Types#

type __complex128#
using mppp::cplex128 = __complex128#

__complex128 is a quadruple-precision complex floating-point type available on GCC, Clang and the Intel compiler. This is the type wrapped by the complex128 class.

Because __complex128 is defined in the <quadmath.h> header, mp++ also provides an alias for __complex128 called mppp::cplex128, so that users of the library need not to include <quadmath.h> (which can be problematic on non-GCC compilers).

Concepts#

template<typename T>
concept mppp::complex128_interoperable#

This concept is satisfied by real-valued types that can interoperate with complex128. Specifically, this concept is satisfied if either:

template<typename T, typename U>
concept mppp::complex128_op_types#

This concept is satisfied if the types T and U are suitable for use in the generic binary functions and operators involving complex128 and other types. Specifically, the concept will be true if either:

template<typename T, typename U>
concept mppp::complex128_cmp_op_types#

This concept is satisfied if the types T and U are suitable for use in the generic comparison operators involving complex128 and other types. Specifically, the concept will be true if either:

Functions#

Real/imaginary parts#

constexpr mppp::real128 mppp::creal(const mppp::complex128 &c)#
constexpr mppp::real128 mppp::cimag(const mppp::complex128 &c)#

Getters for the real/imaginary part.

Parameters:

c – the input argument.

Returns:

the real/imaginary part of c.

constexpr mppp::complex128 &mppp::set_real(mppp::complex128 &c, const mppp::real128 &x)#
constexpr mppp::complex128 &mppp::set_imag(mppp::complex128 &c, const mppp::real128 &x)#

Note

These functions are constexpr only if at least C++14 is being used.

Setters for the real/imaginary part.

Parameters:
  • c – the complex128 whose real/imaginary part will be set.

  • x – the desired value for the real/imaginary part of c.

Returns:

a reference to c.

Conversion#

template<mppp::complex128_interoperable T>
constexpr bool mppp::get(T &rop, const mppp::complex128 &c)#
template<mppp::real128_cpp_complex T>
constexpr bool mppp::get(T &rop, const mppp::complex128 &c)#

Note

The first overload is constexpr only if at least C++14 is being used. The second overload is constexpr only if at least C++20 is being used.

Conversion functions to interoperable and complex C++ types.

These functions, similarly to the conversion operator of complex128, will convert c to T, storing the result of the conversion into rop. Differently from the conversion operator, these functions do not raise any exception: if the conversion is successful, the functions will return true, otherwise the functions will return false. If the conversion fails, rop will not be altered.

The conversion can fail only in the first overload, if either:

  • the imaginary part of c is not zero, or

  • the conversion of the real part of c to T (where T is neither real128 nor real) via mppp::real128::get() returns false.

Parameters:
  • rop – the variable which will store the result of the conversion.

  • c – the value that will be converted to T.

Returns:

true if the conversion succeeds, false otherwise.

Arithmetic#

mppp::real128 mppp::abs(const mppp::complex128 &z)#
mppp::complex128 mppp::arg(const mppp::complex128 &z)#
constexpr mppp::complex128 mppp::conj(const mppp::complex128 &z)#
mppp::complex128 mppp::proj(const mppp::complex128 &z)#

Absolute value, argument, complex conjugate and projection into Riemann sphere.

These functions will return, respectively:

  • \(\left| z \right|\),

  • \(\arg z\),

  • \(\overline{z}\),

  • the projection of \(z\) into Riemann sphere.

Parameters:

z – the input value.

Returns:

the result of the operation.

Roots#

mppp::complex128 mppp::sqrt(const mppp::complex128 &z)#

Square root.

Parameters:

z – the input value.

Returns:

\(\sqrt{z}\).

Exponentiation#

template<typename T, mppp::complex128_op_types<T> U>
mppp::complex128 mppp::pow(const T &x, const T &y)#

Exponentiation.

This function will return \(x^y\). The input arguments are converted to complex128 (if necessary) and the result is computed via the exponentiation function from the quadmath library.

Parameters:
  • x – the base.

  • y – the exponent.

Returns:

\(x^y\).

Throws:

unspecified – any exception raised by the conversion of x and/or y to complex128.

Trigonometry#

mppp::complex128 mppp::sin(const mppp::complex128 &z)#
mppp::complex128 mppp::cos(const mppp::complex128 &z)#
mppp::complex128 mppp::tan(const mppp::complex128 &z)#

Trigonometric functions.

These functions will return, respectively:

  • \(\sin z\),

  • \(\cos z\),

  • \(\tan z\).

Parameters:

z – the input value.

Returns:

the value of the trigonometric function.

mppp::complex128 mppp::asin(const mppp::complex128 &z)#
mppp::complex128 mppp::acos(const mppp::complex128 &z)#
mppp::complex128 mppp::atan(const mppp::complex128 &z)#

Inverse trigonometric functions.

These functions will return, respectively:

  • \(\arcsin z\),

  • \(\arccos z\),

  • \(\arctan z\).

Parameters:

z – the input value.

Returns:

the value of the inverse trigonometric function.

Hyperbolic functions#

mppp::complex128 mppp::sinh(const mppp::complex128 &z)#
mppp::complex128 mppp::cosh(const mppp::complex128 &z)#
mppp::complex128 mppp::tanh(const mppp::complex128 &z)#

Hyperbolic functions.

These functions will return, respectively:

  • \(\sinh z\),

  • \(\cosh z\),

  • \(\tanh z\).

Parameters:

z – the input value.

Returns:

the value of the hyperbolic function.

mppp::complex128 mppp::asinh(const mppp::complex128 &z)#
mppp::complex128 mppp::acosh(const mppp::complex128 &z)#
mppp::complex128 mppp::atanh(const mppp::complex128 &z)#

Inverse hyperbolic functions.

These functions will return, respectively:

  • \(\operatorname{arcsinh} z\),

  • \(\operatorname{arccosh} z\),

  • \(\operatorname{arctanh} z\).

Parameters:

z – the input value.

Returns:

the value of the inverse hyperbolic function.

Exponentials and logarithms#

mppp::complex128 mppp::exp(const mppp::complex128 &z)#
mppp::complex128 mppp::log(const mppp::complex128 &z)#
mppp::complex128 mppp::log10(const mppp::complex128 &z)#

Exponentials and logarithms.

These functions will return, respectively:

  • \(e^z\),

  • \(\log z\),

  • \(\log_{10} z\).

Parameters:

z – the input value.

Returns:

the value of the exponential or logarithm function.

Input/output#

std::ostream &mppp::operator<<(std::ostream &os, const mppp::complex128 &c)#

Output stream operator.

This function will direct to the output stream os the input complex128 c.

Parameters:
  • os – the target stream.

  • c – the input complex128.

Returns:

a reference to os.

Throws:
  • std::overflow_error – in case of (unlikely) overflow errors.

  • std::invalid_argument – if the quadmath printing primitive quadmath_snprintf() returns an error code.

  • unspecified – any exception raised by the public interface of std::ostream or by memory allocation errors.

Mathematical operators#

constexpr mppp::complex128 mppp::operator+(const mppp::complex128 &c)#
constexpr mppp::complex128 mppp::operator-(const mppp::complex128 &c)#

Identity and negation.

Parameters:

x – the argument.

Returns:

\(c\) and \(-c\) respectively.

constexpr mppp::complex128 &mppp::operator++(mppp::complex128 &c)#
constexpr mppp::complex128 &mppp::operator--(mppp::complex128 &c)#

Note

These operators are constexpr only if at least C++14 is being used.

Prefix increment and decrement.

Parameters:

c – the argument.

Returns:

a reference to c after it has been incremented/decremented by one.

constexpr mppp::complex128 mppp::operator++(mppp::complex128 &c, int)#
constexpr mppp::complex128 mppp::operator--(mppp::complex128 &c, int)#

Note

These operators are constexpr only if at least C++14 is being used.

Suffix increment and decrement.

Parameters:

c – the argument.

Returns:

a copy of c before the increment/decrement.

template<typename T, mppp::complex128_op_types<T> U>
constexpr mppp::complex128 mppp::operator+(const T &x, const U &y)#
template<typename T, mppp::complex128_op_types<T> U>
constexpr mppp::complex128 mppp::operator-(const T &x, const U &y)#
template<typename T, mppp::complex128_op_types<T> U>
constexpr mppp::complex128 mppp::operator*(const T &x, const U &y)#
template<typename T, mppp::complex128_op_types<T> U>
constexpr mppp::complex128 mppp::operator/(const T &x, const U &y)#

Binary arithmetic operators.

These operators will return, respectively:

  • \(x+y\),

  • \(x-y\),

  • \(x\times y\),

  • \(x / y\).

Parameters:
  • x – the first operand.

  • y – the second operand.

Returns:

the result of the binary operation.

Throws:

unspecified – any exception thrown by the conversion of x or y to real128 or complex128.

template<typename T, mppp::complex128_op_types<T> U>
constexpr T &mppp::operator+=(T &x, const U &y)#
template<typename T, mppp::complex128_op_types<T> U>
constexpr T &mppp::operator-=(T &x, const U &y)#
template<typename T, mppp::complex128_op_types<T> U>
constexpr T &mppp::operator*=(T &x, const U &y)#
template<typename T, mppp::complex128_op_types<T> U>
constexpr T &mppp::operator/=(T &x, const U &y)#

Note

These operators are constexpr only if at least C++14 is being used.

In-place arithmetic operators.

These operators will set x to, respectively:

  • \(x+y\),

  • \(x-y\),

  • \(x \times y\),

  • \(x / y\).

Parameters:
  • x – the first operand.

  • y – the second operand.

Returns:

a reference to x.

Throws:

unspecified – any exception thrown by the corresponding binary operator, or by the conversion of the result of the binary operation to T.

template<typename T, mppp::complex128_cmp_op_types<T> U>
constexpr bool mppp::operator==(const T &x, const U &y)#
template<typename T, mppp::complex128_cmp_op_types<T> U>
constexpr bool mppp::operator!=(const T &x, const U &y)#

Comparison operators.

These operators will return true if, respectively:

  • \(x = y\),

  • \(x \neq y\),

false otherwise.

Parameters:
  • x – the first operand.

  • y – the second operand.

Returns:

the result of the comparison.

Throws:

unspecified – any exception thrown by the comparison operators of real128.

User-defined literals#

template<char... Chars>
mppp::complex128 mppp::literals::operator""_icq()#

User-defined quadruple-precision imaginary literal.

This operator will return a complex128 with zero real part and imaginary part constructed from the input floating-point literal in decimal or hexadecimal format.

The operator is implemented on top of operator"" _rq().

Throws:

unspecified – any exception thrown by operator"" _rq().