Loading...
Searching...
No Matches
polynomial.h
Go to the documentation of this file.
1#pragma once
2
13
14#include <inttypes.h>
15#include <stdlib.h>
16#include <stdio.h>
17
18#include <nut/modular_math.h>
19
26typedef struct{
29 uint64_t len;
31 uint64_t cap;
34 int64_t *coeffs;
35} nut_Poly;
36
38typedef struct{
40 uint64_t len;
42 uint64_t cap;
45 int64_t *roots;
46} nut_Roots;
47
48
49
58NUT_ATTR_ACCESS(read_write, 1)
59bool nut_Poly_init(nut_Poly *f, uint64_t reserve);
60
64NUT_ATTR_ACCESS(read_write, 1)
66
75NUT_ATTR_ACCESS(read_only, 1)
76NUT_ATTR_ACCESS(read_only, 2)
77int nut_Poly_cmp(const nut_Poly *a, const nut_Poly *b);
78
87NUT_ATTR_ACCESS(read_write, 1)
88bool nut_Roots_init(nut_Roots *roots, uint64_t reserve);
89
93NUT_ATTR_ACCESS(read_write, 1)
95
96
97
106NUT_ATTR_ACCESS(read_write, 1)
107bool nut_Poly_ensure_cap(nut_Poly *f, uint64_t cap);
108
116NUT_ATTR_ACCESS(read_write, 1)
117bool nut_Poly_zero_extend(nut_Poly *f, uint64_t len);
118
127NUT_ATTR_ACCESS(read_write, 1)
128bool nut_Roots_ensure_cap(nut_Roots *roots, uint64_t cap);
129
135NUT_ATTR_ACCESS(read_write, 1)
137
143NUT_ATTR_ACCESS(read_write, 1)
144void nut_Poly_normalize_modn(nut_Poly *f, int64_t n, bool use_negatives);
145
151NUT_ATTR_ACCESS(read_write, 1)
153
154
155
162NUT_ATTR_ACCESS(read_write, 1)
163NUT_ATTR_ACCESS(read_only, 2)
164bool nut_Poly_copy(nut_Poly *restrict g, const nut_Poly *restrict f);
165
172NUT_ATTR_ACCESS(read_write, 1)
173bool nut_Poly_setconst(nut_Poly *f, int64_t c);
174
175
176
186NUT_ATTR_ACCESS(read_only, 1)
187int64_t nut_Poly_eval_modn(const nut_Poly *f, int64_t x, int64_t n);
188
203NUT_ATTR_NONNULL(1, 2, 3, 4, 5, 6)
204NUT_ATTR_ACCESS(read_write, 1)
205NUT_ATTR_ACCESS(read_only, 2)
206NUT_ATTR_ACCESS(read_only, 3)
207NUT_ATTR_ACCESS(read_only, 4)
208NUT_ATTR_ACCESS(read_only, 5)
209NUT_ATTR_ACCESS(read_only, 6)
210int nut_Poly_fprint(FILE *restrict file, const nut_Poly *restrict f, const char *vname, const char *add, const char *sub, const char *pow, bool descending);
211
225NUT_ATTR_NONNULL(1, 2, 3)
226NUT_ATTR_ACCESS(read_write, 1)
227NUT_ATTR_ACCESS(write_only, 2)
228NUT_ATTR_ACCESS(read_only, 3)
229NUT_ATTR_ACCESS(write_only, 4)
230int nut_Poly_parse(nut_Poly *restrict f, int64_t *restrict n, const char *restrict str, const char *restrict *restrict end);
231
241NUT_ATTR_ACCESS(read_write, 1)
242bool nut_Poly_rand_modn(nut_Poly *f, uint64_t max_len, int64_t n);
243
244
245
251NUT_ATTR_NONNULL(1, 2, 3)
252NUT_ATTR_ACCESS(read_write, 1)
253NUT_ATTR_ACCESS(read_only, 2)
254NUT_ATTR_ACCESS(read_only, 3)
255bool nut_Poly_add_modn(nut_Poly *h, const nut_Poly *f, const nut_Poly *g, int64_t n);
256
262NUT_ATTR_NONNULL(1, 2, 3)
263NUT_ATTR_ACCESS(read_write, 1)
264NUT_ATTR_ACCESS(read_only, 2)
265NUT_ATTR_ACCESS(read_only, 3)
266bool nut_Poly_sub_modn(nut_Poly *h, const nut_Poly *f, const nut_Poly *g, int64_t n);
267
273NUT_ATTR_NONNULL(1, 2, 3)
274NUT_ATTR_ACCESS(read_write, 1)
275NUT_ATTR_ACCESS(read_only, 2)
276NUT_ATTR_ACCESS(read_only, 3)
277bool nut_Poly_dot_modn(nut_Poly *h, const nut_Poly *f, const nut_Poly *g, int64_t n);
278
286NUT_ATTR_ACCESS(read_write, 1)
287NUT_ATTR_ACCESS(read_only, 2)
288bool nut_Poly_scale_modn(nut_Poly *g, const nut_Poly *f, int64_t a, int64_t n);
289
290
291
299NUT_ATTR_NONNULL(1, 2, 3)
300NUT_ATTR_ACCESS(read_write, 1)
301NUT_ATTR_ACCESS(read_only, 2)
302NUT_ATTR_ACCESS(read_only, 3)
303bool nut_Poly_mul_modn(nut_Poly *restrict h, const nut_Poly *f, const nut_Poly *g, int64_t n);
304
314NUT_ATTR_NONNULL(1, 2, 6)
315NUT_ATTR_ACCESS(read_write, 1)
316NUT_ATTR_ACCESS(read_only, 2)
317NUT_ATTR_ACCESS(read_write, 6)
318bool nut_Poly_pow_modn(nut_Poly *restrict g, const nut_Poly *restrict f, uint64_t e, int64_t n, uint64_t cn, nut_Poly tmps[restrict static 2]);
319
331NUT_ATTR_ACCESS(read_write, 1)
332NUT_ATTR_ACCESS(read_only, 2)
333bool nut_Poly_pow_modn_tmptmp(nut_Poly *restrict g, const nut_Poly *restrict f, uint64_t e, int64_t n, uint64_t cn);
334
335
336
345NUT_ATTR_NONNULL(1, 2, 3, 6)
346NUT_ATTR_ACCESS(read_write, 1)
347NUT_ATTR_ACCESS(read_only, 2)
348NUT_ATTR_ACCESS(read_only, 3)
349NUT_ATTR_ACCESS(read_write, 6)
350bool nut_Poly_compose_modn(nut_Poly *restrict h, const nut_Poly *f, const nut_Poly *g, int64_t n, uint64_t cn, nut_Poly tmps[restrict static 2]);
351
361NUT_ATTR_NONNULL(1, 2, 3)
362NUT_ATTR_ACCESS(read_write, 1)
363NUT_ATTR_ACCESS(read_only, 2)
364NUT_ATTR_ACCESS(read_only, 3)
365bool nut_Poly_compose_modn_tmptmp(nut_Poly *restrict h, const nut_Poly *f, const nut_Poly *g, int64_t n, uint64_t cn);
366
367
368
382NUT_ATTR_NONNULL(1, 2, 3, 4)
383NUT_ATTR_ACCESS(read_write, 1)
384NUT_ATTR_ACCESS(read_write, 2)
385NUT_ATTR_ACCESS(read_only, 3)
386NUT_ATTR_ACCESS(read_only, 4)
387bool nut_Poly_quotrem_modn(nut_Poly *restrict q, nut_Poly *restrict r, const nut_Poly *restrict f, const nut_Poly *restrict g, int64_t n);
388
389
390
391//TODO: use arrays for temporaries instead of single pointers, maybe provide a nut_Poly[1] typedef as is tradition
409NUT_ATTR_NONNULL(1, 2, 3, 5)
410NUT_ATTR_ACCESS(read_write, 1)
411NUT_ATTR_ACCESS(read_only, 2)
412NUT_ATTR_ACCESS(read_only, 3)
413NUT_ATTR_ACCESS(read_write, 5)
414bool nut_Poly_gcd_modn(nut_Poly *restrict d, const nut_Poly *restrict f, const nut_Poly *restrict g, int64_t n, nut_Poly tmps[restrict static 3]);
415
424NUT_ATTR_NONNULL(1, 2, 3)
425NUT_ATTR_ACCESS(read_write, 1)
426NUT_ATTR_ACCESS(read_only, 2)
427NUT_ATTR_ACCESS(read_only, 3)
428bool nut_Poly_gcd_modn_tmptmp(nut_Poly *restrict d, const nut_Poly *restrict f, const nut_Poly *restrict g, int64_t n);
429
430
431
442NUT_ATTR_NONNULL(1, 2, 4, 6)
443NUT_ATTR_ACCESS(read_write, 1)
444NUT_ATTR_ACCESS(read_only, 2)
445NUT_ATTR_ACCESS(read_only, 4)
446NUT_ATTR_ACCESS(read_write, 6)
447bool nut_Poly_powmod_modn(nut_Poly *restrict h, const nut_Poly *restrict f, uint64_t e, const nut_Poly *restrict g, int64_t n, nut_Poly tmps[restrict static 3]);
448
459NUT_ATTR_NONNULL(1, 2, 4)
460NUT_ATTR_ACCESS(read_write, 1)
461NUT_ATTR_ACCESS(read_only, 2)
462NUT_ATTR_ACCESS(read_only, 4)
463bool nut_Poly_powmod_modn_tmptmp(nut_Poly *restrict h, const nut_Poly *restrict f, uint64_t e, const nut_Poly *restrict g, int64_t n);
464
487NUT_ATTR_NONNULL(1, 2, 5)
488NUT_ATTR_ACCESS(read_write, 1)
489NUT_ATTR_ACCESS(read_only, 2)
490NUT_ATTR_ACCESS(read_write, 5)
491bool nut_Poly_factors_d_modn(nut_Poly *restrict f_d, const nut_Poly *restrict f, uint64_t d, int64_t n, nut_Poly tmps[restrict static 4]);
492
512NUT_ATTR_NONNULL(1, 2, 5)
513NUT_ATTR_ACCESS(read_write, 1)
514NUT_ATTR_ACCESS(read_only, 2)
515NUT_ATTR_ACCESS(read_write, 5)
516bool nut_Poly_factor1_modn(nut_Poly *restrict g, const nut_Poly *restrict f, uint64_t d, int64_t n, nut_Poly tmps[restrict static 4]);
517
529NUT_ATTR_NONNULL(1, 3, 4)
530NUT_ATTR_ACCESS(read_only, 1)
531NUT_ATTR_ACCESS(read_write, 3)
532NUT_ATTR_ACCESS(read_write, 4)
533bool nut_Poly_roots_modn(const nut_Poly *restrict f, int64_t n, nut_Roots *restrict roots, nut_Poly tmps[restrict static 6]);
534
544NUT_ATTR_ACCESS(read_only, 1)
545NUT_ATTR_ACCESS(read_write, 3)
546bool nut_Poly_roots_modn_tmptmp(const nut_Poly *restrict f, int64_t n, nut_Roots *restrict roots);
547
548
#define NUT_ATTR_ACCESS(...)
Wrapper for gcc's access function annotation - no clang equivalent, and currently disabled because it...
#define NUT_ATTR_NONNULL(...)
Wrapper for gnu::nonnull attr.
#define NUT_ATTR_NODISCARD
Wrapper for nodiscard attr - requires return value be used.
#define NUT_ATTR_PURE
Wrapper for gnu::pure attr - similar to const but the function can read non-volatile memory (includin...
bool nut_Poly_compose_modn(nut_Poly *restrict h, const nut_Poly *f, const nut_Poly *g, int64_t n, uint64_t cn, nut_Poly tmps[restrict static 2])
Compose polynomial f(g(x)) mod n and store the result in h.
bool nut_Poly_quotrem_modn(nut_Poly *restrict q, nut_Poly *restrict r, const nut_Poly *restrict f, const nut_Poly *restrict g, int64_t n)
Divide two polynomials to get a quotient and remainder.
bool nut_Poly_roots_modn_tmptmp(const nut_Poly *restrict f, int64_t n, nut_Roots *restrict roots)
Find all roots of a polynomial in an odd prime field.
bool nut_Poly_sub_modn(nut_Poly *h, const nut_Poly *f, const nut_Poly *g, int64_t n)
Subtract polynomials f - g mod n and store the result in h.
bool nut_Poly_factor1_modn(nut_Poly *restrict g, const nut_Poly *restrict f, uint64_t d, int64_t n, nut_Poly tmps[restrict static 4])
Attempt to find a divisor of f_d.
NUT_ATTR_PURE int64_t nut_Poly_eval_modn(const nut_Poly *f, int64_t x, int64_t n)
Evaluate a polynomial mod a number.
bool nut_Poly_mul_modn(nut_Poly *restrict h, const nut_Poly *f, const nut_Poly *g, int64_t n)
Multiply polynomials f*g mod n and store the result in h.
bool nut_Poly_dot_modn(nut_Poly *h, const nut_Poly *f, const nut_Poly *g, int64_t n)
Take the termwise product of polynomials f and g mod n and store the result in h.
bool nut_Poly_compose_modn_tmptmp(nut_Poly *restrict h, const nut_Poly *f, const nut_Poly *g, int64_t n, uint64_t cn)
Compose polynomial f(g(x)) mod n and store the result in h.
bool nut_Poly_rand_modn(nut_Poly *f, uint64_t max_len, int64_t n)
Generate a random polynomial.
bool nut_Poly_roots_modn(const nut_Poly *restrict f, int64_t n, nut_Roots *restrict roots, nut_Poly tmps[restrict static 6])
Find all roots of a polynomial in an odd prime field.
void nut_Poly_normalize_exps_modn(nut_Poly *f, uint64_t cn)
Reduce any exponents over cn.
NUT_ATTR_NODISCARD bool nut_Poly_copy(nut_Poly *restrict g, const nut_Poly *restrict f)
Copy a polynomial.
bool nut_Poly_pow_modn(nut_Poly *restrict g, const nut_Poly *restrict f, uint64_t e, int64_t n, uint64_t cn, nut_Poly tmps[restrict static 2])
Raise f**x mod n and store the result in g.
int nut_Poly_parse(nut_Poly *restrict f, int64_t *restrict n, const char *restrict str, const char *restrict *restrict end)
Convert a string to a polynomial (and possibly modulus)
NUT_ATTR_NODISCARD bool nut_Roots_ensure_cap(nut_Roots *roots, uint64_t cap)
Extend the capacity of a root buffer if needed.
bool nut_Poly_powmod_modn_tmptmp(nut_Poly *restrict h, const nut_Poly *restrict f, uint64_t e, const nut_Poly *restrict g, int64_t n)
Compute the power of a polynomial mod another polynomial.
bool nut_Poly_gcd_modn(nut_Poly *restrict d, const nut_Poly *restrict f, const nut_Poly *restrict g, int64_t n, nut_Poly tmps[restrict static 3])
Find the gcd of two polynomials.
bool nut_Poly_powmod_modn(nut_Poly *restrict h, const nut_Poly *restrict f, uint64_t e, const nut_Poly *restrict g, int64_t n, nut_Poly tmps[restrict static 3])
Compute the power of a polynomial mod another polynomial.
bool nut_Poly_factors_d_modn(nut_Poly *restrict f_d, const nut_Poly *restrict f, uint64_t d, int64_t n, nut_Poly tmps[restrict static 4])
Compute the product of all irreducible factors of degree d.
bool nut_Poly_gcd_modn_tmptmp(nut_Poly *restrict d, const nut_Poly *restrict f, const nut_Poly *restrict g, int64_t n)
Find the gcd of two polynomials.
void nut_Poly_normalize_modn(nut_Poly *f, int64_t n, bool use_negatives)
Reduce coefficients mod n, then normalize.
NUT_ATTR_NODISCARD bool nut_Roots_init(nut_Roots *roots, uint64_t reserve)
Initialize a root buffer with at least a given capacity.
bool nut_Poly_pow_modn_tmptmp(nut_Poly *restrict g, const nut_Poly *restrict f, uint64_t e, int64_t n, uint64_t cn)
Raise f**x mod n and store the result in g.
NUT_ATTR_NODISCARD bool nut_Poly_zero_extend(nut_Poly *f, uint64_t len)
Extend the capacity of a polynomial struct if needed and set any new terms to 0.
void nut_Roots_destroy(nut_Roots *roots)
Free resources held by a root buffer.
NUT_ATTR_PURE int nut_Poly_cmp(const nut_Poly *a, const nut_Poly *b)
Asymptotically compare polynomials.
NUT_ATTR_NODISCARD bool nut_Poly_init(nut_Poly *f, uint64_t reserve)
Initialize a polynomial with at least a given capacity.
void nut_Poly_destroy(nut_Poly *f)
Free resources held by a polynomial struct.
NUT_ATTR_NODISCARD bool nut_Poly_setconst(nut_Poly *f, int64_t c)
Set a polynomial to a constant (linear terms and up zero).
bool nut_Poly_scale_modn(nut_Poly *g, const nut_Poly *f, int64_t a, int64_t n)
Multiply a polynomial f by a scalar a and store the result in h.
bool nut_Poly_add_modn(nut_Poly *h, const nut_Poly *f, const nut_Poly *g, int64_t n)
Add polynomials f + g mod n and store the result in h.
NUT_ATTR_NODISCARD bool nut_Poly_ensure_cap(nut_Poly *f, uint64_t cap)
Extend the capacity of a polynomial struct if needed.
int nut_Poly_fprint(FILE *restrict file, const nut_Poly *restrict f, const char *vname, const char *add, const char *sub, const char *pow, bool descending)
Print a polynomial to a file.
void nut_Poly_normalize(nut_Poly *f)
Strip off terms so the leading term is nonzero if needed.
A polynomial with signed integer coefficients.
Definition polynomial.h:26
uint64_t cap
Maximum length polynomial the coeffs buffer can currently store.
Definition polynomial.h:31
uint64_t len
Length of the polynomial.
Definition polynomial.h:29
int64_t * coeffs
Array of coefficients.
Definition polynomial.h:34
The roots of a polynomial over a finite field, ignoring multiplicity.
Definition polynomial.h:38
int64_t * roots
Array of roots.
Definition polynomial.h:45
uint64_t len
Number of roots, can be 0 if there are none.
Definition polynomial.h:40
uint64_t cap
Maximum number of roots the roots buffer can currently store.
Definition polynomial.h:42