Report a bug
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

# std.complex

This module contains the Complex type, which is used to represent complex numbers, along with related mathematical operations and functions.
Complex will eventually replace the built-in types cfloat, cdouble, creal, ifloat, idouble, and ireal.
Authors:
pure nothrow @nogc @safe auto `complex`(R)(const R `re`)
if (is(R : double));

pure nothrow @nogc @safe auto `complex`(R, I)(const R `re`, const I `im`)
if (is(R : double) && is(I : double));
Helper function that returns a complex number with the specified real and imaginary parts.
Parameters:
 R (template parameter) type of real part of complex number I (template parameter) type of imaginary part of complex number R `re` real part of complex number to be constructed I `im` (optional) imaginary part of complex number, 0 if omitted.
Returns:
Complex instance with real and imaginary parts set to the values provided as input. If neither `re` nor `im` are floating-point numbers, the return type will be Complex!double. Otherwise, the return type is deduced using std.traits.CommonType!(R, I).
Examples:
```auto a = complex(1.0);
static assert(is(typeof(a) == Complex!double));
writeln(a.re); // 1.0
writeln(a.im); // 0.0

auto b = complex(2.0L);
static assert(is(typeof(b) == Complex!real));
writeln(b.re); // 2.0L
writeln(b.im); // 0.0L

auto c = complex(1.0, 2.0);
static assert(is(typeof(c) == Complex!double));
writeln(c.re); // 1.0
writeln(c.im); // 2.0

auto d = complex(3.0, 4.0L);
static assert(is(typeof(d) == Complex!real));
writeln(d.re); // 3.0
writeln(d.im); // 4.0L

auto e = complex(1);
static assert(is(typeof(e) == Complex!double));
writeln(e.re); // 1
writeln(e.im); // 0

auto f = complex(1L, 2);
static assert(is(typeof(f) == Complex!double));
writeln(f.re); // 1L
writeln(f.im); // 2

auto g = complex(3, 4.0L);
static assert(is(typeof(g) == Complex!real));
writeln(g.re); // 3
writeln(g.im); // 4.0L
```
struct `Complex`(T) if (isFloatingPoint!T);
A complex number parametrised by a type T, which must be either float, double or real.
T `re`;
The real part of the number.
T `im`;
The imaginary part of the number.
const @safe string `toString`();

const void `toString`(Writer, Char)(scope Writer `w`, ref scope const FormatSpec!Char `formatSpec`)
if (isOutputRange!(Writer, const(Char)[]));
Converts the complex number to a string representation.
The second form of this function is usually not called directly; instead, it is used via std.string.format, as shown in the examples below. Supported format characters are 'e', 'f', 'g', 'a', and 's'.
Examples:
```auto c = complex(1.2, 3.4);

// Vanilla toString formatting:
writeln(c.toString()); // "1.2+3.4i"

// Formatting with std.string.format specs: the precision and width
// specifiers apply to both the real and imaginary parts of the
// complex number.
import std.format : format;
writeln(format("%.2f", c)); // "1.20+3.40i"
writeln(format("%4.1f", c)); // " 1.2+ 3.4i"
```
this(R : T)(Complex!R `z`);

this(Rx : T, Ry : T)(const Rx `x`, const Ry `y`);

this(R : T)(const R `r`);
Construct a complex number with the specified real and imaginary parts. In the case where a single argument is passed that is not complex, the imaginary part of the result will be zero.
auto `toNative`();
Returns a complex number instance that correponds in size and in ABI to the associated C compiler's _Complex type.
pure nothrow @nogc @safe T `abs`(T)(Complex!T `z`);
Parameters:
 Complex!T `z` A complex number.
Returns:
The absolute value (or modulus) of `z`.
Examples:
```static import core.math;
writeln(abs(complex(1.0))); // 1.0
writeln(abs(complex(0.0, 1.0))); // 1.0
writeln(abs(complex(1.0L, -2.0L))); // core.math.sqrt(5.0L)
```
pure nothrow @nogc @safe T `sqAbs`(T)(Complex!T `z`);

pure nothrow @nogc @safe T `sqAbs`(T)(const T `x`)
if (isFloatingPoint!T);
Parameters:
 Complex!T `z` A complex number. T `x` A real number.
Returns:
The squared modulus of `z`. For genericity, if called on a real number, returns its square.
Examples:
```import std.math.operations : isClose;
writeln(sqAbs(complex(0.0))); // 0.0
writeln(sqAbs(complex(1.0))); // 1.0
writeln(sqAbs(complex(0.0, 1.0))); // 1.0
assert(isClose(sqAbs(complex(1.0L, -2.0L)), 5.0L));
assert(isClose(sqAbs(complex(-3.0L, 1.0L)), 10.0L));
assert(isClose(sqAbs(complex(1.0f,-1.0f)), 2.0f));
```
pure nothrow @nogc @safe T `arg`(T)(Complex!T `z`);
Parameters:
 Complex!T `z` A complex number.
Returns:
The argument (or phase) of `z`.
Examples:
```import std.math.constants : PI_2, PI_4;
writeln(arg(complex(1.0))); // 0.0
writeln(arg(complex(0.0L, 1.0L))); // PI_2
writeln(arg(complex(1.0L, 1.0L))); // PI_4
```
pure nothrow @nogc @safe T `norm`(T)(Complex!T `z`);
Extracts the norm of a complex number.
Parameters:
 Complex!T `z` A complex number
Returns:
The squared magnitude of `z`.
Examples:
```import std.math.operations : isClose;
import std.math.constants : PI;
writeln(norm(complex(3.0, 4.0))); // 25.0
writeln(norm(fromPolar(5.0, 0.0))); // 25.0
assert(isClose(norm(fromPolar(5.0L, PI / 6)), 25.0L));
assert(isClose(norm(fromPolar(5.0L, 13 * PI / 6)), 25.0L));
```
pure nothrow @nogc @safe Complex!T `conj`(T)(Complex!T `z`);
Parameters:
 Complex!T `z` A complex number.
Returns:
The complex conjugate of `z`.
Examples:
```writeln(conj(complex(1.0))); // complex(1.0)
writeln(conj(complex(1.0, 2.0))); // complex(1.0, -2.0)
```
Complex!T `proj`(T)(Complex!T `z`);
Returns the projection of `z` onto the Riemann sphere.
Parameters:
 Complex!T `z` A complex number
Returns:
The projection of `z` onto the Riemann sphere.
Examples:
```writeln(proj(complex(1.0))); // complex(1.0)
writeln(proj(complex(double.infinity, 5.0))); // complex(double.infinity, 0.0)
writeln(proj(complex(5.0, -double.infinity))); // complex(double.infinity, -0.0)
```
pure nothrow @nogc @safe Complex!(CommonType!(T, U)) `fromPolar`(T, U)(const T `modulus`, const U `argument`);
Constructs a complex number given its absolute value and argument.
Parameters:
 T `modulus` The modulus U `argument` The argument
Returns:
The complex number with the given modulus and argument.
Examples:
```import core.math;
import std.math.operations : isClose;
import std.math.algebraic : sqrt;
import std.math.constants : PI_4;
auto z = fromPolar(core.math.sqrt(2.0L), PI_4);
assert(isClose(z.re, 1.0L));
assert(isClose(z.im, 1.0L));
```
pure nothrow @nogc @safe Complex!T `sin`(T)(Complex!T `z`);

pure nothrow @nogc @safe Complex!T `cos`(T)(Complex!T `z`);

pure nothrow @nogc @safe Complex!T `tan`(T)(Complex!T `z`);
Trigonometric functions on complex numbers.
Parameters:
 Complex!T `z` A complex number.
Returns:
The sine, cosine and tangent of `z`, respectively.
Examples:
```static import core.math;
writeln(sin(complex(0.0))); // 0.0
writeln(sin(complex(2.0, 0))); // core.math.sin(2.0)
```
Examples:
```static import core.math;
static import std.math;
writeln(cos(complex(0.0))); // 1.0
writeln(cos(complex(1.3, 0.0))); // core.math.cos(1.3)
writeln(cos(complex(0.0, 5.2))); // std.math.cosh(5.2)
```
Examples:
```static import std.math;

int ceqrel(T)(const Complex!T x, const Complex!T y) @safe pure nothrow @nogc
{
import std.math.operations : feqrel;
const r = feqrel(x.re, y.re);
const i = feqrel(x.im, y.im);
return r < i ? r : i;
}
assert(ceqrel(tan(complex(1.0, 0.0)), complex(std.math.tan(1.0), 0.0)) >= double.mant_dig - 2);
assert(ceqrel(tan(complex(0.0, 1.0)), complex(0.0, std.math.tanh(1.0))) >= double.mant_dig - 2);
```
pure nothrow @nogc @safe Complex!T `asin`(T)(Complex!T `z`);

pure nothrow @nogc @safe Complex!T `acos`(T)(Complex!T `z`);

pure nothrow @nogc @safe Complex!T `atan`(T)(Complex!T `z`);
Inverse trigonometric functions on complex numbers.
Parameters:
 Complex!T `z` A complex number.
Returns:
The arcsine, arccosine and arctangent of `z`, respectively.
Examples:
```import std.math.operations : isClose;
import std.math.constants : PI;
writeln(asin(complex(0.0))); // 0.0
assert(isClose(asin(complex(0.5L)), PI / 6));
```
Examples:
```import std.math.operations : isClose;
import std.math.constants : PI;
import std.math.trigonometry : std_math_acos = acos;
writeln(acos(complex(0.0))); // std_math_acos(0.0)
assert(isClose(acos(complex(0.5L)), PI / 3));
```
Examples:
```import std.math.operations : isClose;
import std.math.constants : PI;
writeln(atan(complex(0.0))); // 0.0
assert(isClose(atan(sqrt(complex(3.0L))), PI / 3));
assert(isClose(atan(sqrt(complex(3.0f))), float(PI) / 3));
```
pure nothrow @nogc @safe Complex!T `sinh`(T)(Complex!T `z`);

pure nothrow @nogc @safe Complex!T `cosh`(T)(Complex!T `z`);

pure nothrow @nogc @safe Complex!T `tanh`(T)(Complex!T `z`);
Hyperbolic trigonometric functions on complex numbers.
Parameters:
 Complex!T `z` A complex number.
Returns:
The hyperbolic sine, cosine and tangent of `z`, respectively.
Examples:
```static import std.math;
writeln(sinh(complex(0.0))); // 0.0
writeln(sinh(complex(1.0L))); // std.math.sinh(1.0L)
writeln(sinh(complex(1.0f))); // std.math.sinh(1.0f)
```
Examples:
```static import std.math;
writeln(cosh(complex(0.0))); // 1.0
writeln(cosh(complex(1.0L))); // std.math.cosh(1.0L)
writeln(cosh(complex(1.0f))); // std.math.cosh(1.0f)
```
Examples:
```import std.math.operations : isClose;
import std.math.trigonometry : std_math_tanh = tanh;
writeln(tanh(complex(0.0))); // 0.0
assert(isClose(tanh(complex(1.0L)), std_math_tanh(1.0L)));
assert(isClose(tanh(complex(1.0f)), std_math_tanh(1.0f)));
```
pure nothrow @nogc @safe Complex!T `asinh`(T)(Complex!T `z`);

pure nothrow @nogc @safe Complex!T `acosh`(T)(Complex!T `z`);

pure nothrow @nogc @safe Complex!T `atanh`(T)(Complex!T `z`);
Inverse hyperbolic trigonometric functions on complex numbers.
Parameters:
 Complex!T `z` A complex number.
Returns:
The hyperbolic arcsine, arccosine and arctangent of `z`, respectively.
Examples:
```import std.math.operations : isClose;
import std.math.trigonometry : std_math_asinh = asinh;
writeln(asinh(complex(0.0))); // 0.0
assert(isClose(asinh(complex(1.0L)), std_math_asinh(1.0L)));
assert(isClose(asinh(complex(1.0f)), std_math_asinh(1.0f)));
```
Examples:
```import std.math.operations : isClose;
import std.math.trigonometry : std_math_acosh = acosh;
writeln(acosh(complex(1.0))); // 0.0
assert(isClose(acosh(complex(3.0L)), std_math_acosh(3.0L)));
assert(isClose(acosh(complex(3.0f)), std_math_acosh(3.0f)));
```
Examples:
```import std.math.operations : isClose;
import std.math.trigonometry : std_math_atanh = atanh;
writeln(atanh(complex(0.0))); // 0.0
assert(isClose(atanh(complex(0.5L)), std_math_atanh(0.5L)));
assert(isClose(atanh(complex(0.5f)), std_math_atanh(0.5f)));
```
pure nothrow @nogc @trusted Complex!real `expi`(real `y`);
Parameters:
 real `y` A real number.
Returns:
The value of cos(y) + i sin(y).

Note `expi` is included here for convenience and for easy migration of code.

Examples:
```import core.math : cos, sin;
writeln(expi(0.0L)); // 1.0L
writeln(expi(1.3e5L)); // complex(cos(1.3e5L), sin(1.3e5L))
```
pure nothrow @nogc @safe Complex!real `coshisinh`(real `y`);
Parameters:
 real `y` A real number.
Returns:
The value of cosh(y) + i sinh(y)

Note `coshisinh` is included here for convenience and for easy migration of code.

Examples:
```import std.math.trigonometry : cosh, sinh;
writeln(coshisinh(3.0L)); // complex(cosh(3.0L), sinh(3.0L))
```
pure nothrow @nogc @safe Complex!T `sqrt`(T)(Complex!T `z`);
Parameters:
 Complex!T `z` A complex number.
Returns:
The square root of `z`.
Examples:
```static import core.math;
writeln(sqrt(complex(0.0))); // 0.0
writeln(sqrt(complex(1.0L, 0))); // core.math.sqrt(1.0L)
writeln(sqrt(complex(-1.0L, 0))); // complex(0, 1.0L)
writeln(sqrt(complex(-8.0, -6.0))); // complex(1.0, -3.0)
```
pure nothrow @nogc @trusted Complex!T `exp`(T)(Complex!T `x`);
Calculates ex.
Parameters:
 Complex!T `x` A complex number
Returns:
The complex base e exponential of `x`
Special Values
x exp(x)
(±0, +0) (1, +0)
(any, +∞) (NAN, NAN)
(any, NAN) (NAN, NAN)
(+∞, +0) (+∞, +0)
(-∞, any) (±0, cis(x.im))
(+∞, any) (±∞, cis(x.im))
(-∞, +∞) (±0, ±0)
(+∞, +∞) (±∞, NAN)
(-∞, NAN) (±0, ±0)
(+∞, NAN) (±∞, NAN)
(NAN, +0) (NAN, +0)
(NAN, any) (NAN, NAN)
(NAN, NAN) (NAN, NAN)
Examples:
```import std.math.operations : isClose;
import std.math.constants : PI;

writeln(exp(complex(0.0, 0.0))); // complex(1.0, 0.0)

auto a = complex(2.0, 1.0);
writeln(exp(conj(a))); // conj(exp(a))

auto b = exp(complex(0.0L, 1.0L) * PI);
assert(isClose(b, -1.0L, 0.0, 1e-15));
```
pure nothrow @nogc @safe Complex!T `log`(T)(Complex!T `x`);
Calculate the natural logarithm of x. The branch cut is along the negative axis.
Parameters:
 Complex!T `x` A complex number
Returns:
The complex natural logarithm of `x`
Special Values
x log(x)
(-0, +0) (-∞, π)
(+0, +0) (-∞, +0)
(any, +∞) (+∞, π/2)
(any, NAN) (NAN, NAN)
(-∞, any) (+∞, π)
(+∞, any) (+∞, +0)
(-∞, +∞) (+∞, 3π/4)
(+∞, +∞) (+∞, π/4)
(±∞, NAN) (+∞, NAN)
(NAN, any) (NAN, NAN)
(NAN, +∞) (+∞, NAN)
(NAN, NAN) (NAN, NAN)
Examples:
```import core.math : sqrt;
import std.math.constants : PI;
import std.math.operations : isClose;

auto a = complex(2.0, 1.0);
writeln(log(conj(a))); // conj(log(a))

auto b = 2.0 * log10(complex(0.0, 1.0));
auto c = 4.0 * log10(complex(sqrt(2.0) / 2, sqrt(2.0) / 2));
assert(isClose(b, c, 0.0, 1e-15));

writeln(log(complex(-1.0L, 0.0L))); // complex(0.0L, PI)
writeln(log(complex(-1.0L, -0.0L))); // complex(0.0L, -PI)
```
pure nothrow @nogc @safe Complex!T `log10`(T)(Complex!T `x`);
Calculate the base-10 logarithm of x.
Parameters:
 Complex!T `x` A complex number
Returns:
The complex base 10 logarithm of `x`
Examples:
```import core.math : sqrt;
import std.math.constants : LN10, PI;
import std.math.operations : isClose;

auto a = complex(2.0, 1.0);
writeln(log10(a)); // log(a) / log(complex(10.0))

auto b = log10(complex(0.0, 1.0)) * 2.0;
auto c = log10(complex(sqrt(2.0) / 2, sqrt(2.0) / 2)) * 4.0;
assert(isClose(b, c, 0.0, 1e-15));
```
pure nothrow @nogc @safe Complex!T `pow`(T, Int)(Complex!T `x`, const Int `n`)
if (isIntegral!Int);

pure nothrow @nogc @trusted Complex!T `pow`(T)(Complex!T `x`, const T `n`);

pure nothrow @nogc @trusted Complex!T `pow`(T)(Complex!T `x`, Complex!T `y`);

pure nothrow @nogc @trusted Complex!T `pow`(T)(const T `x`, Complex!T `n`);
Calculates xn. The branch cut is on the negative axis.
Parameters:
 Complex!T `x` base Int `n` exponent
Returns:
`x` raised to the power of `n`
Examples:
```import std.math.operations : isClose;

auto a = complex(1.0, 2.0);
writeln(pow(a, 2)); // a * a
writeln(pow(a, 3)); // a * a * a
writeln(pow(a, -2)); // 1.0 / (a * a)
assert(isClose(pow(a, -3), 1.0 / (a * a * a)));
```
Examples:
```import std.math.operations : isClose;
writeln(pow(complex(0.0), 2.0)); // complex(0.0)
writeln(pow(complex(5.0), 2.0)); // complex(25.0)

auto a = pow(complex(-1.0, 0.0), 0.5);
assert(isClose(a, complex(0.0, +1.0), 0.0, 1e-16));

auto b = pow(complex(-1.0, -0.0), 0.5);
assert(isClose(b, complex(0.0, -1.0), 0.0, 1e-16));
```
Examples:
```import std.math.operations : isClose;
import std.math.exponential : exp;
import std.math.constants : PI;
auto a = complex(0.0);
auto b = complex(2.0);
writeln(pow(a, b)); // complex(0.0)

auto c = complex(0.0L, 1.0L);
assert(isClose(pow(c, c), exp((-PI) / 2)));
```
Examples:
```import std.math.operations : isClose;
writeln(pow(2.0, complex(0.0))); // complex(1.0)
writeln(pow(2.0, complex(5.0))); // complex(32.0)

auto a = pow(-2.0, complex(-1.0));
assert(isClose(a, complex(-0.5), 0.0, 1e-16));

auto b = pow(-0.5, complex(-1.0));
assert(isClose(b, complex(-2.0), 0.0, 1e-15));
```