View on GitHub

malachite

An arbitrary-precision arithmetic library for Rust.

Malachite for FLINT Users: Gaussian Integers

This page maps the functions of FLINT’s Gaussian integer type, fmpzi_t, onto their Malachite counterpart: GaussianInteger, from the malachite-nz crate. It follows the organization of the fmpzi.h chapter of the FLINT manual, as of FLINT 3.6.0, and is a companion to Malachite for FLINT Users: Integers, whose conventions, including word types and aliasing, apply here as well; the mapping index lists the whole family. Every function is mapped, including three that the header declares but the manual chapter does not list. Where FLINT exposes a function, Malachite often exposes a struct field, an operator, or a trait shared with its real types.

Conventions

The fmpzi representation

A GaussianInteger is a pair of Integers in public fields, real and imaginary. Every pair of parts is a valid value, so there is no constructor: the struct literal is the constructor.

Categories

Each function falls into one of five categories:

  meaning
✓ A Malachite function does the same thing.
≈ A Malachite function serves the same purpose, but its specification differs. The notes say how.
⚙ Malachite does not expose this algorithm or helper; the Malachite column or the notes say what to call instead.
— No counterpart is needed, either because Rust handles it for you or because it is outside Malachite’s scope. The notes say which.
✗ Malachite does not fully support this yet, but will in a future version.

Types, macros and constants

The types are covered under Conventions.

  FLINT Malachite
✓ fmpzi_realref(x) x.real
✓ fmpzi_imagref(x) x.imaginary

fmpzi_realref, fmpzi_imagref. The fields are read and written directly: x.real, x.real = ..., x.real += ..., and &mut x.real for any in-place Integer function. Unlike the rational case on the fmpq page, writing a part directly is safe, because there is no canonical form to disturb.

Basic manipulation

  FLINT Malachite
✓ void fmpzi_init (fmpzi_t x) GaussianInteger::ZERO
— void fmpzi_clear (fmpzi_t x)  
✓ void fmpzi_swap (fmpzi_t x, fmpzi_t y) mem::swap
✓ void fmpzi_zero (fmpzi_t x) GaussianInteger::ZERO
✓ void fmpzi_one (fmpzi_t x) GaussianInteger::ONE
✓ void fmpzi_set (fmpzi_t res, const fmpzi_t x) Clone
✓ void fmpzi_set_si_si (fmpzi_t res, slong a, slong b) GaussianInteger { real: Integer::from(a), imaginary: Integer::from(b) }

fmpzi_init, fmpzi_clear. let x = GaussianInteger::ZERO;, or Default. Dropping replaces clearing; see the GMP page.

fmpzi_swap, fmpzi_zero, fmpzi_one, fmpzi_set. mem::swap(&mut x, &mut y), x = GaussianInteger::ZERO, x = GaussianInteger::ONE, and res = x.clone() or res.clone_from(&x), the latter reusing the destination’s storage as fmpzi_set does.

fmpzi_set_si_si. The struct literal, with each part converted from any primitive integer or from a Natural. A purely real value can also be built with GaussianInteger::from(a).

Input and output

  FLINT Malachite
≈ void fmpzi_print (const fmpzi_t x) Display

fmpzi_print. print!("{x}"). The formats differ: FLINT always prints both parts and *I, as in 3+4*I, 3+0*I, 0-1*I, while Malachite’s Display omits a zero part and a unit coefficient, as in 3+4i, 3, -i.

Random number generation

  FLINT Malachite
≈ void fmpzi_randtest (fmpzi_t res, flint_rand_t state, flint_bitcnt_t bits) random_gaussian_integers, striped_random_gaussian_integers

fmpzi_randtest. Two independent fmpz_randtest draws, one per part, so the notes on the fmpz page apply to each part. Malachite’s generators also draw the parts independently, in plain and striped flavors; they are infinite iterators over a Seed rather than calls against a state, their size parameter is a mean bit length rather than a bound, and they require the random feature.

Properties

  FLINT Malachite
✓ int fmpzi_equal (const fmpzi_t x, const fmpzi_t y) ==
✓ int fmpzi_is_zero (const fmpzi_t x) x == 0u32
✓ int fmpzi_is_one (const fmpzi_t x) x == 1u32

fmpzi_is_zero, fmpzi_is_one. Mixed-type PartialEq against a primitive integer, which holds when the imaginary part is zero and the real part matches.

Units

  FLINT Malachite
✓ int fmpzi_is_unit (const fmpzi_t x) is_unit
✓ slong fmpzi_canonical_unit_i_pow (const fmpzi_t x) canonical_unit_i_pow
✓ void fmpzi_canonicalise_unit (fmpzi_t res, const fmpzi_t x) canonicalize_unit

Units. Both libraries choose the same canonical associate, tie for tie: the one whose argument lies in \((-\pi/4, \pi/4]\), that is, whose real part is positive and at least the imaginary part in absolute value, with \(a + ai\) chosen on the diagonal. Zero is its own canonical form. canonical_unit_i_pow returns the \(k \in \{0, 1, 2, 3\}\) with \(x i^k\) canonical, as a u64; canonicalize_unit has an in-place _assign form.

Norms

  FLINT Malachite
✓ slong fmpzi_bits (const fmpzi_t x) max_significant_bits
✓ void fmpzi_norm (fmpz_t res, const fmpzi_t x) abs_squared

fmpzi_bits. The bit length of the larger part in absolute value. It is not what significant_bits returns for a GaussianInteger, which is the sum of the two parts’ counts.

fmpzi_norm. \(a^2 + b^2\), returned as an Integer.

Arithmetic

  FLINT Malachite
✓ void fmpzi_conj (fmpzi_t res, const fmpzi_t x) conjugate
✓ void fmpzi_neg (fmpzi_t res, const fmpzi_t x) -
✓ void fmpzi_add (fmpzi_t res, const fmpzi_t x, const fmpzi_t y) +
✓ void fmpzi_sub (fmpzi_t res, const fmpzi_t x, const fmpzi_t y) -
✓ void fmpzi_sqr (fmpzi_t res, const fmpzi_t x) square
✓ void fmpzi_mul (fmpzi_t res, const fmpzi_t x, const fmpzi_t y) *
✓ void fmpzi_pow_ui (fmpzi_t res, const fmpzi_t x, ulong exp) pow, pow_assign
✓ void fmpzi_mul_i (fmpzi_t z, const fmpzi_t x) mul_i
✓ void fmpzi_div_i (fmpzi_t z, const fmpzi_t x) div_i
✓ void fmpzi_mul_i_pow_si (fmpzi_t res, const fmpzi_t z, slong k) mul_i_pow, mul_i_pow_assign

Ownership. Each operation comes in the usual ownership variants, x + y, x + &y, &x + y, &x + &y, and x += y, with the by-value forms reusing their operand’s storage; the trait methods have _assign forms, such as square_assign. pow takes a u64 exponent.

fmpzi_mul_i, fmpzi_div_i, fmpzi_mul_i_pow_si. Declared in the header but not listed in the manual chapter. MulIPow takes a u64 exponent; since only \(k \bmod 4\) matters, pass that for a negative FLINT exponent \(k\).

Division

  FLINT Malachite
✓ void fmpzi_divexact (fmpzi_t q, const fmpzi_t x, const fmpzi_t y) div_exact
✓ void fmpzi_divrem (fmpzi_t q, fmpzi_t r, const fmpzi_t x, const fmpzi_t y) div_rem, div_assign_rem
— void fmpzi_divrem_approx (fmpzi_t q, fmpzi_t r, const fmpzi_t x, const fmpzi_t y)  
✓ slong fmpzi_remove_one_plus_i (fmpzi_t res, const fmpzi_t x) remove_one_plus_i, remove_one_plus_i_assign

fmpzi_divexact. As in FLINT, the division must be exact; otherwise the result is unspecified and may be a panic.

fmpzi_divrem. Malachite rounds as FLINT does: each part of the exact quotient is rounded to the nearest integer, with ties rounded up, so the remainder’s norm satisfies \(N(r) \leq N(y) / 2\) and the result agrees with FLINT’s at ties. The / and % operators return the two halves of the same pair.

fmpzi_divrem_approx. Its quotient depends on a double-precision estimate and guarantees only \(N(r) < N(y)\), without fixing which remainder; Malachite has no public counterpart, and div_rem satisfies the stronger bound.

fmpzi_remove_one_plus_i. Returns the reduced number and the exponent as a tuple, as RemovePower does for fmpz_remove; the _assign form reduces in place and returns the exponent. Zero maps to zero with exponent 0, as in FLINT.

GCD

  FLINT Malachite
— void fmpzi_gcd_euclidean (fmpzi_t res, const fmpzi_t x, const fmpzi_t y)  
⚙ void fmpzi_gcd_euclidean_improved (fmpzi_t res, const fmpzi_t x, const fmpzi_t y) Gcd, GcdAssign
— void fmpzi_gcd_binary (fmpzi_t res, const fmpzi_t x, const fmpzi_t y)  
— void fmpzi_gcd_shortest (fmpzi_t res, const fmpzi_t x, const fmpzi_t y)  
✓ void fmpzi_gcd (fmpzi_t res, const fmpzi_t x, const fmpzi_t y) Gcd, GcdAssign

The GCD family. Every FLINT variant returns the GCD in canonical unit form, so all five return the same value, and so does Malachite’s gcd. The named variants differ only in algorithm, and Malachite does not expose them separately.

Primality testing

  FLINT Malachite
✗ int fmpzi_is_prime (const fmpzi_t n)  
✗ int fmpzi_is_probabprime (const fmpzi_t n)  

fmpzi_is_prime, fmpzi_is_probabprime. No counterpart, because Malachite has no bignum primality test; see the fmpz page. FLINT’s test: a purely real or purely imaginary value is prime when its nonzero part is, in absolute value, a prime congruent to 3 modulo 4; any other value is prime when its norm is prime.