Skip to content

Commit 6323582

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 00e541a commit 6323582

File tree

15 files changed

+1265
-2
lines changed

15 files changed

+1265
-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_ore_poly.rst

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
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 operator *D* is stored in the context object
9+
: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 operators
19+
--------------------------------------------------------------------------------
20+
.. type:: ore_poly_which_operator
21+
22+
Represents one of the following supported Ore operators:
23+
24+
.. macro:: ORE_OPERATOR_STANDARD_DERIVATIVE
25+
26+
The standard derivative.
27+
28+
.. macro:: ORE_OPERATOR_EULER_DERIVATIVE
29+
30+
The Euler derivative.
31+
32+
.. function:: ore_poly_which_operator ore_poly_which_operator_randtest(flint_rand_t state)
33+
34+
Return a random Ore operator.
35+
36+
Type compatibility
37+
-------------------------------------------------------------------------------
38+
39+
The ``gr_ore_poly`` type has the same data layout as the following
40+
polynomial types: ``gr_poly``, ``fmpz_poly``, ``fq_poly``, ``fq_nmod_poly``,
41+
``fq_zech_poly``, ``arb_poly``, ``acb_poly``, ``ca_poly``.
42+
Methods in this module can therefore be mixed freely with
43+
methods in the corresponding FLINT modules
44+
when the underlying coefficient type is the same.
45+
It is not directly compatible with the following types:
46+
``fmpq_poly`` (coefficients are stored with a common denominator),
47+
``nmod_poly`` (modulus data is stored as part of the polynomial object).
48+
49+
Weak normalization
50+
-------------------------------------------------------------------------------
51+
52+
A :type:`gr_ore_poly_t` is always normalised by removing leading zeros.
53+
For rings without decidable equality (e.g. rings with inexact
54+
representation), only coefficients that are provably zero will be
55+
removed, and there can thus be spurious leading zeros in the
56+
internal representation.
57+
Methods that depend on knowing the exact degree of a polynomial
58+
will act appropriately, typically by returning ``GR_UNABLE``
59+
when it is unknown whether the leading stored coefficient is nonzero.
60+
61+
Types, macros and constants
62+
-------------------------------------------------------------------------------
63+
64+
.. type:: gr_ore_poly_struct
65+
66+
.. type:: gr_ore_poly_t
67+
68+
Contains a pointer to an array of coefficients (``coeffs``), the used
69+
length (``length``), and the allocated size of the array (``alloc``).
70+
71+
A ``gr_ore_poly_t`` is defined as an array of length one of type
72+
``gr_ore_poly_struct``, permitting a ``gr_ore_poly_t`` to
73+
be passed by reference.
74+
75+
Context object methods
76+
-------------------------------------------------------------------------------
77+
78+
.. function:: void gr_ore_poly_ctx_init(gr_ore_poly_ctx_t ctx, gr_ctx_t base_ring, const ore_poly_which_operator operator)
79+
80+
Initializes ``ctx`` to represent a Ore polynomial ring with
81+
coefficients in ``base_ring`` and the choice of Ore operator
82+
given by ``operator``.
83+
84+
.. function:: void gr_ore_poly_ctx_clear(gr_ore_poly_ctx_t ctx)
85+
86+
Clears the context object ``ctx``.
87+
88+
.. function:: void gr_ore_poly_ctx_init_rand(gr_ore_poly_ctx_t ctx, flint_rand_t state, gr_ctx_t base_ring)
89+
90+
Initializes ``ctx`` with a random Ore operator.
91+
92+
The following methods implement parts of the standard interface
93+
for ``gr`` context objects.
94+
95+
.. function:: int _gr_ore_poly_ctx_set_gen_name(gr_ctx_t ctx, const char * s)
96+
int _gr_ore_poly_ctx_set_gen_names(gr_ctx_t ctx, const char ** s)
97+
98+
Sets the names of the generators to the strings in ``s``.
99+
100+
.. function:: int gr_ore_poly_ctx_write(gr_stream_t out, gr_ore_poly_ctx_t ctx)
101+
truth_t gr_ore_poly_ctx_is_ring(gr_ore_poly_ctx_t ctx)
102+
truth_t gr_ore_poly_ctx_is_zero_ring(gr_ore_poly_ctx_t ctx)
103+
truth_t gr_ore_poly_ctx_is_commutative_ring(gr_ore_poly_ctx_t ctx)
104+
truth_t gr_ore_poly_ctx_is_integral_domain(gr_ore_poly_ctx_t ctx)
105+
truth_t gr_ore_poly_ctx_is_threadsafe(gr_ore_poly_ctx_t ctx)
106+
107+
Memory management
108+
-------------------------------------------------------------------------------
109+
110+
.. function:: void gr_ore_poly_init(gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)
111+
112+
.. function:: void gr_ore_poly_init2(gr_ore_poly_t poly, slong len, gr_ore_poly_ctx_t ctx)
113+
114+
.. function:: void gr_ore_poly_clear(gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)
115+
116+
.. function:: gr_ptr gr_ore_poly_entry_ptr(gr_ore_poly_t poly, slong i, gr_ore_poly_ctx_t ctx)
117+
gr_srcptr gr_ore_poly_entry_srcptr(const gr_ore_poly_t poly, slong i, gr_ore_poly_ctx_t ctx)
118+
119+
.. function:: slong gr_ore_poly_length(const gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)
120+
121+
.. function:: void gr_ore_poly_swap(gr_ore_poly_t poly1, gr_ore_poly_t poly2, gr_ore_poly_ctx_t ctx)
122+
123+
.. function:: void gr_ore_poly_fit_length(gr_ore_poly_t poly, slong len, gr_ore_poly_ctx_t ctx)
124+
125+
.. function:: void _gr_ore_poly_set_length(gr_ore_poly_t poly, slong len, gr_ore_poly_ctx_t ctx)
126+
127+
Basic manipulation
128+
-------------------------------------------------------------------------------
129+
130+
.. function:: void _gr_ore_poly_normalise(gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)
131+
132+
.. function:: int gr_ore_poly_set(gr_ore_poly_t res, const gr_ore_poly_t src, gr_ore_poly_ctx_t ctx)
133+
134+
.. 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)
135+
136+
.. function:: int gr_ore_poly_zero(gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)
137+
int gr_ore_poly_one(gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)
138+
int gr_ore_poly_neg_one(gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)
139+
int gr_ore_poly_gen(gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)
140+
141+
.. function:: int gr_ore_poly_write(gr_stream_t out, const gr_ore_poly_t poly, const char * x, gr_ore_poly_ctx_t ctx)
142+
int _gr_ore_poly_write(gr_stream_t out, gr_srcptr poly, slong n, const char * x, gr_ore_poly_ctx_t ctx)
143+
int _gr_ore_poly_get_str(char ** res, const gr_ore_poly_t f, const char * x, gr_ore_poly_ctx_t ctx)
144+
int gr_ore_poly_get_str(char ** res, const gr_ore_poly_t f, const char * x, gr_ore_poly_ctx_t ctx)
145+
int gr_ore_poly_print(const gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)
146+
147+
.. function:: int _gr_ore_poly_set_str(gr_ptr res, const char * s, const char * x, slong len, gr_ore_poly_ctx_t ctx)
148+
int gr_ore_poly_set_str(gr_ore_poly_t res, const char * s, const char * x, gr_ore_poly_ctx_t ctx)
149+
150+
Parse Ore polynomial from an expression string, assuming that the string in *x* gives
151+
the name of the generator. The underscore method zero-pads the result if
152+
the length of the parsed polynomial is shorter than *len*, and returns
153+
``GR_UNABLE`` if the length of the parsed polynomial exceeds *len*.
154+
Intermediate terms are allowed to be longer than *len*.
155+
156+
Warning: these methods are not currently optimized for polynomials of high degree
157+
and may run with quadratic complexity.
158+
159+
.. function:: int gr_ore_poly_randtest(gr_ore_poly_t poly, flint_rand_t state, slong len, gr_ore_poly_ctx_t ctx)
160+
161+
.. function:: truth_t _gr_ore_poly_equal(gr_srcptr poly1, slong len1, gr_srcptr poly2, slong len2, gr_ore_poly_ctx_t ctx)
162+
truth_t gr_ore_poly_equal(const gr_ore_poly_t poly1, const gr_ore_poly_t poly2, gr_ore_poly_ctx_t ctx)
163+
164+
.. function:: truth_t gr_ore_poly_is_zero(const gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)
165+
truth_t gr_ore_poly_is_one(const gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)
166+
truth_t gr_ore_poly_is_gen(const gr_ore_poly_t poly, gr_ore_poly_ctx_t ctx)
167+
168+
.. function:: int gr_ore_poly_set_si(gr_ore_poly_t poly, slong c, gr_ore_poly_ctx_t ctx)
169+
int gr_ore_poly_set_ui(gr_ore_poly_t poly, ulong c, gr_ore_poly_ctx_t ctx)
170+
int gr_ore_poly_set_fmpz(gr_ore_poly_t poly, const fmpz_t c, gr_ore_poly_ctx_t ctx)
171+
int gr_ore_poly_set_fmpq(gr_ore_poly_t poly, const fmpq_t c, gr_ore_poly_ctx_t ctx)
172+
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)
173+
174+
Arithmetic
175+
-------------------------------------------------------------------------------
176+
177+
.. function:: int gr_ore_poly_neg(gr_ore_poly_t res, const gr_ore_poly_t src, gr_ore_poly_ctx_t ctx)
178+
179+
.. 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)
180+
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)
181+
182+
.. 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)
183+
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)
184+
185+
.. 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)
186+
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)
187+
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)
188+
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)
189+
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)
190+
191+
Sets *res* to *poly* plus the scalar *c* which must be
192+
an element of or coercible to the coefficient ring.
193+
194+
.. 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)
195+
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)
196+
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)
197+
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)
198+
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)
199+
200+
Sets *res* to *poly* minus *c* which must be
201+
an element of or coercible to the coefficient ring.
202+
203+
.. 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)
204+
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)
205+
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)
206+
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)
207+
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)
208+
209+
Sets *res* to *poly* multiplied by *c* (or *x* multiplied by *poly*)
210+
which must be an element of or coercible to the coefficient ring.
211+
212+
.. raw:: latex
213+
214+
\newpage
215+

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, "Dx", 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
@@ -687,6 +687,7 @@ typedef enum
687687
GR_CTX_FMPZ_POLY, GR_CTX_FMPQ_POLY, GR_CTX_GR_POLY,
688688
GR_CTX_FMPZ_MPOLY, GR_CTX_GR_MPOLY,
689689
GR_CTX_FMPZ_MPOLY_Q,
690+
GR_CTX_GR_ORE_POLY,
690691
GR_CTX_GR_SERIES, GR_CTX_SERIES_MOD_GR_POLY,
691692
GR_CTX_GR_MAT,
692693
GR_CTX_GR_VEC,

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, const ore_poly_which_operator operator)
16+
{
17+
gr_ore_poly_ctx_init(ctx, base_ring, operator);
18+
}

0 commit comments

Comments
 (0)