<jupyter_start><jupyter_text>Define a function of which to find the roots<jupyter_code>def function_for_roots(x):
    a = 1.01
    b = -3.04
    c = 2.07
    return a*x**2 + b*x + c    # return quadratic function<jupyter_output><empty_output><jupyter_text>We need a function to check our initial guesses<jupyter_code>def check_initial_values(f, x_min, x_max, tol):
    
    # check our initial guesses
    y_min = f(x_min)
    y_max = f(x_max)
    
    # check that x_min and x_max contain a zero crossing
    if(y_min*y_max>0.0):
        print("No zero crossing found in the range = ",x_min,x_max)
        s = "f(%f) = %f, f(%f) = %f" % (m_min,y_min,x_max,y_max)
        print(s)
        return 0
    
    # if x_min is a root return flag = = 1
    if(np.fabs(y_min)<tol):
        return 1
    
    # if x_max is a root return flag = = 2
    if(np.fabs(y_max)<tol):
        return 2
    
    # if we reach this point, the bracket is valid and
    # we will return 3
    return 3<jupyter_output><empty_output><jupyter_text>Define the main work function that performs the iterative search<jupyter_code>def bisection_root_finding(f, x_min_start, x_max_start, tol):
    
    # this function uses bisection search to find the root
    
    x_min = x_min_start      # minimum x within the bracket
    x_max = x_max_start      # maximum x within the bracket
    x_mid = 0.0              # mid point of bracket
    
    y_min = f(x_min)         # function value at x_min
    y_max = f(x_max)         # function value at x_max
    y_mid = 0.0              # function value at midpoint
    
    imax = 10000             # max number of iterations
    i = 0
    
    # check the intial values
    flag = check_initial_values(f,x_min,x_max, tol)

    if (flag==0):
        print("Error in bisection_root_finding")
        raise ValueError('Initial values invalid', x_min, x_max)
    elif(flag==1):
        # this was a lucky guess
        return x_min
    elif(flag==2):
        # another lucky guess condition
        return x_max
    
    # if we reach here, then we need to conduct the search
    
    # set a flag
    flag = 1

    
    # enter a while loop
    while(flag):

        x_mid = 0.5*(x_min + x_max)  # midpoint
        y_mid = f(x_mid)   # value of y at midpoint
        
        # check if x_mid is a root
        if(np.fabs(y_mid)<tol):
            flag = 0
            
        else:
            # x_mid is not a root
            
            # if the product of the function at midpoint and at one
            # of the end points is greater than zero, replace that endpoint
            if(f(x_min)*f(x_mid)>0):
                # replace x_min with x_mid
                x_min = x_mid
            else:
                # replace x_max with x_mid
                x_max = x_mid
        
        # print out the iteration
        print(x_min, f(x_min),x_max,f(x_max))
        
        # count the iteration
        i += 1
        
        # if we exceed max iterations, then exit
        if(i>=imax):
            print("Exceeded max number of iterations = ",i)
            s = "Min bracket f(%f) = %15.14e" % (x_min,f(x_min))
            print(s)
            s = "Max bracket f(%f) = %15.14e" % (x_max,f(x_max))
            print(s)
            s = "Mid bracket f(%f) = %15.14e" % (x_mid,f(x_mid))
            print(s)
            raise StopItertion('Stopping iterations after ',i)
            
    # We're done!
    return x_mid<jupyter_output><empty_output><jupyter_text>Perform the search<jupyter_code>x_min = 0.0
x_max = 1.5

tolerance = 1.0e-6

# print the intial guess
print(x_min,function_for_roots(x_min))
print(x_max,function_for_roots(x_max))

# perform search
x_root = bisection_root_finding(function_for_roots,x_min,x_max,tolerance)
y_root = function_for_roots(x_root)

s = "Root found with y(%f) = %f" % (x_root,y_root)
print(s)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09259736909981944, 'fraction_numerical': 0.014702089244261026, 'mean_word_length': 2.08022239872915, 'pattern_counts': {'":': 0, '<': 20, '<?xml version=': 0, '>': 20, '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': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '192294', 'license': 'MIT', 'n_tokens_mistral': 1414, 'n_tokens_neox': 1341, 'n_words': 374, 'path': 'Bisection_search.ipynb', 'repo_name': 'natewachter/astr-119-session-7', 'size': '3877'}