Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added functionality and documentation for calculating roots of univariate polynomials #935

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ BUILD_DIRS = aprcl ulong_extras long_extras perm fmpz fmpz_vec fmpz_poly \
fmpq_poly fmpz_mat fmpz_lll mpfr_vec mpfr_mat mpf_vec mpf_mat nmod_vec nmod_poly \
nmod_poly_factor arith mpn_extras nmod_mat fmpq fmpq_vec fmpq_mat padic \
fmpz_poly_q fmpz_poly_mat nmod_poly_mat fmpz_mod_poly \
fmpz_mod_poly_factor fmpz_factor fmpz_poly_factor fft qsieve \
fmpz_mod_poly_factor fmpz_factor fmpz_poly_factor fmpz_poly_roots fft qsieve \
double_extras d_vec d_mat padic_poly padic_mat qadic \
fq fq_vec fq_mat fq_poly fq_poly_factor fq_embed \
fq_nmod fq_nmod_vec fq_nmod_mat fq_nmod_poly fq_nmod_poly_factor fq_nmod_embed \
Expand Down
182 changes: 182 additions & 0 deletions doc/source/fmpz_poly_roots.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
.. _fmpz-poly-roots:

**fmpz_poly_roots.h** -- roots of univariate polynomials over the integers
==========================================================================

Find roots of univariate polynomials over the integers over finite
fields, p-adic or q-adic extensions.

-----------------------------

Roots over finite fields
------------------------

Types, macros and constants
___________________________

Type containing the information of roots over a finite field.

.. type:: fmpz_polynomial_roots_fq_t


Memory management
_________________

.. function:: void fmpz_poly_roots_fq_init2 (fmpz_poly_roots_fq_t roots, slong n, fq_ctx_t fctx)

Initializes ``roots`` for use, with context ``fctx``
to contain at most ``n`` roots. A corresponding call to
:func:`fmpz_poly_roots_fq_clear` must be made to free the memory
used bye the roots.

.. function:: void fmpz_poly_roots_fq_clear (fmpz_poly_roots_fq_t roots, fq_ctx_t fctx)

Clears the given roots, releasing any memory used. It must be
reinitialized in order to be used again.

Calculation of roots
____________________

.. function:: void fmpz_poly_roots_fq (fmpz_poly_roots_fq_t roots, fmpz_poly_t poly, fq_ctx_t fctx)

Takes as input a polynomial ``poly`` and a context of of a
finite field ``fctx`` and initialized ``roots``.

Input and output
________________

.. function:: char * fmpz_poly_roots_fq_get_str (fmpz_poly_roots_fq_t roots, fq_ctx_t fctx)

Returns a representation of ``roots``
as a zero terminated string.

.. function:: int fmpz_poly_roots_fq_print (fmpz_poly_roots_fq_t roots, fq_ctx_t fctx)

Prints a representation of ``roots`` to ``stdout``.
In case of success, returns a positive value. In case of
failure, returns a non-positive value.

.. function:: char * fmpz_poly_roots_fq_get_str_pretty (fmpz_poly_roots_fq_t roots, fq_ctx_t fctx)

Returns a pretty representation of ``roots``
as a zero terminated string.

.. function:: int fmpz_poly_roots_fq_fprint_pretty (FILE * file, fmpz_poly_roots_fq_t roots, fq_ctx_t fctx)

Prints a pretty representation of ``roots`` to ``file``.
In case of success, returns a positive value. In case of
failure, returns a non-positive value.

.. function:: int fmpz_poly_roots_fq_print_pretty (fmpz_poly_roots_fq_t roots, fq_ctx_t fctx)

Prints a pretty representation of ``roots`` to ``stdout``.
In case of success, returns a positive value. In case of
failure, returns a non-positive value.


Roots over padic fields
-----------------------

Types, macros and constants
___________________________

Type containing the information of roots over a p-adic field.

.. type:: fmpz_polynomial_roots_padic_t

Memory management
_________________

.. function:: void fmpz_poly_roots_padic_init2 (fmpz_poly_roots_padic_t roots, slong n, fq_ctx_t fctx)

Initializes ``roots`` for use, with context ``fctx``
to contain at most ``n`` roots. A corresponding call to :func:`fmpz_poly_roots_padic_clear` must be made to free the memory
used bye the roots.

.. function:: void fmpz_poly_roots_padic_clear (fmpz_poly_roots_padic_t roots, fq_ctx_t fctx)

Clears the given roots, releasing any memory used. It must be
reinitialized in order to be used again.

Calculation of roots
____________________

.. function:: void fmpz_poly_roots_padic_fmpz_poly (fmpz_poly_roots_padic_t roots, fmpz_poly_t poly, fq_ctx_t fctx)

Takes as input a polynomial ``poly`` and a context of of a
finite field ``fctx`` and initialized ``roots``.

Input and output
________________


.. function:: char * fmpz_poly_roots_padic_get_str (fmpz_poly_roots_padic_t roots, fq_ctx_t fctx)

Returns a representation of ``roots``
as a zero terminated string.

.. function:: int fmpz_poly_roots_padic_fprint_pretty (FILE * file, fmpz_poly_roots_padic_t roots, fq_ctx_t fctx)

Prints a representation of ``roots`` to ``file``.
In case of success, returns a positive value. In case of
failure, returns a non-positive value.

.. function:: int fmpz_poly_roots_padic_print_pretty (fmpz_poly_roots_padic_t roots, fq_ctx_t fctx)

Prints a representation of ``roots`` to ``stdout``.
In case of success, returns a positive value. In case of
failure, returns a non-positive value.

Roots over q-adic fields
------------------------

Types, macros and constants
___________________________

Type containing the information of roots over an unramified
extension over p-adic field.

.. type:: fmpz_polynomial_roots_qadic_t

Memory management
_________________

.. function:: void fmpz_poly_roots_qadic_init2 (fmpz_poly_roots_qadic_t roots, slong n, fq_ctx_t fctx)

Initializes ``roots`` for use, with context ``fctx``
to contain at most ``n`` roots. A corresponding call to
:func:`fmpz_poly_roots_qadic_clear` must be made to free the memory
used bye the roots.

.. function:: void fmpz_poly_roots_qadic_clear (fmpz_poly_roots_qadic_t roots, fq_ctx_t fctx)

Clears the given roots, releasing any memory used. It must be
reinitialized in order to be used again.

Calculation of roots
________________________

.. function:: void fmpz_poly_roots_qadic (fmpz_poly_roots_qadic_t roots, fmpz_poly_t poly, fq_ctx_t fctx)

Takes as input a polynomial ``poly`` and a context of of a
finite field ``fctx`` and initialized ``roots``.

Input and output
________________

.. function:: char * fmpz_poly_roots_qadic_get_str_pretty (fmpz_poly_roots_qadic_t roots, fq_ctx_t fctx)

Returns a pretty representation of ``roots`` as zero
terminated string.

.. function:: int fmpz_poly_roots_qadic_fprint_pretty (FILE *file, fmpz_poly_roots_qadic_t roots, fq_ctx_t fctx)

Prints a pretty representation of ``roots`` to ``file``.
In case of success, returns a positive value. In case of
failure, returns a non-positive value.

.. function:: int fmpz_poly_roots_qadic_print_pretty (fmpz_poly_roots_qadic_t roots, fq_ctx_t fctx)

Prints a pretty representation of ``roots`` to ``stdout``.
In case of success, returns a positive value. In case of
failure, returns a non-positive value.
1 change: 1 addition & 0 deletions doc/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ Integers
fmpz_poly.rst
fmpz_poly_mat.rst
fmpz_poly_factor.rst
fmpz_poly_roots.rst
fmpz_mpoly.rst
fmpz_mpoly_factor.rst
long_extras.rst
Expand Down
64 changes: 64 additions & 0 deletions fmpz_poly_roots.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#ifndef FMPZ_POLY_ROOTS_H_
#define FMPZ_POLY_ROOTS_H_

#include "fmpz_poly.h"

#include "fq.h"
#include "padic.h"
#include "qadic.h"

typedef struct
{
fq_struct *x0;
slong *multiplicity;
slong num;
slong alloc;
} fmpz_poly_roots_fq_struct;

typedef fmpz_poly_roots_fq_struct fmpz_poly_roots_fq_t[1];

void fmpz_poly_roots_fq_init2 (fmpz_poly_roots_fq_t roots, slong n, fq_ctx_t fctx);
void fmpz_poly_roots_fq_clear (fmpz_poly_roots_fq_t roots, fq_ctx_t fctx);
void fmpz_poly_roots_fq_print (fmpz_poly_roots_fq_t roots, fq_ctx_t fctx);
char* fmpz_poly_roots_fq_get_str_pretty (fmpz_poly_roots_fq_t roots, fq_ctx_t fctx);
int fmpz_poly_roots_fq_fprint_pretty (FILE *file, fmpz_poly_roots_fq_t roots, fq_ctx_t fctx);
int fmpz_poly_roots_fq_print_pretty (fmpz_poly_roots_fq_t roots, fq_ctx_t fctx);
void fmpz_poly_roots_fq(fmpz_poly_roots_fq_t roots, fmpz_poly_t poly, fq_ctx_t fctx);

typedef struct
{
padic_struct *x0;
slong *multiplicity;
slong num;
slong alloc;
} fmpz_poly_roots_padic_struct;

typedef fmpz_poly_roots_padic_struct fmpz_poly_roots_padic_t[1];

void fmpz_poly_roots_padic_init2 (fmpz_poly_roots_padic_t roots, slong n);
void fmpz_poly_roots_padic_clear (fmpz_poly_roots_padic_t roots);
char* fmpz_poly_roots_padic_get_str (fmpz_poly_roots_padic_t roots, padic_ctx_t fctx);
int fmpz_poly_roots_padic_fprint (FILE* file, fmpz_poly_roots_padic_t roots, padic_ctx_t fctx);
int fmpz_poly_roots_padic_print (fmpz_poly_roots_padic_t roots, padic_ctx_t fctx);
void fmpz_poly_roots_padic (fmpz_poly_roots_padic_t roots, fmpz_poly_t poly,
padic_ctx_t fctx);

typedef struct
{
qadic_struct *x0;
slong *multiplicity;
slong num;
slong alloc;
} fmpz_poly_roots_qadic_struct;

typedef fmpz_poly_roots_qadic_struct fmpz_poly_roots_qadic_t[1];

void fmpz_poly_roots_qadic_init2 (fmpz_poly_roots_qadic_t roots, slong n);
void fmpz_poly_roots_qadic_clear (fmpz_poly_roots_qadic_t roots);
char* fmpz_poly_roots_qadic_get_str_pretty (fmpz_poly_roots_qadic_t roots, qadic_ctx_t fctx);
int fmpz_poly_roots_qadic_fprint_pretty (FILE * file, fmpz_poly_roots_qadic_t roots, qadic_ctx_t fctx);
int fmpz_poly_roots_qadic_print_pretty (fmpz_poly_roots_qadic_t roots, qadic_ctx_t fctx);
void fmpz_poly_roots_qadic (fmpz_poly_roots_qadic_t roots, fmpz_poly_t poly,
qadic_ctx_t fctx);

#endif
132 changes: 132 additions & 0 deletions fmpz_poly_roots/fq_roots.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#include "flint.h"
#include "fq_vec.h"
#include "fq_poly.h"
#include "fmpz_poly.h"
#include "fmpz_mod_poly.h"
#include "fmpz_poly_roots.h"

void
fmpz_poly_roots_fq_init2 (fmpz_poly_roots_fq_t roots, slong n, fq_ctx_t fctx)
{
roots->x0 = _fq_vec_init (n, fctx);
roots->multiplicity = flint_malloc (sizeof (slong) * n);
roots->num = n;
roots->alloc = n;
}

void
fmpz_poly_roots_fq_clear (fmpz_poly_roots_fq_t roots, fq_ctx_t fctx)
{
_fq_vec_clear (roots->x0, roots->alloc, fctx);
flint_free (roots->multiplicity);
}


char *
fmpz_poly_roots_fq_get_str (fmpz_poly_roots_fq_t roots, fq_ctx_t fctx)
{
char * buffer = NULL;
size_t buffer_size = 0;
FILE * out = open_memstream(&buffer, &buffer_size);

_fq_vec_fprint (out, roots->x0, roots->num, fctx);
fclose(out);

return buffer;
}

void
fmpz_poly_roots_fq_print (fmpz_poly_roots_fq_t roots, fq_ctx_t fctx)
{
_fq_vec_print (roots->x0, roots->num, fctx);
}

char *
fmpz_poly_roots_fq_get_str_pretty (fmpz_poly_roots_fq_t roots, fq_ctx_t fctx)
{
char * buffer = NULL;
size_t buffer_size = 0;
FILE * out = open_memstream(&buffer, &buffer_size);
slong j;

for (j = 0; j < roots->num; j++)
{
fq_fprint_pretty (out, roots->x0 + j, fctx);
flint_fprintf (out, " %wd\n", roots->multiplicity[j]);
}

fclose(out);

return buffer;
}

int
fmpz_poly_roots_fq_fprint_pretty (FILE* file, fmpz_poly_roots_fq_t roots, fq_ctx_t fctx)
{
slong j;

for (j = 0; j < roots->num; j++)
{
fq_fprint_pretty (file, roots->x0 + j, fctx);
flint_fprintf (file, " %wd\n", roots->multiplicity[j]);
}

return 1;
}

int
fmpz_poly_roots_fq_print_pretty (fmpz_poly_roots_fq_t roots, fq_ctx_t fctx)
{
fmpz_poly_roots_fq_fprint_pretty(stdout, roots, fctx);
return 1;
}

void
fmpz_poly_roots_fq (fmpz_poly_roots_fq_t roots, fmpz_poly_t poly, fq_ctx_t fctx)
{
slong j, k, num;

fmpz_mod_ctx_t fmctx;
fmpz_mod_poly_t mpoly;
fq_poly_factor_t f;
fq_t lead;
fq_poly_t fpoly;

fmpz_mod_ctx_init(fmctx, fq_ctx_prime(fctx));
fmpz_mod_poly_init (mpoly, fmctx);
fmpz_mod_poly_set_fmpz_poly (mpoly, poly, fmctx);

fq_init (lead, fctx);
fq_poly_factor_init (f, fctx);
fq_poly_init (fpoly, fctx);
fq_poly_set_fmpz_mod_poly (fpoly, mpoly, fctx);
fq_poly_factor(f, lead, fpoly, fctx);
fq_clear(lead, fctx);

fmpz_mod_poly_clear (mpoly, fmctx);
fmpz_mod_ctx_clear(fmctx);
fq_poly_clear (fpoly, fctx);

num = 0;

for (j = 0; j < f->num; j++)
{
if (fq_poly_degree (f->poly + j, fctx) == 1)
num++;
}

fmpz_poly_roots_fq_init2 (roots, num, fctx);

k = 0;

for (j = 0; j < f->num; j++)
{
if (fq_poly_degree (f->poly + j, fctx) == 1)
{
fq_poly_get_coeff (roots->x0 + k, f->poly + j, 0, fctx);
fq_neg(roots->x0 + k, roots->x0 + k, fctx);
roots->multiplicity[k] = f->exp[j];
k++;
}
}
}
Loading