Skip to content

Commit

Permalink
Add get/set_str methods for gr_poly (flintlib#2238)
Browse files Browse the repository at this point in the history
* Add get/set_str methods for gr_poly
  • Loading branch information
fredrik-johansson authored Feb 4, 2025
1 parent 90f5c30 commit 2ddde79
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 8 deletions.
15 changes: 15 additions & 0 deletions doc/source/gr_poly.rst
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,23 @@ Basic manipulation
int gr_poly_gen(gr_poly_t poly, gr_ctx_t ctx)

.. function:: int gr_poly_write(gr_stream_t out, const gr_poly_t poly, const char * x, gr_ctx_t ctx)
int _gr_poly_write(gr_stream_t out, gr_srcptr poly, slong n, const char * x, gr_ctx_t ctx)
int _gr_poly_get_str(char ** res, const gr_poly_t f, const char * x, gr_ctx_t ctx)
int gr_poly_get_str(char ** res, const gr_poly_t f, const char * x, gr_ctx_t ctx)
int gr_poly_print(const gr_poly_t poly, gr_ctx_t ctx)

.. function:: int _gr_poly_set_str(gr_ptr res, const char * s, const char * x, slong len, gr_ctx_t ctx)
int gr_poly_set_str(gr_poly_t res, const char * s, const char * x, gr_ctx_t ctx)

Parse polynomial from an expression string, assuming that the string in *x* gives
the name of the generator. The underscore method zero-pads the result if
the length of the parsed polynomial is shorter than *len*, and returns
``GR_UNABLE`` if the length of the parsed polynomial exceeds *len*.
Intermediate terms are allowed to be longer than *len*.

Warning: these methods are not currently optimized for polynomials of high degree
and may run with quadratic complexity.

.. function:: int gr_poly_randtest(gr_poly_t poly, flint_rand_t state, slong len, gr_ctx_t ctx)

.. function:: truth_t _gr_poly_equal(gr_srcptr poly1, slong len1, gr_srcptr poly2, slong len2, gr_ctx_t ctx)
Expand Down
2 changes: 0 additions & 2 deletions src/gr_mat/diagonalization.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,6 @@ gr_mat_diagonalization_generic(gr_vec_t D, gr_mat_t L, gr_mat_t R, const gr_mat_
if (gr_mat_is_square(A, ctx) != T_TRUE)
return GR_DOMAIN;

gr_ctx_println(ctx);

gr_ctx_init_fmpz(ZZ);
gr_vec_init(eigenvalues, 0, ctx);
gr_vec_init(mult, 0, ZZ);
Expand Down
5 changes: 5 additions & 0 deletions src/gr_poly.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,12 @@ WARN_UNUSED_RESULT int gr_poly_one(gr_poly_t poly, gr_ctx_t ctx);
WARN_UNUSED_RESULT int gr_poly_neg_one(gr_poly_t poly, gr_ctx_t ctx);
WARN_UNUSED_RESULT int gr_poly_gen(gr_poly_t poly, gr_ctx_t ctx);

int _gr_poly_write(gr_stream_t out, gr_srcptr poly, slong len, const char * x, gr_ctx_t ctx);
int gr_poly_write(gr_stream_t out, const gr_poly_t poly, const char * x, gr_ctx_t ctx);
int _gr_poly_get_str(char ** res, gr_srcptr f, slong len, const char * x, gr_ctx_t ctx);
int gr_poly_get_str(char ** res, const gr_poly_t poly, const char * x, gr_ctx_t ctx);
int _gr_poly_set_str(gr_ptr res, const char * s, const char * x, slong len, gr_ctx_t ctx);
int gr_poly_set_str(gr_poly_t res, const char * s, const char * x, gr_ctx_t ctx);
int gr_poly_print(const gr_poly_t poly, gr_ctx_t ctx);

int gr_poly_randtest(gr_poly_t poly, flint_rand_t state, slong len, gr_ctx_t ctx);
Expand Down
54 changes: 54 additions & 0 deletions src/gr_poly/set_str.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
Copyright (C) 2025 Fredrik Johansson
This file is part of FLINT.
FLINT is free software: you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License (LGPL) as published
by the Free Software Foundation; either version 3 of the License, or
(at your option) any later version. See <https://www.gnu.org/licenses/>.
*/

#include "gr_vec.h"
#include "gr_poly.h"

int
gr_poly_set_str(gr_poly_t res, const char * s, const char * x, gr_ctx_t ctx)
{
gr_ctx_t rctx;
int status = GR_SUCCESS;
gr_ctx_init_gr_poly(rctx, ctx);
status |= gr_ctx_set_gen_name(rctx, x);
status |= gr_set_str(res, s, rctx);
gr_ctx_clear(rctx);
return status;
}

int
_gr_poly_set_str(gr_ptr res, const char * s, const char * x, slong len, gr_ctx_t ctx)
{
gr_poly_t t;
int status;
gr_poly_init(t, ctx);
status = gr_poly_set_str(t, s, x, ctx);

if (status == GR_SUCCESS)
{
if (t->length <= len)
{
_gr_vec_swap(res, t->coeffs, t->length, ctx);
status |= _gr_vec_zero(GR_ENTRY(res, t->length, ctx->sizeof_elem), len - t->length, ctx);
/* make sure t is a valid polynomial before clearing
just so that we don't strike the debug assertion in gr_poly_clear */
_gr_poly_set_length(t, 0, ctx);
}
else
{
status |= _gr_vec_zero(res, len, ctx);
status = GR_UNABLE;
}
}

gr_poly_clear(t, ctx);
return status;
}
2 changes: 2 additions & 0 deletions src/gr_poly/test/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
#include "t-roots.c"
#include "t-roots_other.c"
#include "t-rsqrt_series.c"
#include "t-set_str.c"
#include "t-shift_left_right.c"
#include "t-sqrt_series.c"
#include "t-squarefree_part.c"
Expand Down Expand Up @@ -136,6 +137,7 @@ test_struct tests[] =
TEST_FUNCTION(gr_poly_roots),
TEST_FUNCTION(gr_poly_roots_other),
TEST_FUNCTION(gr_poly_rsqrt_series),
TEST_FUNCTION(gr_poly_set_str),
TEST_FUNCTION(gr_poly_shift_left_right),
TEST_FUNCTION(gr_poly_sqrt_series),
TEST_FUNCTION(gr_poly_squarefree_part),
Expand Down
80 changes: 80 additions & 0 deletions src/gr_poly/test/t-set_str.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
Copyright (C) 2025 Fredrik Johansson
This file is part of FLINT.
FLINT is free software: you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License (LGPL) as published
by the Free Software Foundation; either version 3 of the License, or
(at your option) any later version. See <https://www.gnu.org/licenses/>.
*/

#include "test_helpers.h"
#include "ulong_extras.h"
#include "fmpz.h"
#include "gr_vec.h"
#include "gr_poly.h"

TEST_FUNCTION_START(gr_poly_set_str, state)
{
slong iter;

for (iter = 0; iter < 1000 * flint_test_multiplier(); iter++)
{
int status = GR_SUCCESS;
gr_ctx_t ctx;
gr_poly_t f, g;
slong glen;
char * s;

gr_ctx_init_random(ctx, state);
gr_poly_init(f, ctx);
gr_poly_init(g, ctx);

status |= gr_poly_randtest(f, state, 1 + n_randint(state, 10), ctx);
status |= gr_poly_randtest(g, state, 1 + n_randint(state, 10), ctx);

if (n_randint(state, 2))
{
status |= gr_poly_get_str(&s, f, "XX", ctx);
status |= gr_poly_set_str(g, s, "XX", ctx);
glen = -1;

if ((ctx->which_ring == GR_CTX_FMPZ || ctx->which_ring == GR_CTX_FMPQ) &&
status != GR_SUCCESS)
{
flint_printf("FAIL: unable over ZZ or QQ\n\n");
flint_printf("f = %{gr_poly}\n\n", f, ctx);
flint_printf("s = %s\n\n", s);
flint_abort();
}
}
else
{
status |= _gr_poly_get_str(&s, f->coeffs, f->length, "XX", ctx);
glen = n_randint(state, 10);
gr_poly_fit_length(g, glen, ctx);
status |= _gr_poly_set_str(g->coeffs, s, "XX", glen, ctx);
_gr_poly_set_length(g, glen, ctx);
_gr_poly_normalise(g, ctx);
}

if (status == GR_SUCCESS && gr_poly_equal(f, g, ctx) == T_FALSE)
{
flint_printf("FAIL: get_str, set_str roundtrip\n\n");
flint_printf("f = %{gr_poly}\n\n", f, ctx);
flint_printf("s = %s\n\n", s);
flint_printf("glen = %wd\n\n", glen);
flint_printf("g = %{gr_poly}\n\n", g, ctx);
flint_abort();
}

flint_free(s);

gr_poly_clear(f, ctx);
gr_poly_clear(g, ctx);
gr_ctx_clear(ctx);
}

TEST_FUNCTION_END(state);
}
34 changes: 28 additions & 6 deletions src/gr_poly/write.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,15 @@ want_parens(const char * s)
}

int
gr_poly_write(gr_stream_t out, const gr_poly_t poly, const char * x, gr_ctx_t ctx)
_gr_poly_write(gr_stream_t out, gr_srcptr poly, slong n, const char * x, gr_ctx_t ctx)
{
int status;
slong i, n;
slong i;
slong sz;
char * s;
int printed_previously = 0;

sz = ctx->sizeof_elem;
n = gr_poly_length(poly, ctx);
status = GR_SUCCESS;

if (n == 0)
Expand All @@ -75,10 +74,10 @@ gr_poly_write(gr_stream_t out, const gr_poly_t poly, const char * x, gr_ctx_t ct

for (i = 0; i < n; i++)
{
if (gr_is_zero(GR_ENTRY(poly->coeffs, i, sz), ctx) == T_TRUE)
if (gr_is_zero(GR_ENTRY(poly, i, sz), ctx) == T_TRUE)
continue;

gr_get_str(&s, GR_ENTRY(poly->coeffs, i, sz), ctx);
gr_get_str(&s, GR_ENTRY(poly, i, sz), ctx);

if (i >= 1 && !strcmp(s, "1"))
{
Expand Down Expand Up @@ -159,7 +158,7 @@ gr_poly_write(gr_stream_t out, const gr_poly_t poly, const char * x, gr_ctx_t ct

/*
gr_stream_write(out, "(");
status |= gr_write(out, GR_ENTRY(poly->coeffs, i, sz), ctx);
status |= gr_write(out, GR_ENTRY(poly, i, sz), ctx);
gr_stream_write(out, ")");
if (i == 1)
Expand All @@ -179,10 +178,33 @@ gr_poly_write(gr_stream_t out, const gr_poly_t poly, const char * x, gr_ctx_t ct
return status;
}

int
gr_poly_write(gr_stream_t out, const gr_poly_t poly, const char * x, gr_ctx_t ctx)
{
return _gr_poly_write(out, poly->coeffs, poly->length, x, ctx);
}

int
gr_poly_print(const gr_poly_t poly, gr_ctx_t ctx)
{
gr_stream_t out;
gr_stream_init_file(out, stdout);
return gr_poly_write(out, poly, "x", ctx);
}

int
_gr_poly_get_str(char ** res, gr_srcptr f, slong len, const char * x, gr_ctx_t ctx)
{
gr_stream_t out;
int status;
gr_stream_init_str(out);
status = _gr_poly_write(out, f, len, x, ctx);
*res = out->s;
return status;
}

int
gr_poly_get_str(char ** res, const gr_poly_t f, const char * x, gr_ctx_t ctx)
{
return _gr_poly_get_str(res, f->coeffs, f->length, x, ctx);
}

0 comments on commit 2ddde79

Please sign in to comment.