<jupyter_start><jupyter_text>Creating function that we want to find the roots for<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 quadratic<jupyter_output><empty_output><jupyter_text>Function to check if initial values are valid<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
    if(y_min*y_max>=0.0):
        print("No zero crossing found in the range = ", x_min,x_max)
        s = "func(%f) = %f, func(%f) = %f" % (x_min,y_min,x_max,y_max)
        print(s)
        return 0
    
    #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 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>Time to create a function to perform the iterative search<jupyter_code>def bisection_root_finding(f, x_min_start, x_max_start, tol):
    
    #This function uses a bisection search to find the roots of the function
    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
    y_max = f(x_max) #function value at x_max
    y_mid = 0.0 #function value at mid point
    
    imax = 1000 #set maximum number of iterations
    i = 0 #iteration counter
    
    #check for initial 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):
        #lucky guess
        return x_min
    elif(flag==2):
        #another lucky guess
        return x_max
    #if this point is reached, search needs to be conducted 
    
    #set a flag
    flag = 1
    
    #create a while loop 
    while(flag):
        x_mid = 0.5*(x_min + x_max) #x mid point 
        y_mid = f(x_mid) #function value at x_mid
        
        #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 mid point 
            #and at one of the end points is greater than zero
            #then replace this 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_min
                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 have exceeded max number of
        #iterations, exit
        
        if(i>imax):
            print("Exceeded max number of iterations = ", 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 iterations after ', i)
            
    #All done!
    return x_mid<jupyter_output><empty_output><jupyter_text>Time to perform Bisection Search  First Root<jupyter_code>x_min = 0.0 
x_max = 1.5
tolerance = 1.0e-6

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

x_root = bisection_root_finding(function_for_roots, x_min, x_max, tolerance)
y_root = function_for_roots(x_root)

a = "Root found with f(%f) = %f" % (x_root, y_root)
print(a)<jupyter_output><empty_output><jupyter_text>Second Root<jupyter_code>x_min = 1.5
x_max = 3.0
tolerance = 1.0e-6

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

x_root = bisection_root_finding(function_for_roots, x_min, x_max, tolerance)
y_root = function_for_roots(x_root)

a = "Root found with f(%f) = %f" % (x_root, y_root)
print(a)<jupyter_output><empty_output><jupyter_text>The Bisection Method took 18 iterations to converge  Time to graph f(x) vs x<jupyter_code>x = np.linspace(0,3,1000) #range for the x-axis
a = 1.01
b = -3.04
c = 2.07
y_1 = a*x**2 + b*x + c #creating the function
plt.plot(x, y_1)
plt.axhline(y = 0.0, color = 'k') #horizontal line
plt.plot(0.0, 2.07, 'ro') #initial guess
plt.plot(1.5, -0.2175000000000007, 'ro') #initial guess
plt.plot(3.0, 2.0399999999999987, 'ro') #initial guess
plt.plot(1.040863037109375,0.000001, 'go' ) #Root 1
plt.plot(1.969030, -0.000001, 'go') #Root 2
plt.xlim([0,3])
plt.ylim([-0.5,2.1])
plt.xlabel('x') #label for x-axis
plt.ylabel('f(x)') #label for y-axis
plt.show()<jupyter_output><empty_output>
StarcoderdataJupyterStructuredCleanDedup