/* Copyright (C) 2014 William Hart 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 "flint.h" #include "mpn_extras.h" #include "nmod_vec.h" #include "nmod_poly.h" mp_limb_t _nmod_poly_discriminant(mp_srcptr poly, slong len, nmod_t mod) { mp_ptr der = _nmod_vec_init(len - 1); slong dlen = len - 1; mp_limb_t res, pow; _nmod_poly_derivative(der, poly, len, mod); NMOD_VEC_NORM(der, dlen); if (dlen == 0) { _nmod_vec_clear(der); return 0; } res = _nmod_poly_resultant(poly, len, der, dlen, mod); pow = n_powmod2_preinv(poly[len - 1], len - dlen - 2, mod.n, mod.ninv); res = n_mulmod2_preinv(res, pow, mod.n, mod.ninv); if ((len & 3) == 0 || (len & 3) == 3) /* degree is not 0, 1 mod 4 */ res = nmod_neg(res, mod); _nmod_vec_clear(der); return res; } mp_limb_t nmod_poly_discriminant(const nmod_poly_t f) { const slong len = f->length; if (len <= 1) return 0; else return _nmod_poly_discriminant(f->coeffs, len, f->mod); }