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.

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.

  1 - ? = (?) - pierwsza różnica nieokreślona
  4 - 1 = 3
  9 - 4 = 5
16 - 9 = 7
...

Zwróć uwagę, iż z kwadratów zrobił nam się ciąg kolejnych liczb nieparzystych. Liczymy dalej:

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.

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

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:

v0 = (x0,y0) = (x0,f(x0))
v1 = (x1,y1) = (x1,f(x1))
v2 = (x2,y2) = (x2,f(x2))
v3 = (x3,y3) = (x3,f(x3))

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

Tworzymy ilorazy różnicowe rzędu 0:

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

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

(?) - 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:

Została nam ostatnia kolumna:

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

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

 


do podrozdziału  do strony 

Przykładowa implementacja

Program interpoluje funkcję:

 

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.