#include "nmod.h"
#include "nmod_vec.h"
#include "nmod_poly.h"
ulong
_nmod_poly_discriminant(nn_srcptr poly, slong len, nmod_t mod)
{
nn_ptr der = _nmod_vec_init(len - 1);
slong dlen = len - 1;
ulong 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)
res = nmod_neg(res, mod);
_nmod_vec_clear(der);
return res;
}
ulong
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);
}