Skip to content

Commit f4704c9

Browse files
committed
Add generic Ore polynomial module
This contains only the basic structure so far, such as memory management, additive arithmetic, and multiplication from the left by an element of the base ring.
1 parent 726ee2d commit f4704c9

File tree

16 files changed

+1317
-2
lines changed

16 files changed

+1317
-2
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ set(_BUILD_DIRS
261261
acb_theta dirichlet bernoulli hypgeom
262262

263263
gr gr_generic gr_vec gr_mat
264-
gr_poly gr_mpoly gr_special
264+
gr_poly gr_mpoly gr_ore_poly gr_special
265265

266266
calcium
267267
fmpz_mpoly_q

Makefile.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ HEADER_DIRS := \
210210
acb_theta dirichlet bernoulli hypgeom \
211211
\
212212
gr gr_generic gr_vec gr_mat \
213-
gr_poly gr_mpoly gr_special \
213+
gr_poly gr_mpoly gr_ore_poly gr_special \
214214
\
215215
calcium \
216216
fmpz_mpoly_q \

doc/source/gr_domains.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,17 @@ Polynomial rings
315315
with monomial ordering *ord*.
316316
Elements have type :type:`gr_mpoly_struct`.
317317

318+
Ore polynomials
319+
-------------------------------------------------------------------------------
320+
321+
.. 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)
322+
323+
Initializes *ctx* to a ring of densely represented Ore polynomials over the
324+
given *base_ring*, with the choice of Ore algebra structure given by
325+
*which_algebra*. The Ore algebra structure may refer to a distinguished
326+
generator of *base_ring*; this will be the generator of index *base_var*.
327+
Elements have type :type:`gr_ore_poly_struct`.
328+
318329
Power series
319330
-------------------------------------------------------------------------------
320331

doc/source/gr_ore_poly.rst

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
.. _gr-ore-poly:
2+
3+
**gr_ore_poly.h** -- dense univariate Ore polynomials over generic rings
4+
===============================================================================
5+
6+
A :type:`gr_ore_poly_t` represents a univariate Ore polynomial `L \in R[D]`
7+
implemented as a dense array of coefficients in a generic ring *R*.
8+
The choice of Ore algebra structure (e.g. with `D` being the standard
9+
derivative or Euler derivative) is stored in the context object
10+
:type:`gr_ore_poly_ctx_t`.
11+
12+
Most functions are provided in two versions: an underscore method which
13+
operates directly on pre-allocated arrays of coefficients and generally
14+
has some restrictions (often requiring the lengths to be nonzero
15+
and not supporting aliasing of the input and output arrays),
16+
and a non-underscore method which performs automatic memory
17+
management and handles degenerate cases.
18+
19+
Ore algebra types
20+
--------------------------------------------------------------------------------
21+
.. type:: ore_algebra_t
22+
23+
Represents one of the following supported Ore algebra types:
24+
25+
.. macro:: ORE_ALGEBRA_DERIVATIVE
26+
27+
The endomorphism `\sigma` is the identity, and the `\sigma`-derivation
28+
`\delta` is the derivative `\frac{d}{dx}` with respect to a generator
29+
`x` of the base ring.
30+
31+
.. macro:: ORE_ALGEBRA_EULER_DERIVATIVE
32+
33+
The endomorphism `\sigma` is the identity, and the `\sigma`-derivation
34+
`\delta` is the Euler derivative `x\cdot\frac{d}{dx}` with respect to a
35+
generator `x` of the base ring.
36+
37+
.. macro:: ORE_ALGEBRA_FORWARD_SHIFT
38+
39+
The endomorphism `\sigma` is the shift `x \mapsto x + 1` with respect
40+
to a generator `x` of the base ring, and the `\sigma`-derivation
41+
`\delta` is the zero map.
42+
43+
.. macro:: ORE_ALGEBRA_FORWARD_DIFFERENCE
44+
45+
The endomorphism `\sigma` is the shift `x \mapsto x + 1` with respect
46+
to a generator `x` of the base ring, and the `\sigma`-derivation
47+
`\delta` maps `x \mapsto 1`.
48+
49+
.. function:: ore_algebra_t ore_algebra_randtest(flint_rand_t state)
50+
51+
Return a random Ore algebra type.
52+
53+
Type compatibility
54+
-------------------------------------------------------------------------------
55+
56+
The ``gr_ore_poly`` type has the same data layout as ``gr_poly``.
57+
Methods of ``gr_poly`` can therefore be used for linear and container
58+
operations on a ``gr_ore_poly``, given that one is careful about providing
59+
the right context object.
60+
61+
Weak normalization
62+
-------------------------------------------------------------------------------
63+
64+
A :type:`gr_ore_poly_t` is always normalised by removing leading zeros.
65+
For rings without decidable equality (e.g. rings with inexact
66+
representation), only coefficients that are provably zero will be
67+
removed, and there can thus be spurious leading zeros in the
68+
internal representation.
69+
Methods that depend on knowing the exact degree of a polynomial
70+
will act appropriately, typically by returning ``GR_UNABLE``
71+
when it is unknown whether the leading stored coefficient is nonzero.
72+
73+
Types, macros and constants
74+
-------------------------------------------------------------------------------
75+
76+
.. type:: gr_ore_poly_struct
77+
78+
.. type:: gr_ore_poly_t
79+
80+
Contains a pointer to an array of coefficients (``coeffs``), the used
81+
length (``length``), and the allocated size of the array (``alloc``).
82+
83+
A ``gr_ore_poly_t`` is defined as an array of length one of type
84+
``gr_ore_poly_struct``, permitting a ``gr_ore_poly_t`` to
85+
be passed by reference.
86+
87+
Context object methods
88+
-------------------------------------------------------------------------------
89+
90+
.. function:: 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)
91+
92+
Initializes ``ctx`` to a ring of densely represented Ore polynomials over
93+
the given ``base_ring``, with the choice of Ore algebra structure given by
94+
``which_algebra``. The Ore algebra structure may refer to a distinguished
95+
generator of ``base_ring``; this will be the generator of index
96+
``base_var``.
97+
98+
.. function:: void gr_ore_poly_ctx_clear(gr_ore_poly_ctx_t ctx)
99+
100+
Clears the context object ``ctx``.
101+
102+
.. function:: void gr_ore_poly_ctx_init_rand(gr_ore_poly_ctx_t ctx, flint_rand_t state, gr_ctx_t base_ring)
103+
104+
Initializes ``ctx`` with a random Ore algebra structure.
105+
106+
The following methods implement parts of the standard interface
107+
for ``gr`` context objects.
108+
109+
.. function:: int _gr_ore_poly_ctx_set_gen_name(gr_ctx_t ctx, const char * s)
110+
int _gr_ore_poly_ctx_set_gen_names(gr_ctx_t ctx, const char ** s)
111+
112+
Sets the name of the generator to the string in ``s``, respectively the
113+
first string in ``s``.
114+
115+
.. function:: int gr_ore_poly_ctx_write(gr_stream_t out, gr_ore_poly_ctx_t ctx)
116+
truth_t gr_ore_poly_ctx_is_ring(gr_ore_poly_ctx_t ctx)
117+
truth_t gr_ore_poly_ctx_is_zero_ring(gr_ore_poly_ctx_t ctx)
118+
truth_t gr_ore_poly_ctx_is_commutative_ring(gr_ore_poly_ctx_t ctx)
119+
truth_t gr_ore_poly_ctx_is_integral_domain(gr_ore_poly_ctx_t ctx)
120+
truth_t gr_ore_poly_ctx_is_threadsafe(gr_ore_poly_ctx_t ctx)
121+
122+
Memory management
123+
-------------------------------------------------------------------------------
124+
125+
.. function:: void gr_ore_poly_init(gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)
126+
127+
.. function:: void gr_ore_poly_init2(gr_ore_poly_t poly, slong len, gr_ore_poly_ctx_t ctx)
128+
129+
.. function:: void gr_ore_poly_clear(gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)
130+
131+
.. function:: gr_ptr gr_ore_poly_coeff_ptr(gr_ore_poly_t poly, slong i, gr_ore_poly_ctx_t ctx)
132+
gr_srcptr gr_ore_poly_coeff_srcptr(const gr_ore_poly_t poly, slong i, gr_ore_poly_ctx_t ctx)
133+
134+
.. function:: slong gr_ore_poly_length(const gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)
135+
136+
.. function:: void gr_ore_poly_swap(gr_ore_poly_t poly1, gr_ore_poly_t poly2, gr_ore_poly_ctx_t ctx)
137+
138+
.. function:: void gr_ore_poly_fit_length(gr_ore_poly_t poly, slong len, gr_ore_poly_ctx_t ctx)
139+
140+
.. function:: void _gr_ore_poly_set_length(gr_ore_poly_t poly, slong len, gr_ore_poly_ctx_t ctx)
141+
142+
Basic manipulation
143+
-------------------------------------------------------------------------------
144+
145+
.. function:: void _gr_ore_poly_normalise(gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)
146+
147+
.. function:: int gr_ore_poly_set(gr_ore_poly_t res, const gr_ore_poly_t src, gr_ore_poly_ctx_t ctx)
148+
149+
.. function:: int gr_ore_poly_truncate(gr_ore_poly_t res, const gr_ore_poly_t poly, slong newlen, gr_ore_poly_ctx_t ctx)
150+
151+
.. function:: int gr_ore_poly_zero(gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)
152+
int gr_ore_poly_one(gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)
153+
int gr_ore_poly_neg_one(gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)
154+
int gr_ore_poly_gen(gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)
155+
156+
.. function:: int gr_ore_poly_write(gr_stream_t out, const gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)
157+
int _gr_ore_poly_write(gr_stream_t out, gr_srcptr poly, slong n, gr_ore_poly_ctx_t ctx)
158+
int _gr_ore_poly_get_str(char ** res, const gr_ore_poly_t f, gr_ore_poly_ctx_t ctx)
159+
int gr_ore_poly_get_str(char ** res, const gr_ore_poly_t f, gr_ore_poly_ctx_t ctx)
160+
int gr_ore_poly_print(const gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)
161+
162+
.. function:: int _gr_ore_poly_set_str(gr_ptr res, const char * s, slong len, gr_ore_poly_ctx_t ctx)
163+
int gr_ore_poly_set_str(gr_ore_poly_t res, const char * s, gr_ore_poly_ctx_t ctx)
164+
165+
Parse Ore polynomial from an expression string, assuming the name of the
166+
generator is the one set in *ctx*. The underscore method zero-pads the
167+
result if the length of the parsed polynomial is shorter than *len*,
168+
and returns ``GR_UNABLE`` if the length of the parsed polynomial exceeds
169+
*len*. Intermediate terms are allowed to be longer than *len*.
170+
171+
.. function:: int gr_ore_poly_randtest(gr_ore_poly_t poly, flint_rand_t state, slong len, gr_ore_poly_ctx_t ctx)
172+
173+
.. function:: truth_t _gr_ore_poly_equal(gr_srcptr poly1, slong len1, gr_srcptr poly2, slong len2, gr_ore_poly_ctx_t ctx)
174+
truth_t gr_ore_poly_equal(const gr_ore_poly_t poly1, const gr_ore_poly_t poly2, gr_ore_poly_ctx_t ctx)
175+
176+
.. function:: truth_t gr_ore_poly_is_zero(const gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)
177+
truth_t gr_ore_poly_is_one(const gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)
178+
truth_t gr_ore_poly_is_gen(const gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)
179+
180+
.. function:: int gr_ore_poly_set_si(gr_ore_poly_t poly, slong c, gr_ore_poly_ctx_t ctx)
181+
int gr_ore_poly_set_ui(gr_ore_poly_t poly, ulong c, gr_ore_poly_ctx_t ctx)
182+
int gr_ore_poly_set_fmpz(gr_ore_poly_t poly, const fmpz_t c, gr_ore_poly_ctx_t ctx)
183+
int gr_ore_poly_set_fmpq(gr_ore_poly_t poly, const fmpq_t c, gr_ore_poly_ctx_t ctx)
184+
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)
185+
186+
Arithmetic
187+
-------------------------------------------------------------------------------
188+
189+
.. function:: int gr_ore_poly_neg(gr_ore_poly_t res, const gr_ore_poly_t src, gr_ore_poly_ctx_t ctx)
190+
191+
.. function:: int _gr_ore_poly_add(gr_ptr res, gr_srcptr poly1, slong len1, gr_srcptr poly2, slong len2, gr_ore_poly_ctx_t ctx)
192+
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)
193+
194+
.. function:: int _gr_ore_poly_sub(gr_ptr res, gr_srcptr poly1, slong len1, gr_srcptr poly2, slong len2, gr_ore_poly_ctx_t ctx)
195+
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)
196+
197+
.. function:: 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)
198+
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)
199+
int gr_ore_poly_add_fmpz(gr_ore_poly_t res, const gr_ore_poly_t poly, const fmpz c, gr_ore_poly_ctx_t ctx)
200+
int gr_ore_poly_add_fmpq(gr_ore_poly_t res, const gr_ore_poly_t poly, const fmpq c, gr_ore_poly_ctx_t ctx)
201+
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)
202+
203+
Sets *res* to *poly* plus the scalar *c* which must be
204+
an element of or coercible to the coefficient ring.
205+
206+
.. function:: 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)
207+
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)
208+
int gr_ore_poly_sub_fmpz(gr_ore_poly_t res, const gr_ore_poly_t poly, const fmpz c, gr_ore_poly_ctx_t ctx)
209+
int gr_ore_poly_sub_fmpq(gr_ore_poly_t res, const gr_ore_poly_t poly, const fmpq c, gr_ore_poly_ctx_t ctx)
210+
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)
211+
212+
Sets *res* to *poly* minus *c* which must be
213+
an element of or coercible to the coefficient ring.
214+
215+
.. function:: 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)
216+
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)
217+
int gr_ore_poly_mul_fmpz(gr_ore_poly_t res, const gr_ore_poly_t poly, const fmpz c, gr_ore_poly_ctx_t ctx)
218+
int gr_ore_poly_mul_fmpq(gr_ore_poly_t res, const gr_ore_poly_t poly, const fmpq c, gr_ore_poly_ctx_t ctx)
219+
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)
220+
221+
Sets *res* to *poly* multiplied by *c* (or *x* multiplied by *poly*)
222+
which must be an element of or coercible to the coefficient ring.
223+
224+
.. raw:: latex
225+
226+
\newpage
227+

doc/source/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ Generic rings
6060
gr_mat.rst
6161
gr_poly.rst
6262
gr_mpoly.rst
63+
gr_ore_poly.rst
6364

6465
.. only:: not latex
6566

doc/source/index_generic.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@
1616
gr_mat.rst
1717
gr_poly.rst
1818
gr_mpoly.rst
19+
gr_ore_poly.rst
1920

src/generic_files/io.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "gr.h"
2727
#include "gr_vec.h"
2828
#include "gr_poly.h"
29+
#include "gr_ore_poly.h"
2930
#include "gr_mat.h"
3031

3132
int _gr_mat_write(gr_stream_t out, const gr_mat_t mat, int linebreaks, gr_ctx_t ctx);
@@ -728,6 +729,14 @@ int flint_vfprintf(FILE * fs, const char * ip, va_list vlist)
728729
res += out->len;
729730
ip += STRING_LENGTH("gr_poly}");
730731
}
732+
else if (IS_FLINT_TYPE(ip, "gr_ore_poly"))
733+
{
734+
const gr_ore_poly_struct * elem = va_arg(vlist, const gr_ore_poly_struct *);
735+
gr_ctx_struct * ctx = va_arg(vlist, gr_ctx_struct *);
736+
GR_MUST_SUCCEED(gr_ore_poly_write(out, elem, ctx));
737+
res += out->len;
738+
ip += STRING_LENGTH("gr_ore_poly}");
739+
}
731740
else if (IS_FLINT_TYPE(ip, "gr_mat"))
732741
{
733742
const gr_mat_struct * elem = va_arg(vlist, const gr_mat_struct *);

src/gr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -689,6 +689,7 @@ typedef enum
689689
GR_CTX_FMPZ_POLY, GR_CTX_FMPQ_POLY, GR_CTX_GR_POLY,
690690
GR_CTX_FMPZ_MPOLY, GR_CTX_GR_MPOLY,
691691
GR_CTX_FMPZ_MPOLY_Q,
692+
GR_CTX_GR_ORE_POLY,
692693
GR_CTX_GR_FRACTION,
693694
GR_CTX_GR_SERIES, GR_CTX_SERIES_MOD_GR_POLY,
694695
GR_CTX_GR_MAT,

src/gr/ore_poly.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
Copyright (C) 2025 Ricardo Buring
3+
4+
This file is part of FLINT.
5+
6+
FLINT is free software: you can redistribute it and/or modify it under
7+
the terms of the GNU Lesser General Public License (LGPL) as published
8+
by the Free Software Foundation; either version 3 of the License, or
9+
(at your option) any later version. See <https://www.gnu.org/licenses/>.
10+
*/
11+
12+
#include "gr_ore_poly.h"
13+
14+
void
15+
gr_ctx_init_gr_ore_poly(gr_ctx_t ctx, gr_ctx_t base_ring, slong base_var, const ore_algebra_t which_algebra)
16+
{
17+
gr_ore_poly_ctx_init(ctx, base_ring, base_var, which_algebra);
18+
}

0 commit comments

Comments
 (0)