_Jenny

Numerical Methods

Oct 6th, 2025 (edited)
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.66 KB | Source Code | 0 0
  1. import math
  2. import matplotlib.pyplot as plt
  3.  
  4. # ---------------------------
  5. # Function and derivative
  6. # ---------------------------
  7. def f(h):
  8.     return h**3 - 10*h + 5*math.exp(-h/2) - 2
  9.  
  10. def df(h):
  11.     return 3*h**2 - 10 - (5/2)*math.exp(-h/2)
  12.  
  13.  
  14. # ---------------------------
  15. # Bisection Method
  16. # ---------------------------
  17. def bisection(a, b, es):
  18.     # fa, fb = f(a), f(b)
  19.     fa=f(a)
  20.     fb=f(b)
  21.     if fa*fb > 0:
  22.        print("Bisection method fails.")
  23.        return None
  24.  
  25.         # raise ValueError("No root in interval: f(a) and f(b) have same sign")
  26.     iters = []
  27.     xr_old = None
  28.     k = 1
  29.  
  30.     while True:   # infinite loop until we break
  31.         xr = (a + b) / 2
  32.         fr = f(xr)
  33.         ea = abs((xr - xr_old) / xr) * 100 if xr_old is not None else None
  34.         iters.append((k, a, b, xr, fr, ea))
  35.         if fr == 0:
  36.             break
  37.         # interval update
  38.         if fa * fr < 0:
  39.             # b, fb = xr, fr
  40.             b = xr
  41.             fb = fr
  42.         else:
  43.             # a, fa = xr, fr
  44.             a = xr
  45.             fa = fr
  46.  
  47.         # stopping criteria
  48.         if (ea is not None and ea <= es):
  49.             break
  50.  
  51.         xr_old = xr
  52.         k += 1
  53.  
  54.     return iters
  55.  
  56.  
  57. # ---------------------------
  58. # False Position Method
  59. # ---------------------------
  60. def false_position(a, b,es):
  61.     fa, fb = f(a), f(b)
  62.     if fa*fb > 0:
  63.         print("False position method is not applicable because f(xl) and f(xu) have the same sign.")
  64.         return None
  65.    
  66.     iters = []
  67.     xr_old = None
  68.     k = 1
  69.  
  70.     while True:   # run until break
  71.         xr = b - fb * (b - a) / (fb - fa)
  72.         fr = f(xr)
  73.         ea = abs((xr - xr_old) / xr) * 100 if xr_old is not None else None
  74.         iters.append((k, a, b, xr, fr, ea))
  75.         if fr == 0:
  76.             break
  77.         # interval update
  78.         if fa * fr < 0:
  79.             # b, fb = xr, fr
  80.             b = xr
  81.             fb = fr
  82.         else:
  83.             # a, fa = xr, fr
  84.             a = xr
  85.             fa = fr
  86.  
  87.         # stopping criteria
  88.         if (ea is not None and ea <= es):
  89.             break
  90.  
  91.         xr_old = xr
  92.         k += 1
  93.  
  94.     return iters
  95.  
  96. # ---------------------------
  97. # Newton–Raphson Method
  98. # ---------------------------
  99. def newton(x0, es):
  100.     iters = []
  101.     xr_old = x0
  102.     # x = x0
  103.     k = 1
  104.  
  105.     while True:
  106.         fx = f(xr_old)
  107.         dfx = df(xr_old)
  108.  
  109.         if dfx == 0:
  110.             print("Derivative zero. Not applicable")
  111.             return None
  112.  
  113.         xr = xr_old - fx / dfx
  114.         ea = abs((xr - xr_old) / xr) * 100
  115.         iters.append((k, xr_old, fx, dfx, xr, ea))
  116.  
  117.         # stopping criteria
  118.         if (ea is not None and ea <= es):
  119.             break
  120.  
  121.         xr_old = xr
  122.         k += 1
  123.  
  124.     return iters
  125.  
  126.  
  127. # ---------------------------
  128. # Secant Method
  129. # ---------------------------
  130. def secant(x0, x1, es):
  131.     iters = []
  132.     k = 1
  133.  
  134.     while True:
  135.         f0, f1 = f(x0), f(x1)
  136.         if f1 - f0 == 0:
  137.             print("Division by zero. Not applicable")
  138.             return None
  139.  
  140.         x2 = x1 - (f1 * (x1 - x0)) / (f1 - f0)
  141.  
  142.         ea = abs((x2 - x1) / x2) * 100
  143.         iters.append((k, x0, x1, x2, f(x2), ea))
  144.  
  145.         # stopping criteria
  146.         if (ea is not None and ea <= es) :
  147.             break
  148.  
  149.         # x0, x1 = x1, x2
  150.         x0 = x1
  151.         x1 = x2
  152.         k += 1
  153.  
  154.     return iters
  155.  
  156.  
  157. # ---------------------------
  158. # Run all methods
  159. # ---------------------------
  160.  
  161. es=0.001
  162. a=0.1
  163. b=0.4
  164. bis = bisection(a,b,es)
  165. fp  = false_position(a,b,es)
  166. h0 = 1.5
  167. h1 = 2.0
  168. newt = newton(h0,es)
  169. sec  = secant(h0,h1,es)
  170.  
  171. def r5(x): return float(f"{x:.5f}")
  172.  
  173.  
  174. # ---------------------------
  175. # Print Results
  176. # ---------------------------
  177. print("\n--- Final Roots ---")
  178. print("Bisection root:", r5(bis[-1][3]), "Iterations:", len(bis))
  179. print("False-Position root:", r5(fp[-1][3]), "Iterations:", len(fp))
  180. print("Newton–Raphson root:", r5(newt[-1][4]), "Iterations:", len(newt))
  181. print("Secant root:", r5(sec[-1][3]), "Iterations:", len(sec))
  182.  
  183.  
  184. # ---------------------------
  185. # Print Tables
  186. # ---------------------------
  187. print("\n--- Bisection Table ---")
  188. print("Iter\t a\t\t b\t\t xr\t\t f(xr)\t\t ea(%)")
  189. for row in bis:
  190.     print(f"{row[0]:<4}\t{row[1]:.6f}\t{row[2]:.6f}\t{row[3]:.6f}\t{row[4]:.6e}\t{row[5]}")
  191.  
  192. print("\n--- False Position Table ---")
  193. print("Iter\t a\t\t b\t\t xr\t\t f(xr)\t\t ea(%)")
  194. for row in fp:
  195.     print(f"{row[0]:<4}\t{row[1]:.6f}\t{row[2]:.6f}\t{row[3]:.6f}\t{row[4]:.6e}\t{row[5]}")
  196.  
  197. print("\n--- Newton–Raphson Table ---")
  198. print("Iter\t x_i\t\t f(x_i)\t\t f'(x_i)\t x_{i+1}\t\t ea(%)")
  199. for row in newt:
  200.     print(f"{row[0]:<4}\t{row[1]:.6f}\t{row[2]:.6e}\t{row[3]:.6f}\t{row[4]:.6f}\t{row[5]}")
  201.  
  202. print("\n--- Secant Table ---")
  203. print("Iter\t x_{i-1}\t x_i\t\t x_{i+1}\t f(x_{i+1})\t ea(%)")
  204. for row in sec:
  205.     print(f"{row[0]:<4}\t{row[1]:.6f}\t{row[2]:.6f}\t{row[3]:.6f}\t{row[4]:.6e}\t{row[5]}")
  206.  
  207.  
  208. # ---------------------------
  209. # Plot Convergence
  210. # ---------------------------
  211. def extract_err(iters, idx=-1):
  212.     return [row[idx] for row in iters if row[idx] is not None]
  213.  
  214. plt.figure()
  215. plt.semilogy(range(1, len(extract_err(bis,5))+1), extract_err(bis,5), 'o-', label="Bisection")
  216. plt.semilogy(range(1, len(extract_err(fp,5))+1), extract_err(fp,5), 'o-', label="False Position")
  217. plt.semilogy(range(1, len(extract_err(newt,5))+1), extract_err(newt,5), 'o-', label="Newton–Raphson")
  218. plt.semilogy(range(1, len(extract_err(sec,5))+1), extract_err(sec,5), 'o-', label="Secant")
  219.  
  220. plt.xlabel("Iteration")
  221. plt.ylabel("Approx. relative error (%)")
  222. plt.title("Convergence Comparison")
  223. plt.legend()
  224. plt.grid(True, which="both")
  225. plt.show()
  226.  
Advertisement
Add Comment
Please, Sign In to add comment