Skip to content

Commit 53f185d

Browse files
committed
Add gr_poly_add_scalar, gr_poly_sub_scalar, etc.
1 parent 4a89949 commit 53f185d

File tree

7 files changed

+573
-15
lines changed

7 files changed

+573
-15
lines changed

doc/source/gr_poly.rst

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -158,16 +158,6 @@ Arithmetic
158158
int _gr_poly_mullow(gr_ptr res, gr_srcptr poly1, slong len1, gr_srcptr poly2, slong len2, slong len, gr_ctx_t ctx)
159159
int gr_poly_mullow(gr_poly_t res, const gr_poly_t poly1, const gr_poly_t poly2, slong len, gr_ctx_t ctx)
160160

161-
.. function:: int gr_poly_mul_scalar(gr_poly_t res, const gr_poly_t poly, gr_srcptr c, gr_ctx_t ctx)
162-
int gr_poly_scalar_mul(gr_poly_t res, gr_srcptr c, const gr_poly_t poly, gr_ctx_t ctx)
163-
int gr_poly_mul_ui(gr_poly_t res, const gr_poly_t poly, ulong c, gr_ctx_t ctx)
164-
int gr_poly_mul_si(gr_poly_t res, const gr_poly_t poly, slong c, gr_ctx_t ctx)
165-
int gr_poly_mul_fmpz(gr_poly_t res, const gr_poly_t poly, const fmpz c, gr_ctx_t ctx)
166-
int gr_poly_mul_fmpq(gr_poly_t res, const gr_poly_t poly, const fmpq c, gr_ctx_t ctx)
167-
168-
Sets *res* to *poly* multiplied by the scalar *c* (or the scalar *c* multiplied by *poly*)
169-
which must be an element of or coercible to the coefficient ring.
170-
171161
.. function:: int _gr_poly_mul_karatsuba(gr_ptr res, gr_srcptr poly1, slong len1, gr_srcptr poly2, slong len2, gr_ctx_t ctx)
172162
int gr_poly_mul_karatsuba(gr_poly_t res, const gr_poly_t poly1, const gr_poly_t poly2, gr_ctx_t ctx)
173163

@@ -190,6 +180,41 @@ Arithmetic
190180
algorithm with `O(n^{1.5})` complexity, the ring must overload :func:`_gr_poly_mul` to dispatch
191181
to :func:`_gr_poly_mul_toom33` above some cutoff.
192182

183+
.. function:: int gr_poly_add_scalar(gr_poly_t res, const gr_poly_t poly, gr_srcptr c, gr_ctx_t ctx)
184+
int gr_poly_add_ui(gr_poly_t res, const gr_poly_t poly, ulong c, gr_ctx_t ctx)
185+
int gr_poly_add_si(gr_poly_t res, const gr_poly_t poly, slong c, gr_ctx_t ctx)
186+
int gr_poly_add_fmpz(gr_poly_t res, const gr_poly_t poly, const fmpz c, gr_ctx_t ctx)
187+
int gr_poly_add_fmpq(gr_poly_t res, const gr_poly_t poly, const fmpq c, gr_ctx_t ctx)
188+
189+
Sets *res* to *poly* plus the scalar *c* which must be
190+
an element of or coercible to the coefficient ring.
191+
192+
.. function:: int gr_poly_sub_scalar(gr_poly_t res, const gr_poly_t poly, gr_srcptr c, gr_ctx_t ctx)
193+
int gr_poly_sub_ui(gr_poly_t res, const gr_poly_t poly, ulong c, gr_ctx_t ctx)
194+
int gr_poly_sub_si(gr_poly_t res, const gr_poly_t poly, slong c, gr_ctx_t ctx)
195+
int gr_poly_sub_fmpz(gr_poly_t res, const gr_poly_t poly, const fmpz c, gr_ctx_t ctx)
196+
int gr_poly_sub_fmpq(gr_poly_t res, const gr_poly_t poly, const fmpq c, gr_ctx_t ctx)
197+
198+
Sets *res* to *poly* minus the scalar *c* which must be
199+
an element of or coercible to the coefficient ring.
200+
201+
.. function:: int gr_poly_mul_scalar(gr_poly_t res, const gr_poly_t poly, gr_srcptr c, gr_ctx_t ctx)
202+
int gr_poly_scalar_mul(gr_poly_t res, gr_srcptr c, const gr_poly_t poly, gr_ctx_t ctx)
203+
int gr_poly_mul_ui(gr_poly_t res, const gr_poly_t poly, ulong c, gr_ctx_t ctx)
204+
int gr_poly_mul_si(gr_poly_t res, const gr_poly_t poly, slong c, gr_ctx_t ctx)
205+
int gr_poly_mul_fmpz(gr_poly_t res, const gr_poly_t poly, const fmpz c, gr_ctx_t ctx)
206+
int gr_poly_mul_fmpq(gr_poly_t res, const gr_poly_t poly, const fmpq c, gr_ctx_t ctx)
207+
208+
Sets *res* to *poly* multiplied by the scalar *c* (or the scalar *c* multiplied by *poly*)
209+
which must be an element of or coercible to the coefficient ring.
210+
211+
.. function:: int gr_poly_addmul_scalar(gr_poly_t res, const gr_poly_t poly, gr_srcptr c, gr_ctx_t ctx)
212+
213+
Adds *poly* multiplied by the scalar *c* to *res*.
214+
215+
.. function:: int gr_poly_submul_scalar(gr_poly_t res, const gr_poly_t poly, gr_srcptr c, gr_ctx_t ctx)
216+
217+
Subtracts *poly* multiplied by the scalar *c* from *res*.
193218

194219
Powering
195220
--------------------------------------------------------------------------------

src/gr/polynomial.c

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,12 +360,60 @@ polynomial_neg(gr_poly_t res, const gr_poly_t mat, gr_ctx_t ctx)
360360
return gr_poly_neg(res, mat, POLYNOMIAL_ELEM_CTX(ctx));
361361
}
362362

363+
int
364+
polynomial_add_ui(gr_poly_t res, const gr_poly_t poly, ulong c, gr_ctx_t ctx)
365+
{
366+
return gr_poly_add_ui(res, poly, c, POLYNOMIAL_ELEM_CTX(ctx));
367+
}
368+
369+
int
370+
polynomial_add_si(gr_poly_t res, const gr_poly_t poly, slong c, gr_ctx_t ctx)
371+
{
372+
return gr_poly_add_si(res, poly, c, POLYNOMIAL_ELEM_CTX(ctx));
373+
}
374+
375+
int
376+
polynomial_add_fmpz(gr_poly_t res, const gr_poly_t poly, const fmpz_t c, gr_ctx_t ctx)
377+
{
378+
return gr_poly_add_fmpz(res, poly, c, POLYNOMIAL_ELEM_CTX(ctx));
379+
}
380+
381+
int
382+
polynomial_add_fmpq(gr_poly_t res, const gr_poly_t poly, const fmpq_t c, gr_ctx_t ctx)
383+
{
384+
return gr_poly_add_fmpq(res, poly, c, POLYNOMIAL_ELEM_CTX(ctx));
385+
}
386+
363387
int
364388
polynomial_add(gr_poly_t res, const gr_poly_t poly1, const gr_poly_t poly2, gr_ctx_t ctx)
365389
{
366390
return gr_poly_add(res, poly1, poly2, POLYNOMIAL_ELEM_CTX(ctx));
367391
}
368392

393+
int
394+
polynomial_sub_ui(gr_poly_t res, const gr_poly_t poly, ulong c, gr_ctx_t ctx)
395+
{
396+
return gr_poly_sub_ui(res, poly, c, POLYNOMIAL_ELEM_CTX(ctx));
397+
}
398+
399+
int
400+
polynomial_sub_si(gr_poly_t res, const gr_poly_t poly, slong c, gr_ctx_t ctx)
401+
{
402+
return gr_poly_sub_si(res, poly, c, POLYNOMIAL_ELEM_CTX(ctx));
403+
}
404+
405+
int
406+
polynomial_sub_fmpz(gr_poly_t res, const gr_poly_t poly, const fmpz_t c, gr_ctx_t ctx)
407+
{
408+
return gr_poly_sub_fmpz(res, poly, c, POLYNOMIAL_ELEM_CTX(ctx));
409+
}
410+
411+
int
412+
polynomial_sub_fmpq(gr_poly_t res, const gr_poly_t poly, const fmpq_t c, gr_ctx_t ctx)
413+
{
414+
return gr_poly_sub_fmpq(res, poly, c, POLYNOMIAL_ELEM_CTX(ctx));
415+
}
416+
369417
int
370418
polynomial_sub(gr_poly_t res, const gr_poly_t poly1, const gr_poly_t poly2, gr_ctx_t ctx)
371419
{
@@ -391,7 +439,7 @@ polynomial_mul_fmpz(gr_poly_t res, const gr_poly_t poly, const fmpz_t c, gr_ctx_
391439
}
392440

393441
int
394-
polynomial_mul_fmpq(gr_poly_t res, const gr_poly_t poly, fmpq_t c, gr_ctx_t ctx)
442+
polynomial_mul_fmpq(gr_poly_t res, const gr_poly_t poly, const fmpq_t c, gr_ctx_t ctx)
395443
{
396444
return gr_poly_mul_fmpq(res, poly, c, POLYNOMIAL_ELEM_CTX(ctx));
397445
}
@@ -618,7 +666,15 @@ gr_method_tab_input _gr_poly_methods_input[] =
618666
before converting to the dense representation, to avoid O(n^2) behavior */
619667
{GR_METHOD_SET_STR, (gr_funcptr) gr_generic_set_str_balance_additions},
620668
{GR_METHOD_NEG, (gr_funcptr) polynomial_neg},
669+
{GR_METHOD_ADD_UI, (gr_funcptr) polynomial_add_ui},
670+
{GR_METHOD_ADD_SI, (gr_funcptr) polynomial_add_si},
671+
{GR_METHOD_ADD_FMPZ, (gr_funcptr) polynomial_add_fmpz},
672+
{GR_METHOD_ADD_FMPQ, (gr_funcptr) polynomial_add_fmpq},
621673
{GR_METHOD_ADD, (gr_funcptr) polynomial_add},
674+
{GR_METHOD_SUB_UI, (gr_funcptr) polynomial_sub_ui},
675+
{GR_METHOD_SUB_SI, (gr_funcptr) polynomial_sub_si},
676+
{GR_METHOD_SUB_FMPZ, (gr_funcptr) polynomial_sub_fmpz},
677+
{GR_METHOD_SUB_FMPQ, (gr_funcptr) polynomial_sub_fmpq},
622678
{GR_METHOD_SUB, (gr_funcptr) polynomial_sub},
623679
{GR_METHOD_MUL, (gr_funcptr) polynomial_mul},
624680
{GR_METHOD_MUL_OTHER, (gr_funcptr) polynomial_mul_other},

src/gr_poly.h

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,17 +120,33 @@ WARN_UNUSED_RESULT int gr_poly_mul(gr_poly_t res, const gr_poly_t poly1, const g
120120
WARN_UNUSED_RESULT int _gr_poly_mullow_generic(gr_ptr res, gr_srcptr poly1, slong len1, gr_srcptr poly2, slong len2, slong n, gr_ctx_t ctx);
121121
GR_POLY_INLINE WARN_UNUSED_RESULT int _gr_poly_mullow(gr_ptr res, gr_srcptr poly1, slong len1, gr_srcptr poly2, slong len2, slong len, gr_ctx_t ctx) { return GR_POLY_BINARY_TRUNC_OP(ctx, POLY_MULLOW)(res, poly1, len1, poly2, len2, len, ctx); }
122122
WARN_UNUSED_RESULT int gr_poly_mullow(gr_poly_t res, const gr_poly_t poly1, const gr_poly_t poly2, slong n, gr_ctx_t ctx);
123+
124+
WARN_UNUSED_RESULT int _gr_poly_mul_karatsuba(gr_ptr res, gr_srcptr poly1, slong len1, gr_srcptr poly2, slong len2, gr_ctx_t ctx);
125+
WARN_UNUSED_RESULT int gr_poly_mul_karatsuba(gr_poly_t res, const gr_poly_t poly1, const gr_poly_t poly2, gr_ctx_t ctx);
126+
WARN_UNUSED_RESULT int _gr_poly_mul_toom33(gr_ptr res, gr_srcptr poly1, slong len1, gr_srcptr poly2, slong len2, gr_ctx_t ctx);
127+
WARN_UNUSED_RESULT int gr_poly_mul_toom33(gr_poly_t res, const gr_poly_t poly1, const gr_poly_t poly2, gr_ctx_t ctx);
128+
129+
WARN_UNUSED_RESULT int gr_poly_add_scalar(gr_poly_t res, const gr_poly_t poly, gr_srcptr c, gr_ctx_t ctx);
130+
WARN_UNUSED_RESULT int gr_poly_add_ui(gr_poly_t res, const gr_poly_t poly, ulong c, gr_ctx_t ctx);
131+
WARN_UNUSED_RESULT int gr_poly_add_si(gr_poly_t res, const gr_poly_t poly, slong c, gr_ctx_t ctx);
132+
WARN_UNUSED_RESULT int gr_poly_add_fmpz(gr_poly_t res, const gr_poly_t poly, const fmpz_t c, gr_ctx_t ctx);
133+
WARN_UNUSED_RESULT int gr_poly_add_fmpq(gr_poly_t res, const gr_poly_t poly, const fmpq_t c, gr_ctx_t ctx);
134+
135+
WARN_UNUSED_RESULT int gr_poly_sub_scalar(gr_poly_t res, const gr_poly_t poly, gr_srcptr c, gr_ctx_t ctx);
136+
WARN_UNUSED_RESULT int gr_poly_sub_ui(gr_poly_t res, const gr_poly_t poly, ulong c, gr_ctx_t ctx);
137+
WARN_UNUSED_RESULT int gr_poly_sub_si(gr_poly_t res, const gr_poly_t poly, slong c, gr_ctx_t ctx);
138+
WARN_UNUSED_RESULT int gr_poly_sub_fmpz(gr_poly_t res, const gr_poly_t poly, const fmpz_t c, gr_ctx_t ctx);
139+
WARN_UNUSED_RESULT int gr_poly_sub_fmpq(gr_poly_t res, const gr_poly_t poly, const fmpq_t c, gr_ctx_t ctx);
140+
123141
WARN_UNUSED_RESULT int gr_poly_mul_scalar(gr_poly_t res, const gr_poly_t poly, gr_srcptr c, gr_ctx_t ctx);
124142
WARN_UNUSED_RESULT int gr_poly_scalar_mul(gr_poly_t res, gr_srcptr c, const gr_poly_t poly, gr_ctx_t ctx);
125143
WARN_UNUSED_RESULT int gr_poly_mul_ui(gr_poly_t res, const gr_poly_t poly, ulong c, gr_ctx_t ctx);
126144
WARN_UNUSED_RESULT int gr_poly_mul_si(gr_poly_t res, const gr_poly_t poly, slong c, gr_ctx_t ctx);
127145
WARN_UNUSED_RESULT int gr_poly_mul_fmpz(gr_poly_t res, const gr_poly_t poly, const fmpz_t c, gr_ctx_t ctx);
128146
WARN_UNUSED_RESULT int gr_poly_mul_fmpq(gr_poly_t res, const gr_poly_t poly, const fmpq_t c, gr_ctx_t ctx);
129147

130-
WARN_UNUSED_RESULT int _gr_poly_mul_karatsuba(gr_ptr res, gr_srcptr poly1, slong len1, gr_srcptr poly2, slong len2, gr_ctx_t ctx);
131-
WARN_UNUSED_RESULT int gr_poly_mul_karatsuba(gr_poly_t res, const gr_poly_t poly1, const gr_poly_t poly2, gr_ctx_t ctx);
132-
WARN_UNUSED_RESULT int _gr_poly_mul_toom33(gr_ptr res, gr_srcptr poly1, slong len1, gr_srcptr poly2, slong len2, gr_ctx_t ctx);
133-
WARN_UNUSED_RESULT int gr_poly_mul_toom33(gr_poly_t res, const gr_poly_t poly1, const gr_poly_t poly2, gr_ctx_t ctx);
148+
WARN_UNUSED_RESULT int gr_poly_addmul_scalar(gr_poly_t res, const gr_poly_t poly, gr_srcptr c, gr_ctx_t ctx);
149+
WARN_UNUSED_RESULT int gr_poly_submul_scalar(gr_poly_t res, const gr_poly_t poly, gr_srcptr c, gr_ctx_t ctx);
134150

135151
/* powering */
136152

src/gr_poly/add_scalar.c

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
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 "fmpq.h"
13+
#include "gr_poly.h"
14+
15+
int
16+
gr_poly_add_scalar(gr_poly_t res, const gr_poly_t poly, gr_srcptr c, gr_ctx_t ctx)
17+
{
18+
int status;
19+
slong len = poly->length;
20+
21+
if (len == 0) {
22+
if (gr_is_zero(c, ctx) == T_TRUE) {
23+
return gr_poly_zero(res, ctx);
24+
} else {
25+
gr_poly_fit_length(res, 1, ctx);
26+
_gr_poly_set_length(res, 1, ctx);
27+
status = gr_set(res->coeffs, c, ctx);
28+
_gr_poly_normalise(res, ctx);
29+
return status;
30+
}
31+
}
32+
33+
status = GR_SUCCESS;
34+
35+
if (res != poly) {
36+
status |= gr_poly_set(res, poly, ctx);
37+
}
38+
39+
if (gr_is_zero(c, ctx) != T_TRUE) {
40+
gr_ptr constant_coeff = gr_poly_entry_ptr(res, 0, ctx);
41+
status |= gr_add(constant_coeff, constant_coeff, c, ctx);
42+
if (len == 1 && gr_is_zero(constant_coeff, ctx) == T_TRUE) {
43+
_gr_poly_set_length(res, 0, ctx);
44+
}
45+
}
46+
47+
return status;
48+
}
49+
50+
int
51+
gr_poly_add_ui(gr_poly_t res, const gr_poly_t poly, ulong c, gr_ctx_t ctx)
52+
{
53+
int status;
54+
slong len = poly->length;
55+
56+
if (len == 0) {
57+
if (c == 0) {
58+
return gr_poly_zero(res, ctx);
59+
} else {
60+
gr_poly_fit_length(res, 1, ctx);
61+
_gr_poly_set_length(res, 1, ctx);
62+
status = gr_set_ui(res->coeffs, c, ctx);
63+
_gr_poly_normalise(res, ctx);
64+
return status;
65+
}
66+
}
67+
68+
status = GR_SUCCESS;
69+
70+
if (res != poly) {
71+
status |= gr_poly_set(res, poly, ctx);
72+
}
73+
74+
if (c != 0) {
75+
gr_ptr constant_coeff = gr_poly_entry_ptr(res, 0, ctx);
76+
status |= gr_add_ui(constant_coeff, constant_coeff, c, ctx);
77+
if (len == 1 && gr_is_zero(constant_coeff, ctx) == T_TRUE) {
78+
_gr_poly_set_length(res, 0, ctx);
79+
}
80+
}
81+
82+
return status;
83+
}
84+
85+
int
86+
gr_poly_add_si(gr_poly_t res, const gr_poly_t poly, slong c, gr_ctx_t ctx)
87+
{
88+
int status;
89+
slong len = poly->length;
90+
91+
if (len == 0) {
92+
if (c == 0) {
93+
return gr_poly_zero(res, ctx);
94+
} else {
95+
gr_poly_fit_length(res, 1, ctx);
96+
_gr_poly_set_length(res, 1, ctx);
97+
status = gr_set_si(res->coeffs, c, ctx);
98+
_gr_poly_normalise(res, ctx);
99+
return status;
100+
}
101+
}
102+
103+
status = GR_SUCCESS;
104+
105+
if (res != poly) {
106+
status |= gr_poly_set(res, poly, ctx);
107+
}
108+
109+
if (c != 0) {
110+
gr_ptr constant_coeff = gr_poly_entry_ptr(res, 0, ctx);
111+
status |= gr_add_si(constant_coeff, constant_coeff, c, ctx);
112+
if (len == 1 && gr_is_zero(constant_coeff, ctx) == T_TRUE) {
113+
_gr_poly_set_length(res, 0, ctx);
114+
}
115+
}
116+
117+
return status;
118+
}
119+
120+
int
121+
gr_poly_add_fmpz(gr_poly_t res, const gr_poly_t poly, const fmpz_t c, gr_ctx_t ctx)
122+
{
123+
int status;
124+
slong len = poly->length;
125+
126+
if (len == 0) {
127+
if (fmpz_is_zero(c)) {
128+
return gr_poly_zero(res, ctx);
129+
} else {
130+
gr_poly_fit_length(res, 1, ctx);
131+
_gr_poly_set_length(res, 1, ctx);
132+
status = gr_set_fmpz(res->coeffs, c, ctx);
133+
_gr_poly_normalise(res, ctx);
134+
return status;
135+
}
136+
}
137+
138+
status = GR_SUCCESS;
139+
140+
if (res != poly) {
141+
status |= gr_poly_set(res, poly, ctx);
142+
}
143+
144+
if (!fmpz_is_zero(c)) {
145+
gr_ptr constant_coeff = gr_poly_entry_ptr(res, 0, ctx);
146+
status |= gr_add_fmpz(constant_coeff, constant_coeff, c, ctx);
147+
if (len == 1 && gr_is_zero(constant_coeff, ctx) == T_TRUE) {
148+
_gr_poly_set_length(res, 0, ctx);
149+
}
150+
}
151+
152+
return status;
153+
}
154+
155+
int
156+
gr_poly_add_fmpq(gr_poly_t res, const gr_poly_t poly, const fmpq_t c, gr_ctx_t ctx)
157+
{
158+
int status;
159+
slong len = poly->length;
160+
161+
if (len == 0) {
162+
if (fmpq_is_zero(c)) {
163+
return gr_poly_zero(res, ctx);
164+
} else {
165+
gr_poly_fit_length(res, 1, ctx);
166+
_gr_poly_set_length(res, 1, ctx);
167+
status = gr_set_fmpq(res->coeffs, c, ctx);
168+
_gr_poly_normalise(res, ctx);
169+
return status;
170+
}
171+
}
172+
173+
status = GR_SUCCESS;
174+
175+
if (res != poly) {
176+
status |= gr_poly_set(res, poly, ctx);
177+
}
178+
179+
if (!fmpq_is_zero(c)) {
180+
gr_ptr constant_coeff = gr_poly_entry_ptr(res, 0, ctx);
181+
status |= gr_add_fmpq(constant_coeff, constant_coeff, c, ctx);
182+
if (len == 1 && gr_is_zero(constant_coeff, ctx) == T_TRUE) {
183+
_gr_poly_set_length(res, 0, ctx);
184+
}
185+
}
186+
187+
return status;
188+
}

0 commit comments

Comments
 (0)