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 Lagrange'a

SPIS TREŚCI REMANENT
Podrozdziały
 

Algorytm

Opisana w poprzednim rozdziale interpolacja wielomianowa wymaga dosyć skomplikowanych obliczeń w celu wyznaczenia współczynników wielomianu. Istnieje jednak prostsza metoda, zwana interpolacją Lagrange'a. Jest to odmiana interpolacji wielomianowej i posiada ona wszystkie jej wady – na przykład efekt Rungego przy wielomianach wyższych stopni. Zaletą jest tu dużo prostszy sposób wyliczania wartości. Przyjrzyjmy się tej metodzie.

Mamy pewną funkcję f(x), dla której znamy NN węzłów (xi,yi), gdzie i = 0...NN - 1. Symbole xi i yi to współrzędne x i y i-tego węzła, a NN to liczba wszystkich węzłów:

Tworzymy tzw. funkcję przełączającą, o następującej własności:

Mianownik ułamków jest tak skonstruowany, że nigdy nie przyjmuje wartości 0 (jeśli węzły są różne), ponieważ (xi - xi) jest pomijane. Z kolei, jeśli x jest równe współrzędnej xi, to licznik i mianownik mają tę samą wartość, zatem ich iloraz jest równy 1 i cała funkcja przyjmuje wartość 1. Jeśli x przybiera wartość  współrzędnej węzła innego niż i-ty, to jedna z różnic w liczniku zawsze przyjmie wartość 0, przez co wartość całego iloczynu ułamków wyniesie 0. W pozostałych przypadkach funkcja może przyjmować dowolne wartości.

Wielomian interpolacyjny otrzymujemy z równania:

Zauważ, że w tym przypadku nie musimy rozwiązywać równań liniowych, co znacznie upraszcza procedurę. Sposób postępowania jest następujący:

Określamy liczbę węzłów NN i zapamiętujemy ich współrzędne. Do wyznaczenia interpolacji dla x wyliczamy wartość wielomianu interpolacyjnego Lagrange'a bezpośrednio na podstawie posiadanych węzłów.


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ędne y wg przepisu funkcji i dostaje współrzędne NN węzłów interpolacyjnych.  Następnie generuje N  pseudolosowych punktów z przedziału <XS;XE> i wylicza dla nich wartość wielomianu interpolacyjnego Lagrange'a na podstawie wzoru:

C++
// Interpolacja wielomianowa
// Lagrange'a
// (C)2026 mgr Jerzy Wałaszek
// Metody numeryczne 0075
//---------------------------

#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
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];

// 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 = 1; i < NN - 1; i++)
     nx[i] = XS + dx * i;
  nx[0] = XS;
  nx[NN - 1] = XE;

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

// Oblicza wartość wielomianu
// interpolacyjnego Lagrange'a
//----------------------------
double f_i(double x)
{
  // Wynik aproksymacji
  double r = 0.0;

  for(int i = 0; i < NN; i++)
  {
     // Obliczamy L(x)
     double L = 1.0;
     for(int j = 0; j < NN; j++)
     {
       if(i != j)
         L *= (x - nx[j]) /
              (nx[i] - nx[j]);
     }

     // Dodajemy L do wyniku
     r += L * ny[i];
  }

  return r;
}

// 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();

  cout << "Interpolacja wielomianowa "
          "Lagrange'a\n"
          "--------------------------"
          "----------\n\n";

  // Generujemy N punktów x,
  // liczymy dla nich y
  // przy pomocy wielomianu
  // Lagrange'a
  // 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 Lagrange'a
------------------------------------

x =  0.5912, f(x) =  0.5573, interpolacja f(x) =  0.5574
x = -1.3469, f(x) = -0.9750, interpolacja f(x) = -0.9748
x =  0.5035, f(x) =  0.4825, interpolacja f(x) =  0.4825
x = -0.4657, f(x) = -0.4490, interpolacja f(x) = -0.4490
x = -0.3717, f(x) = -0.3632, interpolacja f(x) = -0.3632
x = -1.4490, f(x) = -0.9926, interpolacja f(x) = -0.9924
x = -1.1086, f(x) = -0.8951, interpolacja f(x) = -0.8950
x = -1.1818, f(x) = -0.9253, interpolacja f(x) = -0.9251
x = -1.0468, f(x) = -0.8658, interpolacja f(x) = -0.8658
x =  1.5191, f(x) =  0.9987, interpolacja f(x) =  0.9985
Python (dodatek)
# Interpolacja wielomianowa
# Lagrange'a
# (C)2026 mgr Jerzy Wałaszek
# Metody numeryczne 0075
#---------------------------

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
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 = []

# 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
    nx.append(XS)
    dx = (XE - XS) / (NN - 1)
    for i in range(1,NN - 1):
        nx.append(XS + dx * i)
    nx.append(XE)

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

# Oblicza wartość wielomianu
# interpolacyjnego Lagrange'a
#----------------------------
def f_i(x):
    # Wynik aproksymacji
    r = 0.0

    for i in range(NN):
        # Obliczamy L(x)
        L = 1.0
        for j in range(NN):
            if i != j:
                L *= ((x - nx[j]) /
                   (nx[i] - nx[j]))

        # Dodajemy L do wyniku
        r += L * ny[i]

    return r

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

# Generujemy węzły aproksymacji
set_nodes()

print("Interpolacja wielomianowa "
      "Lagrange'a\n"
      "--------------------------"
      "----------\n")

# Generujemy N punktów x,
# liczymy dla nich y
# przy pomocy wielomianu
# Lagrange'a
# i wyświetlamy wynik
for _ 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.