<jupyter_start><jupyter_text>Define a function for which we will use 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 #get the roots of ax^2 +bx + c
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 contains a zero crossing
    if(y_min*y_max>=0.0): #if this is true then there is no zero crossing and will print the following
        print("No zero crossing found the range=",x_min,x_max)
        s = "f(%f) = %f, f(%f) = %f" % (x_min,y_min,x_max,y_max)
        print(s)
        return 0.             #now will check other cases, 2 more
    #if x_min is a root, then return flag == 1
    if(np.fabs(y_min)<tol):
        return 1
    # if x_max is a root, then return == 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 will perform the search<jupyter_code>def bisection_root_finding(f, x_min_start, x_max_start, tol): #Tolerance, What do we want to call zero??
    #this function uses bisection search to find a root
    
    x_min = x_min_start # minimum x in bracket
    x_max = x_max_start # maximum x in bracket
    x_mid = 0.0         #mid point
    
    y_min = f(x_min) #function value at x_min    #evaulate function at x_min and x_max
    y_max = f(x_max)#function value at x_max
    y_mid = 0 #function value at mid point
    
    imax = 10000 #set a maximum number of iterations
    i = 0        #iteration counter
    
    #check the initial values
    flag = check_initial_values(f,x_min,x_max,tol)   # flag will have 1 of 4 values, 0,1,2,3
    if(flag==0):
        print("Error in bisection_root_finding().")
        raise ValueError('Initial values invalid',x_min,x_max)
    elif(flag==1):
        #lucky guess
        return x_min
    elif(flag==2):
        #another lucky guess
        return x_max
    #if we reach here, then we need to conduct the search
    #set a flag
    flag = 1
    #enter a while loop, do this as long as it is not equal to zero
    while(flag):
        x_mid = 0.5*(x_min+x_max) #mid point
        y_mid = f(x_mid)         #function value at x_mid
        
        #print("HERE ",x_mid,y_mid,x_max,y_max)
        
        #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 the midpoint
                #and at one of the end points is greater than
                #zero, replace this end point
            if(f(x_min)*f(x_mid)>0):   #product if it is zer0 we know that x_min and midpoint are on one side of the crossing, this is how we...
                #replace x_min with x_mid         #...start narrowing our bracket
                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),x_mid,f(x_mid)) #print just so we can see what is going on
            
            #count the iteration
            i += 1
            
            #if we hace exceeded the max number
            #of iterations, exit
            if(i>=imax):   #there is something wrong if we take 10000 iterations to do this 
                print("Exceeded max number of iteratinons=",i)
                s  = "Min bracket f(%f)= %f" % (x_min,f(x_min))
                print(s)
                s  = "Max bracket f(%f)= %f" % (x_max,f(x_max))
                print(s)
                s  = "Mid bracket f(%f)= %f" % (x_mid,f(x_mid))
                print(s)
                raise StopIteration('Stopping interations after',i)
    #we are done
    return x_mid<jupyter_output><empty_output><jupyter_text>Perform the search!<jupyter_code>x_min1 = 1.7
x_max1 = 2.5
tolerance = 1.0e-6

#print the intial guess
print(x_min1,function_for_roots(x_min1))
print(x_max1,function_for_roots(x_max1))

x_root1 = bisection_root_finding(function_for_roots,x_min1,x_max1,tolerance)
y_root1 = function_for_roots(x_root1)

s = "Root found with y(%f) = %f" % (x_root1,y_root1)
print(s)
x_min2 = 0.5
x_max2 = 1.5
tolerance = 1.0e-6

#print the intial guess
print(x_min2,function_for_roots(x_min2))
print(x_max2,function_for_roots(x_max2))

x_root2 = bisection_root_finding(function_for_roots,x_min2,x_max2,tolerance)
y_root2 = function_for_roots(x_root2)

s = "Root found with y(%f) = %f" % (x_root2,y_root2)
print(s)<jupyter_output><empty_output><jupyter_text>Here is the result<jupyter_code>a = 1.01
b = -3.04
c = 2.07

x = np.linspace(0,3,1000)
y = function_for_roots(x)
y_1 = function_for_roots(x_min1)
y_2 = function_for_roots(x_max1)
y_3 = function_for_roots(x_min2)
y_4 = function_for_roots(x_max2)

y_5 = 0*x

fig = plt.figure(figsize=(7,7))


point1 = plt.plot(x_root1,y_root1,'ro',label = 'root1')
point2 = plt.plot(x_root2,y_root2,'ro',label = 'root2')
point3 = plt.plot(x_min1,y_1,'bo',label='point3')
point4 = plt.plot(x_max1,y_2,'bo',label='point4')
point5 = plt.plot(x_min2,y_3,'yo',label='point5')
point6 = plt.plot(x_max2,y_4,'yo',label='point6')
plt.ylim(-0.5,2.1)
plt.xlim(0,3)
plt.plot(x,function_for_roots(x))
plt.plot(x,y_5)
plt.legend()

plt.show()


#It takes my code 18 iterations to run<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1057116953762466, 'fraction_numerical': 0.027379873073436083, 'mean_word_length': 2.5911458333333335, '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': '18313', 'license': 'MIT', 'n_tokens_mistral': 2146, 'n_tokens_neox': 2032, 'n_words': 545, 'path': 'hw-3.ipynb', 'repo_name': 'ericgc10/astr-119-hw-3', 'size': '5515'}