gr_ore_poly.h
#include <flint/gr_ore_poly.h>This module implements Ore polynomials with coefficients in a ring given by a generic context [Ore1933; BroPet1996]. The multiplication is twisted by an endomorphism of and a -derivation (an additive map with ) through the commutation rule
With and , , Ore polynomials are linear differential operators; with , , linear recurrence (shift) operators; and so on for the predefined algebras listed below. The context of an Ore polynomial ring is a gr_ctx_t, so Ore polynomials can be used with the generic functions (gr_mul composes operators) and in other generic structures.
Example#
The program below multiplies differential operators over , where , and recurrence operators, where . Coefficients are written on the left of the powers of the generator.
#include <flint/flint.h>
#include <flint/gr.h>
#include <flint/gr_poly.h>
#include <flint/gr_ore_poly.h>
int main(void)
{
gr_ctx_t QQ, QQx, Dx, Sx;
gr_ore_poly_t L, M, P;
gr_ctx_init_fmpq(QQ);
gr_ctx_init_gr_poly(QQx, QQ); /* base ring Q[x] */
/* differential operators: D x = x D + 1 */
gr_ore_poly_ctx_init(Dx, QQx, 0, ORE_ALGEBRA_DERIVATIVE);
gr_ore_poly_init(L, Dx);
gr_ore_poly_init(M, Dx);
gr_ore_poly_init(P, Dx);
GR_MUST_SUCCEED(gr_ore_poly_set_str(L, "D", Dx));
GR_MUST_SUCCEED(gr_ore_poly_set_str(M, "x", Dx));
GR_MUST_SUCCEED(gr_ore_poly_mul(P, L, M, Dx));
flint_printf("D * x = "); gr_ore_poly_print(P, Dx); flint_printf("\n");
GR_MUST_SUCCEED(gr_ore_poly_set_str(L, "x*D^2 + D - x", Dx));
GR_MUST_SUCCEED(gr_ore_poly_set_str(M, "D + x^2", Dx));
GR_MUST_SUCCEED(gr_ore_poly_mul(P, L, M, Dx));
flint_printf("L * M = "); gr_ore_poly_print(P, Dx); flint_printf("\n");
gr_ore_poly_clear(L, Dx);
gr_ore_poly_clear(M, Dx);
gr_ore_poly_clear(P, Dx);
gr_ore_poly_ctx_clear(Dx);
/* recurrence operators: S x = (x + 1) S */
gr_ore_poly_ctx_init(Sx, QQx, 0, ORE_ALGEBRA_FORWARD_SHIFT);
GR_MUST_SUCCEED(_gr_ore_poly_ctx_set_gen_name(Sx, "S"));
gr_ore_poly_init(L, Sx);
gr_ore_poly_init(P, Sx);
GR_MUST_SUCCEED(gr_ore_poly_set_str(L, "S - x - 1", Sx));
GR_MUST_SUCCEED(gr_ore_poly_mul(P, L, L, Sx));
flint_printf("(S - x - 1)^2 = "); gr_ore_poly_print(P, Sx); flint_printf("\n");
gr_ore_poly_clear(L, Sx);
gr_ore_poly_clear(P, Sx);
gr_ore_poly_ctx_clear(Sx);
gr_ctx_clear(QQx);
gr_ctx_clear(QQ);
return 0;
}D * x = 1 + x*D L * M = (4*x - x^3) + (-x + 5*x^2)*D + (1 + x^3)*D^2 + x*D^3 (S - x - 1)^2 = (1 + 2*x + x^2) + (-3 - 2*x)*S + S^2
Ore algebras#
The predefined Ore algebra structures, an enumeration with the values below. Except for the commutative and Frobenius algebras, they act on a distinguished generator of the base ring, which must currently be a univariate polynomial ring (created with gr_ctx_init_gr_poly); otherwise and return GR_UNABLE.
ORE_ALGEBRA_CUSTOM: and given by a user function (gr_ore_poly_ctx_init_custom).ORE_ALGEBRA_COMMUTATIVE: , ; ordinary polynomials in .ORE_ALGEBRA_DERIVATIVE: , ; linear differential operators.ORE_ALGEBRA_EULER_DERIVATIVE: , (the Euler operator ).ORE_ALGEBRA_FORWARD_SHIFT: , ; linear recurrence operators.ORE_ALGEBRA_FORWARD_DIFFERENCE: , (the operator ).ORE_ALGEBRA_BACKWARD_SHIFT: , .ORE_ALGEBRA_BACKWARD_DIFFERENCE: , (the operator ).ORE_ALGEBRA_Q_SHIFT: , ; linear -difference operators (gr_ore_poly_ctx_init_q_shift).ORE_ALGEBRA_MAHLER: , ; linear Mahler operators with base (gr_ore_poly_ctx_init_mahler).ORE_ALGEBRA_FROBENIUS: the Frobenius automorphism of a finite field (), computed withgr_fq_frobenius.
The value ORE_POLY_NUM_ALGEBRAS is the number of algebra types.
Returns a random Ore algebra type, favouring the derivative and the forward shift, for testing.
Types and conventions#
An Ore polynomial: an array coeffs of alloc coefficients in the base ring, of which the first length are used; the coefficient of is at index . The layout is that of gr_poly_t, so the functions of gr_poly that do not multiply (copying, truncation, addition, scalar operations, and the container functions) can be applied to the coefficient arrays with the base ring context.
The context of an Ore polynomial ring, a gr_ctx_t. Its data (type _gr_ore_poly_ctx_struct, compatible with the context data of gr_poly rings) holds the base ring, a degree limit, the name of the generator (D by default), the algebra type, the function computing and , and algebra-specific data (type gr_ore_poly_ore_data_t: the index of the distinguished generator base_var, and for -shifts, or the Mahler base).
GR_ORE_POLY_CTX(ctx)GR_ORE_POLY_ELEM_CTX(ctx)GR_ORE_POLY_ORE_DATA(ctx)The context data, the base ring, and the algebra-specific data of an Ore polynomial context.
The context argument of the functions is the context of the Ore polynomial ring (not the base ring as in gr_poly). As in gr_poly, Ore polynomials are weakly normalised (a leading coefficient is removed only if it is provably zero, so the length bounds the order plus one over inexact rings), functions returning int return status codes, and the functions with a leading underscore work on coefficient arrays without memory management.
Contexts#
void gr_ore_poly_ctx_init(gr_ore_poly_ctx_t ctx, gr_ctx_t base_ring, slong base_var, const ore_algebra_t which_algebra)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)Initialise ctx as the ring of Ore polynomials over base_ring with the predefined algebra which_algebra, acting on the generator with index base_var of the base ring. These are for the algebras without parameters; the -shift and Mahler algebras have their own constructors. The two functions are the same.
int gr_ore_poly_ctx_init_q_shift(gr_ore_poly_ctx_t ctx, gr_ctx_t base_ring, slong base_var, gr_srcptr q)int gr_ore_poly_ctx_init_mahler(gr_ore_poly_ctx_t ctx, gr_ctx_t base_ring, slong base_var, slong mahler_base)void gr_ore_poly_ctx_init_custom(gr_ore_poly_ctx_t ctx, gr_ctx_t base_ring, const gr_ore_poly_sigma_delta_t sigma_delta, void * ore_data)void * gr_ore_poly_ctx_data_ptr(gr_ore_poly_ctx_t ctx)gr_ore_poly_ctx_init_custom initialises ctx with a user-defined algebra: sigma_delta computes and (see gr_ore_poly_sigma_delta), and ore_data is a pointer to data for it, which sigma_delta can retrieve with gr_ore_poly_ctx_data_ptr(ctx). The data is not freed by gr_ore_poly_ctx_clear.
void gr_ore_poly_ctx_init_randtest(gr_ore_poly_ctx_t ctx, flint_rand_t state, gr_ctx_t base_ring)void gr_ore_poly_ctx_init_randtest2(gr_ctx_t base_ring, gr_ore_poly_ctx_t ctx, flint_rand_t state)Initialise ctx with a random algebra over base_ring, or (the second function) over a random base ring that it initialises in base_ring, for testing.
void gr_ore_poly_ctx_clear(gr_ore_poly_ctx_t ctx)Clears the context and the algebra data it owns.
int _gr_ore_poly_ctx_set_gen_name(gr_ctx_t ctx, const char * s)int _gr_ore_poly_ctx_set_gen_names(gr_ctx_t ctx, const char ** s)int gr_ore_poly_gens_recursive(gr_vec_t vec, gr_ore_poly_ctx_t ctx)Set the name of the generator to s (respectively s[0]), and set vec to the generators of the base ring (as constant Ore polynomials) followed by .
int gr_ore_poly_ctx_write(gr_stream_t out, gr_ore_poly_ctx_t ctx)Context methods. Whether the ring is a ring, the zero ring or thread-safe is inherited from the base ring; commutativity and the absence of zero divisors are currently reported as T_UNKNOWN.
Memory management#
void gr_ore_poly_init(gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)void gr_ore_poly_init2(gr_ore_poly_t poly, slong len, gr_ore_poly_ctx_t ctx)void gr_ore_poly_clear(gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)Initialise poly as zero (with space for len coefficients), and clear it.
gr_ptr gr_ore_poly_coeff_ptr(gr_ore_poly_t poly, slong i, gr_ore_poly_ctx_t ctx)gr_srcptr gr_ore_poly_coeff_srcptr(const gr_ore_poly_t poly, slong i, gr_ore_poly_ctx_t ctx)slong gr_ore_poly_length(const gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)Return a pointer to the coefficient of , and the length.
void gr_ore_poly_swap(gr_ore_poly_t poly1, gr_ore_poly_t poly2, gr_ore_poly_ctx_t ctx)void gr_ore_poly_set_shallow(gr_ore_poly_t res, const gr_ore_poly_t x, const gr_ore_poly_ctx_t ctx)Swap two Ore polynomials in constant time, and make res a shallow copy of x sharing its coefficients.
void gr_ore_poly_fit_length(gr_ore_poly_t poly, slong len, gr_ore_poly_ctx_t ctx)void _gr_ore_poly_set_length(gr_ore_poly_t poly, slong len, gr_ore_poly_ctx_t ctx)void _gr_ore_poly_normalise(gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)Ensure space for len coefficients, set the length without normalising, and remove provably zero leading coefficients, as the gr_poly functions of the same names.
Basic manipulation#
int gr_ore_poly_set(gr_ore_poly_t res, const gr_ore_poly_t src, gr_ore_poly_ctx_t ctx)int gr_ore_poly_truncate(gr_ore_poly_t poly, const gr_ore_poly_t src, slong newlen, gr_ore_poly_ctx_t ctx)Set res to a copy of src, or to src with the terms of order newlen and higher removed.
int gr_ore_poly_zero(gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)int gr_ore_poly_one(gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)int gr_ore_poly_neg_one(gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)int gr_ore_poly_gen(gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)Set poly to , , or the generator .
int gr_ore_poly_set_si(gr_ore_poly_t poly, slong x, gr_ore_poly_ctx_t ctx)int gr_ore_poly_set_ui(gr_ore_poly_t poly, ulong x, gr_ore_poly_ctx_t ctx)int gr_ore_poly_set_fmpz(gr_ore_poly_t poly, const fmpz_t x, gr_ore_poly_ctx_t ctx)int gr_ore_poly_set_fmpq(gr_ore_poly_t poly, const fmpq_t x, gr_ore_poly_ctx_t ctx)int gr_ore_poly_set_other(gr_ore_poly_t poly, gr_srcptr x, gr_ctx_t x_ctx, gr_ore_poly_ctx_t ctx)Set poly to a constant converted into the base ring. The function gr_ore_poly_set_other accepts an Ore polynomial with the same context (copied), an element of the base ring, an element of the coefficient ring of the base ring when the base ring is a univariate polynomial ring, or an integer or rational number (fmpz and fmpq contexts), each giving a constant; it returns GR_UNABLE for any other ring.
truth_t _gr_ore_poly_equal(gr_srcptr poly1, slong len1, gr_srcptr poly2, slong len2, gr_ore_poly_ctx_t ctx)truth_t gr_ore_poly_equal(const gr_ore_poly_t poly1, const gr_ore_poly_t poly2, gr_ore_poly_ctx_t ctx)truth_t gr_ore_poly_is_zero(const gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)truth_t gr_ore_poly_is_one(const gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)truth_t gr_ore_poly_is_gen(const gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)Comparisons, decided coefficientwise in the base ring. The underscore version requires .
Input and output#
int _gr_ore_poly_write(gr_stream_t out, gr_srcptr poly, slong len, gr_ore_poly_ctx_t ctx)int gr_ore_poly_write(gr_stream_t out, const gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)int _gr_ore_poly_get_str(char ** res, gr_srcptr f, slong len, gr_ore_poly_ctx_t ctx)int gr_ore_poly_get_str(char ** res, const gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)int gr_ore_poly_print(const gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)Write the Ore polynomial as an expression in the generator name of the context, with the coefficients on the left of the powers of , to a stream, to a new string (to be freed with flint_free), or to standard output.
int _gr_ore_poly_set_str(gr_ptr res, const char * s, slong len, gr_ore_poly_ctx_t ctx)int gr_ore_poly_set_str(gr_ore_poly_t res, const char * s, gr_ore_poly_ctx_t ctx)Parse an Ore polynomial from an expression in the generator name of the context and the generator names of the base ring; products are evaluated in the Ore algebra, so D*x and x*D differ. The underscore version writes exactly len coefficients (zero-padding) and returns GR_UNABLE if the result is longer; intermediate results may be longer.
int gr_ore_poly_randtest(gr_ore_poly_t poly, flint_rand_t state, slong len, gr_ore_poly_ctx_t ctx)int _gr_ore_poly_randtest_default(gr_ore_poly_t res, flint_rand_t state, gr_ore_poly_ctx_t ctx)Set poly to a random Ore polynomial of length at most len (respectively a random length below 5), for testing.
Action#
int gr_ore_poly_sigma_delta(gr_ptr sigma, gr_ptr delta, gr_srcptr a, gr_ore_poly_ctx_t ctx)int gr_ore_poly_sigma(gr_ptr res, gr_srcptr a, gr_ore_poly_ctx_t ctx)int gr_ore_poly_delta(gr_ptr res, gr_srcptr a, gr_ore_poly_ctx_t ctx)Compute and , or one of them, by calling the function stored in the context.
int sigma_delta_unable(gr_ptr sigma, gr_ptr delta, gr_srcptr a, gr_ore_poly_ctx_struct * ctx)int sigma_delta_commutative(gr_ptr sigma, gr_ptr delta, gr_srcptr a, gr_ore_poly_ctx_struct * ctx)int sigma_delta_derivative(gr_ptr sigma, gr_ptr delta, gr_srcptr a, gr_ore_poly_ctx_struct * ctx)int sigma_delta_euler_derivative(gr_ptr sigma, gr_ptr delta, gr_srcptr a, gr_ore_poly_ctx_struct * ctx)int sigma_delta_forward_shift(gr_ptr sigma, gr_ptr delta, gr_srcptr a, gr_ore_poly_ctx_struct * ctx)int sigma_delta_backward_shift(gr_ptr sigma, gr_ptr delta, gr_srcptr a, gr_ore_poly_ctx_struct * ctx)int sigma_delta_forward_difference(gr_ptr sigma, gr_ptr delta, gr_srcptr a, gr_ore_poly_ctx_struct * ctx)int sigma_delta_backward_difference(gr_ptr sigma, gr_ptr delta, gr_srcptr a, gr_ore_poly_ctx_struct * ctx)int sigma_delta_compose(gr_ptr sigma, gr_ptr delta, gr_srcptr a, gr_ore_poly_ctx_struct * ctx)int sigma_delta_mahler(gr_ptr sigma, gr_ptr delta, gr_srcptr a, gr_ore_poly_ctx_struct * ctx)int sigma_delta_frobenius(gr_ptr sigma, gr_ptr delta, gr_srcptr a, gr_ore_poly_ctx_struct * ctx)The functions implementing and for the predefined algebras, with the signature gr_ore_poly_sigma_delta_t (sigma_delta_unable always returns GR_UNABLE; sigma_delta_compose, used for -shifts, composes with the stored ).
The array of the sigma_delta functions of the predefined algebras, indexed by ore_algebra_t (sigma_delta_unable for ORE_ALGEBRA_CUSTOM).
int gr_ore_poly_apply(gr_ptr res, const gr_ore_poly_t P, gr_srcptr f, gr_ore_poly_ctx_t ctx)int gr_ore_poly_apply_custom(gr_ptr res, const gr_ore_poly_t P, gr_srcptr f, gr_srcptr d1, gr_ore_poly_ctx_t ctx)Set res to the result of applying P to the base ring element f. The first function uses the standard interpretation of P as an operator acting on the base ring (derivative operators differentiate, shift operators shift, etc.). In the second one, the generator acts by where d1 is the value ; any d1 defines a valid action.
Conversions#
The following functions convert between expressions of a linear differential or difference operator in different bases, represented as Ore polynomials in different Ore polynomial rings over the same base ring.
Rewrite op, of length len, from ORE_ALGEBRA_EULER_DERIVATIVE to ORE_ALGEBRA_DERIVATIVE (first function), or from ORE_ALGEBRA_DERIVATIVE to ORE_ALGEBRA_EULER_DERIVATIVE (second function). In the latter case the result is multiplied by a power of : . Here ctx is the common base ring and var is the index of the generator of ctx on which the derivations act. The output vector res has the same length len as op and must not alias it.
int _gr_ore_poly_shift_convert(gr_ptr res, slong * p, gr_srcptr op, slong len, ore_algebra_t src_alg, ore_algebra_t dst_alg, slong var, gr_ctx_t ctx)int _gr_ore_poly_shift_convert_difference(gr_ptr res, slong * p, gr_srcptr op, slong len, int to_backward, slong var, gr_ctx_t ctx)Rewrite op from src_alg to dst_alg, where both are among the builtin shift and difference algebras (corresponding to operators written in terms of the forward and backward shifts , and the forward and backward differences , ). The result satisfies . Here ctx is the common base ring and var is the index of the generator of ctx on which acts. Conversions that cross between the forward side (, ) and the backward side (, ) currently require a generic univariate polynomial base ring and otherwise return GR_UNABLE. The function returns an error status when the source or destination algebra is not of the required type. The output vector res has the same length len as op and must not alias it.
The second function is the specialisation to conversions between ORE_ALGEBRA_FORWARD_DIFFERENCE and ORE_ALGEBRA_BACKWARD_DIFFERENCE, the flag to_backward giving the direction.
int gr_ore_poly_convert(gr_ore_poly_t res, slong * p, const gr_ore_poly_t op, gr_ore_poly_ctx_t res_ctx, gr_ore_poly_ctx_t op_ctx)Convert op from op_ctx to res_ctx. The meaning of the output parameter p depends on the algebra. For a conversion within the differential family, where is the generator of the base ring specified in the source context. For a conversion within the shift/difference family, (a power of the forward shift ). No attempt is currently made to minimise or its absolute value.
For , the Euler derivative acts on as multiplication by and acts as the backward shift . The following functions convert between differential and difference operators in a way compatible with this action, mapping and , and inversely.
int _gr_ore_poly_euler_to_backshift_univar(gr_ptr res, slong reslen, gr_srcptr op, slong len, gr_ctx_t ctx)int _gr_ore_poly_backshift_to_euler_univar(gr_ptr res, slong reslen, gr_srcptr op, slong len, gr_ctx_t ctx)The two inverse rewritings of the isomorphism between the Euler operator and the backward shift . The common base ring ctx must be a univariate polynomial ring. The caller allocates res to reslen, one more than the largest coefficient degree of op.
int gr_ore_poly_differential_to_shift(gr_ore_poly_t res, slong * p, const gr_ore_poly_t op, gr_ore_poly_ctx_t res_ctx, gr_ore_poly_ctx_t op_ctx)int gr_ore_poly_shift_to_differential(gr_ore_poly_t res, slong * p, const gr_ore_poly_t op, gr_ore_poly_ctx_t res_ctx, gr_ore_poly_ctx_t op_ctx)Given a differential operator op represented as an element of op_ctx, compute a shift/difference operator res in res_ctx and an integer p such that the above correspondence maps op to (first function); or, conversely, given a shift/difference operator op, compute a differential operator res and p such that the correspondence maps op to (second function). The generators of the base rings specified in the source and destination contexts play the role of and (first function), or and (second function). No attempt is currently made to minimise or its absolute value.
Arithmetic#
int gr_ore_poly_neg(gr_ore_poly_t res, const gr_ore_poly_t src, gr_ore_poly_ctx_t ctx)int _gr_ore_poly_add(gr_ptr res, gr_srcptr poly1, slong len1, gr_srcptr poly2, slong len2, gr_ore_poly_ctx_t ctx)int gr_ore_poly_add(gr_ore_poly_t res, const gr_ore_poly_t poly1, const gr_ore_poly_t poly2, gr_ore_poly_ctx_t ctx)int _gr_ore_poly_sub(gr_ptr res, gr_srcptr poly1, slong len1, gr_srcptr poly2, slong len2, gr_ore_poly_ctx_t ctx)int gr_ore_poly_sub(gr_ore_poly_t res, const gr_ore_poly_t poly1, const gr_ore_poly_t poly2, gr_ore_poly_ctx_t ctx)Negation, sum and difference, coefficientwise.
int gr_ore_poly_add_ui(gr_ore_poly_t res, const gr_ore_poly_t poly, ulong c, gr_ore_poly_ctx_t ctx)int gr_ore_poly_add_si(gr_ore_poly_t res, const gr_ore_poly_t poly, slong c, gr_ore_poly_ctx_t ctx)int gr_ore_poly_add_fmpz(gr_ore_poly_t res, const gr_ore_poly_t poly, const fmpz_t c, gr_ore_poly_ctx_t ctx)int gr_ore_poly_add_fmpq(gr_ore_poly_t res, const gr_ore_poly_t poly, const fmpq_t c, gr_ore_poly_ctx_t ctx)int gr_ore_poly_add_other(gr_ore_poly_t res, const gr_ore_poly_t poly, gr_srcptr x, gr_ctx_t x_ctx, gr_ore_poly_ctx_t ctx)int gr_ore_poly_sub_ui(gr_ore_poly_t res, const gr_ore_poly_t poly, ulong c, gr_ore_poly_ctx_t ctx)int gr_ore_poly_sub_si(gr_ore_poly_t res, const gr_ore_poly_t poly, slong c, gr_ore_poly_ctx_t ctx)int gr_ore_poly_sub_fmpz(gr_ore_poly_t res, const gr_ore_poly_t poly, const fmpz_t c, gr_ore_poly_ctx_t ctx)int gr_ore_poly_sub_fmpq(gr_ore_poly_t res, const gr_ore_poly_t poly, const fmpq_t c, gr_ore_poly_ctx_t ctx)int gr_ore_poly_sub_other(gr_ore_poly_t res, const gr_ore_poly_t poly, gr_srcptr x, gr_ctx_t x_ctx, gr_ore_poly_ctx_t ctx)Add or subtract a constant . The _other versions accept the same kinds of elements as gr_ore_poly_set_other, including an Ore polynomial with the same context.
int gr_ore_poly_mul_ui(gr_ore_poly_t res, const gr_ore_poly_t poly, ulong c, gr_ore_poly_ctx_t ctx)int gr_ore_poly_mul_si(gr_ore_poly_t res, const gr_ore_poly_t poly, slong c, gr_ore_poly_ctx_t ctx)int gr_ore_poly_mul_fmpz(gr_ore_poly_t res, const gr_ore_poly_t poly, const fmpz_t c, gr_ore_poly_ctx_t ctx)int gr_ore_poly_mul_fmpq(gr_ore_poly_t res, const gr_ore_poly_t poly, const fmpq_t c, gr_ore_poly_ctx_t ctx)int gr_ore_poly_other_mul(gr_ore_poly_t res, gr_srcptr x, gr_ctx_t x_ctx, const gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)Multiply by an integer or rational constant (which commutes with ), or multiply on the left by , that is compute : an Ore polynomial with the same context is multiplied with gr_ore_poly_mul, and the other kinds of elements accepted by gr_ore_poly_set_other are constants with .
int _gr_ore_poly_lmul_gen(gr_ptr res, gr_srcptr poly, slong len, gr_ore_poly_ctx_t ctx)int gr_ore_poly_lmul_gen(gr_ore_poly_t res, const gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)Set res to the left product . The underscore version requires and writes coefficients.
int _gr_ore_poly_mul(gr_ptr res, gr_srcptr poly1, slong len1, gr_srcptr poly2, slong len2, gr_ore_poly_ctx_t ctx)int gr_ore_poly_mul(gr_ore_poly_t res, const gr_ore_poly_t poly1, const gr_ore_poly_t poly2, gr_ore_poly_ctx_t ctx)Set res to the product in the Ore algebra, computed as with the powers obtained by repeated left multiplication by : applications of and and multiplications in the base ring. The underscore version requires positive lengths, writes coefficients and does not allow aliasing.
int _gr_ore_poly_divrem(gr_ptr Q, gr_ptr R, gr_srcptr U, slong lenU, gr_srcptr V, slong lenV, gr_ore_poly_ctx_t ctx)int gr_ore_poly_divrem(gr_ore_poly_t Q, gr_ore_poly_t R, const gr_ore_poly_t U, gr_ore_poly_t V, gr_ore_poly_ctx_t ctx)int gr_ore_poly_div(gr_ore_poly_t Q, const gr_ore_poly_t U, gr_ore_poly_t V, gr_ore_poly_ctx_t ctx)int gr_ore_poly_rem(gr_ore_poly_t R, const gr_ore_poly_t U, gr_ore_poly_t V, gr_ore_poly_ctx_t ctx)Compute the right Euclidean division with , which exists and is unique when the leading coefficient of and its images under the powers of are invertible (over a field with injective, for instance). Each step divides the leading coefficient of the current remainder by and subtracts , for from down to 0; the eliminated coefficients of are then set to exact zeros (in inexact rings they would otherwise only be approximately zero). The non-underscore functions return GR_DOMAIN if ; the underscore version requires and writes coefficients of and of . (In FLINT 3.6 and earlier the last step, , was skipped, so that for example divided by gave and .)
References#
- [Ore1933] O. Ore. Theory of non-commutative polynomials. Annals of Mathematics 34 (1933), 480–508. https://doi.org/10.2307/1968173
- [BroPet1996] M. Bronstein and M. Petkovšek. An introduction to pseudo-linear algebra. Theoretical Computer Science 157 (1996), 3–33. https://doi.org/10.1016/0304-3975(95)00173-5
The FLINT team, “gr_ore_poly.h (module overview),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/gr_ore_poly/index.html (generated 2026-11-02).
@misc{flint-doc-gr-ore-poly-index,
author = {{The FLINT team}},
title = {{gr\_ore\_poly.h (module overview)}},
howpublished = {FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev},
year = {2026},
url = {https://flintlib.org/doc/gr_ore_poly/index.html},
note = {Generated 2026-11-02}
}