Skip to content

Commit e8fedc5

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 e8fedc5

File tree

16 files changed

+1293
-2
lines changed

16 files changed

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

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)