Przeczytaj
Wiemy już, że istnieją błędy przybliżeń, wśród których wyróżniamy błąd bezwzględnybłąd bezwzględny oraz błąd względnybłąd względny. W tym e‑materiale użyjemy języka Python do obliczenia i wizualizacji tych błędów.
Znając definicje błędów bezwzględnego oraz względnego, możemy napisać funkcje obliczające odpowiednie wartości. Przetestujemy je dla wartości zmierzonych: 225 i 250 oraz wartości dokładnej 242.
30from math import fabs
def blad_bezwzgledny(x, x0):
""" x - wartość dokładna
x0 - wartość zmierzona"""
return fabs(x-x0)
def blad_wzgledny(x, x0):
""" x - wartość dokładna
x0 - wartość zmierzona"""
d = blad_bezwzgledny(x,x0)
return d / x
def blad_wzgledny_proc(x, x0):
""" x - wartość dokładna
x0 - wartość zmierzona"""
d = blad_bezwzgledny(x,x0)
return round((d / x) * 100, 2)
# przykładowe wywołanie
print("Wartość błędu przybliżenia dla 250:", blad_bezwzgledny(242, 250))
print("Wartość błędu przybliżenia dla 225:", blad_bezwzgledny(242, 225))
print("Wartość błędu względnego dla 250:", blad_wzgledny(242, 250))
print("Wartość błędu względnego dla 225:", blad_wzgledny(242, 225))
print("Wartość błędu względnego procentowo dla 250:", blad_wzgledny_proc(242, 250))
print("Wartość błędu względnego procentowo dla 225:", blad_wzgledny_proc(242, 225))
Wynikiem wykonania kodu dla wartości zmierzonych 225 i 250 oraz wartości dokładnej 242 jest:
6Wartość błędu przybliżenia dla 250: 8.0
Wartość błędu przybliżenia dla 225: 17.0
Wartość błędu względnego dla 250: 0.03305785123966942
Wartość błędu względnego dla 225: 0.07024793388429752
Wartość błędu względnego procentowo dla 250: 3.31
Wartość błędu względnego procentowo dla 225: 7.02
Przeanalizujmy teraz sytuację, w której symulujemy „ręczne” obliczenie wartości za pomocą zaokrąglenia. Prześledźmy błąd bezwzględny oraz względny dla kolejnych zaokrągleń liczby pi.
W przykładzie mamy podaną wartość liczby pi z dokładnością do 42 miejsc po przecinku. W języku Python w module math
wartość liczby pi jest zapisana jako math.pi
z dostępną precyzją – w tym przypadku 3.141592653589793
. Będziemy obliczali błąd bezwzględny i względny oraz błąd względny wyrażony w procentach dla kolejnych przybliżeń: od dwóch miejsc po przecinku, czyli wartości 3.14
, do 15 miejsc po przecinku, a więc dokładnej wartości, kiedy błąd będzie wynosił 0. Sprawdzimy kilka obliczonych wartości.
Wartość dokładna to 3.141592653589793
Wartość zmierzona | Błąd względny | Błąd względny w procentach |
| 0.0005069573828972128 | 0.05069573828972128 |
| 2.0804409260601893e‑07 | 2.0804409260601892e‑05 |
| 3.1172263038059322e‑12 | 3.117226303805932e‑10 |
| 0.0 | 0.0 |
Napiszmy kod, który pozwoli zobrazować błąd w zależności od kolejnych zaokrągleń. Przygotujemy dwa wykresy w celu odpowiedniego doboru skali.
Bibliotekę matplotlib
omawialiśmy również w e‑materiale Modelowanie ruchów Browna w języku PythonModelowanie ruchów Browna w języku Python.
54# importujemy niezbędne funkcje i moduły
from math import fabs
import matplotlib.pyplot as plt
# definiujemy funkcje pomocnicze
def blad_bezwzgledny(x, x0):
""" x - wartość dokładna
x0 - wartość zmierzona"""
return fabs(x - x0)
def blad_wzgledny(x, x0):
""" x - wartość dokładna
x0 - wartość zmierzona"""
d = blad_bezwzgledny(x,x0)
return d / x
def blad_wzgledny_proc_dokladn(x, x0):
""" x - wartość dokładna
x0 - wartość zmierzona"""
d = blad_bezwzgledny(x,x0)
return (d / x) * 100 # tutaj zwaracamy dokładną wartość, bez zaokrąglenia
# wartości niezbędne dla obliczeń
pi = 3.141592653589793
wartosci = [x for x in range(2, 16)]
bl_bezw = []
bl_wzgl = []
bl_wzgp = []
# w pętli sprawdzamy coraz dokładniejsze przybliżenie wartości pi
# używamy funkcji round() - która zaokrągla wynik, dając wartość z błędem
for x in range(2, 16):
base = round(pi, x)
print("Obliczamy błąd przybliżenia dla wartości: ", base)
bl_bezw.append(blad_bezwzgledny(pi, base))
bl_wzgl.append(blad_wzgledny(pi, base))
bl_wzgp.append(blad_wzgledny_proc_dokladn(pi, base))
# pierwszy wykres
plt.plot(wartosci, bl_bezw, label = "Błąd bezwzględny")
plt.plot(wartosci, bl_wzgl, label = "Błąd względny")
plt.legend()
plt.title("Wartość bazowa pi = " + str(pi))
plt.grid(True)
plt.show()
# drugi wykres
plt.plot(wartosci, bl_wzgp, label = "Błąd względny procentowo")
plt.legend()
plt.title("Wartość bazowa pi = " + str(pi))
plt.grid(True)
plt.show()
Wykres pierwszy – błąd względny oraz bezwzględny wartościowo:

Wykres drugi – błąd względny procentowo:

Możemy zauważyć, że błąd przybliżenia (zarówno względny, jak i bezwzględny) zmienia się – maleje wraz ze wzrostem dokładności obserwowanej liczby.
Napiszmy kod, który pozwoli zaokrąglić liczbę pi do takiego momentu, dla którego błąd względny przekroczy 0,01 procenta – wówczas zatrzymamy kolejne zaokrąglenia.
63# importujemy niezbędne funkcje i moduły
from math import fabs
import matplotlib.pyplot as plt
# definiujemy funkcje pomocnicze
def blad_bezwzgledny(x, x0):
""" x - wartość dokładna
x0 - wartość zmierzona"""
return fabs(x - x0)
def blad_wzgledny(x, x0):
""" x - wartość dokładna
x0 - wartość zmierzona"""
d = blad_bezwzgledny(x, x0)
return d / x
def blad_wzgledny_proc_dokladn(x, x0):
""" x - wartość dokładna
x0 - wartość zmierzona"""
d = blad_bezwzgledny(x, x0)
return (d / x) * 100 # tutaj zwaracamy dokładną wartość, bez zaokrąglenia
pi = 3.141592653589793
bl_bezw = []
bl_wzgl = []
bl_wzgp = []
przyblizenia = []
ok = ""
for dokladnosc in range(15, 1, -1):
wartosc = round(pi, dokladnosc)
blad_wzgledny_v = blad_wzgledny(pi, wartosc)
blad_bezwzgledny_v = blad_bezwzgledny(pi, wartosc)
blad_proc = blad_wzgledny_proc_dokladn(pi, wartosc)
if blad_proc > 0.01:
break
else:
bl_bezw.append(blad_bezwzgledny_v)
bl_wzgl.append(blad_wzgledny_v)
bl_wzgp.append(blad_proc)
ok = str(wartosc)
przyblizenia.append(dokladnosc)
# przygotowujemy wartości X, bazując na długości listy przybliżeń
X = [ x for x in range(len(przyblizenia)) ]
# pierwszy wykres
plt.plot(X, bl_bezw, label = "Błąd bezwzględny")
plt.plot(X, bl_wzgl, label = "Błąd względny")
plt.legend()
plt.title("Wartość bazowa pi = " + str(pi) + ". Ostatni wynik w założonym błędzie = " + str(ok))
plt.grid(True)
plt.show()
# drugi wykres
plt.plot(X, bl_wzgp, label = "Błąd względny procentowo")
plt.legend()
plt.title("Wartość bazowa pi = " + str(pi) + ". Ostatni wynik w założonym błędzie = " + str(ok))
plt.grid(True)
plt.show()
Wykres pierwszy – błąd względny oraz bezwzględny wartościowo:

Wykres drugi – błąd względny procentowo:

W języku Python istnieje moduł o nazwie Decimal
. Zapewnia on obsługę arytmetyki zmiennoprzecinkowej i podaje dokładniejsze wyniki. Prześledźmy to na przykładzie dodawania do siebie dwóch wartości rzeczywistych: 0.1 + 0.2
. Z lekcji matematyki wiemy, że wynik powinien wynosić 0.3,
a jednak program w języku Python wyświetla następującą wartość:
2print(0.1+0.2)
# 0.30000000000000004
Wynik jest większy niż 0.3
- niewiele, ale jednak większy. Jest to związane ze sposobem, w jaki język Python przechowuje w pamięci liczby. Zobaczymy, jak wygląda ta sama sytuacja, kiedy użyjemy modułu Decimal
. Pamiętajmy, że liczby podajemy jako parametr typu str
.
5a = Decimal("0.1")
b = Decimal("0.2")
c = a + b
print(c)
# 0.3
Zauważmy, że wartości podane po wykorzystaniu modułu Decimal
są dokładniejsze.
10a = 0.1
b = 0.3
c = 3 * a -b
if c == 0:
print("Wynik poprawny = 0.")
else:
print("Wynik niepoprawny; wartość = ",c)
# Wynik niepoprawny; wartość = 5.551115123125783e-17
11from decimal import *
x = Decimal("0.1")
y = Decimal("0.3")
z = 3 * x - y
if z == 0:
print("Wynik poprawny = 0.")
else:
print("Wynik niepoprawny; wartość = ",z)
# Wynik poprawny = 0.
Dla komputera obliczenie 3 * 0.1 - 0.3
daje wynik 5.551115123125783e‑17
. Jest on bardzo bliski zeru, jednak nie jest to dokładnie zero. Natomiast zastosowanie do tego obliczenia modułu i typu danych Decimal
daje oczekiwany wynik.
Słownik
wyraża bezwzględną różnicę pomiędzy wartością zmierzoną a dokładną; obliczamy go zgodnie ze wzorem:
gdzie
informuje, o ile procent różni się wartość zmierzona od dokładnej; obliczamy go zgodnie ze wzorem:
gdzie