Serwis Edukacyjny
w I-LO w Tarnowie
obrazek

Materiały dla uczniów liceum

  Wyjście       Spis treści       Wstecz       Dalej  

obrazek

Autor artykułu: mgr Jerzy Wałaszek

©2026 mgr Jerzy Wałaszek

obrazek

Interpolacja

Interpolacja Newtona

SPIS TREŚCI REMANENT
Podrozdziały
 

Algorytm

Interpolacja Newtona jest kolejną z metod interpolacji wielomianowej. Polega ona na tworzeniu wielomianu, który przechodzi przez wszystkie węzły interpolacji. Przy budowie tego wielomianu interpolacja Newtona wykorzystuje rekurencję i tzw. różnice dzielone, które tworzą proces rekursywnego dzielenia. Różnice dzielone wykorzystywano dawniej do wyliczania tablic logarytmów i funkcji trygonometrycznych. Algorytm różnic dzielonych zastosował Charles Babage (zwany Ojcem Komputerów) w swojej maszynie różnicowej w roku 1822:

Maszyna Różnicowa Charlesa Babbage'a

W algorytmie interpolacji Newtona wykorzystywane są tzw. ilorazy różnicowe tworzone rekurencyjnie. Na prostym przypadku zobaczmy, jaka jest idea tworzenia różnic. Utwórzmy tabelę, w której pierwszej kolumnie znajdują się kwadraty kolejnych liczb naturalnych. Kolumnę nazwijmy różnicami stopnia 0, r0.

\[\begin{array}{rrrrr}
r_0 & & & & \\
1 & . & . & . & . \\
4 & . & . & . & . \\
9 & . & . & . & . \\
16 & . & . & . & . \\
25 & . & . & . & . \\
36 & . & . & . & . \\
49 & . & . & . & . \\
64 & . & . & . & .
\end{array}\]

Następna kolumna powstaje z różnic wyrazów kolumny poprzedniej: od wyrazu leżącego w tym samym wierszu w sąsiedniej kolumnie odejmujemy wyraz leżący nad nim.

\[\begin{aligned}
&1 - ? = (?) \\
&4 - 1 = 3 \\
&9 - 4 = 5 \\
&16 - 9 = 7 \\
&... \\
&\begin{array}{rrrrr}
r_0 & r_1 & & & \\
1 & (?) & . & . & . \\
4 & 3 & . & . & . \\
9 & 5 & . & . & . \\
16 & 7 & . & . & . \\
25 & 9 & . & . & . \\
36 & 11 & . & . & . \\
49 & 13 & . & . & . \\
64 & 15 & . & . & .
\end{array}
\end{aligned}\]

(?) oznacza wartość nieokreśloną (pomyśl dlaczego?). Zwróć uwagę, iż z kwadratów zrobił nam się ciąg kolejnych liczb nieparzystych. Liczymy dalej:

\[\begin{array}{rrrrr}
r_0 & r_1 & r_2 & & \\
1 & (?) & (?) & . & . \\
4 & 3 & (?) & . & . \\
9 & 5 & 2 & . & . \\
16 & 7 & 2 & . & . \\
25 & 9 & 2 & . & . \\
36 & 11 & 2 & . & . \\
49 & 13 & 2 & . & . \\
64 & 15 & 2 & . & .
\end{array}\]

Różnice stopnia drugiego to wartość stała, równa 2 (bo różnica dwóch kolejnych liczb nieparzystych zawsze jest równa 2). Dwie pierwsze wartości są nieokreślone, bo dla nich nie da się policzyć różnic.

\[\begin{array}{rrrrr}
r_0 & r_1 & r_2 & r_3 & \\
1 & (?) & (?) & (?) & . \\
4 & 3 & (?) & (?) & . \\
9 & 5 & 2 & (?) & . \\
16 & 7 & 2 & 0 & . \\
25 & 9 & 2 & 0 & . \\
36 & 11 & 2 & 0 & . \\
49 & 13 & 2 & 0 & . \\
64 & 15 & 2 & 0 & .
\end{array}\]

Różnice stopnia trzeciego są zerowe. Dalej nie ma już potrzeby liczyć, bo otrzymamy tylko same zera.

\[\begin{array}{rrrrr}
r_0 & r_1 & r_2 & r_3 & r_4 \\
1 & (?) & (?) & (?) & (?) \\
4 & 3 & (?) & (?) & (?) \\
9 & 5 & 2 & (?) & (?) \\
16 & 7 & 2 & 0 & (?) \\
25 & 9 & 2 & 0 & 0 \\
36 & 11 & 2 & 0 & 0 \\
49 & 13 & 2 & 0 & 0 \\
64 & 15 & 2 & 0 & 0
\end{array}\]

Gdy znamy już ideę tablicowania różnic, możemy wrócić do interpolacji Newtona. Wykorzystuje ona tzw. ilorazy różnicowe. Prześledźmy sposób postępowania. W przedziale interpolacyjnym mamy cztery węzły interpolacyjne (muszą być różne, inaczej otrzymamy dzielenie przez 0) o współrzędnych:

\[\begin{aligned}
&v_0 = (x_0, y_0) = (x_0, f(x_0)) \\
&v_1 = (x_1, y_1) = (x_1, f(x_1)) \\
&v_2 = (x_2, y_2) = (x_2, f(x_2)) \\
&v_3 = (x_3, y_3) = (x_3, f(x_3))
\end{aligned}\]

Węzły powinny być równomiernie rozłożone.

Tworzymy ilorazy różnicowe rzędu 0:

\[\begin{array}{rrrr}
r_0 & & & \\
f[x_0] & . & . & . \\
f[x_1] & . & . & . \\
f[x_2] & . & . & . \\
f[x_3] & . & . & .
\end{array}\]

Wartość ilorazu różnicowego rzędu 0 f[xi], to po prostu wartość współrzędnej yi węzła vi:

\[f[x_i] = y_i\]

Iloraz różnicowy rzędu 1 powstaje jako różnica ilorazów różnicowych stopnia 0 podzielonych przez różnicę współrzędnych x:

\[\begin{aligned}
&\begin{array}{rrrr}
r_0 & r_1 & & \\
f[x_0] & (?) & . & . \\
f[x_1] & f[x_0, x_1] & . & . \\
f[x_2] & f[x_1, x_2] & . & . \\
f[x_3] & f[x_2, x_3] & . & .
\end{array} \\
&f[x_i, x_{i + 1}] = \dfrac{f[x_{i + 1}] - f[x_i]}{x_{i + 1} - x_i} \\
&f[x_i, x_{i + 1}] = \dfrac{y_{i + 1} - y_i}{x_{i + 1} - x_i}
\end{aligned}\]

(?) - tego nie liczymy, bo nie da się utworzyć ilorazu różnicowego.

Liczymy ilorazy różnicowe stopnia 2. Powstają one identycznie, jak ilorazy różnicowe stopnia 1:

\[\begin{aligned}
&\begin{array}{rrrr}
r_0 & r_1 & r_2 & \\
f[x_0] & (?) & (?) & . \\
f[x_1] & f[x_0, x_1] & (?) & . \\
f[x_2] & f[x_1, x_2] & f[x_0, x_1, x_2] & . \\
f[x_3] & f[x_2, x_3] & f[x_1, x_2, x_3] & .
\end{array} \\
&f[x_i, x_{i + 1}, x_{i + 2}] = \dfrac{f[x_{i + 1}, x_{i + 2}] - f[x_i, x_{i + 1}]}{x_{i + 2} - x_i} \\
&f[x_i, x_{i + 1}, x_{i + 2}] = \dfrac{\dfrac{y_{i + 2} - y_{i + 1}}{x_{i + 2} - x_{i + 1}} - \dfrac{y_{i + 1} - y_i}{x_{i + 1} - x_i}}{x_{i + 2} - x_i}
\end{aligned}\]

Została nam ostatnia kolumna:

\[\begin{aligned}
&\begin{array}{cccc}
r_0 & r_1 & r_2 & r_3 \\
f[x_0] & (?) & (?) & (?) \\
f[x_1] & f[x_0,x_1] & (?) & (?) \\
f[x_2] & f[x_1,x_2] & f[x_0,x_1,x_2] & (?) \\
f[x_3] & f[x_2,x_3] & f[x_1,x_2,x_3] & f[x_0,x_1,x_2,x_3]
\end{array} \\\\
&f[x_i,x_{i+1},x_{i+2},x_{i+3}] = \frac{f[x_{i+1},x_{i+2},x_{i+3}] - f[x_i,x_{i+1},x_{i+2}]}{x_{i+3} - x_i}
\end{aligned}\]

Elementy przekątnej są współczynnikami wielomianu interpolacyjnego Newtona.

\[\begin{array}{cccc}
r_0 & r_1 & r_2 & r_3 \\
\color{red}{a_0 = f[x_0]} & (?) & (?) & (?) \\
f[x_1] & \color{red}{a_1 = f[x_0, x_1]} & (?) & (?) \\
f[x_2] & f[x_1, x_2] & \color{red}{a_2 = f[x_0, x_1, x_2]} & (?) \\
f[x_3] & f[x_2, x_3] & f[x_1, x_2, x_3] & \color{red}{a_3 = f[x_0, x_1, x_2, x_3]}
\end{array}\]

Dla czterech węzłów wielomian interpolacyjny Newtona ma postać:

\[W_3 (x) = a_0 + a_1 (x - x_0) + a_2 (x - x_0) (x - x_1) + a_3 (x - x_0) (x - x_1) (x - x_2)\]

 


do podrozdziału  do strony 

Przykładowa implementacja

Program interpoluje funkcję:

  \[y = \sin(x); x \in \left\langle -\dfrac{\pi}{2}; \dfrac{\pi}{2} \right\rangle\]

Przedział <-π/2;π/2>. W przedziale program generuje NN równoodległych współrzędnych x, wylicza dla nich współrzędną y wg przepisu funkcji i dostaje współrzędne NN węzłów interpolacyjnych. Na ich podstawie wyznacza współczynniki wielomianu interpolacyjnego Newtona. Następnie generuje N pseudolosowych punktów w przedziale <XP;XE> i   przy pomocy wielomianu interpolacyjnego Newtona wylicza wartości współrzędnych y tych punktów, po czym wyświetla wyniki.

C++
// Interpolacja wielomianowa
// Newtona
// (C)2026 mgr Jerzy Wałaszek
// Metody numeryczne 0076
//---------------------------

#include <iostream>
#include <windows.h>
#include <iomanip>
#define _USE_MATH_DEFINES
#include <cmath>
#include <cstdlib>
#include <ctime>

using namespace std;

// STAŁE
//------

// Przedział interpolacji
// od XS do XE
const double XS = -M_PI / 2;
const double XE =  M_PI / 2;
// liczba węzłów interpolacji
const int NN = 6;
// Liczba interpolowanych
// punktów
const int N = 10;

// Tablice
//--------

// Współrzędne x węzłów
double nx[NN];
// Współrzędne y węzłów
double ny[NN];
// Współczynniki wielomianu
double a[NN];

// Funkcje
//--------

// Funkcja interpolowana
//----------------------
double f(double x)
{
  return sin(x);
}

// Funkcja zwraca wartość
// pseudolosową w przedziale
// <0,1)
//--------------------------
double random()
{
  return rand() /
         ((double)RAND_MAX + 1);
}

// Funkcja wyznacza węzły
// dla wielomianu
//-----------------------
void set_nodes()
{
  // Wyznaczamy NN węzłów
  // w równych odległościach
  int i;
  double dx = (XE - XS) / (NN - 1);
  for(i = 0; i < NN; i++)
     nx[i] = XS + dx * i;

  // Dla współrzędnych x
  // liczymy współrzędne y
  for(i = 0; i < NN; i++)
    ny[i] = f(nx[i]);
}

// Oblicza wartość
// interpolowaną za pomocą
// schematu Hornera
//------------------------
double f_i(double x)
{
  int i;
  double r = a[NN-1];
  for(i = NN - 2; i >= 0; i--)
    r = r * (x - nx[i]) + a[i];
  return r;
}

// Wylicza współczynniki wielomianu
// interpolacyjnego Newtona
//---------------------------------
void set_a()
{
  int i, j;

  // Kopiujemy wartości początkowe
  // do tablicy współczynników
  for(i = 0; i < NN; i++)
    a[i] = ny[i];

  // Liczymy w miejscu od końca
  for(j = 1; j < NN; j++)
    for(i = NN - 1; i >= j; i--)
      a[i] = (a[i] - a[i-1]) /
             (nx[i] - nx[i-j]);
}

// Program główny
//---------------
int main()
{
  int i;

  SetConsoleOutputCP(CP_UTF8);
  SetConsoleCP(CP_UTF8);

  cout << setprecision(4)
       << fixed;

  // Inicjujemy generator
  // pseudolosowy
  srand(time(nullptr));

  // Generujemy węzły
  set_nodes();

  // Obliczamy współczynniki
  // wielomianu Newtona
  set_a();

  cout << "Interpolacja wielomianowa "
          "Newtona\n"
          "--------------------------"
          "-------\n\n";

  // Generujemy N punktów x
  // i liczymy dla nich y
  // przy pomocy wielomianu
  // Newtona
  // i wyświetlamy wynik
  double x,y;
  for(i = 0; i < N; i++)
  {
    x = XS + random() * (XE - XS);
    y = f_i(x);
    cout << "x = "
         << setw(7) << x
         << ", f(x) = "
         << setw(7) << f(x)
         << ", interpolacja f(x) = "
         << setw(7) << y
         << endl;
  }

  cout << endl;
  system("pause");
  return 0;
}
Wynik:
Interpolacja wielomianowa Newtona
---------------------------------

x = -1.5117, f(x) = -0.9983, interpolacja f(x) = -0.9981
x =  1.2545, f(x) =  0.9504, interpolacja f(x) =  0.9502
x = -0.6943, f(x) = -0.6399, interpolacja f(x) = -0.6399
x = -0.0012, f(x) = -0.0012, interpolacja f(x) = -0.0012
x =  1.5358, f(x) =  0.9994, interpolacja f(x) =  0.9993
x =  1.1873, f(x) =  0.9274, interpolacja f(x) =  0.9272
x = -0.9111, f(x) = -0.7902, interpolacja f(x) = -0.7902
x =  0.0206, f(x) =  0.0206, interpolacja f(x) =  0.0206
x = -0.4180, f(x) = -0.4059, interpolacja f(x) = -0.4060
x = -1.0989, f(x) = -0.8907, interpolacja f(x) = -0.8906
Python (dodatek)
# Interpolacja wielomianowa
# Newtona
# (C)2026 mgr Jerzy Wałaszek
# Metody numeryczne 0076
#---------------------------

from math import sin, pi
from random import uniform

# STAŁE
#------

# Przedział interpolacji
# od XS do XE
XS = -pi / 2
XE =  pi / 2
# liczba węzłów interpolacji
NN = 6
# Liczba interpolowanych
# punktów
N = 10

# Tablice
#--------

# Współrzędne x węzłów
nx = []
# Współrzędne y węzłów
ny = []
# Współczynniki wielomianu
a = []

# Funkcje
#--------

# Funkcja interpolowana
#----------------------
def f(x):
    return sin(x)

# Funkcja wyznacza węzły
# dla wielomianu
#-----------------------
def set_nodes():
    # Wyznaczamy NN węzłów
    # w równych odległościach
    dx = (XE - XS) / (NN - 1)
    for i in range(NN):
         nx.append(XS + dx * i)

    # Dla współrzędnych x
    # liczymy współrzędne y
    for i in nx:
        ny.append(f(i))

# Oblicza wartość
# interpolowaną za pomocą
# schematu Hornera
#------------------------
def f_i(x):
    r = a[NN-1]
    for i in reversed(range(NN - 1)):
        r = r * (x - nx[i]) + a[i]
    return r

# Wylicza współczynniki wielomianu
# interpolacyjnego Newtona
#---------------------------------
def set_a():
    # Kopiujemy wartości początkowe
    # do tablicy współczynników
    for i in ny:
        a.append(i)

    # Liczymy w miejscu od końca
    for j in range(1,NN):
        for i in reversed(range(j,NN)):
            a[i] = ((a[i] - a[i-1]) /
                    (nx[i] - nx[i-j]))

# Program główny
#---------------

# Generujemy węzły
set_nodes()

# Obliczamy współczynniki
# wielomianu Newtona
set_a()

print("Interpolacja wielomianowa "
      "Newtona\n"
      "--------------------------"
      "-------\n")

# Generujemy N punktów x
# i liczymy dla nich y
# przy pomocy wielomianu
# Newtona
# i wyświetlamy wynik
for i in range(N):
    x = uniform(XS,XE)
    y = f_i(x)
    print(f"x = {x:7.4f}"
          f", f(x) = {f(x):7.4f}"
          f", interpolacja f(x) = "
          f"{y:7.4f}")

print()
input("Naciśnij Enter...")

do podrozdziału  do strony 

Zespół Przedmiotowy
Chemii-Fizyki-Informatyki

w I Liceum Ogólnokształcącym
im. Kazimierza Brodzińskiego
w Tarnowie
ul. Piłsudskiego 4
©2026 mgr Jerzy Wałaszek

Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone pod warunkiem podania źródła oraz niepobierania za to pieniędzy.
Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.

Informacje dodatkowe.