.. _gr-domains:

**gr.h (continued)** -- builtin domains and types
===============================================================================

Coercions
-------------------------------------------------------------------------------

.. function:: int gr_ctx_cmp_coercion(gr_ctx_t ctx1, gr_ctx_t ctx2)

    Returns 1 if coercing elements into *ctx1* is more meaningful,
    and returns -1 otherwise.



Domain properties
-------------------------------------------------------------------------------

.. function:: truth_t gr_ctx_is_finite(gr_ctx_t ctx)
              truth_t gr_ctx_is_multiplicative_group(gr_ctx_t ctx)
              truth_t gr_ctx_is_ring(gr_ctx_t ctx)
              truth_t gr_ctx_is_commutative_ring(gr_ctx_t ctx)
              truth_t gr_ctx_is_integral_domain(gr_ctx_t ctx)
              truth_t gr_ctx_is_unique_factorization_domain(gr_ctx_t ctx)
              truth_t gr_ctx_is_field(gr_ctx_t ctx)
              truth_t gr_ctx_is_algebraically_closed(gr_ctx_t ctx)
              truth_t gr_ctx_is_rational_vector_space(gr_ctx_t ctx)
              truth_t gr_ctx_is_real_vector_space(gr_ctx_t ctx)
              truth_t gr_ctx_is_complex_vector_space(gr_ctx_t ctx)
              truth_t gr_ctx_is_finite_characteristic(gr_ctx_t ctx)
              truth_t gr_ctx_is_ordered_ring(gr_ctx_t ctx)
              truth_t gr_ctx_is_zero_ring(gr_ctx_t ctx)

    Returns whether the structure satisfies the respective
    mathematical property.
    The result can be ``T_UNKNOWN``.

.. function:: truth_t gr_ctx_is_approx_commutative_ring(gr_ctx_t ctx)

    Returns whether the structure `\tilde R` implemented by ``ctx`` is assumed
    to represent an approximate version of a structure `R` with the
    respective mathematical property.
    The usual axioms need not hold exactly as long as they hold
    within a small perturbation, i.e. an axiom of the type `a = b` in `R` is
    replaced by an axiom of the type
    `|\tilde a - \tilde b| < \varepsilon` in `\tilde R`.
    For example, polynomials with floating-point coefficients are
    considered an approximate commutative ring, but two by two matrices
    with floating-point coefficients are not.

    The exact structure is trivially considered an approximate version of
    itself; for example, every commutative ring is considered to be an
    approximate commutative ring.

.. function:: truth_t gr_ctx_is_exact(gr_ctx_t ctx)

    Returns whether the representation of elements is always exact.

.. function:: truth_t gr_ctx_is_canonical(gr_ctx_t ctx)

    Returns whether the representation of elements is always canonical.

.. function:: truth_t gr_ctx_has_real_prec(gr_ctx_t ctx)

    Returns whether *ctx* or a base field thereof represents real or complex
    numbers using finite-precision approximations.
    This returns ``T_TRUE`` both for floating-point approximate
    fields and for rigorous fields based on ball or interval arithmetic.

.. function:: int gr_ctx_set_real_prec(gr_ctx_t ctx, slong prec)
              int gr_ctx_get_real_prec(slong * prec, gr_ctx_t ctx)

    Sets or retrieves the floating-point precision in bits.

Debugging
-------------------------------------------------------------------------------

.. function:: void gr_ctx_init_debug(gr_ctx_t ctx, gr_ctx_t elem_ctx, int flags, double unable_probability)

    Initialize *ctx* to a wrapper around *elem_ctx* for debugging.
    This will execute supported methods (currently only a handful
    of methods are supported, e.g. ``gr_add``) as if one is computing
    directly over *elem_ctx*, but with added debugging features.

    If *unable_probability* is positive, some methods will randomly return
    ``GR_UNABLE`` and predicates will randomly return ``T_UNKNOWN``.

    The following flags are supported:

    * ``GR_DEBUG_WRAP`` - wrap elements in a box with a pointer. This allows
      performing extra checks such as whether a variable is being cleared
      twice or whether the wrong context object is passed as input. It can
      also help catch some bugs that are not revealed when entries are
      stored shallowly.

    * ``GR_DEBUG_VERBOSE`` - print debugging information for each operation.

    * ``GR_DEBUG_TIMING`` - print elapsed time for each operation.


Groups
-------------------------------------------------------------------------------

.. function:: void gr_ctx_init_perm(gr_ctx_t ctx, ulong n)

    Initializes *ctx* to the symmetric group `S_n` representing
    permutations of `[0, 1, \ldots, n - 1]`.
    Elements are currently represented as pointers (the representation
    may change in the future).

.. function:: void gr_ctx_init_psl2z(gr_ctx_t ctx)

    Initializes *ctx* to the modular group `\text{PSL}(2, \mathbb{Z})`
    with elements of type :type:`psl2z_t`.

.. function:: int gr_ctx_init_dirichlet_group(gr_ctx_t ctx, ulong q)

    Initializes *ctx* to the Dirichlet group `G_q`
    with elements of type :type:`dirichlet_char_t`.
    Fails and returns ``GR_DOMAIN`` if *q* is zero.
    Fails and returns ``GR_UNABLE`` if *q* has a prime factor
    larger than `10^{16}`, which is currently unsupported
    by the implementation.

Basic rings and fields
-------------------------------------------------------------------------------

.. function:: void gr_ctx_init_random(gr_ctx_t ctx, flint_rand_t state)
              void gr_ctx_init_random_commutative_ring(gr_ctx_t ctx, flint_rand_t state)
              void gr_ctx_init_random_field(gr_ctx_t ctx, flint_rand_t state)

    Initializes *ctx* to a random ring. This will currently
    only generate base rings and composite rings over certain
    simple base rings.

.. function:: void gr_ctx_init_fmpz(gr_ctx_t ctx)

    Initializes *ctx* to the ring of integers
    `\mathbb{Z}` with elements of type :type:`fmpz`.

.. function:: void gr_ctx_init_fmpq(gr_ctx_t ctx)

    Initializes *ctx* to the field of rational numbers
    `\mathbb{Q}` with elements of type :type:`fmpq`.

.. function:: void gr_ctx_init_fmpzi(gr_ctx_t ctx)

    Initializes *ctx* to the ring of Gaussian integers
    `\mathbb{Z}[i]` with elements of type :type:`fmpzi_t`.

Residue rings and finite fields
-------------------------------------------------------------------------------

.. function:: int gr_ctx_set_is_field(gr_ctx_t ctx, truth_t is_field)

    Set whether the given ring is actually a field. For example,
    in the case of `\mathbb{Z}/n\mathbb{Z}`, this sets whether
    the modulus is prime. This can speed up some computations and
    enable some functions to complete that otherwise would
    return ``GR_UNABLE``.

See:

* :func:`gr_ctx_init_nmod`
  :func:`gr_ctx_init_nmod8`
  :func:`gr_ctx_init_nmod32`
  :func:`gr_ctx_init_nmod_redc`
  :func:`gr_ctx_init_nmod_redc_fast`

.. function:: void gr_ctx_init_fmpz_mod(gr_ctx_t ctx, const fmpz_t n)

    Initializes *ctx* to the ring `\mathbb{Z}/n\mathbb{Z}`
    of integers modulo *n* where
    elements have type :type:`fmpz`. The modulus must be positive.

* :func:`gr_ctx_init_mpn_mod`

    Initializes *ctx* to the ring `\mathbb{Z}/n\mathbb{Z}`
    of integers modulo *n* where
    elements are flat limb arrays with the same number of limbs as *n*.

.. function:: void gr_ctx_init_fq(gr_ctx_t ctx, const fmpz_t p, slong d, const char * var)
              void gr_ctx_init_fq_nmod(gr_ctx_t ctx, ulong p, slong d, const char * var)
              void gr_ctx_init_fq_zech(gr_ctx_t ctx, ulong p, slong d, const char * var)

    Initializes *ctx* to the finite field `\mathbb{F}_q`
    where `q = p^d`. It is assumed (not checked) that *p* is prime.
    The variable name *var* can be ``NULL`` to use a default.

    The corresponding element types are ``fq_t``, ``fq_nmod_t``, ``fq_zech_t``.
    The ``fq_zech`` context requires `q < 2^{64}` (and in practice a much
    smaller value than this).

Number fields and algebraic numbers
-------------------------------------------------------------------------------

.. function:: void gr_ctx_init_nf(gr_ctx_t ctx, const fmpq_poly_t poly)
              void gr_ctx_init_nf_fmpz_poly(gr_ctx_t ctx, const fmpz_poly_t poly)

    Initializes *ctx* to the number field with defining polynomial
    ``poly`` which *must* be irreducible (this is not checked).
    The elements have type :type:`nf_elem_t`.

.. function:: void gr_ctx_init_real_qqbar(gr_ctx_t ctx)
              void gr_ctx_init_complex_qqbar(gr_ctx_t ctx)

    Initializes *ctx* to the field of real or complex algebraic
    numbers with elements of type :type:`qqbar_t`.

.. function:: void _gr_ctx_qqbar_set_limits(gr_ctx_t ctx, slong deg_limit, slong bits_limit)

    Limit degrees of intermediate operands of a *qqbar* context
    to *deg_limit* and their bit sizes to *bits_limit* (approximately).
    The limits refer to the sizes of resultants prior to
    factorization (see :func:`qqbar_binop_within_limits`), so for example
    adding two degree-100 algebraic numbers
    requires a degree limit of at least 10000.
    Warning: currently not all methods respect these limits.

Real and complex numbers
-------------------------------------------------------------------------------

.. function:: void gr_ctx_init_real_arb(gr_ctx_t ctx, slong prec)
              void gr_ctx_init_complex_acb(gr_ctx_t ctx, slong prec)

    Initializes *ctx* to the field of real or complex
    numbers represented by elements of type :type:`arb_t`
    and  :type:`acb_t`.

.. function:: void gr_ctx_arb_set_prec(gr_ctx_t ctx, slong prec)
              slong gr_ctx_arb_get_prec(gr_ctx_t ctx)

    Sets or retrieves the bit precision of *ctx* which must be
    an Arb context (this is currently not checked).

.. function:: void gr_ctx_init_real_ca(gr_ctx_t ctx)
              void gr_ctx_init_complex_ca(gr_ctx_t ctx)
              void gr_ctx_init_real_algebraic_ca(gr_ctx_t ctx)
              void gr_ctx_init_complex_algebraic_ca(gr_ctx_t ctx)

    Initializes *ctx* to the field of real, complex, real algebraic
    or complex algebraic numbers represented by elements of type
    :type:`ca_t`.

.. function:: void gr_ctx_ca_set_option(gr_ctx_t ctx, slong option, slong value)
              slong gr_ctx_ca_get_option(gr_ctx_t ctx, slong option)

    Sets or retrieves options of a Calcium context object.

.. function:: void gr_ctx_init_gr_complex(gr_ctx_t ctx, gr_ctx_t real_ctx)

    Initializes *ctx* to a generic implementation of the complex algebra `R[i]`
    where `R` is represented by *real_ctx*.
    Elements `a + bi` are represented as pairs `(a, b)` of elements of `R`
    stored contiguously in memory.

    Typically `R` will be an implementation of the real numbers or a subring
    of the real numbers in which case this creates the complex numbers or
    a subring of the complex numbers. This construction
    also makes sense e.g. over real vector spaces and even general rings
    (where `i` will just be a formal element satisfying `i^2 = -1`),
    but in that case operations beyond basic arithmetic (e.g. absolute value)
    may not make sense.

Extended number sets
-------------------------------------------------------------------------------

.. function:: void gr_ctx_init_complex_extended_ca(gr_ctx_t ctx)

    Like :func:`gr_ctx_init_complex_ca` but allows special values
    (infinities, undefined).

Floating-point arithmetic
-------------------------------------------------------------------------------

Although domains of floating-point numbers approximate
real and complex fields, they are not rings or fields.
Floating-point arithmetic can be used in many places where a ring
or field is normally assumed, but predicates like "is field"
return false.

* Equality compares equality of floating-point numbers,
  with the special rule that NaN is not equal to itself.
* In general, the following implementations do not currently
  guarantee correct rounding except for atomic arithmetic operations
  (add, sub, mul, div, sqrt) on real floating-point numbers.

.. function:: void gr_ctx_init_real_float_arf(gr_ctx_t ctx, slong prec)

    Initializes *ctx* to the floating-point arithmetic with elements
    of type :type:`arf_t` and a default precision of *prec* bits.

.. function:: void gr_ctx_init_complex_float_acf(gr_ctx_t ctx, slong prec)

    Initializes *ctx* to the complex floating-point arithmetic with elements
    of type :type:`acf_t` and a default precision of *prec* bits.

Vectors
-------------------------------------------------------------------------------

.. function:: void gr_ctx_init_vector_gr_vec(gr_ctx_t ctx, gr_ctx_t base_type)

    Initializes *ctx* to the domain of all vectors (of any length)
    over the given *base_type*.
    Elements have type :type:`gr_vec_struct`.

.. function:: void gr_ctx_init_vector_space_gr_vec(gr_ctx_t ctx, gr_ctx_t base_type, slong n)

    Initializes *ctx* to the space of all vectors of length *n*
    over the given *base_type*.
    Elements have type :type:`gr_vec_struct`.

Matrices
-------------------------------------------------------------------------------

.. function:: void gr_ctx_init_matrix_domain(gr_ctx_t ctx, gr_ctx_t base_ring)

    Initializes *ctx* to the domain of all matrices (of any shape)
    over the given *base_ring*.
    Elements have type :type:`gr_mat_struct`.

.. function:: void gr_ctx_init_matrix_space(gr_ctx_t ctx, gr_ctx_t base_ring, slong n, slong m)

    Initializes *ctx* to the space of matrices over *base_ring*
    with *n* rows and *m* columns.
    Elements have type :type:`gr_mat_struct`.

.. function:: void gr_ctx_init_matrix_ring(gr_ctx_t ctx, gr_ctx_t base_ring, slong n)

    Initializes *ctx* to the ring of matrices over *base_ring*
    with *n* rows columns.
    Elements have type :type:`gr_mat_struct`.

Polynomial rings
-------------------------------------------------------------------------------

.. function:: void gr_ctx_init_fmpz_poly(gr_ctx_t ctx)

    Initializes *ctx* to a ring of integer polynomials of
    type :type:`fmpz_poly_struct`.

.. function:: void gr_ctx_init_fmpq_poly(gr_ctx_t ctx)

    Initializes *ctx* to a ring of rational polynomials of
    type :type:`fmpq_poly_struct`.

.. function:: void gr_ctx_init_gr_poly(gr_ctx_t ctx, gr_ctx_t base_ring)

    Initializes *ctx* to a ring of densely represented univariate polynomials
    over the given *base_ring*.
    Elements have type :type:`gr_poly_struct`.

.. function:: void gr_ctx_init_random_poly(gr_ctx_t ctx, flint_rand_t state)

    Initializes *ctx* to a random univariate polynomial ring.

.. function:: void gr_ctx_init_fmpz_mpoly(gr_ctx_t ctx, slong nvars, const ordering_t ord)

    Initializes *ctx* to a ring of sparsely represented multivariate
    polynomials in *nvars* variables over the integers,
    with monomial ordering *ord*.
    Elements have type :type:`fmpz_mpoly_struct`.

.. function:: void gr_ctx_init_fmpq_mpoly(gr_ctx_t ctx, slong nvars, const ordering_t ord)

    Initializes *ctx* to a ring of sparsely represented multivariate
    polynomials in *nvars* variables over the rationals,
    with monomial ordering *ord*.
    Elements have type :type:`fmpq_mpoly_struct`.

.. function:: void gr_ctx_init_gr_mpoly(gr_ctx_t ctx, gr_ctx_t base_ring, slong nvars, const ordering_t ord)

    Initializes *ctx* to a ring of sparsely represented multivariate
    polynomials in *nvars* variables over the given *base_ring*,
    with monomial ordering *ord*.
    Elements have type :type:`gr_mpoly_struct`.

.. function:: void gr_ctx_init_random_mpoly(gr_ctx_t ctx, flint_rand_t state)

    Initializes *ctx* to a random multivariate polynomial ring.

Ore polynomials
-------------------------------------------------------------------------------

.. function:: void gr_ctx_init_gr_ore_poly(gr_ctx_t ctx, gr_ctx_t base_ring, slong base_var, const ore_algebra_t which_algebra)

    Initializes *ctx* to a ring of densely represented Ore polynomials over the
    given *base_ring*, with the choice of Ore algebra structure given by
    *which_algebra*. The Ore algebra structure may refer to a distinguished
    generator of *base_ring*; this will be the generator of index *base_var*.
    Elements have type :type:`gr_ore_poly_struct`.

Power series
-------------------------------------------------------------------------------

See :func:`gr_series_ctx_init` and :func:`gr_series_mod_ctx_init`
in :ref:`gr-series`.

.. function:: void gr_ctx_init_random_series(gr_ctx_t ctx, flint_rand_t state)

    Initializes *ctx* to a random power series ring.

Fraction fields
-------------------------------------------------------------------------------

.. function:: void gr_ctx_init_gr_fraction(gr_ctx_t ctx, gr_ctx_t domain, int flags)

    Initializes *ctx* to a generic implementation of the fraction field
    over the given integral domain *domain*.
    Fractions are represented as pairs of elements of *domain*, stored
    consecutively in memory as (numerator, denominator).
    By default, fractions are simplified by removing common content between
    the numerator and denominator (using :func:`gr_gcd`) and normalising the
    denominator by a canonical unit (using :func:`gr_canonical_associate`).
    The following optional *flags* can be set:

    .. macro :: GR_FRACTION_NO_REDUCTION

        Setting this flag disables canonicalisation, allowing
        one to perform fraction field arithmetic over domains which do not
        implement GCD or unit canonicalisation.
        This flag can also improve performance in certain cases when
        GCDs are more expensive than just allowing coefficients to blow up.

    .. macro :: GR_FRACTION_STRONGLY_CANONICAL

        Assert that fractions are in strongly canonical form,
        meaning that `a/b = c/d` if and only if `a = c` and `b = d`.
        Setting this flag allows faster equality testing.
        This should be valid in UFDs that implement a correct GCD and
        correct unit canonicalisation, but need not be true over
        integral domains which are not UFDs. In this future this may
        be automatic.

    This constructor does not verify that *domain* is really an integral
    domain. The behavior over non-integral domains is undefined, as no attempt
    is made to detect the product of two nonzero denominators becoming zero.
    In the future, such checks may be implemented as an optional feature.

.. function:: void gr_ctx_init_fmpz_mpoly_q(gr_ctx_t ctx, slong nvars, const ordering_t ord)

    Initializes *ctx* to a ring of sparsely represented multivariate
    fractions in *nvars* variables over the integers (equivalently, rationals),
    with monomial ordering *ord*.
    Elements have type :type:`fmpz_mpoly_q_struct`.

.. function:: void gr_ctx_init_fmpz_mod_mpoly_q(gr_ctx_t ctx, slong nvars, const ordering_t ord, const fmpz_t mod)

    Initializes *ctx* to a ring of sparsely represented multivariate
    fractions in *nvars* variables over the `\mathbb{F}_mod` field,
    with monomial ordering *ord*, and *mod* being a prime number.
    The user is responsible
    for verifying that *mod* is a prime number;
    if *mod* is composite, undefined behaviour may occur.
    Elements have type :type:`fmpz_mod_mpoly_q_struct`.

Symbolic expressions
-------------------------------------------------------------------------------

.. function:: void gr_ctx_init_fexpr(gr_ctx_t ctx)

    Initializes *ctx* to handle symbolic expressions.
    Elements have type :type:`fexpr_struct`.

.. raw:: latex

    \newpage
