<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def bezier_roots(coeffs):
 r"""Compute polynomial roots from a polynomial in the Bernstein basis. .. note:: This assumes the caller passes in a 1D array but does not check. This takes the polynomial .. math:: f(s) = \sum_{j = 0}^n b_{j, n} \cdot C_j. and uses the variable :math:`\sigma = \frac{s}{1 - s}` to rewrite as .. math:: \begin{align*} f(s) &= (1 - s)^n \sum_{j = 0}^n \binom{n}{j} C_j \sigma^j \\ &= (1 - s)^n \sum_{j = 0}^n \widetilde{C_j} \sigma^j. \end{align*} Then it uses an eigenvalue solver to find the roots of .. math:: g(\sigma) = \sum_{j = 0}^n \widetilde{C_j} \sigma^j and convert them back into roots of :math:`f(s)` via :math:`s = \frac{\sigma}{1 + \sigma}`. For example, consider .. math:: \begin{align*} f_0(s) &= 2 (2 - s)(3 + s) \\ &= 12(1 - s)^2 + 11 \cdot 2s(1 - s) + 8 s^2 \end{align*} First, we compute the companion matrix for .. math:: g_0(\sigma) = 12 + 22 \sigma + 8 \sigma^2 .. testsetup:: bezier-roots0, bezier-roots1, bezier-roots2 import numpy as np import numpy.linalg from bezier._algebraic_intersection import bernstein_companion from bezier._algebraic_intersection import bezier_roots .. doctest:: bezier-roots0 array([[-2.75, -1.5 ], [ 1. , 0. ]]) then take the eigenvalues of the companion matrix: .. doctest:: bezier-roots0 array([-2. , -0.75]) after transforming them, we have the roots of :math:`f(s)`: .. doctest:: bezier-roots0 array([ 2., -3.]) array([ 2., -3.]) In cases where :math:`s = 1` is a root, the lead coefficient of :math:`g` would be :math:`0`, so there is a reduction in the companion matrix. .. math:: \begin{align*} f_1(s) &= 6 (s - 1)^2 (s - 3) (s - 5) \\ &= 90 (1 - s)^4 + 33 \cdot 4s(1 - s)^3 + 8 \cdot 6s^2(1 - s)^2 \end{align*} .. doctest:: bezier-roots1 :options: +NORMALIZE_WHITESPACE array([[-2.75 , -1.875], [ 1. , 0. ]]) 4 2 so the roots are a combination of the roots determined from :math:`s = \frac{\sigma}{1 + \sigma}` and the number of factors of :math:`(1 - s)` (i.e. the difference between the degree and the effective degree):
 .. doctest:: bezier-roots1 array([3., 5., 1., 1.]) In some cases, a polynomial is represented with an "elevated" degree: .. math:: \begin{align*} f_2(s) &= 3 (s^2 + 1) \\ &= 3 (1 - s)^3 + 3 \cdot 3s(1 - s)^2 + 4 \cdot 3s^2(1 - s) + 6 s^3 \end{align*} This results in a "point at infinity" :math:`\sigma = -1 \Longleftrightarrow s = \infty`: .. doctest:: bezier-roots2 array([[-2. , -1.5, -0.5], [ 1. , 0. , 0. ], [ 0. , 1. , 0. ]]) array([-1. +0.j , -0.5+0.5j, -0.5-0.5j]) so we drop any values :math:`\sigma` that are sufficiently close to :math:`-1`: .. doctest:: bezier-roots2 True Args: coeffs (numpy.ndarray):
 A 1D array of coefficients in the Bernstein basis. Returns: numpy.ndarray: A 1D array containing the roots. """

    companion, degree, effective_degree = bernstein_companion(coeffs)
    if effective_degree:
        sigma_roots = np.linalg.eigvals(companion)
        # Filter out `sigma = -1`, i.e. "points at infinity".
        # We want the error ||(sigma - (-1))|| ~= 2^{-52}
        to_keep = np.abs(sigma_roots + 1.0) > _SIGMA_THRESHOLD
        sigma_roots = sigma_roots[to_keep]
        s_vals = sigma_roots / (1.0 + sigma_roots)
    else:
        s_vals = np.empty((0,), order="F")
    if effective_degree != degree:
        delta = degree - effective_degree
        s_vals = np.hstack([s_vals, [1] * delta])
    return s_vals