Skip to content

Commit

Permalink
Merge pull request #2068 from Jake-Moss/fmpz_mod_mpoly_compose_fmpz_m…
Browse files Browse the repository at this point in the history
…od_mpoly_gen

Add missing fmpz_mod_mpoly_compose_ functions
  • Loading branch information
albinahlback authored Oct 1, 2024
2 parents 47bef34 + 0926c48 commit 85b9c06
Show file tree
Hide file tree
Showing 10 changed files with 1,069 additions and 218 deletions.
1 change: 1 addition & 0 deletions doc/source/fmpz_mod_mpoly.rst
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,7 @@ Evaluation
Return `1` for success and `0` for failure.

.. function:: int fmpz_mod_mpoly_compose_fmpz_mod_mpoly_geobucket(fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_t B, fmpz_mod_mpoly_struct * const * C, const fmpz_mod_mpoly_ctx_t ctxB, const fmpz_mod_mpoly_ctx_t ctxAC)
int fmpz_mod_mpoly_compose_fmpz_mod_mpoly_horner(fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_t B, fmpz_mod_mpoly_struct * const * C, const fmpz_mod_mpoly_ctx_t ctxB, const fmpz_mod_mpoly_ctx_t ctxAC)
int fmpz_mod_mpoly_compose_fmpz_mod_mpoly(fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_t B, fmpz_mod_mpoly_struct * const * C, const fmpz_mod_mpoly_ctx_t ctxB, const fmpz_mod_mpoly_ctx_t ctxAC)

Set *A* to the evaluation of *B* where the variables are replaced by the corresponding elements of the array *C*.
Expand Down
130 changes: 57 additions & 73 deletions src/fmpq_mpoly/test/t-compose_fmpq_mpoly.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ TEST_FUNCTION_START(fmpq_mpoly_compose_fmpq_mpoly, state)
slong i, j, v;

{
fmpq_mpoly_t A, A1, A2, B;
slong nvarsAC = 2, nvarsB = 3;
fmpq_mpoly_t A, A1, A2, B, B1;
fmpq_mpoly_struct * Cp[3];
fmpq_mpoly_struct C[3];
fmpq_mpoly_ctx_t ctxAC, ctxB;
slong * c;

fmpq_mpoly_ctx_init(ctxB, 3, ORD_LEX);
fmpq_mpoly_ctx_init(ctxAC, 2, ORD_LEX);
fmpq_mpoly_ctx_init(ctxB, nvarsB, ORD_LEX);
fmpq_mpoly_ctx_init(ctxAC, nvarsAC, ORD_LEX);

fmpq_mpoly_init(B, ctxB);
fmpq_mpoly_init(A, ctxAC);
Expand All @@ -42,39 +44,61 @@ TEST_FUNCTION_START(fmpq_mpoly_compose_fmpq_mpoly, state)
fmpq_mpoly_set_str_pretty(C + 1, "x1 - x2", NULL, ctxAC);
fmpq_mpoly_set_str_pretty(C + 2, "1", NULL, ctxAC);
if (fmpq_mpoly_compose_fmpq_mpoly(A, B, Cp, ctxB, ctxAC))
{
printf("FAIL\n");
flint_printf("Check non-example 1\n", i);
fflush(stdout);
flint_abort();
}
TEST_FUNCTION_FAIL("Check non-example 1\n");

fmpq_mpoly_set_str_pretty(C + 0, "x1", NULL, ctxAC);
fmpq_mpoly_set_str_pretty(C + 1, "2*x2", NULL, ctxAC);
fmpq_mpoly_set_str_pretty(C + 2, "1", NULL, ctxAC);
if (fmpq_mpoly_compose_fmpq_mpoly(A, B, Cp, ctxB, ctxAC))
{
printf("FAIL\n");
flint_printf("Check non-example 2\n", i);
fflush(stdout);
flint_abort();
}
TEST_FUNCTION_FAIL("Check non-example 2\n");

fmpq_mpoly_set_str_pretty(C + 0, "2*x1", NULL, ctxAC);
fmpq_mpoly_set_str_pretty(C + 1, "x2", NULL, ctxAC);
fmpq_mpoly_set_str_pretty(C + 2, "1", NULL, ctxAC);
if (!fmpq_mpoly_compose_fmpq_mpoly(A, B, Cp, ctxB, ctxAC))
{
printf("FAIL\n");
flint_printf("Check example 3\n", i);
fflush(stdout);
flint_abort();
}
TEST_FUNCTION_FAIL("Check example 3\n");

/* Aliased generator composition */
c = (slong *) flint_malloc(nvarsB*sizeof(slong));
fmpq_mpoly_init(B1, ctxB);
fmpq_mpoly_set(B1, B, ctxB);
for (i = 0; i < nvarsB; i++)
c[i] = i;

fmpq_mpoly_compose_fmpq_mpoly_gen(B1, B1, c, ctxB, ctxB);
if (!fmpq_mpoly_equal(B, B1, ctxB))
TEST_FUNCTION_FAIL("Check composition with aliased generators\n");

/* Reverse the generators, twice */
for (i = 0; i < nvarsB; i++)
c[i] = nvarsB - i - 1;

fmpq_mpoly_compose_fmpq_mpoly_gen(B1, B1, c, ctxB, ctxB);
if (fmpq_mpoly_equal(B, B1, ctxB))
TEST_FUNCTION_FAIL("Check composition with reversed aliased generators\n");

fmpq_mpoly_compose_fmpq_mpoly_gen(B1, B1, c, ctxB, ctxB);
if (!fmpq_mpoly_equal(B, B1, ctxB))
TEST_FUNCTION_FAIL("Check composition with un-reversed aliased generators\n");

/* Composition with zero polys */
fmpq_mpoly_zero(B1, ctxB);

fmpq_mpoly_compose_fmpq_mpoly_gen(A, B1, c, ctxB, ctxAC);
if (!fmpq_mpoly_is_zero(B1, ctxB))
TEST_FUNCTION_FAIL("Check composition with generators of zero poly\n");

fmpq_mpoly_set_str_pretty(C + 0, "2*x1", NULL, ctxAC);
fmpq_mpoly_set_str_pretty(C + 1, "x2", NULL, ctxAC);
fmpq_mpoly_set_str_pretty(C + 2, "1", NULL, ctxAC);
if (!fmpq_mpoly_compose_fmpq_mpoly(A, B1, Cp, ctxB, ctxAC))
TEST_FUNCTION_FAIL("Check example 4\n");

if (!fmpq_mpoly_is_zero(A, ctxAC))
TEST_FUNCTION_FAIL("Check composition with zero poly\n");

fmpq_mpoly_clear(B, ctxB);
fmpq_mpoly_clear(A, ctxAC);
fmpq_mpoly_clear(A1, ctxAC);
fmpq_mpoly_clear(A2, ctxAC);
for (i = 0; i < 3; i++)
fmpq_mpoly_clear(C + i, ctxAC);

Expand Down Expand Up @@ -131,22 +155,12 @@ TEST_FUNCTION_START(fmpq_mpoly_compose_fmpq_mpoly, state)
fmpq_mpoly_compose_fmpq_mpoly_gen(A, B, c, ctxB, ctxAC);

if (!fmpq_mpoly_compose_fmpq_mpoly(A1, B, C, ctxB, ctxAC))
{
printf("FAIL\n");
flint_printf("Check composition success with generators\n"
"i: %wd, j: %wd\n", i, j);
fflush(stdout);
flint_abort();
}
TEST_FUNCTION_FAIL("Check composition success with generators\n"
"i: %wd, j: %wd\n", i, j);

if (!fmpq_mpoly_equal(A, A1, ctxAC))
{
printf("FAIL\n");
flint_printf("Check composition with generators\n"
"i: %wd, j: %wd\n", i, j);
fflush(stdout);
flint_abort();
}
TEST_FUNCTION_FAIL("Check composition with generators\n"
"i: %wd, j: %wd\n", i, j);

fmpq_mpoly_assert_canonical(A, ctxAC);
fmpq_mpoly_assert_canonical(A1, ctxAC);
Expand Down Expand Up @@ -196,20 +210,10 @@ TEST_FUNCTION_START(fmpq_mpoly_compose_fmpq_mpoly, state)
coeff_bits = n_randint(state, 100) + 1;
fmpq_mpoly_randtest_bits(f, state, len1, coeff_bits, exp_bits, ctx);
if (!fmpq_mpoly_compose_fmpq_mpoly(g, f, vals1, ctx, ctx))
{
printf("FAIL\n");
flint_printf("Check composition success\ni: %wd\n", i);
fflush(stdout);
flint_abort();
}
TEST_FUNCTION_FAIL("Check composition success\ni: %wd\n", i);

if (!fmpq_mpoly_equal(f, g, ctx))
{
printf("FAIL\n");
flint_printf("Check composition with identity\ni: %wd\n", i);
fflush(stdout);
flint_abort();
}
TEST_FUNCTION_FAIL("Check composition with identity\ni: %wd\n", i);

fmpq_mpoly_clear(g, ctx);
fmpq_mpoly_clear(f, ctx);
Expand Down Expand Up @@ -276,41 +280,21 @@ TEST_FUNCTION_START(fmpq_mpoly_compose_fmpq_mpoly, state)
vals3[v] = (fmpq *) flint_malloc(sizeof(fmpq));
fmpq_init(vals3[v]);
if (!fmpq_mpoly_evaluate_all_fmpq(vals3[v], vals1[v], vals2, ctx2))
{
printf("FAIL\n");
flint_printf("Check evaluation success\ni: %wd\n", i);
fflush(stdout);
flint_abort();
}
TEST_FUNCTION_FAIL("Check evaluation success\ni: %wd\n", i);
}

fmpq_mpoly_randtest_bound(f, state, len1, coeff_bits, exp_bound1, ctx1);

if (!fmpq_mpoly_compose_fmpq_mpoly(g, f, vals1, ctx1, ctx2))
{
printf("FAIL\n");
flint_printf("Check composition success\ni: %wd\n", i);
fflush(stdout);
flint_abort();
}
TEST_FUNCTION_FAIL("Check composition success\ni: %wd\n", i);
fmpq_mpoly_assert_canonical(g, ctx2);

if (!fmpq_mpoly_evaluate_all_fmpq(fe, f, vals3, ctx1) ||
!fmpq_mpoly_evaluate_all_fmpq(ge, g, vals2, ctx2))
{
printf("FAIL\n");
flint_printf("Check evaluation success\ni: %wd\n", i);
fflush(stdout);
flint_abort();
}
TEST_FUNCTION_FAIL("Check evaluation success\ni: %wd\n", i);

if (!fmpq_equal(fe, ge))
{
printf("FAIL\n");
flint_printf("Check composition and evalall commute\ni: %wd\n", i);
fflush(stdout);
flint_abort();
}
TEST_FUNCTION_FAIL("Check composition and evalall commute\ni: %wd\n", i);

for (v = 0; v < nvars1; v++)
{
Expand Down
9 changes: 9 additions & 0 deletions src/fmpz_mod_mpoly.h
Original file line number Diff line number Diff line change
Expand Up @@ -570,10 +570,19 @@ int fmpz_mod_mpoly_compose_fmpz_mod_mpoly_geobucket(fmpz_mod_mpoly_t A,
const fmpz_mod_mpoly_t B, fmpz_mod_mpoly_struct * const * C,
const fmpz_mod_mpoly_ctx_t ctxB, const fmpz_mod_mpoly_ctx_t ctxAC);

int fmpz_mod_mpoly_compose_fmpz_mod_mpoly_horner(fmpz_mod_mpoly_t A,
const fmpz_mod_mpoly_t B, fmpz_mod_mpoly_struct * const * C,
const fmpz_mod_mpoly_ctx_t ctxB, const fmpz_mod_mpoly_ctx_t ctxAC);

int fmpz_mod_mpoly_compose_fmpz_mod_mpoly(fmpz_mod_mpoly_t A,
const fmpz_mod_mpoly_t B, fmpz_mod_mpoly_struct * const * C,
const fmpz_mod_mpoly_ctx_t ctxB, const fmpz_mod_mpoly_ctx_t ctxAC);

void fmpz_mod_mpoly_compose_fmpz_mod_mpoly_gen(fmpz_mod_mpoly_t A,
const fmpz_mod_mpoly_t B, const slong * c,
const fmpz_mod_mpoly_ctx_t ctxB, const fmpz_mod_mpoly_ctx_t ctxAC);


/* Multiplication ************************************************************/

void fmpz_mod_mpoly_mul(fmpz_mod_mpoly_t A,
Expand Down
6 changes: 3 additions & 3 deletions src/fmpz_mod_mpoly/compose_fmpz_mod_mpoly.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,14 @@ int fmpz_mod_mpoly_compose_fmpz_mod_mpoly(
matrix_no_good:

fmpz_mat_clear(M);
/*

for (i = 0; i < ctxB->minfo->nvars; i++)
{
if (C[i]->length > 1)
{
return nmod_mpoly_compose_nmod_mpoly_horner(A, B, C, ctxB, ctxAC);
return fmpz_mod_mpoly_compose_fmpz_mod_mpoly_horner(A, B, C, ctxB, ctxAC);
}
}
*/

return fmpz_mod_mpoly_compose_fmpz_mod_mpoly_geobucket(A, B, C, ctxB, ctxAC);
}
48 changes: 48 additions & 0 deletions src/fmpz_mod_mpoly/compose_fmpz_mod_mpoly_gen.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
Copyright (C) 2020 Daniel Schultz
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 "fmpz_mat.h"
#include "mpoly.h"
#include "fmpz_mod_mpoly.h"

/* evaluate B(x_1,...,x_n) at x_i = y_c[i], y_j are vars of ctxAC */
void fmpz_mod_mpoly_compose_fmpz_mod_mpoly_gen(fmpz_mod_mpoly_t A,
const fmpz_mod_mpoly_t B, const slong * c,
const fmpz_mod_mpoly_ctx_t ctxB, const fmpz_mod_mpoly_ctx_t ctxAC)
{
fmpz_mat_t M;

if (B->length == 0)
{
fmpz_mod_mpoly_zero(A, ctxAC);
return;
}

fmpz_mat_init(M, ctxAC->minfo->nfields + 1, ctxB->minfo->nfields);
mpoly_compose_mat_gen(M, c, ctxB->minfo, ctxAC->minfo);

if (A == B)
{
fmpz_mod_mpoly_t T;
fmpz_mod_mpoly_init(T, ctxAC);
_fmpz_mod_mpoly_compose_mat(T, B, M, ctxB, ctxAC);
fmpz_mod_mpoly_swap(A, T, ctxAC);
fmpz_mod_mpoly_clear(T, ctxAC);
}
else
{
_fmpz_mod_mpoly_compose_mat(A, B, M, ctxB, ctxAC);
}

fmpz_mat_clear(M);

return;
}
Loading

0 comments on commit 85b9c06

Please sign in to comment.