Advertisement
Python253

newton_polynomial_interpolation_demo

May 23rd, 2024
690
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.37 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # Filename: newton_polynomial_interpolation_demo.py
  4. # Version: 1.0.0
  5. # Author: Jeoi Reqi
  6.  
  7. """
  8. Description:
  9.    - This script demonstrates polynomial interpolation using Newton's divided differences method.
  10.    - It calculates coefficients of the interpolating polynomial, evaluates the polynomial at specific points,
  11.      finds the minimum value of a function, and calculates error bounds and errors for given points.
  12.  
  13. Requirements:
  14.    - Python 3.x
  15.    - NumPy
  16.    - SciPy
  17.    - Matplotlib
  18.  
  19. Functions:
  20.    - newtdd:
  21.        Computes coefficients of interpolating polynomial using Newton's divided differences method.
  22.    - nest:
  23.        Evaluates the interpolating polynomial at a specific point.
  24.    - f5:
  25.        Defines a function used for finding the minimum value.
  26.    - g:
  27.        Defines a function used for error calculation.
  28.    - h:
  29.        Defines a function used for error calculation.
  30.    - divided_diff:
  31.        Calculates the divided differences table.
  32.    - newton_poly:
  33.        Evaluates the Newton polynomial at specific points.
  34.  
  35. Usage:
  36.    - Run the script and observe the printed results.
  37.  
  38. Expected Example Output:
  39.  
  40.    --------------------------------------------------------
  41.         :: Running The Newton Interpolation Test ::
  42.    --------------------------------------------------------
  43.    [Interpolating Polynomial Coefficients]:
  44.    [1.433329   1.98987    3.2589     3.68066667 4.00041667]
  45.  
  46.    [Interpolating Polynomial at x = 0.82]:
  47.    1.9589097744
  48.  
  49.    [Interpolating Polynomial at x = 0.98]:
  50.    2.6128479663999995
  51.  
  52.    [Minimum value of f5]:
  53.    -848.0804466745346
  54.  
  55.    --------------------------------------------------------
  56.    Error bounds and errors:
  57.    --------------------------------------------------------
  58.    Ec1: -5.3734377101298326e-05
  59.    Er1: 2.3348514214704963e-05
  60.    Ec2: 0.00021656582286280922
  61.    Er2: 0.00010660542393381434
  62.    --------------------------------------------------------
  63.  
  64. Additional Notes:
  65.    - Ensure NumPy, SciPy, and Matplotlib are installed in your Python environment.
  66.    - This script replicates functionality from MATLAB code.
  67. """
  68.  
  69. import numpy as np
  70. from scipy.optimize import minimize_scalar
  71. import matplotlib.pyplot as plt
  72.  
  73. def newtdd(x_vals, y_vals, n):
  74.     """
  75.    Calculate coefficients of interpolating polynomial using Newton's divided differences method.
  76.  
  77.    Parameters:
  78.        x_vals (ndarray): Array of x-coordinates of data points.
  79.        y_vals (ndarray): Array of y-coordinates of data points.
  80.        n (int): Number of data points.
  81.  
  82.    Returns:
  83.        ndarray: Coefficients of the interpolating polynomial.
  84.    """
  85.     v = np.zeros((n, n))
  86.     for j in range(n):
  87.         v[j][0] = y_vals[j]
  88.     for i in range(1, n):
  89.         for j in range(n - i):
  90.             v[j][i] = (v[j+1][i-1] - v[j][i-1]) / (x_vals[i+j] - x_vals[j])
  91.     return v[0]
  92.  
  93. def nest(coeff, x_vals, t):
  94.     """
  95.    Evaluate the interpolating polynomial at a specific point.
  96.  
  97.    Parameters:
  98.        coeff (ndarray): Coefficients of the interpolating polynomial.
  99.        x_vals (ndarray): Array of x-coordinates of data points.
  100.        t (float): Point at which to evaluate the polynomial.
  101.  
  102.    Returns:
  103.        float: Value of the polynomial at point t.
  104.    """
  105.     n = len(coeff)
  106.     result = coeff[-1]
  107.     for i in range(2, n+1):
  108.         result = result * (t - x_vals[n-i]) + coeff[n-i]
  109.     return result
  110.  
  111. def f5(x_val):
  112.     """
  113.    Define a function used for finding the minimum value.
  114.  
  115.    Parameters:
  116.        x_val (float): Input value.
  117.  
  118.    Returns:
  119.        float: Result of the function.
  120.    """
  121.     return -8 * x_val * (4 * x_val**4 + 20 * x_val**2 + 15) * np.exp(x_val**2)
  122.  
  123. def g(x_val):
  124.     """
  125.    Define a function used for error calculation.
  126.  
  127.    Parameters:
  128.        x_val (float): Input value.
  129.  
  130.    Returns:
  131.        float: Result of the function.
  132.    """
  133.     return np.exp(x_val**2)
  134.  
  135. def h(x_val):
  136.     """
  137.    Define a function used for error calculation.
  138.  
  139.    Parameters:
  140.        x_val (float): Input value.
  141.  
  142.    Returns:
  143.        float: Result of the function.
  144.    """
  145.     return (x_val - 0.6) * (x_val - 0.7) * (x_val - 0.8) * (x_val - 0.9) * (x_val - 1)
  146.  
  147. def divided_diff(x_vals, y_vals):
  148.     '''
  149.    Function to calculate the divided differences table.
  150.  
  151.    Parameters:
  152.        x_vals (ndarray): Array of x-coordinates of data points.
  153.        y_vals (ndarray): Array of y-coordinates of data points.
  154.  
  155.    Returns:
  156.        ndarray: Divided differences table.
  157.    '''
  158.     n = len(y_vals)
  159.     coef = np.zeros([n, n])
  160.     # The first column is y
  161.     coef[:,0] = y_vals
  162.  
  163.     for j in range(1,n):
  164.         for i in range(n-j):
  165.             coef[i][j] = (coef[i+1][j-1] - coef[i][j-1]) / (x_vals[i+j]-x_vals[i])
  166.  
  167.     return coef
  168.  
  169. def newton_poly(coef, x_values, points):
  170.     '''
  171.    Evaluate the Newton polynomial at points.
  172.  
  173.    Parameters:
  174.        coef (ndarray): Coefficients of the interpolating polynomial.
  175.        x_values (ndarray): Array of x-coordinates of data points.
  176.        points (ndarray): Points at which to evaluate the polynomial.
  177.  
  178.    Returns:
  179.        ndarray: Value of the polynomial at points.
  180.    '''
  181.     n = len(coef) - 1
  182.     p = coef[n]
  183.     for k in range(1, n + 1):
  184.         p = coef[n-k] + (points - x_values[n-k]) * p
  185.     return p
  186.  
  187. # Define the data points
  188. x_data = np.array([0.6, 0.7, 0.8, 0.9, 1.0])
  189. y_data = np.array([1.433329, 1.632316, 1.896481, 2.247908, 2.718282])
  190.  
  191. # Calculate the coefficients of interpolating polynomial
  192. coefficients = newtdd(x_data, y_data, len(x_data))
  193.  
  194. # Evaluate the interpolating polynomial at specific points
  195. P4_082 = nest(coefficients, x_data, 0.82)
  196. P4_098 = nest(coefficients, x_data, 0.98)
  197.  
  198. # Find the minimum value of f5
  199. f_5max = minimize_scalar(f5, bounds=(0.6, 1)).fun
  200.  
  201. # Calculate error bounds and errors for specific points
  202. Ec1 = f_5max * h(0.82) / 120
  203. Er1 = np.abs(P4_082 - g(0.82))
  204. Ec2 = f_5max * h(0.98) / 120
  205. Er2 = np.abs(P4_098 - g(0.98))
  206.  
  207. # Print the results
  208. print("-" * 56)
  209. print("     :: Running The Newton Interpolation Test ::")
  210. print("-" * 56)
  211. print("[Interpolating Polynomial Coefficients]:")
  212. print(coefficients, "\n")
  213. print("[Interpolating Polynomial at x = 0.82]:")
  214. print(P4_082, "\n")
  215. print("[Interpolating Polynomial at x = 0.98]:")
  216. print(P4_098, "\n")
  217. print("[Minimum value of f5]:")
  218. print(f_5max, "\n")
  219. print("-" * 56)
  220. print("Error bounds and errors:")
  221. print("-" * 56)
  222. print("Ec1:", Ec1)
  223. print("Er1:", Er1)
  224. print("Ec2:", Ec2)
  225. print("Er2:", Er2)
  226. print("-" * 56)
  227.  
  228. # Test Newton's Polynomial Interpolation
  229. x_test = np.array([-5, -1, 0, 2])
  230. y_test = np.array([-2, 6, 1, 3])
  231. coefficients_test = divided_diff(x_test, y_test)[0, :]
  232. x_new = np.arange(-5, 2.1, 0.1)
  233. y_new = newton_poly(coefficients_test, x_test, x_new)
  234.  
  235. # Plot the results
  236. plt.figure(figsize=(12, 8))
  237. plt.plot(x_test, y_test, 'bo', label='Data Points')  # Label the data points as 'Data Points'
  238. plt.plot(x_new, y_new, label='Newton Polynomial Interpolation')
  239. plt.xlabel('x')
  240. plt.ylabel('y')
  241. plt.title('Newton Polynomial Interpolation Test')
  242.  
  243. # Annotate each data point with its corresponding polynomial value
  244. for idx, (x, y) in enumerate(zip(x_test, y_test)):
  245.     plt.text(x, y, f'P{idx+1}: {coefficients_test[idx]:.4f}', fontsize=12, ha='right', va='bottom')
  246.  
  247. plt.legend()  # Show legend with labels
  248. plt.grid(True)
  249. plt.show()
  250.  
  251.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement