Пример #1
0
def newton(f, xo, ft, **keyargs):
	"""Returns an approximation of the function's root via newton's method.
	
	Assumes that the function is appropriate for this method, i.e., in the
	neighborhood of xo, the function
	- Is continuous
	- Has one and only one root
	- Has it's first derivative != 0
	
	f: The function. (python-compatible function)
	xo: The initial guess. (float)
	ft: The tolerance function. (python-compatible function)
	**keyargs: Any keyword:value the tolerance function might take. (dict)
	
	E.g. newton(fx, 1.5, aux.tol_iter, n=10**1)
	Note: It might be necessary to modify this function for some tolerance 
	functions. As is, it checks if ft(keyargs) is True in order to stop.
	"""
	
	if ft(**keyargs):
		return xo
	else:
		try:
			return newton(f, xo - (f(xo) / d_n(f, 1)(xo)), ft, **keyargs)
		except ZeroDivisionError:
			raise ValueError('d/dx f must be != 0')
Пример #2
0
def t_rootfinding():
	
	print 'rootfinding...'
	
	def test_it(expected, result, max_error):
		
		diff = abs(expected-result)
		if diff < max_error:
			print 'OK'
		else:
			print 'FAIL'
			print '		Expected:', expected
			print '		Got:', result
			print '		Difference:', diff
			print '		Tolerance:', max_error
	
		
	def rp(x, k=1, min=-1, max=1):
		"""Random polynomial of degree k at x"""
		
		coeffs = numpy.random.uniform(min, max, size=k+1)
		return sum([coeffs[i]*x**i for i in xrange(len(coeffs))])
	
	x = sympy.symbols('x')
	
	# Number of tests
	n = 4
	
	# Maximum iterations
	iter = 10
	
	# How much can the tests differ from the expected results? Adjust 
	# according to the method and number of iterations.
	max_error = 10**-8
	
	# For simplicity, test only for degree 1 polynomials with roots in a known
	# interval
	print '	Newton...'
	i = 0
	while i < n:
		p = sympy.lambdify(x, rp(x, 1))
		guess = numpy.random.randint(-10, 10)
		dx = d_n(p, 1)
		if dx(x) != 0:
			try:
				expected = optimize.newton(p, guess, dx, maxiter=iter)
			except RuntimeError:	# Doesn't return if approximation
				continue
			print '		Test {}/{}'.format(i+1, n),
			result = rootfinding.newton(p, guess, tol_iter, n=iter)
			test_it(expected, result, max_error)
			i += 1
	
	# The secant method as isn't able to stop if the difference between the 
	# guesses is less than tolerance, whereas scipy's does:
	# github.com/scipy/scipy/blob/v0.14.0/scipy/optimize/zeros.py#L45
	# This (important) feature (and the tests) will soon be implemented 
	print '	Secant... SKIP'
	
	print '	Bisection...'
	
	# Slow method
	iter = 10**2
	
	i = 0
	while i < n:
		p = sympy.lambdify(x, rp(x, 1))
		try:
			expected = optimize.bisect(p, -10, 10, maxiter=iter)
		except RuntimeError:	# Doesn't return if approximation
			continue
		except ValueError:		# Sem raizes no intervalo (um coeff = 0)
			continue
		print '		Test {}/{}'.format(i+1, n),
		result = rootfinding.bisec(p, -10, 10, tol_iter, n=iter)
		test_it(expected, result, max_error)
		i += 1
Пример #3
0
def t_rootfinding():

    print 'rootfinding...'

    def test_it(expected, result, max_error):

        diff = abs(expected - result)
        if diff < max_error:
            print 'OK'
        else:
            print 'FAIL'
            print '		Expected:', expected
            print '		Got:', result
            print '		Difference:', diff
            print '		Tolerance:', max_error

    def rp(x, k=1, min=-1, max=1):
        """Random polynomial of degree k at x"""

        coeffs = numpy.random.uniform(min, max, size=k + 1)
        return sum([coeffs[i] * x**i for i in xrange(len(coeffs))])

    x = sympy.symbols('x')

    # Number of tests
    n = 4

    # Maximum iterations
    iter = 10

    # How much can the tests differ from the expected results? Adjust
    # according to the method and number of iterations.
    max_error = 10**-8

    # For simplicity, test only for degree 1 polynomials with roots in a known
    # interval
    print '	Newton...'
    i = 0
    while i < n:
        p = sympy.lambdify(x, rp(x, 1))
        guess = numpy.random.randint(-10, 10)
        dx = d_n(p, 1)
        if dx(x) != 0:
            try:
                expected = optimize.newton(p, guess, dx, maxiter=iter)
            except RuntimeError:  # Doesn't return if approximation
                continue
            print '		Test {}/{}'.format(i + 1, n),
            result = rootfinding.newton(p, guess, tol_iter, n=iter)
            test_it(expected, result, max_error)
            i += 1

    # The secant method as isn't able to stop if the difference between the
    # guesses is less than tolerance, whereas scipy's does:
    # github.com/scipy/scipy/blob/v0.14.0/scipy/optimize/zeros.py#L45
    # This (important) feature (and the tests) will soon be implemented
    print '	Secant... SKIP'

    print '	Bisection...'

    # Slow method
    iter = 10**2

    i = 0
    while i < n:
        p = sympy.lambdify(x, rp(x, 1))
        try:
            expected = optimize.bisect(p, -10, 10, maxiter=iter)
        except RuntimeError:  # Doesn't return if approximation
            continue
        except ValueError:  # Sem raizes no intervalo (um coeff = 0)
            continue
        print '		Test {}/{}'.format(i + 1, n),
        result = rootfinding.bisec(p, -10, 10, tol_iter, n=iter)
        test_it(expected, result, max_error)
        i += 1