/* Copyright (C) 2010, 2016 William Hart Copyright (C) 2010, Andy Novocin 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 2.1 of the License, or (at your option) any later version. See . */ #include #include #include #include "flint.h" #include "fmpz.h" #include "fmpz_poly.h" #include "ulong_extras.h" int main(void) { int i, result = 1; FLINT_TEST_INIT(state); flint_printf("CLD_bound...."); fflush(stdout); /* test that CLD_bound is between the absolute value of the n-th coeff of f' and the sum of the absolute values of the coeffs of f' */ for (i = 0; i < 100 * flint_test_multiplier(); i++) { fmpz_poly_t a, b, g; fmpz_t sum, bound; slong xpow, j; slong bits = n_randint(state, 200) + 1; fmpz_poly_init(a); fmpz_poly_init(b); fmpz_poly_init(g); fmpz_init(sum); fmpz_init(bound); do { fmpz_poly_randtest(a, state, n_randint(state, 200), bits); if (!fmpz_poly_is_zero(a)) { xpow = 0; while (fmpz_is_zero(a->coeffs + xpow)) xpow++; fmpz_poly_shift_right(a, a, xpow); } fmpz_poly_derivative(b, a); fmpz_poly_gcd(g, a, b); } while (!fmpz_poly_is_one(g)); fmpz_poly_scalar_abs(b, b); for (j = 0; j < b->length && result; j++) { fmpz_poly_CLD_bound(bound, a, j); result &= (fmpz_cmp(b->coeffs + j, bound) <= 0); fmpz_add(sum, b->coeffs + j, b->coeffs + j); } result &= (fmpz_cmp(bound, sum) <= 0); if (!result) { flint_printf("FAIL:\n"); flint_printf("length = %wd, bits = %wd, j = %wd\n", a->length, bits, j - 1); fmpz_print(b->coeffs + j - 1), flint_printf("\n\n"); fmpz_print(bound), flint_printf("\n\n"); fmpz_print(sum), flint_printf("\n\n"); abort(); } fmpz_poly_clear(a); fmpz_poly_clear(b); fmpz_poly_clear(g); fmpz_clear(sum); fmpz_clear(bound); } /* let f have a factor g (by setting f = g*h) then check that the bounds for f*g'/g are valid */ for (i = 0; i < 100 * flint_test_multiplier(); i++) { fmpz_poly_t a, b, c, d, g; fmpz_t bound; slong xpow, j; slong bits = n_randint(state, 200) + 1; fmpz_poly_init(a); fmpz_poly_init(b); fmpz_poly_init(c); fmpz_poly_init(d); fmpz_poly_init(g); fmpz_init(bound); do { do { fmpz_poly_randtest(a, state, n_randint(state, 100) + 2, bits); if (!fmpz_poly_is_zero(a)) { xpow = 0; while (fmpz_is_zero(a->coeffs + xpow)) xpow++; fmpz_poly_shift_right(a, a, xpow); } } while (a->length < 2); do { fmpz_poly_randtest(b, state, n_randint(state, 100) + 1, bits); if (!fmpz_poly_is_zero(b)) { xpow = 0; while (fmpz_is_zero(b->coeffs + xpow)) xpow++; fmpz_poly_shift_right(b, b, xpow); } } while (fmpz_poly_is_zero(b)); fmpz_poly_mul(c, a, b); fmpz_poly_derivative(d, c); fmpz_poly_gcd(g, c, d); } while (!fmpz_poly_is_one(g)); fmpz_poly_derivative(g, a); fmpz_poly_mul(b, b, g); for (j = 0; j < b->length && result; j++) { fmpz_poly_CLD_bound(bound, c, j); result &= (fmpz_cmp(b->coeffs + j, bound) <= 0); } if (!result) { flint_printf("FAIL:\n"); flint_printf("length = %wd, bits = %wd, j = %wd\n", a->length, bits, j - 1); fmpz_print(b->coeffs + j - 1), flint_printf("\n\n"); fmpz_print(bound), flint_printf("\n\n"); abort(); } fmpz_poly_clear(a); fmpz_poly_clear(b); fmpz_poly_clear(c); fmpz_poly_clear(d); fmpz_poly_clear(g); fmpz_clear(bound); } FLINT_TEST_CLEANUP(state); flint_printf("PASS\n"); return 0; }