<jupyter_start><jupyter_text>Solve a quadratic equation, $x^2 + b x + c = 0$.Write a function which receives $b$ and $c$, the coefficients of a monic quadratic polynomial, $x^2 + b x + c$, and returns the pair of its roots. Your function should always return two values, even if quadratic has a double root.For example, given a quadratic $x^2 - 2x + 1$, your function should return a pair of $(1, 1)$. Of course, in floating point, your answers may differ from an exact unity.Your function also must correctly handle complex roots (to this end, you might need the `cmath` module from the standard library).<jupyter_code>def solve_quad(b, c):
    """Solve a quadratic equation, x**2 + bx + c = 0.
    
    Parameters
    ----------
    b, c : float
       Coefficients
       
    Returns
    -------
    x1, x2 : float or complex
       Roots.
    """
    import cmath
    determinant = cmath.sqrt(b * b - 4 * c)
    
    #to avoid underflow and overflow we use the property that the multiplication of two roots is equal to c
    #in order to avoid the 0 root which is caused by underflow or overflow, we use the quadratic root formula where -b and determinant are of same sign. 
    #i.e. (-b) * determinant > 0 => b*determinant <0
    if b*determinant.real < 0.:
        x1 = (-b + determinant) / 2.
    else:
        x1 = (-b - determinant) / 2.
    return (x1, c / x1)
    # ... enter your code here ...<jupyter_output><empty_output><jupyter_text>Test the your function on several examples against a calculation by hand. Once you're sure that your function works, try these five test cases below. Note that the last two test cases are special: they test whether your function handles extreme cases where a too simple approach is prone to a catastrophic cancellation. Make sure your function passes all five tests.This exercise is graded, each test case contributes a 20% of the grade.<jupyter_code>from numpy import allclose
variants = [{'b': 4.0, 'c': 3.0},
            {'b': 2.0, 'c': 1.0},
            {'b': 0.5, 'c': 4.0},
            {'b': 1e10, 'c': 3.0},
            {'b': -1e10, 'c': 4.0},]
for var in variants:
    x1, x2 = solve_quad(**var)
    print(allclose(x1*x2, var['c']))<jupyter_output>True
True
True
True
True
{'fraction_non_alphanumeric': 0.10936799641416405, 'fraction_numerical': 0.02285970416853429, 'mean_word_length': 2.854922279792746, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 10, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '483824', 'license': 'MIT', 'n_tokens_mistral': 714, 'n_tokens_neox': 665, 'n_words': 309, 'path': 'NumericalAnalysis/Week1/week_1_quadratic.ipynb', 'repo_name': 'pradeeptadas/coursera', 'size': '2231'}