Search code examples
pythonnumerical-methods

Using Python to write code for the Secant method


I need to write a code using python for the Secant method (in numerical analysis). The code should find a solution for the equation f(x) = 0, where f is a general function. The solution should have m decimal digits (for example, if m = 4, then the solution should have 4 decimal digits).

The function we are required to build should receive two numbers (x1,x0), which are two initial guesses for the equation f(x) = 0, and two numbers (m,n), where m is the same number I mentioned earlier, and n is the accuracy of the solution. for exmaple if n = 4, then the accuracy is defined to be the difference |x(k+1)-x(k)| < 10^(-4). x(k) is the solution of the current iteration, and x(k+1) is the solution of the next iteration.

To examine my code, I imported the math module, but I keep getting errors. Can you help me find the problems in my code?

Thank you

import math
def Secant_Method(x0,x1,m,n):
    delta_x = x1 - x0
    x_k = x1
    x_k1 = x0
    itr_num = 1
    while (abs(delta_x) > 10**(-n)) and (f(x_k) > 10**(-m)):
        x_k2 = x_k - f(x_k)*((x_k - x_k1)/(f(x_k) - f(x_k1)))
        delta_x = abs(x_k2 - x_k1)
        x_k1 = x_k
        x_k = x_k2
        itr_num += 1
    return x_k2, itr_num
f(x) = math.asin(x) - 0.5
Secant_Method(0.5,0.6,4,4)

This is the error I get:

---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-6-7ea489c76165> in <module>
     13     return x_k2, itr_num
     14 
---> 15 f = math.asin(x)
     16 Secant_Method(0.5,0.6,4,4)

NameError: name 'x' is not defined

Solution

  • The problem is with the f(x) = math.asin(x) - 0.5 line. You can't do this in python. If you want to create a lambda like in Matlab you should do something like (recommended):

    def f(x):
      return math.asin(x) - 0.5
    

    Or:

    f = lambda x : math.asin(x) - 0.5
    

    The first one is more Pythony.

    Other than that you should also pass this fun to the Secant method:

    import math
    def Secant_Method(x0,x1,m,n,f):
        delta_x = x1 - x0
        x_k = x1
        x_k1 = x0
        itr_num = 1
        while (abs(delta_x) > 10**(-n)) and (f(x_k) > 10**(-m)):
            x_k2 = x_k - f(x_k)*((x_k - x_k1)/(f(x_k) - f(x_k1)))
            delta_x = abs(x_k2 - x_k1)
            x_k1 = x_k
            x_k = x_k2
            itr_num += 1
        return x_k2, itr_num
    f(x) = math.asin(x) - 0.5
    Secant_Method(0.5,0.6,4,4,f)