Skip to content

Conversation

@Jake-Moss
Copy link
Contributor

The documentation for fmpz_mpoly_deflate (and similar) states

If any stride[v] is zero, the corresponding numerator e - shift[v] is assumed to
be zero, and the quotient is defined as zero. This allows the function to undo the
operation performed by fmpz_mpoly_inflate() when possible.

The previous comment and if-statement did not align, meaning that the denominator was not being checked leading to divisions by zero when stride[v] is 0.

Here is a MWE

#include "flint/fmpz_mpoly.h"

int main(void) {
    fmpz_mpoly_ctx_t ctx;
    fmpz_mpoly_t x, res;
    fmpz *stride, *shift;

    const char *vars = "x";

    fmpz_mpoly_ctx_init(ctx, 1, ORD_LEX);
    fmpz_mpoly_init(x, ctx);
    fmpz_mpoly_init(res, ctx);

    fmpz_mpoly_gen(x, 0, ctx);

    stride = flint_malloc(ctx->minfo->nvars * sizeof(fmpz));
    shift = flint_malloc(ctx->minfo->nvars * sizeof(fmpz));
    for (int i = 0; i < ctx->minfo->nvars; i++) {
      fmpz_init(stride + i);
      fmpz_init(shift + i);
    }

    fmpz_mpoly_print_pretty(x, &vars, ctx); flint_printf("\n");

    // Division by zero here
    fmpz_mpoly_deflate(res, x, shift, stride, ctx);

    fmpz_mpoly_print_pretty(res, &vars, ctx); flint_printf("\n");

    for (int i = 0; i < ctx->minfo->nvars; i++) {
      fmpz_clear(stride + i);
      fmpz_clear(shift + i);
    }
    flint_free(stride);
    flint_free(shift);

    fmpz_mpoly_clear(x, ctx);
    fmpz_mpoly_ctx_clear(ctx);
    return 0;
}

Without this patch:

~/ λ gcc scratch.c -lflint
~/ λ ./a.out
x
Exception (fmpz_divexact). Division by zero.
aborted (core dumped)

With:

~/ λ gcc scratch.c -lflint
~/ λ ./a.out
x
1

From python-flint here: flintlib/python-flint#216 (comment)

The documentation for `fmpz_mpoly_deflate` (and similar) states

> If any `stride[v]` is zero, the corresponding numerator `e - shift[v]` is assumed to
> be zero, and the quotient is defined as zero. This allows the function to undo the
> operation performed by `fmpz_mpoly_inflate()` when possible.

The previous comment and if-statement did not align meaning that the denominator was not
being checked leading to divisions by zero when `stride[v]` is 0.
@Jake-Moss
Copy link
Contributor Author

Jake-Moss commented Sep 8, 2024

I believe I was miss-using the deflation functions that caused me to run into this, however it still does not look quite right to me in it's current form.

@albinahlback
Copy link
Collaborator

Could you add a test case for this?

@Jake-Moss
Copy link
Contributor Author

Done, I've added the test to the fmpz_mpoly suite rather than the mpoly tests as it has existing inflation/deflation tests.

@fredrik-johansson fredrik-johansson merged commit 1f98483 into flintlib:main Sep 17, 2024
13 checks passed
@fredrik-johansson
Copy link
Collaborator

Looks good, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants