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

Metoda Simpsona

SPIS TREŚCI
Podrozdziały

Algorytm całkowania metodą Simpsona

 
obrazek

Metoda Simpsona jest najdokładniejszą z opisanych tutaj metod przybliżonego całkowania. W metodzie prostokątów całka oznaczona przybliżana była funkcjami stałymi - liczyliśmy sumę pól prostokątów. W metodzie trapezów całkę przybliżaliśmy za pomocą funkcji liniowych - obliczaliśmy sumy pól trapezów. W metodzie Simpsona stosujemy jako przybliżenie parabolę - będziemy obliczali sumy wycinków obszarów pod parabolą. Zasada jest następująca:

Przedział całkowania <xp, xk> dzielimy na n + 1 równo odległych punktów xo, x1, x2 ,..., xn:

dla i = 0,1,2,...,n
obrazek

Dla każdych dwóch sąsiednich punktów wyznaczamy punkt środkowy ti wg wzoru:

dla i = 1,2,...,n

Obliczamy odległość między dwoma sąsiednimi punktami.

obrazek

Dla każdego wyznaczonego w ten sposób punktu obliczamy wartość funkcji f(x) w tym punkcie:

punkty podziałowe
dla i = 0,1,2,...,n
fi = f(xi)
punkty środkowe
dla i = 1,2,...,n
fti = f(ti)

W każdym podprzedziale <xi - 1, xi> przybliżamy funkcję za pomocą paraboli g(x) o następującej postaci:

dla i = 1,2,...,n

Parabola gi(x) musi przechodzić przez punkty: (xi-1, fi - 1), (ti, fti), (xi, fi). Współczynniki ai, bi i ci wyznaczymy zatem z układu trzech równań:

dla i = 1,2,...,n

Uwaga:

W metodzie Simpsona chodzi o wyznaczenia pola pod parabolą w danym podprzedziale, a nie jej współczynników. Możemy zatem pójść inną drogą. Załóżmy, iż powyższe współczynniki są znane (ostatecznie możemy je przecież wyliczyć).

Pole pod parabolą w przedziale <xi - 1, xi> będzie równe całce oznaczonej:

dla i = 1,2,...,n

Funkcja pierwotna jest bardzo prosta w tym przypadku i ma wzór następujący:

dla i = 1,2,...,n

Wartość całki obliczymy zgodnie z definicją Newtona-Leibniza:

dla i = 1,2,...,n

Teraz postaramy się uprościć maksymalnie otrzymane wyrażenie. W tym celu wyciągamy przed nawias wspólny czynnik i całość dzielimy przez 6:

dla i = 1,2,...,n

Zwróćcie uwagę, iż wyrażenia w nawiasach są odpowiednio wartościami funkcji fi -1, fi oraz fti. Natomiast różnica

jest odległością dx pomiędzy dwoma sąsiednimi punktami podziałowymi. Zatem po uproszczeniu otrzymujemy ostateczny wzór:

dla i = 1,2,...,n

Wzór ten pozwala wyliczyć pole obszaru pod parabolą aproksymującą funkcję f(x) w przedziale <xi - 1, xi>. Wartość całej całki otrzymamy sumując te pola, czyli:

Jest to wzór wyliczania przybliżonej wartości całki oznaczonej za pomocą metody Simpsona. Ponieważ w obliczanych sumach wartości funkcji się powtarzają dwukrotnie (z wyjątkiem pierwszej i ostatniej), do obliczeń komputerowych stosujemy efektywniejszy wzór otrzymywania powyższej sumy:

 


do podrozdziału  do strony 

Opis algorytmu

Specyfikacja problemu

Dane wejściowe

xp - początek przedziału całkowania, xp ∈ R
xk - koniec przedziału całkowania, xk ∈ R
n - liczba punktów podziałowych, n ∈ N
f(x) - funkcja rzeczywista, której całkę liczymy

Dane wyjściowe

s - przybliżona wartość całki oznaczonej funkcji f(x) w przedziale <xp, xk>, s ∈ R

Zmienne pomocnicze

st - suma wartości funkcji w punktach środkowych, st ∈ R
dx - odległość między dwoma sąsiednimi punktami podziałowymi, dx ∈ R
x - pozycja punktu podziałowego, x ∈ R
i - licznik punktów podziałowych, i ∈ N

Lista kroków

K01: s ← 0; st ← 0
K02:
K03: Dla i = 1,2,...,n:
    wykonuj kroki K04...K06
K04:     x ← xp +  i  ·dx
K05:    
K06:     Jeśli i < n,
    to s ← s +  f(x)
K07:
K08: Zakończ

Schemat blokowy

obrazek

Odczytujemy krańce przedziału całkowania <xp ,xk>. Do obliczenia całki metodą Simpsona musimy zliczyć dwie sumy -  wartości funkcji w punktach podziałowych xi oraz wartości funkcji w punktach środkowych przedziałów ti. Pierwszą sumę będziemy obliczać w zmiennej s, drugą w st. Obie na początku przyjmują wartość 0. Wyznaczamy dalej odległość pomiędzy dwoma sąsiednimi punktami podziałowymi dx i rozpoczynamy pętlę, w której zmienna i pełni rolę numeru punktu podziałowego i środkowego. Pętla ta wykonuje się n-razy od i = 1 do i = n włącznie, czyli jest to zwykła pętla iteracyjna typu FOR.

W pętli wyznaczamy wartość punktu podziałowego xi i umieszczamy ją w zmiennej x. Następnie obliczamy wartość funkcji w punkcie środkowym ti, który jest odległy o połowę dx od wyznaczonego wcześniej punktu xi. Wartość tę dodajemy do sumy st.

Drugą sumę tworzymy w zmiennej s. Jednakże powinna ona zawierać jedynie wartości funkcji dla punktów podziałowych od x1 do xn - 1. Dlatego przed sumowaniem sprawdzamy, czy indeks i jest w odpowiednim zakresie.

Po zakończeniu pętli wyznaczamy wartość całki w zmiennej s zgodnie z podanym wzorem, wyprowadzamy ten wynik dla użytkownika i kończymy wykonywanie algorytmu.


do podrozdziału  do strony 

Przykładowe programy

W celu zobrazowania dokładności metody Simpsona zmniejszyliśmy w naszych przykładach liczbę punktów podziałowych do n = 10. Wynik obliczenia całki jest niezmieniony w stosunku do metod prostokątów i trapezów. Zachęcamy do eksperymentów z liczbą N.

C++
// Obliczanie całki oznaczonej
// metodą Simpsona
// ---------------------------
//(C)2004 mgr Jerzy Wałaszek

#include <iomanip>
#include <iostream>
#include <cstdlib>

using namespace std;

// Tutaj definiujemy funkcję
double f(double x)
{
  return(x * x + 2 * x);
}

// Program główny
int main()
{
  //liczba punktów podziałowych
  const int N = 10;
  double xp,xk,s,st,dx,x;
  int i;

  // 3 cyfry po przecinku
  cout << setprecision(3)
  // format stałoprzecinkowy
       << fixed;

  cout << "Obliczanie calki oznaczonej\n"
          " za pomoca metody Simpsona\n"
          "---------------------------\n"
          "(C)2004 mgr J.Walaszek  I LO\n\n"
          "f(x) = x * x + 2 * x\n\n"
          "Poczatek przedzialu calkowania\n\n"
          "xp = ";
  cin >> xp;
  cout << "\nKoniec przedzialu calkowania\n\n"
          "xk = ";
  cin >> xk;
  cout << endl;
  s  = 0; st = 0;
  dx = (xk - xp) / N;
  for(i = 1; i <= N; i++)
  {
    x = xp + i * dx;
    st += f(x - dx / 2);
    if(i < N) s += f(x);
  }
  s = dx / 6 * (f(xp) + f(xk) + 2 * s + 4 * st);
  cout << "Wartosc calki wynosi : "
       << s
       << endl << endl;
  system("pause");
  return 0;
}
Pascal
// Obliczanie całki oznaczonej
// metodą Simpsona
// ---------------------------
// (C)2004 mgr Jerzy Wałaszek

program int_simpson;

// Tutaj definiujemy funkcję
function f(x : double) : double;
begin
  f := x * x + 2 * x;
end;

// Program główny

// liczba punktów podziałowych
const N = 10;

var
  xp,xk,s,st,dx,x : double;
  i : integer;

begin
  writeln('Obliczanie calki oznaczonej');
  writeln(' za pomoca metody Simpsona');
  writeln('---------------------------');
  writeln('(C)2004 mgr J.Walaszek I LO');
  writeln;
  writeln('f(x) = x * x + 2 * x');
  writeln;
  writeln('Poczatek przedzialu calkowania');
  writeln;
  write('xp = '); readln(xp);
  writeln;
  writeln('Koniec przedzialu calkowania');
  writeln;
  write('xk = '); readln(xk);
  writeln;
  s  := 0; st := 0;
  dx := (xk - xp) / N;
  for i := 1 to N do
  begin
    x  := xp + i * dx;
    st := st + f(x - dx / 2);
    if i < N then s := s + f(x);
  end;
  s := dx / 6 * (f(xp) + f(xk) + 2 * s + 4 * st);
  writeln('Wartosc calki wynosi : ',s:0:3);
  writeln;
  writeln('Nacisnij klawisz Enter...');
  readln;
end.
Basic
' Obliczanie całki oznaczonej
' metodą Simpsona 
' ---------------------------
' (C)2004 mgr Jerzy Wałaszek

Declare Function f(x As Double) _
                     As Double

' Program główny

' liczba punktów podziałowych
const N = 10

Dim As Double xp,xk,s,st,x,dx
Dim As Integer i

Print "Obliczanie  calki oznaczonej"
Print " za pomoca  metody Simpsona"
Print "----------------------------"
Print "(C)2004 mgr J.Walaszek  I LO"
Print
Print "f(x) = x * x + 2 * x"
Print
Print "Poczatek przedzialu calkowania"
Print
input "xp = ", xp
Print
Print "Koniec przedzialu calkowania"
Print
Input "xk = ", xk
Print
s  = 0: st = 0
dx = (xk - xp) / N
for i = 1 to N
  x  = xp + i * dx
  st += f(x - dx / 2)
  if i < N then s += f(x)
Next
s = dx / 6 * _
    (f(xp) + f(xk) + 2 * s + 4 * st)
print Using _
      "Wartosc calki wynosi : ####.###";s
Print
Print "Nacisnij klawisz Enter..."
Sleep
End

' Tutaj definiujemy funkcję
function f(x as Double) As Double
  f = x * x + 2 * x
End Function
Python (dodatek)
# Obliczanie całki oznaczonej
# metodą Simpsona 
# ---------------------------
# (C)2026 mgr Jerzy Wałaszek

# Tutaj definiujemy funkcję
def f(x):
    return x * x + 2 * x

# Program główny

# liczba punktów podziałowych
n = 10

print("Obliczanie  całki oznaczonej")
print(" za pomocą  metody Simpsona")
print("----------------------------")
print("(C)2026 mgr J.Wałaszek  I LO")
print()
print("f(x) = x * x + 2 * x")
print()
print("Początek przedziału całkowania")
print()
xp = float(input("xp = "))
print()
print("Koniec przedziału całkowania")
print()
xk = float(input("xk = "))
print()
s  = 0
st = 0
dx = (xk - xp) / n
for i in range(1, n + 1):
    x  = xp + i * dx
    st += f(x - dx / 2)
    if i < n: s += f(x)
s = dx / 6 * \
    (f(xp) + f(xk) + 2 * s + 4 * st)
print("Wartość całki wynosi : ",end="")
print("%.3f" % s)
print()
input("Naciśnij Enter...")
Wynik:
Obliczanie  całki oznaczonej
 za pomocą  metody Simpsona
----------------------------
(C)2026 mgr J.Wałaszek  I LO

f(x) = x * x + 2 * x

Początek przedziału całkowania

xp = 0

Koniec przedziału całkowania

xk = 1

Wartość całki wynosi : 1.333

Naciśnij Enter...
JavaScript
<html>
<head>
  <title>Całkowanie numeryczne metodą Simpsona</title>
</head>
<body>
<script language="JavaScript">

//*************************************************
//** Obliczanie całki oznaczonej metodą Simpsona **
//** ------------------------------------------- **
//**  (C)2004 mgr Jerzy Wałaszek I LO w Tarnowie **
//*************************************************

//*******************************
//** Tutaj definiujemy funkcję **
//*******************************

function f(x)
{
  return(x * x + 2 * x);
}

function js_simpson()
{
  var N = 10; //liczba punktów podziałowych
  var xp,xk,s,st,dx,x,i,t;

  xp = parseFloat(document.frm_simpson.xp_inp.value);
  xk = parseFloat(document.frm_simpson.xk_inp.value);
  if(isNaN(xp) || isNaN(xk))
    t = "<font color=red><b>Popraw dane wejściowe!</b></font>";
  else
  {
    s  = 0; st = 0;
    dx = (xk - xp) / N;
    for(i = 1; i <= N; i++)
    {
      x = xp + i * dx;
      st += f(x - dx / 2);
      if(i < N) s += f(x);
    };
    s = dx / 6 * (f(xp) + f(xk) + 2 * s + 4 * st);
    t = Math.floor(s * 1000) / 1000;
  };
  document.getElementById("t_out").innerHTML = t;
}

</script>

<form method="POST"
      name="frm_simpson"
      style="border: 2px solid #FF9900;
             padding-left: 4px;
             padding-right: 4px;
             padding-top: 1px;
             padding-bottom: 1px;
             background-color: #FFFFCC">
  <h2 style="text-align: center">
    Obliczanie całki oznaczonej<br>
    za pomocą metody Simpsona
  </h2>
  <hr>
  <p style="text-align: center">
    (C)2004 mgr Jerzy Wałaszek I LO w Tarnowie
  </p>
  <p style="text-align: center">
    Całkowana funkcja:
  </p>
  <p style="text-align: center">
    <i>f(x) = x<sup>2</sup> + 2x</i>
  </p>
  <p style="text-align: center">
    Tutaj określ przedział całkowania
  </p>
  <p style="text-align: center">
    Początek <i>x<sub>p</sub></i> =
    <input type="text" name="xp_inp" size="20" value="0">
    i koniec <i>x<sub>k</sub> </i>=
    <input type="text" name="xk_inp" size="20" value="1">
  </p>
  <p style="text-align: center">
    <input onclick="js_simpson();" type="button"
           value="Oblicz całkę" name="B1">
  </p>
  <p style="text-align: center">
    Wartość całki wynosi
  </p>
  <p id="t_out" style="text-align: center">...</p>
</form>
</body>
</html>

Obliczanie całki oznaczonej
za pomocą metody Simpsona


(C)2004 mgr Jerzy Wałaszek I LO w Tarnowie

Całkowana funkcja:

f(x) = x2 + 2x

Tutaj określ przedział całkowania

Początek xp =
    koniec xk =

Wartość całki wynosi

...


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.