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): AnArithmeticContextfor both parts or aComplexContextfor 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): AnArithmeticContextfor both parts or aComplexContextfor 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): AnArithmeticContextfor both components or aComplexContextfor 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): AnArithmeticContextfor both parts or aComplexContextfor 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): AnArithmeticContextfor both parts or aComplexContextfor 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): AnArithmeticContextfor both parts or aComplexContextfor 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): AnArithmeticContextfor both parts or aComplexContextfor 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): AnArithmeticContextfor both parts or aComplexContextfor 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): AnArithmeticContextfor both parts or aComplexContextfor 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): AnArithmeticContextfor both components or aComplexContextfor 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): AnArithmeticContextfor both parts or aComplexContextfor 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): AnArithmeticContextfor both parts or aComplexContextfor 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): AnArithmeticContextfor both components or aComplexContextfor 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): AnArithmeticContextfor both parts or aComplexContextfor 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): AnArithmeticContextfor both components or aComplexContextfor 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): AnArithmeticContextfor both components or aComplexContextfor 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): AnArithmeticContextfor both parts or aComplexContextfor 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): AnArithmeticContextfor both parts or aComplexContextfor 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): AnArithmeticContextfor both components or aComplexContextfor 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): AnArithmeticContextfor both components or aComplexContextfor 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): AnArithmeticContextfor both parts or aComplexContextfor 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): AnArithmeticContextfor both parts or aComplexContextfor 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; seeConversionLimits.
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; seeConversionLimits.
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; seeConversionLimits.
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; seeConversionLimits.
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,scientificorhexadecimal.limits(Optional[ConversionLimits]): Optional per-call conversion limits; seeConversionLimits.
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 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.