def _check_non_simple(coeffs):
    r"""Checks that a polynomial has no non-simple roots.

    Does so by computing the companion matrix :math:`A` of :math:`f'`
    and then evaluating the rank of :math:`B = f(A)`. If :math:`B` is not
    full rank, then :math:`f` and :math:`f'` have a shared factor.

    See: https://dx.doi.org/10.1016/0024-3795(70)90023-6

    .. note::

       This assumes that :math:`f \neq 0`.

    Args:
        coeffs (numpy.ndarray): ``d + 1``-array of coefficients in monomial /
            power basis.

    Raises:
        NotImplementedError: If the polynomial has non-simple roots.
    """
    coeffs = _strip_leading_zeros(coeffs)
    num_coeffs, = coeffs.shape
    if num_coeffs < 3:
        return

    deriv_poly = polynomial.polyder(coeffs)
    companion = polynomial.polycompanion(deriv_poly)
    # NOTE: ``polycompanion()`` returns a C-contiguous array.
    companion = companion.T
    # Use Horner's method to evaluate f(companion)
    num_companion, _ = companion.shape
    id_mat = np.eye(num_companion, order="F")
    evaluated = coeffs[-1] * id_mat
    for index in six.moves.xrange(num_coeffs - 2, -1, -1):
        coeff = coeffs[index]
        evaluated = (
            _helpers.matrix_product(evaluated, companion) + coeff * id_mat
        )
    if num_companion == 1:
        # NOTE: This relies on the fact that coeffs is normalized.
        if np.abs(evaluated[0, 0]) > _NON_SIMPLE_THRESHOLD:
            rank = 1
        else:
            rank = 0
    else:
        rank = np.linalg.matrix_rank(evaluated)
    if rank < num_companion:
        raise NotImplementedError(_NON_SIMPLE_ERR, coeffs)
def _check_non_simple ( coeffs ) : coeffs = _strip_leading_zeros ( coeffs ) num_coeffs , = coeffs . shape if num_coeffs < 3 : return deriv_poly = polynomial . polyder ( coeffs ) companion = polynomial . polycompanion ( deriv_poly ) companion = companion . T num_companion , _ = companion . shape id_mat = np . eye ( num_companion , order = "F" ) evaluated = coeffs [ - 1 ] * id_mat for index in six . moves . xrange ( num_coeffs - 2 , - 1 , - 1 ) : coeff = coeffs [ index ] evaluated = ( _helpers . matrix_product ( evaluated , companion ) + coeff * id_mat ) if num_companion == 1 : if np . abs ( evaluated [ 0 , 0 ] ) > _NON_SIMPLE_THRESHOLD : rank = 1 else : rank = 0 else : rank = np . linalg . matrix_rank ( evaluated ) if rank < num_companion : raise NotImplementedError ( _NON_SIMPLE_ERR , coeffs )
r"""Checks that a polynomial has no non-simple roots.

    Does so by computing the companion matrix :math:`A` of :math:`f'`
    and then evaluating the rank of :math:`B = f(A)`. If :math:`B` is not
    full rank, then :math:`f` and :math:`f'` have a shared factor.

    See: https://dx.doi.org/10.1016/0024-3795(70)90023-6

    .. note::

       This assumes that :math:`f \neq 0`.

    Args:
        coeffs (numpy.ndarray): ``d + 1``-array of coefficients in monomial /
            power basis.

    Raises:
        NotImplementedError: If the polynomial has non-simple roots.