Skip to content

Commit

Permalink
Merge pull request flintlib#2157 from GiacomoPope/gr_poly_extra_scala…
Browse files Browse the repository at this point in the history
…r_methods

add extra methods for gr_poly scalar multiplication
  • Loading branch information
fredrik-johansson authored Jan 15, 2025
2 parents 8bf46d2 + 96c6801 commit aa7dc8c
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 0 deletions.
7 changes: 7 additions & 0 deletions doc/source/gr_poly.rst
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,13 @@ Arithmetic
int gr_poly_mullow(gr_poly_t res, const gr_poly_t poly1, const gr_poly_t poly2, slong len, gr_ctx_t ctx)

.. function:: int gr_poly_mul_scalar(gr_poly_t res, const gr_poly_t poly, gr_srcptr c, gr_ctx_t ctx)
int gr_poly_mul_ui(gr_poly_t res, const gr_poly_t poly, ulong c, gr_ctx_t ctx)
int gr_poly_mul_si(gr_poly_t res, const gr_poly_t poly, slong c, gr_ctx_t ctx)
int gr_poly_mul_fmpz(gr_poly_t res, const gr_poly_t poly, const fmpz c, gr_ctx_t ctx)
int gr_poly_mul_fmpq(gr_poly_t res, const gr_poly_t poly, const fmpq c, gr_ctx_t ctx)

Sets *res* to *poly* multiplied by the scalar *c* which must be
an element of or coercible to the coefficient ring.

.. function:: int _gr_poly_mul_karatsuba(gr_ptr res, gr_srcptr poly1, slong len1, gr_srcptr poly2, slong len2, gr_ctx_t ctx)
int gr_poly_mul_karatsuba(gr_poly_t res, const gr_poly_t poly1, const gr_poly_t poly2, gr_ctx_t ctx)
Expand Down
56 changes: 56 additions & 0 deletions src/gr/polynomial.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,30 @@ polynomial_sub(gr_poly_t res, const gr_poly_t poly1, const gr_poly_t poly2, gr_c
return gr_poly_sub(res, poly1, poly2, POLYNOMIAL_ELEM_CTX(ctx));
}

int
polynomial_mul_ui(gr_poly_t res, const gr_poly_t poly, ulong c, gr_ctx_t ctx)
{
return gr_poly_mul_ui(res, poly, c, POLYNOMIAL_ELEM_CTX(ctx));
}

int
polynomial_mul_si(gr_poly_t res, const gr_poly_t poly, slong c, gr_ctx_t ctx)
{
return gr_poly_mul_si(res, poly, c, POLYNOMIAL_ELEM_CTX(ctx));
}

int
polynomial_mul_fmpz(gr_poly_t res, const gr_poly_t poly, const fmpz_t c, gr_ctx_t ctx)
{
return gr_poly_mul_fmpz(res, poly, c, POLYNOMIAL_ELEM_CTX(ctx));
}

int
polynomial_mul_fmpq(gr_poly_t res, const gr_poly_t poly, fmpq_t c, gr_ctx_t ctx)
{
return gr_poly_mul_fmpq(res, poly, c, POLYNOMIAL_ELEM_CTX(ctx));
}

int
polynomial_mul(gr_poly_t res, const gr_poly_t poly1, const gr_poly_t poly2, gr_ctx_t ctx)
{
Expand All @@ -391,6 +415,33 @@ polynomial_mul(gr_poly_t res, const gr_poly_t poly1, const gr_poly_t poly2, gr_c
return gr_poly_mul(res, poly1, poly2, POLYNOMIAL_ELEM_CTX(ctx));
}

int
polynomial_mul_other(gr_poly_t res, const gr_poly_t f, gr_srcptr x, gr_ctx_t x_ctx, gr_ctx_t ctx)
{
if (x_ctx == POLYNOMIAL_ELEM_CTX(ctx))
{
return gr_poly_mul_scalar(res, f, x, x_ctx);
}
else if (x_ctx->which_ring == GR_CTX_GR_POLY &&
POLYNOMIAL_ELEM_CTX(x_ctx) == POLYNOMIAL_ELEM_CTX(ctx) &&
!strcmp(POLYNOMIAL_CTX(x_ctx)->var, POLYNOMIAL_CTX(ctx)->var))
{
return polynomial_mul(res, f, x, ctx);
}
else
{
gr_poly_t t;
int status = GR_SUCCESS;

polynomial_init(t, ctx);
status = polynomial_set_other(t, x, x_ctx, ctx);
if (status == GR_SUCCESS)
status = polynomial_mul(res, f, t, ctx);
polynomial_clear(t, ctx);
return status;
}
}

int
polynomial_div(gr_poly_t res, const gr_poly_t x, const gr_poly_t y, const gr_ctx_t ctx)
{
Expand Down Expand Up @@ -549,6 +600,11 @@ gr_method_tab_input _gr_poly_methods_input[] =
{GR_METHOD_ADD, (gr_funcptr) polynomial_add},
{GR_METHOD_SUB, (gr_funcptr) polynomial_sub},
{GR_METHOD_MUL, (gr_funcptr) polynomial_mul},
{GR_METHOD_MUL_OTHER, (gr_funcptr) polynomial_mul_other},
{GR_METHOD_MUL_UI, (gr_funcptr) polynomial_mul_ui},
{GR_METHOD_MUL_SI, (gr_funcptr) polynomial_mul_si},
{GR_METHOD_MUL_FMPZ, (gr_funcptr) polynomial_mul_fmpz},
{GR_METHOD_MUL_FMPQ, (gr_funcptr) polynomial_mul_fmpq},
{GR_METHOD_POW_UI, (gr_funcptr) polynomial_pow_ui},
{GR_METHOD_POW_SI, (gr_funcptr) polynomial_pow_si},
{GR_METHOD_POW_FMPZ, (gr_funcptr) polynomial_pow_fmpz},
Expand Down
4 changes: 4 additions & 0 deletions src/gr_poly.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ WARN_UNUSED_RESULT int _gr_poly_mullow_generic(gr_ptr res, gr_srcptr poly1, slon
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); }
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);
WARN_UNUSED_RESULT int gr_poly_mul_scalar(gr_poly_t res, const gr_poly_t poly, gr_srcptr c, gr_ctx_t ctx);
WARN_UNUSED_RESULT int gr_poly_mul_ui(gr_poly_t res, const gr_poly_t poly, ulong c, gr_ctx_t ctx);
WARN_UNUSED_RESULT int gr_poly_mul_si(gr_poly_t res, const gr_poly_t poly, slong c, gr_ctx_t ctx);
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);
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);

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);
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);
Expand Down
81 changes: 81 additions & 0 deletions src/gr_poly/mul_scalar.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
(at your option) any later version. See <https://www.gnu.org/licenses/>.
*/

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

Expand All @@ -31,3 +32,83 @@ gr_poly_mul_scalar(gr_poly_t res, const gr_poly_t poly, gr_srcptr c, gr_ctx_t ct
_gr_poly_normalise(res, ctx);
return status;
}

int
gr_poly_mul_ui(gr_poly_t res, const gr_poly_t poly, ulong c, gr_ctx_t ctx)
{
int status;
slong len = poly->length;

if (len == 0 || c == 0)
return gr_poly_zero(res, ctx);

if (res != poly)
{
gr_poly_fit_length(res, len, ctx);
_gr_poly_set_length(res, len, ctx);
}

status = _gr_vec_mul_scalar_ui(res->coeffs, poly->coeffs, len, c, ctx);
_gr_poly_normalise(res, ctx);
return status;
}

int
gr_poly_mul_si(gr_poly_t res, const gr_poly_t poly, slong c, gr_ctx_t ctx)
{
int status;
slong len = poly->length;

if (len == 0 || c == 0)
return gr_poly_zero(res, ctx);

if (res != poly)
{
gr_poly_fit_length(res, len, ctx);
_gr_poly_set_length(res, len, ctx);
}

status = _gr_vec_mul_scalar_si(res->coeffs, poly->coeffs, len, c, ctx);
_gr_poly_normalise(res, ctx);
return status;
}

int
gr_poly_mul_fmpz(gr_poly_t res, const gr_poly_t poly, const fmpz_t c, gr_ctx_t ctx)
{
int status;
slong len = poly->length;

if (len == 0 || fmpz_is_zero(c))
return gr_poly_zero(res, ctx);

if (res != poly)
{
gr_poly_fit_length(res, len, ctx);
_gr_poly_set_length(res, len, ctx);
}

status = _gr_vec_mul_scalar_fmpz(res->coeffs, poly->coeffs, len, c, ctx);
_gr_poly_normalise(res, ctx);
return status;
}

int
gr_poly_mul_fmpq(gr_poly_t res, const gr_poly_t poly, const fmpq_t c, gr_ctx_t ctx)
{
int status;
slong len = poly->length;

if (len == 0 || fmpq_is_zero(c))
return gr_poly_zero(res, ctx);

if (res != poly)
{
gr_poly_fit_length(res, len, ctx);
_gr_poly_set_length(res, len, ctx);
}

status = _gr_vec_mul_scalar_fmpq(res->coeffs, poly->coeffs, len, c, ctx);
_gr_poly_normalise(res, ctx);
return status;
}

0 comments on commit aa7dc8c

Please sign in to comment.