API reference

apn_mojo.complex

Complex lets you configure its real and imaginary Floats separately and rounds each arithmetic result once per component. See the Complex tutorial for examples, Batch for arrays, and reductions for totals and dot products.

Complex numbers with Float components, their contexts and functions, one declaration per name.

Every operation rounds each component of the exact result once. A ComplexContext sets each component's format, rounding and traps; an ArithmeticContext sets both. Apply a function to batches with vmap, as in vmap[apn_mojo.complex.sqrt]()(values).

Summary

Name Kind Summary
abs function The magnitude, sqrt(real**2 + imag**2), rounded once (numpy's abs).
acos function The principal arccosine, each part correctly rounded.
acosh function The principal inverse hyperbolic cosine, each part correctly rounded.
add function The add left + right, each component rounded once.
angle function The argument, atan2(imag, real), correctly rounded, in [-pi, pi].
asin function The principal arcsine, each part correctly rounded.
asinh function The principal inverse hyperbolic sine, each part correctly rounded.
atan function The principal arctangent, each part correctly rounded.
atanh function The principal inverse hyperbolic tangent, each part correctly rounded.
conjugate function The conjugate, real - imag i (numpy's conjugate).
cos function The cosine, each part correctly rounded.
cosh function The hyperbolic cosine, each part correctly rounded.
divide function The divide left / right, each component rounded once.
exp function The exponential, each part correctly rounded.
imag function The imaginary part (numpy's imag).
log function The principal logarithm, each part correctly rounded.
multiply function The multiply left * right, each component rounded once.
norm_sqr function The squared magnitude, real**2 + imag**2, rounded once.
pow function The principal power base**exponent, each part correctly rounded.
pow_int function The power for a signed integral exponent, each component rounded once.
real function The real part (numpy's real).
reciprocal function 1 / value, each component rounded once (numpy's reciprocal).
sin function The sine, each part correctly rounded.
sinh function The hyperbolic sine, each part correctly rounded.
sqrt function The principal square root, each component rounded once.
stable_hash function A 64-bit hash of the representation, stable across processes and releases.
subtract function The subtract left - right, each component rounded once.
tan function The tangent, each part correctly rounded.
tanh function The hyperbolic tangent, each part correctly rounded.
Complex struct A complex number with two Float components.
ComplexContext struct A pair of arithmetic contexts, one per component.

Functions

abs

Source: apn_mojo/complex/math.mojo

def abs(
    value: Complex,
    *,
    context: Optional[ArithmeticContext] = None,
) raises -> Float

The magnitude, sqrt(real**2 + imag**2), rounded once (numpy's abs).

The squared magnitude is never rounded first, so it cannot overflow or underflow early. An infinite component gives +inf even when the other is NaN.

Arguments

  • value (Complex): The Complex.
  • context (Optional[ArithmeticContext]): The output format; by default the larger component precision.

Returns

Float: The nonnegative magnitude as a Float.

Raises

Error: On a trapped condition.

acos

Source: apn_mojo/complex/elementary.mojo

def acos(
    value: Complex,
    *,
    context: _ComplexContextArgument = _ComplexContextArgument(),
) raises -> Complex

The principal arccosine, each part correctly rounded.

On the cuts the imaginary zero's sign selects the side: acos(2 - 0i) is +0 + 1.317i.

Arguments

  • value (Complex): The Complex.
  • context (_ComplexContextArgument): An ArithmeticContext for both parts or a ComplexContext for each; by default each part's format, rounded to nearest-even.

Returns

Complex: The value, each part rounded once.

Raises

Error: On a trapped condition in either part, or past the budget.

acosh

Source: apn_mojo/complex/elementary.mojo

def acosh(
    value: Complex,
    *,
    context: _ComplexContextArgument = _ComplexContextArgument(),
) raises -> Complex

The principal inverse hyperbolic cosine, each part correctly rounded.

On the cut (-inf, 1) the imaginary zero's sign selects the side: acosh(-2 + 0i) is 1.317 + i pi.

Arguments

  • value (Complex): The Complex.
  • context (_ComplexContextArgument): An ArithmeticContext for both parts or a ComplexContext for each; by default each part's format, rounded to nearest-even.

Returns

Complex: The value, each part rounded once.

Raises

Error: On a trapped condition in either part, or past the budget.

add

Source: apn_mojo/complex/math.mojo

def add(
    left: _ComplexArgument,
    right: _ComplexArgument,
    *,
    context: _ComplexContextArgument = _ComplexContextArgument(),
) raises -> Complex

The add left + right, each component rounded once.

Either operand may be a Complex, Float, Integer, Rational, integer literal or typed native number; real operands keep real semantics, so a real zero never changes the other operand's imaginary zero sign.

Arguments

  • left (_ComplexArgument): The first operand.
  • right (_ComplexArgument): The second operand.
  • context (_ComplexContextArgument): An ArithmeticContext for both components or a ComplexContext for each; by default the merged component formats, rounded to nearest-even.

Returns

Complex: The Complex result; both components are published together.

Raises

Error: When a trapped condition occurs in either component.

angle

Source: apn_mojo/complex/elementary.mojo

def angle(
    value: Complex,
    *,
    context: Optional[ArithmeticContext] = None,
) raises -> Float

The argument, atan2(imag, real), correctly rounded, in [-pi, pi].

Arguments

  • value (Complex): The Complex.
  • context (Optional[ArithmeticContext]): The output format, rounding mode, traps and budget; by default the larger part format, rounded to nearest-even.

Returns

Float: The angle rounded once; arg(-1 + 0i) is pi and arg(-1 - 0i) is -pi.

Raises

Error: On a trapped condition, or past the budget.

asin

Source: apn_mojo/complex/elementary.mojo

def asin(
    value: Complex,
    *,
    context: _ComplexContextArgument = _ComplexContextArgument(),
) raises -> Complex

The principal arcsine, each part correctly rounded.

On the cuts (-inf, -1) and (1, inf) the imaginary zero's sign selects the side: asin(2 + 0i) is pi/2 + 1.317i.

Arguments

  • value (Complex): The Complex.
  • context (_ComplexContextArgument): An ArithmeticContext for both parts or a ComplexContext for each; by default each part's format, rounded to nearest-even.

Returns

Complex: The value, each part rounded once.

Raises

Error: On a trapped condition in either part, or past the budget.

asinh

Source: apn_mojo/complex/elementary.mojo

def asinh(
    value: Complex,
    *,
    context: _ComplexContextArgument = _ComplexContextArgument(),
) raises -> Complex

The principal inverse hyperbolic sine, each part correctly rounded.

On the cuts of the imaginary axis the real zero's sign selects the side.

Arguments

  • value (Complex): The Complex.
  • context (_ComplexContextArgument): An ArithmeticContext for both parts or a ComplexContext for each; by default each part's format, rounded to nearest-even.

Returns

Complex: The value, each part rounded once.

Raises

Error: On a trapped condition in either part, or past the budget.

atan

Source: apn_mojo/complex/elementary.mojo

def atan(
    value: Complex,
    *,
    context: _ComplexContextArgument = _ComplexContextArgument(),
) raises -> Complex

The principal arctangent, each part correctly rounded.

On the cuts of the imaginary axis the real zero's sign selects the side: atan(+0 + 2i) is pi/2 + 0.549i.

Arguments

  • value (Complex): The Complex.
  • context (_ComplexContextArgument): An ArithmeticContext for both parts or a ComplexContext for each; by default each part's format, rounded to nearest-even.

Returns

Complex: The value, each part rounded once.

Raises

Error: On a trapped condition in either part, or past the budget.

atanh

Source: apn_mojo/complex/elementary.mojo

def atanh(
    value: Complex,
    *,
    context: _ComplexContextArgument = _ComplexContextArgument(),
) raises -> Complex

The principal inverse hyperbolic tangent, each part correctly rounded.

atanh(+-1) has an infinite real part with divide-by-zero; on the cuts the imaginary zero's sign selects the side.

Arguments

  • value (Complex): The Complex.
  • context (_ComplexContextArgument): An ArithmeticContext for both parts or a ComplexContext for each; by default each part's format, rounded to nearest-even.

Returns

Complex: The value, each part rounded once.

Raises

Error: On a trapped condition in either part, or past the budget.

conjugate

Source: apn_mojo/complex/math.mojo

def conjugate(value: Complex) raises -> Complex

The conjugate, real - imag i (numpy's conjugate).

Arguments

  • value (Complex): The Complex.

Returns

Complex: The conjugate, exactly.

Raises

Error: Only on a checked size error.

cos

Source: apn_mojo/complex/elementary.mojo

def cos(
    value: Complex,
    *,
    context: _ComplexContextArgument = _ComplexContextArgument(),
) raises -> Complex

The cosine, each part correctly rounded.

cos z = cosh(iz).

Arguments

  • value (Complex): The Complex.
  • context (_ComplexContextArgument): An ArithmeticContext for both parts or a ComplexContext for each; by default each part's format, rounded to nearest-even.

Returns

Complex: The value, each part rounded once.

Raises

Error: On a trapped condition in either part, or past the budget.

cosh

Source: apn_mojo/complex/elementary.mojo

def cosh(
    value: Complex,
    *,
    context: _ComplexContextArgument = _ComplexContextArgument(),
) raises -> Complex

The hyperbolic cosine, each part correctly rounded.

cosh(x + iy) = cosh x cos y + i sinh x sin y.

Arguments

  • value (Complex): The Complex.
  • context (_ComplexContextArgument): An ArithmeticContext for both parts or a ComplexContext for each; by default each part's format, rounded to nearest-even.

Returns

Complex: The value, each part rounded once.

Raises

Error: On a trapped condition in either part, or past the budget.

divide

Source: apn_mojo/complex/math.mojo

def divide(
    left: _ComplexArgument,
    right: _ComplexArgument,
    *,
    context: _ComplexContextArgument = _ComplexContextArgument(),
) raises -> Complex

The divide left / right, each component rounded once.

Division by complex zero makes each finite nonzero component of the dividend an infinity, with divide-by-zero.

Either operand may be a Complex, Float, Integer, Rational, integer literal or typed native number; real operands keep real semantics, so a real zero never changes the other operand's imaginary zero sign.

Arguments

  • left (_ComplexArgument): The first operand.
  • right (_ComplexArgument): The second operand.
  • context (_ComplexContextArgument): An ArithmeticContext for both components or a ComplexContext for each; by default the merged component formats, rounded to nearest-even.

Returns

Complex: The Complex result; both components are published together.

Raises

Error: When a trapped condition occurs in either component.

exp

Source: apn_mojo/complex/elementary.mojo

def exp(
    value: Complex,
    *,
    context: _ComplexContextArgument = _ComplexContextArgument(),
) raises -> Complex

The exponential, each part correctly rounded.

exp(x + iy) = e**x (cos y + i sin y); a real argument keeps its imaginary zero's sign.

Arguments

  • value (Complex): The Complex.
  • context (_ComplexContextArgument): An ArithmeticContext for both parts or a ComplexContext for each; by default each part's format, rounded to nearest-even.

Returns

Complex: The value, each part rounded once.

Raises

Error: On a trapped condition in either part, or past the budget.

imag

Source: apn_mojo/complex/math.mojo

def imag(value: Complex) raises -> Float

The imaginary part (numpy's imag).

Arguments

  • value (Complex): The Complex.

Returns

Float: The imaginary component, exactly.

Raises

Error: Only on a checked size error.

log

Source: apn_mojo/complex/elementary.mojo

def log(
    value: Complex,
    *,
    context: _ComplexContextArgument = _ComplexContextArgument(),
) raises -> Complex

The principal logarithm, each part correctly rounded.

The imaginary part is in [-pi, pi]; on the negative real axis its sign follows the imaginary zero's, so log(-1 + 0i) is i pi and log(-1 - 0i) is -i pi. log(0) is -inf with divide-by-zero.

Arguments

  • value (Complex): The Complex.
  • context (_ComplexContextArgument): An ArithmeticContext for both parts or a ComplexContext for each; by default each part's format, rounded to nearest-even.

Returns

Complex: The value, each part rounded once.

Raises

Error: On a trapped condition in either part, or past the budget.

multiply

Source: apn_mojo/complex/math.mojo

def multiply(
    left: _ComplexArgument,
    right: _ComplexArgument,
    *,
    context: _ComplexContextArgument = _ComplexContextArgument(),
) raises -> Complex

The multiply left * right, each component rounded once.

Either operand may be a Complex, Float, Integer, Rational, integer literal or typed native number; real operands keep real semantics, so a real zero never changes the other operand's imaginary zero sign.

Arguments

  • left (_ComplexArgument): The first operand.
  • right (_ComplexArgument): The second operand.
  • context (_ComplexContextArgument): An ArithmeticContext for both components or a ComplexContext for each; by default the merged component formats, rounded to nearest-even.

Returns

Complex: The Complex result; both components are published together.

Raises

Error: When a trapped condition occurs in either component.

norm_sqr

Source: apn_mojo/complex/math.mojo

def norm_sqr(
    value: Complex,
    *,
    context: Optional[ArithmeticContext] = None,
) raises -> Float

The squared magnitude, real**2 + imag**2, rounded once.

Arguments

  • value (Complex): The Complex.
  • context (Optional[ArithmeticContext]): The output format; by default the larger component precision.

Returns

Float: The squared magnitude as a Float.

Raises

Error: On a trapped condition.

pow

Source: apn_mojo/complex/elementary.mojo

def pow(
    base: Complex,
    exponent: Complex,
    *,
    context: _ComplexContextArgument = _ComplexContextArgument(),
) raises -> Complex

The principal power base**exponent, each part correctly rounded.

A zero exponent gives 1 + 0i, an integral real exponent is an integer power, and otherwise the power is exp(exponent log base) with the principal logarithm. Powers that are exact, such as (-4)**0.25 = 1 + i and (-2)**0.5 = +0 + sqrt(2) i, come out exactly.

Arguments

  • base (Complex): The base.
  • exponent (Complex): The exponent.
  • context (_ComplexContextArgument): An ArithmeticContext for both parts or a ComplexContext for each; by default the base's part formats.

Returns

Complex: The power, each part rounded once.

Raises

Error: On a trapped condition in either part, or past the budget.

pow_int

Source: apn_mojo/complex/math.mojo

def pow_int(
    value: Complex,
    exponent: Integer,
    *,
    context: _ComplexContextArgument = _ComplexContextArgument(),
) raises -> Complex

The power for a signed integral exponent, each component rounded once.

A zero exponent gives a real one. Complex zero to a negative power is (+inf, NaN) with divide-by-zero; an infinite input gives (+inf, NaN) for a positive power and complex zero for a negative one. A part that is exactly zero takes MPC's sign for a base on an axis, and for an inexact power of a diagonal base (|re| == |im|); an exact power of a diagonal base follows the exponent's phase, which can differ from MPC's beyond the eighth power. Either can differ from repeated multiplication.

Arguments

  • value (Complex): The base.
  • exponent (Integer): The exponent, of any size.
  • context (_ComplexContextArgument): An ArithmeticContext for both components or a ComplexContext for each; by default each component's format, rounded to nearest-even.

Returns

Complex: value ** exponent.

Raises

Error: When a trapped condition occurs in either component.

real

Source: apn_mojo/complex/math.mojo

def real(value: Complex) raises -> Float

The real part (numpy's real).

Arguments

  • value (Complex): The Complex.

Returns

Float: The real component, exactly.

Raises

Error: Only on a checked size error.

reciprocal

Source: apn_mojo/complex/math.mojo

def reciprocal(
    value: _ComplexArgument,
    *,
    context: _ComplexContextArgument = _ComplexContextArgument(),
) raises -> Complex

1 / value, each component rounded once (numpy's reciprocal).

Arguments

  • value (_ComplexArgument): The operand.
  • context (_ComplexContextArgument): An ArithmeticContext for both components or a ComplexContext for each; by default the operand's component formats, rounded to nearest-even.

Returns

Complex: The Complex reciprocal.

Raises

Error: When a trapped condition occurs in either component.

sin

Source: apn_mojo/complex/elementary.mojo

def sin(
    value: Complex,
    *,
    context: _ComplexContextArgument = _ComplexContextArgument(),
) raises -> Complex

The sine, each part correctly rounded.

sin z = -i sinh(iz).

Arguments

  • value (Complex): The Complex.
  • context (_ComplexContextArgument): An ArithmeticContext for both parts or a ComplexContext for each; by default each part's format, rounded to nearest-even.

Returns

Complex: The value, each part rounded once.

Raises

Error: On a trapped condition in either part, or past the budget.

sinh

Source: apn_mojo/complex/elementary.mojo

def sinh(
    value: Complex,
    *,
    context: _ComplexContextArgument = _ComplexContextArgument(),
) raises -> Complex

The hyperbolic sine, each part correctly rounded.

sinh(x + iy) = sinh x cos y + i cosh x sin y.

Arguments

  • value (Complex): The Complex.
  • context (_ComplexContextArgument): An ArithmeticContext for both parts or a ComplexContext for each; by default each part's format, rounded to nearest-even.

Returns

Complex: The value, each part rounded once.

Raises

Error: On a trapped condition in either part, or past the budget.

sqrt

Source: apn_mojo/complex/math.mojo

def sqrt(
    value: Complex,
    *,
    context: _ComplexContextArgument = _ComplexContextArgument(),
) raises -> Complex

The principal square root, each component rounded once.

The real part is nonnegative, and the imaginary part follows the sign of the input's imaginary part on both sides of the negative real axis, signed zero included: sqrt(Complex(-4, +0)) is (0, 2) and the -0 side gives (0, -2).

Arguments

  • value (Complex): The Complex.
  • context (_ComplexContextArgument): An ArithmeticContext for both components or a ComplexContext for each; by default each component's format, rounded to nearest-even.

Returns

Complex: The principal root.

Raises

Error: When a trapped condition occurs in either component.

stable_hash

Source: apn_mojo/complex/math.mojo

def stable_hash(z: Complex) -> UInt64

A 64-bit hash of the representation, stable across processes and releases.

The algorithm is APNH-64: tag 4, then the real and the imaginary component, each encoded as for a Float. Unlike Mojo's Hasher, its output never changes, so stored hashes stay valid.

Arguments

  • z (Complex): The Complex number.

Returns

UInt64: The hash.

subtract

Source: apn_mojo/complex/math.mojo

def subtract(
    left: _ComplexArgument,
    right: _ComplexArgument,
    *,
    context: _ComplexContextArgument = _ComplexContextArgument(),
) raises -> Complex

The subtract left - right, each component rounded once.

Either operand may be a Complex, Float, Integer, Rational, integer literal or typed native number; real operands keep real semantics, so a real zero never changes the other operand's imaginary zero sign.

Arguments

  • left (_ComplexArgument): The first operand.
  • right (_ComplexArgument): The second operand.
  • context (_ComplexContextArgument): An ArithmeticContext for both components or a ComplexContext for each; by default the merged component formats, rounded to nearest-even.

Returns

Complex: The Complex result; both components are published together.

Raises

Error: When a trapped condition occurs in either component.

tan

Source: apn_mojo/complex/elementary.mojo

def tan(
    value: Complex,
    *,
    context: _ComplexContextArgument = _ComplexContextArgument(),
) raises -> Complex

The tangent, each part correctly rounded.

tan z = -i tanh(iz).

Arguments

  • value (Complex): The Complex.
  • context (_ComplexContextArgument): An ArithmeticContext for both parts or a ComplexContext for each; by default each part's format, rounded to nearest-even.

Returns

Complex: The value, each part rounded once.

Raises

Error: On a trapped condition in either part, or past the budget.

tanh

Source: apn_mojo/complex/elementary.mojo

def tanh(
    value: Complex,
    *,
    context: _ComplexContextArgument = _ComplexContextArgument(),
) raises -> Complex

The hyperbolic tangent, each part correctly rounded.

tanh z = sinh z / cosh z.

Arguments

  • value (Complex): The Complex.
  • context (_ComplexContextArgument): An ArithmeticContext for both parts or a ComplexContext for each; by default each part's format, rounded to nearest-even.

Returns

Complex: The value, each part rounded once.

Raises

Error: On a trapped condition in either part, or past the budget.

Structs

Complex

Source: apn_mojo/complex/value.mojo

struct Complex(
    Boolable,
    Equatable,
    ImplicitlyCopyable,
    Writable,
    _ComplexComparison,
    _ComplexSource,
    _BatchElement,
)

A complex number with two Float components.

The components have independent precisions and common exponent bounds. Every operation rounds each component of the exact result once: a product rounds ac - bd and ad + bc, never the products first.

Operation Contract
z + w, z - w, z * w, z / w Each component rounded once; either side may be real or exact
z ** n Signed integral power, each component rounded once
+z, -z Exact, same formats
z += w and the other compound forms Keep the destination's formats; unchanged on error
z == w, z != w Exact equality; signed zeros are equal, NaN never is
Bool(z) False only for complex zero

Special values are decided by each operation as a whole, not by a chain of real operations. Printing shows Complex(real, imag) with exact hexadecimal components, which the text parser accepts.

Limitations

There is no ordering, no hashing and no implicit conversion to a native number. A native number cannot be the left operand of ==.

Implements

Boolable, Copyable, Equatable, ImplicitlyCopyable, Writable, _BatchElement, _ComplexComparison, _ComplexSource, _MapArgument

Complex.__init__ { #Complex.init .api-name }

def __init__(
    out self,
    *,
    context: _ComplexContextArgument = _ComplexContextArgument(),
) raises

Complex zero: +0 in both components.

Arguments

  • context (_ComplexContextArgument): The component formats.

Raises

Error: Only on an invalid context.

def __init__(
    out self,
    real: _FloatArgument,
    *,
    context: _ComplexContextArgument = _ComplexContextArgument(),
) raises

A real value with imaginary +0.

Arguments

  • real (_FloatArgument): The real part; any exact or Float value.
  • context (_ComplexContextArgument): The component formats; by default the real part's format.

Raises

Error: On a trapped condition.

def __init__(
    out self,
    real: _FloatArgument,
    imag: _FloatArgument,
    *,
    context: _ComplexContextArgument = _ComplexContextArgument(),
) raises

Construct from both components, each rounded once.

A component without a Float format takes its partner's; with neither, both use 128 bits. The exponent bounds must agree unless a context is given.

Arguments

  • real (_FloatArgument): The real part.
  • imag (_FloatArgument): The imaginary part.
  • context (_ComplexContextArgument): The component formats.

Raises

Error: When the bounds differ without a context, or on a trapped condition.

def __init__(
    out self,
    text: String,
    *,
    context: _ComplexContextArgument = _ComplexContextArgument(),
    allow_whitespace: Bool = False,
    allow_underscores: Bool = False,
    limits: Optional[ConversionLimits] = None,
) raises

Parse real, imaginary, algebraic or paired text.

Accepts 3, 4j, -j, 3+4j, 3-4i, (3+4j), (3,4) and the display form Complex(3, 4). Each component uses Float's decimal, hexadecimal and binary grammar; both are validated before either rounds.

Arguments

  • text (String): The number.
  • context (_ComplexContextArgument): The component formats.
  • allow_whitespace (Bool): Accept surrounding and component-boundary whitespace.
  • allow_underscores (Bool): Accept single underscores between digits.
  • limits (Optional[ConversionLimits]): Optional per-call conversion limits; see ConversionLimits.

Raises

Error: When the text is not a valid number, naming the byte offset; on a trapped condition; or when it exceeds limits.

1 more overload

A copy, rounded to the context when one is given.

def __init__(
    out self,
    value: Self,
    *,
    context: _ComplexContextArgument = _ComplexContextArgument(),
) raises

Complex.conjugate

def conjugate(self) -> Self

The complex conjugate.

Returns

Self: The same real part and the negated imaginary part, formats kept.

Complex.from_json

def from_json(
    text: String,
    *,
    limits: Optional[ConversionLimits] = None,
) raises -> Self

Read a Complex from its version-1 JSON record, without rounding.

Arguments

  • text (String): The JSON record.
  • limits (Optional[ConversionLimits]): Optional per-call conversion limits; see ConversionLimits.

Returns

Self: The Complex the record holds.

Raises

Error: When the text is not exactly that schema, or the component bounds differ.

Complex.imag

def imag(self) -> Float

The imaginary part.

Returns

Float: An independent Float.

Complex.imag_format

def imag_format(self) -> FloatFormat

The imaginary part's format.

Returns

FloatFormat: The format.

Complex.is_finite

def is_finite(self) -> Bool

Whether both components are finite.

Returns

Bool: True when neither is infinite or NaN.

Complex.is_infinite

def is_infinite(self) -> Bool

Whether either component is infinite.

Returns

Bool: True when either is an infinity; is_nan may also be true.

Complex.is_nan

def is_nan(self) -> Bool

Whether either component is NaN.

Returns

Bool: True when either is NaN.

Complex.is_zero

def is_zero(self) -> Bool

Whether both components are zero, of either sign.

Returns

Bool: True for complex zero.

Complex.parse

def parse(
    text: String,
    *,
    context: _ComplexContextArgument = _ComplexContextArgument(),
    allow_whitespace: Bool = False,
    allow_underscores: Bool = False,
    limits: Optional[ConversionLimits] = None,
) raises -> Self

Parse text; the same contract as the text constructor.

Arguments

  • text (String): The number.
  • context (_ComplexContextArgument): The component formats.
  • allow_whitespace (Bool): Accept surrounding and component-boundary whitespace.
  • allow_underscores (Bool): Accept single underscores between digits.
  • limits (Optional[ConversionLimits]): Optional per-call conversion limits; see ConversionLimits.

Returns

Self: The parsed Complex.

Raises

Error: When the text is not a valid number, on a trapped condition, or when it exceeds limits.

Complex.real

def real(self) -> Float

The real part.

Returns

Float: An independent Float.

Complex.real_format

def real_format(self) -> FloatFormat

The real part's format.

Returns

FloatFormat: The format.

Complex.representation_cmp

def representation_cmp(self, other: Self) -> Int

Compare representations in a strict total order: the real components by Float.representation_cmp, then the imaginary ones.

Arguments

  • other (Self): The other Complex.

Returns

Int: -1, 0 or 1; 0 exactly when same_representation holds.

Complex.same_representation

def same_representation(self, other: Self) -> Bool

Whether both components are the same representation.

See Float.same_representation: signed zeros, formats and NaN count.

Arguments

  • other (Self): The other Complex.

Returns

Bool: True when both components match.

Complex.to_json

def to_json(self, *, limits: Optional[ConversionLimits] = None) raises -> String

Write the version-1 JSON record: two complete Float records.

Arguments

  • limits (Optional[ConversionLimits]): Optional per-call conversion limits; see ConversionLimits.

Returns

String: Compact canonical JSON.

Raises

Error: When the output exceeds limits.

Complex.to_string

def to_string(
    self,
    base: Int = 10,
    *,
    notation: StaticString = "auto",
    limits: Optional[ConversionLimits] = None,
) raises -> String

Write Complex(real, imag), by default as print does.

Each part is written as Float.to_string writes it: the shortest decimal that reads back, laid out by notation (auto, positional or scientific), or the exact value with hexadecimal, base 16 or base 2.

Arguments

  • base (Int): 10 for decimal, 16 or 2 for the exact value.
  • notation (StaticString): auto, positional, scientific or hexadecimal.
  • limits (Optional[ConversionLimits]): Optional per-call conversion limits; see ConversionLimits.

Returns

String: The text.

Raises

Error: When the base or notation is invalid or the output exceeds limits.

Complex.write_to

def write_to(self, mut writer: Some[Writer])

Write Complex(real, imag) with each part as a Float prints.

Arguments

  • writer (mut Some[Writer]): The destination.

ComplexContext

Source: apn_mojo/complex/context.mojo

struct ComplexContext(ImplicitlyCopyable, Writable)

A pair of arithmetic contexts, one per component.

Use it for different precisions, rounding modes or traps in the real and imaginary parts; an ArithmeticContext applies to both. The two formats must have common exponent bounds.

Implements

Copyable, ImplicitlyCopyable, Writable

ComplexContext.__init__ { #ComplexContext.init .api-name }

def __init__(out self, context: ArithmeticContext)

The same context for both components.

Arguments

  • context (ArithmeticContext): The context.
def __init__(
    out self,
    *,
    real: Optional[ArithmeticContext] = None,
    imag: Optional[ArithmeticContext] = None,
) raises

One context per component.

Arguments

  • real (Optional[ArithmeticContext]): The real part's context; the defaults when omitted.
  • imag (Optional[ArithmeticContext]): The imaginary part's context; the real one when omitted.

Raises

Error: When the two formats have different exponent bounds.

ComplexContext.imag

def imag(self) -> ArithmeticContext

The imaginary part's context.

Returns

ArithmeticContext: The context.

ComplexContext.real

def real(self) -> ArithmeticContext

The real part's context.

Returns

ArithmeticContext: The context.

ComplexContext.write_to

def write_to(self, mut writer: Some[Writer])

Write both contexts.

Arguments

  • writer (mut Some[Writer]): The destination.

Formats and contexts

Float components retain their formats when no context overrides them. An exact component adopts its partner's format; two exact components default to 128 bits. Typed native floats contribute their own precision. Exponent bounds must agree. Operators merge precision separately for the two parts.

An ArithmeticContext applies the same settings to both components. A ComplexContext selects them separately, with shared exponent bounds. Parsing validates both component inputs before rounding either one.

Components accept integers, rationals, Floats, integer literals, native integers up to 64 bits, and typed native floats. Decimal text or a Rational preserves the exact source until the component's final rounding; the resulting binary Float can still be an approximation.

Rules and special values

Real operands affect only the parts that the operation calls for. Adding a real positive zero to (1, -0) preserves the imaginary negative zero; adding a complex (+0, +0) can change it. For nonfinite values, arithmetic follows the MPC rules described in Complex architecture.

abs returns the magnitude, as NumPy's does, and norm_sqr returns its square. Both return a Float and use the larger component precision unless you supply a context. The family also provides angle, conjugate, real, and imag. sqrt returns the principal square root, respecting the imaginary zero's sign on a branch cut. Integer powers accept exponents of either sign and arbitrary width. A part of a power that is exactly zero takes MPC's sign for a base on an axis, such as (3i)**-2, and for an inexact power of a diagonal base; an exact power of a diagonal base, such as (1 + i)**12, follows the exponent's phase, which can differ from MPC's sign there.

Equality compares stored values across formats. Zero signs compare equal, a NaN component makes equality false, and comparison with a real value requires a zero imaginary part. Typed native values belong on the right. For representation-based dictionary keys, use ComplexKey.

Elementary functions

exp, log, sqrt, pow, sin, cos, tan, sinh, cosh, tanh, asin, acos, atan, asinh, acosh and atanh round each part correctly in its own mode: each part is the exact part rounded once, as MPC gives it, and angle returns the argument as a correctly rounded Float. Special values follow C99 Annex G, and a part that is zero for every argument of its kind, such as the imaginary part of exp(x + 0i), is an exact zero with the sign the annex gives.

On a branch cut the sign of a zero part selects the side: log(-1 + 0i) is pi i and log(-1 - 0i) is -pi i; without a signed zero, a point on a cut takes the counter-clockwise continuous value. pow(z, w) is exp(w log z), and exact when it can be: pow(-4, 1/4) is 1 + i.

Like the Float functions, these functions certify their rounding within the context's max_precision and raise if that budget is insufficient. See Correct rounding.

Text and JSON

Accepted text includes 3, 4j, -j, 3+4j, 3-4i, 3+j, (3+4j), (3,4), and Complex(3, 4). Components follow Float grammar rules; 1e+2-3e-1j, for example, describes 100 - 0.3j before rounding. Suffixes are lowercase i or j.

complex_interchange.mojo Download
"""Complex text and JSON."""

from apn_mojo import (
    Complex,
    ComplexContext,
    ArithmeticContext,
    FloatFormat,
    ConversionLimits,
)


def main() raises:
    var z = Complex("3-4j")
    print(z)
    print(z.to_string(2))
    var settings = ComplexContext(
        real=ArithmeticContext(format=FloatFormat(8)),
        imag=ArithmeticContext(format=FloatFormat(11)),
    )
    var decimal = Complex.parse("0.1+0.3i", context=settings)
    var restored = Complex.from_json(decimal.to_json())
    print(restored == decimal)
    print(
        restored.real_format().precision(), restored.imag_format().precision()
    )
    print(Complex.from_json(Complex("-0-0j").to_json()))
    print(
        Complex("12+34j", limits=ConversionLimits(max_digits=4, max_values=1))
    )

Run from the repository root pixi run mojo run -I src docs/examples/complex_interchange.mojo

Output

Complex(3.0, -4.0)
Complex(0b11p0, -0b1p2)
True
8 11
Complex(-0.0, -0.0)
Complex(12.0, 34.0)

to_string() writes each component as a Float does, by default the shortest decimal; to_string(16) writes them exactly, without format metadata. JSON preserves the two values and formats. A Complex value counts as one logical value under ConversionLimits; one budget covers both components.