Click here to Skip to main content
15,899,679 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am trying to improve my program that will allow all of the parameters in the compute_bisection function to be set by the user.

What I have tried:

My computer_bisection function:
def compute_bisection(f, a, b, n=10, tol_interval=1e-5, tol_f=1e-8):
    '''This simple function applies up to n iterations of the bisection algorithm'''
    
    # Let us first check the conditions to apply the bisection alg. are satisfied
    if a >= b:
        raise ValueError('The bisec. alg. requires a<b')
    if f(a)*f(b) > 0:
        raise ValueError('The bisec. alg. requires f(a) and f(b) are different signs')
        
    # Now, perform the bisection algorithm
    current_iter = 0
    while current_iter < n:
        c = (b+a)/2 # bisect the interval [a,b], i.e., compute mid-point
        
        # Check if c is an (approx.) root
        if np.abs(f(c)) < tol_f:
            break
        
        # Check if dividing [a,b] in half makes the interval too small to continue
        if (b-a)/2 < tol_interval:
            break
            
        # Determine if a or b should be replaced with c
        if f(a)*f(c) < 0:
            b = c
        else:
            a = c
        
        current_iter += 1
    
    return (a, b, c)


My plot_bisection function :
def plot_bisection(f, a, b, n, x_min, x_max, grid_pts = 100, show_final_interval = False):
    # Compute approximate root with bisec. alg. 
    (a_n, b_n, c) = compute_bisection(f, a, b, n)
    
    ############################################
    # Everything below this line involves making plots of the results 
    ############################################
    fig = plt.figure(figsize=(10,5))
    x = np.linspace(x_min,x_max,grid_pts)
    
    # First, plot function and axes
    plt.plot(x,f(x),'b',linewidth=2) #plot of function f
    plt.axvline(0, linewidth=1, linestyle=':', c='k') #plot typical y-axis
    plt.axhline(0, linewidth=1, linestyle=':', c='k') #plot typical x-axis
    
    # Title information
    title_str = 'Approx. root is ' + '{:.6}'.format(c) + '. Use this to update interval [a,b].'
    plt.title(title_str, fontsize=14)
    
    # Create a dict (dictionary) of properties of items used in annotations
    bbox_pt = dict(boxstyle='round', fc='0.9')
    bbox_text = dict(boxstyle="round", fc='b', color='r', alpha=0.25, linewidth=2) 
    arrowprops = dict(arrowstyle='->', facecolor='black', alpha=0.5, linewidth=2) 
    y_min, y_max = plt.ylim() #get min and max y-values from plot to offset annotations
    y_range = y_max - y_min
    x_range = x_max - x_min
    
    # Now plot relevant points and annotate
    
    # First annotate parts of the plot involving the points a and b
    if show_final_interval:
        plt.scatter(a_n,f(a_n),s=70,c='k')
        
        plt.annotate(r'$(a_n,f(a_n))$', fontsize=12, xy=(a_n,f(a_n)), xytext=(a_n+0.2*x_range,f(a_n)-0.35*y_range),
                 bbox=bbox_pt, arrowprops=arrowprops)
        
        plt.scatter(b_n,f(b_n),s=70,c='k')
        
        plt.annotate(r'$(b_n,f(b_n))$', fontsize=12, xy=(b_n,f(b_n)), xytext=(b_n+0.2*x_range,f(b_n)-0.35*y_range),
                 bbox=bbox_pt, arrowprops=arrowprops)
        
    else:
        plt.scatter(a,f(a),s=70,c='k')
        
        plt.annotate(r'$(a,f(a))$', fontsize=12, xy=(a,f(a)), xytext=(a+0.1*x_range,f(a)-0.25*y_range),
                     bbox=bbox_pt, arrowprops=arrowprops)
        
        plt.scatter(b,f(b),s=70,c='k')
        
        plt.annotate(r'$(b,f(b))$', fontsize=12, xy=(b,f(b)), xytext=(b+0.1*x_range,f(b)-0.25*y_range),
                 bbox=bbox_pt, arrowprops=arrowprops)

    # Now annotate the part of the plot involving the approximate root c    
    plt.scatter(c,f(c),s=70,c='r')
    
    plt.annotate('Approx. root\nfrom ' + str(n) + '\nstep(s) of bisec.\nalgorithm', fontsize=12, xy=(c,f(c)), 
                     xytext=(c-0.2*x_range,f(c)+0.25*y_range), color='w',
                     bbox = bbox_text, arrowprops=arrowprops)
    
    plt.annotate(r'$(c,f(c))$', fontsize=12, xy=(c,f(c)), xytext=(c+0.1*x_range,f(c)-0.25*y_range),
                 bbox=bbox_pt, arrowprops=arrowprops)
Posted
Updated 2-Oct-20 7:52am
Comments
[no name] 2-Oct-20 19:39pm    
What you need is a "user interface" and a "settings" data store. The parameters are what matter; your function is irrelevant at this point.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900