def solve_tise(V, x_interval, E_interval, mass):
    xmin, xmax, nsteps = x_interval
    unitlessV = lambda x: V((x * abs(xmax - xmin) + xmin)) * abs(
        xmax - xmin)**2 * (2 * mass / H_BAR**2)
    unitlessx_interval = (0, 1, nsteps)
    unitlessE_interval = np.array(E_interval) * abs(xmax - xmin)**2 * (
        2 * mass / H_BAR**2)

    unitless_energy = rootfind.hybrid_secant(f=error,
                                             root_interval=unitlessE_interval,
                                             tolerance=1e-8,
                                             verbose=True,
                                             f_eq=schrod_eq,
                                             dep_i=(0, 1),
                                             interval=unitlessx_interval,
                                             order=4,
                                             V=unitlessV)
    energy = unitless_energy * abs(xmax - xmin)**-2 * H_BAR**2 / (2 * mass)
    norm = normalize(energy, V, x_interval)
    xpoints, ypoints = ode.solve(f_eq=schrod_eq,
                                 dep_i=(0, 1),
                                 interval=x_interval,
                                 order=4,
                                 return_points=True,
                                 V=V,
                                 E=energy)
    num_soln = xpoints, ypoints[0, :]

    return (energy, num_soln)
def solve_tise(V,x_interval,E_interval,mass):
    xmin,xmax,nsteps = x_interval
    unitlessV = lambda x: V((x*abs(xmax-xmin)+xmin)) * abs(xmax-xmin)**2 * (2*mass/H_BAR**2)
    unitlessx_interval = (0,1,nsteps)
    unitlessE_interval = np.array(E_interval) * abs(xmax-xmin)**2 * (2*mass/H_BAR**2)
        
    unitless_energy = rootfind.hybrid_secant(f = error,
                        root_interval = unitlessE_interval,
                        tolerance = 1e-8,
                        verbose = True,
                          f_eq = schrod_eq,
                          dep_i = (0,1),
                          interval = unitlessx_interval,
                          order = 4,
                          V = unitlessV)
    energy = unitless_energy * abs(xmax-xmin)**-2 * H_BAR**2 / (2*mass)
    norm = normalize(energy,V,x_interval)
    xpoints,ypoints = ode.solve(f_eq = schrod_eq,
                        dep_i = (0,1),
                        interval = x_interval,
                        order = 4,
                        return_points = True,
                        V = V,
                        E = energy)
    num_soln = xpoints, ypoints[0,:]
    
    return (energy,num_soln)
def error_plot(E):
    xpoints, ypoints = ode.solve(f_eq=schrod_eq,
                                 dep_i=(0, 1),
                                 interval=(0, 1, 1000),
                                 order=4,
                                 return_points=True,
                                 V=stepV,
                                 E=E)
    pylab.plot(xpoints, ypoints[0, :])
    #    print(ypoints[:,-1])
    return ypoints[0, -1]
def error_plot(E):
    xpoints,ypoints = ode.solve(f_eq = schrod_eq,
                 dep_i = (0,1),
                 interval = (0,1,1000),
                 order = 4,
                 return_points = True,
                 V = stepV,
                 E = E )
    pylab.plot(xpoints,ypoints[0,:])
#    print(ypoints[:,-1])
    return ypoints[0,-1]
def error_with_plot(E, **kwargs):
    """ Calculates the error of the endpoint and adds the intermediate plot to the
    plot queue.
    
    Returns the error (final value of differential equation)
    
    E: energy of guess
    **kwargs: keyword arguments for ode.solve()
    """
     
    xpoints,ypoints = ode.solve(return_points = True, E = E, **kwargs)
    plt.plot(xpoints,ypoints[0,:])
    return ypoints[0,-1]
def error_with_plot(E, **kwargs):
    """ Calculates the error of the endpoint and adds the intermediate plot to the
    plot queue.
    
    Returns the error (final value of differential equation)
    
    E: energy of guess
    **kwargs: keyword arguments for ode.solve()
    """

    xpoints, ypoints = ode.solve(return_points=True, E=E, **kwargs)
    plt.plot(xpoints, ypoints[0, :])
    return ypoints[0, -1]
def error(E, plot=False, **kwargs):
    """ Calculates the error of the endpoint.
    
    Returns the error (final value of differential equation)
    
    E: energy of guess
    plot: add plot to queue
    **kwargs: keyword arguments for ode.solve()
    """

    if plot:
        return error_with_plot(E, **kwargs)
    else:
        endpoint = ode.solve(E = E, **kwargs)
        return endpoint[0]
def error(E, plot=False, **kwargs):
    """ Calculates the error of the endpoint.
    
    Returns the error (final value of differential equation)
    
    E: energy of guess
    plot: add plot to queue
    **kwargs: keyword arguments for ode.solve()
    """

    if plot:
        return error_with_plot(E, **kwargs)
    else:
        endpoint = ode.solve(E=E, **kwargs)
        return endpoint[0]
def normalize(E, V, interval):
    """ Use the Simpson method of integration from the SciPy module to
        normalize the wave function.
        
        Returns normalized numerical wavefunction (xpoints,ypoints).
    """
    xpoints,ypoints = ode.solve(f_eq = schrod_eq,
                        dep_i = (0,1),
                        interval = interval,
                        order = 4,
                        return_points = True,
                        V = V,
                        E = E )
    num_points = interval[2]
    ypoints_sq = np.power(ypoints[0,0:int(num_points/2)],2) # strip out phi values and square
    int_val = 2*integrate.simps(ypoints_sq,xpoints[0:int(num_points/2)])
    return np.array([xpoints,ypoints/np.sqrt(int_val)])
def normalize(E, V, interval):
    """ Use the Simpson method of integration from the SciPy module to
        normalize the wave function.
        
        Returns normalized numerical wavefunction (xpoints,ypoints).
    """
    xpoints,ypoints = ode.solve(f_eq = schrod_eq,
                        dep_i = (0,1),
                        interval = interval,
                        order = 4,
                        return_points = True,
                        V = V,
                        E = E )
    num_points = interval[2]
    ypoints_sq = np.power(ypoints[0,0:int(num_points/2)],2) # strip out phi values and square
    int_val = 2*integrate.simps(ypoints_sq,xpoints[0:int(num_points/2)])
    return np.array([xpoints,ypoints/np.sqrt(int_val)])
def normalize(E, V, interval):
    """ Use the Romberg method of integration from the SciPy module to
        normalize the wave function.
    """
    min, max, steps = interval
    k = np.ceil(np.log2(steps - 1))
    int_interval = (min, max, np.exp2(k) + 1)
    xpoints, ypoints = ode.solve(f_eq=schrod_eq,
                                 dep_i=(0, 1),
                                 interval=int_interval,
                                 order=4,
                                 return_points=True,
                                 V=V,
                                 E=E)
    ypoints = np.power(ypoints[0, :], 2)  # strip out phi values and square
    dx = (max - min) / (np.exp2(k))
    A2 = integrate.romb(ypoints, dx)
    return 1 / np.sqrt(A2)
def normalize(E, V, interval):
    """ Use the Romberg method of integration from the SciPy module to
        normalize the wave function.
    """
    min,max,steps = interval
    k = np.ceil(np.log2(steps - 1))
    int_interval = (min,max,np.exp2(k)+1)
    xpoints,ypoints = ode.solve(f_eq = schrod_eq,
                        dep_i = (0,1),
                        interval = int_interval,
                        order = 4,
                        return_points = True,
                        V = V,
                        E = E )
    ypoints = np.power(ypoints[0,:],2) # strip out phi values and square
    dx = (max-min)/(np.exp2(k))
    A2 = integrate.romb(ypoints,dx)
    return 1/np.sqrt(A2)
def error(E, **kwargs):
    endpoint = ode.solve(E=E, **kwargs)
    return endpoint[0]
def error(E, **kwargs):
    endpoint = ode.solve(E = E, **kwargs)
    return endpoint[0]