View on GitHub

malachite

An arbitrary-precision arithmetic library for Rust.

Malachite for FLINT Users: Rational Vectors

This page maps the functions of FLINT’s rational vector module, fmpq_vec.h, onto their Malachite counterpart: RationalVector, from the malachite-q crate. It follows the organization of the fmpq_vec.h chapter of the FLINT manual, as of FLINT 3.6.0. It is a companion to Malachite for FLINT Users: Integer Vectors, whose conventions apply here as well, and to Malachite for FLINT Users: Rationals; the mapping index lists the whole family.

Every section of the chapter is mapped below: 13 rows across 8 sections, of which 8 are ✓, 3 ≈, 1 —, and 1 ✗. All of the chapter’s functions have names beginning with an underscore, and all are included (see Representation). The one ✗ row is a random generator, _fmpq_vec_randtest_uniq_sorted.

Conventions

Representation

fmpq_vec.h has no vector object. Every function works on a bare array, an fmpq * together with a separate slong length, which the caller allocates, tracks, and frees, and every function name begins with an underscore. As on the integer vector page, those functions are mapped here.

RationalVector is a single public field, elements, of type Vec<Rational>. Both libraries store the elements entrywise: each element is a rational number of its own, in lowest terms, rather than a numerator over a denominator shared by the whole vector, as in fmpq_poly. to_numerators_and_denominator gives the common-denominator form when it is wanted.

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.

Memory management

  FLINT Malachite
✓ fmpq * _fmpq_vec_init(slong n) zero
— void _fmpq_vec_clear(fmpq * vec, slong n)  

_fmpq_vec_init returns n zeros, each with denominator 1, which is zero, the Vector method that returns the zero vector of a given dimension: RationalVector::zero(n). _fmpq_vec_clear is Drop, which runs when the vector goes out of scope.

Randomisation

  FLINT Malachite
≈ void _fmpq_vec_randtest(fmpq * f, flint_rand_t state, slong len, flint_bitcnt_t bits) random_rational_vectors_with_dimension, striped_random_rational_vectors_with_dimension, random_rational_vectors_with_dimension_from_iterator
✗ void _fmpq_vec_randtest_uniq_sorted(fmpq * vec, flint_rand_t state, slong len, flint_bitcnt_t bits)  

_fmpq_vec_randtest fills a vector of length len, drawing each element with fmpq_randtest, which caps the numerator and denominator at bits bits. Half the time it makes the vector sparse, exactly as _fmpz_vec_randtest does. Malachite’s counterparts are infinite iterators of vectors of a given dimension. The elements of the first two come from random_rationals or striped_random_rationals, which take a mean bit length with no cap, and there is no sparse mode, so the distributions differ. The third takes its elements from any iterator, so a bounded element stream, such as random_rational_range, gives a hard bound on the values.

_fmpq_vec_randtest_uniq_sorted produces distinct elements in ascending order. It draws a vector with _fmpq_vec_randtest, then repeatedly sorts it and redraws any element equal to its neighbour until none are. Malachite has no generator of distinct sorted vectors yet. The implementation throws an error unless bits is at least four times the bit length of len, a requirement the manual does not state; since FLINT counts the bit length of 0 as 1, this means bits must be at least 4 even when len is 0 or 1.

Bit sizes and heights

  FLINT Malachite
✓ void _fmpq_vec_max_height(fmpz_t height, const fmpq * vec, slong len) Height, HeightRef
✓ flint_bitcnt_t _fmpq_vec_max_height_bits(const fmpq * vec, slong len) height_significant_bits

The height of a rational number \(p/q\) in lowest terms is \(\max(|p|, q)\), and max_height is the largest height of any element, with max_height_bits its bit length. These are Height’s to_height (or into_height) and height_significant_bits. Since every element is kept in lowest terms, the height is the numerator or denominator of one of the elements, so HeightRef lends it rather than building it. The index of an element of largest height, which this chapter does not provide, is height_index.

As in FLINT, the height of the 0-dimensional vector is 0. Every other vector has height at least 1, since every denominator is at least 1; a vector of zeros has height 1, the height of \(0 = 0/1\). Malachite’s RationalPolynomial gives its zero polynomial, which has no coefficients, height 1 rather than 0.

Comparison

  FLINT Malachite
✓ int _fmpq_vec_equal(const fmpq * vec1, const fmpq * vec2, slong len) PartialEq

_fmpq_vec_equal compares two arrays over a length the caller supplies; PartialEq on RationalVector also requires the dimensions to match. Since every element is kept in lowest terms, two vectors are equal exactly when their elements are identical. A RationalVector can also be compared with an IntegerVector, NaturalVector, or UnsignedVector, which it equals when it has the same dimension and the same values.

Sorting

  FLINT Malachite
✓ void _fmpq_vec_sort(fmpq * vec, slong len) sort

The manual does not say in which order _fmpq_vec_sort sorts; the implementation uses the C library’s qsort with fmpq_cmp, so the order is ascending by value, as for _fmpz_vec_sort. It is sort, a Vector method, which sorts in place by value.

Conversions

  FLINT Malachite
✓ void _fmpq_vec_set_fmpz_vec(fmpq * res, const fmpz * vec, slong len) From<IntegerVector>
✓ void _fmpq_vec_get_fmpz_vec_fmpz(fmpz * num, fmpz_t den, const fmpq * a, slong len) to_numerators_and_denominator

_fmpq_vec_set_fmpz_vec converts each integer to a rational with denominator 1, which is From<IntegerVector>; the conversion takes the IntegerVector by value, so clone it first if it is still needed. The reverse, TryFrom<RationalVector> for IntegerVector, succeeds when every element is an integer, and has no counterpart in this chapter.

_fmpq_vec_get_fmpz_vec_fmpz writes a vector over a common denominator: the least common multiple of the elements’ denominators, with each numerator scaled to it. It is 1 for the empty vector. to_numerators_and_denominator computes the same denominator and numerators, returning them as an IntegerVector and a Natural; into_numerators_and_denominator consumes the vector instead of cloning its elements, and from_numerators_and_denominator converts back, a direction this chapter does not provide. fmpq_vec.h declares _fmpq_vec_get_fmpz_vec_fmpz twice, with identical prototypes.

Dot product

  FLINT Malachite
✓ void _fmpq_vec_dot(fmpq_t res, const fmpq * vec1, const fmpq * vec2, slong len) Dot

_fmpq_vec_dot sets res to \(\sum_i a_i b_i\), which is \(0\) for the empty vector. It is Dot’s v.dot(w) for RationalVector, with each vector taken by value or by reference; the vectors must have the same dimension. FLINT computes it with one fmpq_addmul per pair, each reducing to lowest terms (see fmpq_addmul). Dot instead writes each vector as integer numerators over a common denominator, takes one integer dot product, and reduces once. Unlike _fmpz_vec_dot, there is no _fmpq_vec_dot_general with an initial term, subtraction, or reversal.

Input and output

  FLINT Malachite
≈ int _fmpq_vec_fprint(FILE * file, const fmpq * vec, slong len) Display, Serialize
≈ int _fmpq_vec_print(const fmpq * vec, slong len) Display, Serialize

The vector formats differ, hence ≈, as for integer vectors. FLINT writes the length, two spaces, and then the elements separated by single spaces, so \((1/2, -2, 3)\) is 3 1/2 -2 3 and the empty vector is 0. Malachite’s Display writes (1/2, -2, 3), with () for the 0-dimensional vector. The elements themselves are written the same way by both libraries, as p/q, or as just p when the denominator is 1. With the serde feature, RationalVector is serialized as a plain list of its elements.

Unlike fmpz_vec.h, this chapter has no functions for reading a vector. Malachite’s FromStr reads the form that Display writes, and Deserialize reads the serialized form.