We studied several methods to solve equations numerically.
import numpy as np
import math
from matplotlib import pyplot as plt
np.set_printoptions(suppress=True, precision=5)
#################################################################
# The following function finds a root of a given equation
# using the Newton Method. Its parameters are:
# fn: the given function for which a solution is found
# dfn: derivative of fn
# init: the initial guess for the solution
# eps: error limit; default value is 1e-4 or 0.00001
# maxiter: maximum number of iterations for which the update
# loop runs
# The function returns the solution and the errors array
# containing the error at each iteration. The data in this
# array may be used to see how the error changes from one
# iteration to another.
#################################################################
def root_newton(fn, dfn, init, eps=1e-5, maxiter=50) :
errors = np.zeros(maxiter)
errors[0] = abs(fn(init))
if errors[0] <= eps :
print('Initial value is the solution!')
return init, errors
x0 = init
i = 0
while errors[i] >= eps and i < maxiter :
x0 = x0 - fn(x0) / dfn(x0)
i = i + 1
errors[i] = abs(fn(x0))
if i >= maxiter :
print('Good Solution not found in ', i, ' iterations!')
else :
print('Found Solution after ', i, ' iterations.')
return x0, errors
Given below is the code for finding the value of $\sqrt[3]{\pi^{e}}$ ($\pi^e\approx22$ and therefore its cuberoot is $\approx2.8$).
First, we need to define the necessary function and its derivative. The function we want is $$f(x) = x^3 - \pi^e$$Its derivative is $3x^2$. These are defined by the two functions
def solve_eqn(x) :
return x ** 3 - math.pi ** math.e
def d_solve_eqn(x) :
return 3. * x ** 2
We are ready to use the Newton Method defined above to solve the equation now. The cell below shows the necessary steps, prints the solution and also the absolute errors at each iteration. We can see that the Newton Method found the correct value to 4 decimal places in just 7 iterations starting from an initial guess of $1$.
We also plot the errors to see how quickly (or slowly) they are decreasing with each iteration. What do you infer from the plot of errors?
ans, err = root_newton(solve_eqn, d_solve_eqn, 1.)
print(ans)
print(' Absolute Errors at each stage:')
print(err)
plt.grid(True)
plt.plot(err[:17])
plt.show()
def root_bisection(fn, xlow, xhigh, eps=1e-5, maxiter=50) :
# Insert your code as per the above parameters and
# using the update equation (Equation 1)
# Declare the errors array exactly as in root_newton method
errors = np.zeros(maxiter)
return xnew, errors
def root_secant(fn, init, step=1., eps=1e-5, maxiter=50) :
# Insert your code here as per the above parameters
# using the update equations (Equation 2 and Equation 3)
# above.
x0 = init
return x0, errors