Pogreške u numeričkom računanju¶
Pogledajmo jedan zanimljiv primjer. Podsjetimo se da je Taylorov red za funkciju $\cos x$ $$\cos x=\sum_{n=0}^\infty (-1)^n\frac{x^{2n}}{(2n)!}$$
import math
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
def func_cos(x, n):
cos_approx = 0
for i in range(n):
coef = (-1)**i
num = x**(2*i)
denom = math.factorial(2*i)
cos_approx += ( coef ) * ( (num)/(denom) )
return cos_approx
angles = np.arange(-2*np.pi,2*np.pi,0.1)
p_cos = np.cos(angles)
fig, ax = plt.subplots()
ax.plot(angles,p_cos)
for i in range(1,6):
t_cos = [func_cos(angle,i) for angle in angles]
ax.plot(angles,t_cos)
ax.set_ylim([-7,4])
# set up legend
legend_lst = ['cos() function']
for i in range(1,6):
legend_lst.append(f'Taylor Series - {i} clanova reda')
ax.legend(legend_lst, loc=3)
plt.show()
Uočimo, što je veći stupanj polinoma to je funkcija $\cos x$ bolje aproksimirana polinomom.
Podsjetimo se da je Taylorov red za funkciju $\sin x$ $$\sin x=\sum_{n=0}^\infty (-1)^n\frac{x^{2n+1}}{(2n+1)!}$$ Sada ćemo implementirati jednostavnu funkciju kojom se računa vrijednost funkcije $\sin(x)$ uz pomoć reda. Uzet ćemo onoliko članova reda koji daju doprinos sumiranjem u računalu (vidi while petlju u donjem kodu)
import math
import numpy as np
def AprSin(x):
sin_approx = 0
t=x
a=abs(t)
n=1
while sin_approx+t!= sin_approx:
sin_approx=sin_approx+t
t=-(x**2)/((n+1)*(n+2))*t
a=max(a,abs(t))
n=n+2
print("n=", n)
print("t=",t)
print("Maksimalni član="f"{a:.2e}")
return sin_approx
Pogledajmo što dobivamo ako pomoću implementirane funkcije računamo vrijednosti $\sin x$ za $x=\frac{\pi}{2},\frac{11\pi}{2},\frac{21\pi}{2},\frac{31\pi}{2}.$ Ispisujemo maksimalni član reda, broj elemenata reda koji su uzeti u obzir u izračun, te posljednji član reda koji je uzet u obzir
print("sin(pi/2)=",AprSin(math.pi/2))
print("sin(11pi/2)=",AprSin(11*math.pi/2))
print("sin(21pi/2)=", AprSin(21*math.pi/2))
print("sin(31pi/2)=",AprSin(31*math.pi/2))
n= 23 t= -1.253899540535457e-18 Maksimalni član=1.57e+00 sin(pi/2)= 1.0000000000000002 n= 75 t= -2.623194179687491e-17 Maksimalni član=3.07e+06 sin(11pi/2)= -1.0000000002128728 n= 121 t= 6.46934878239496e-18 Maksimalni član=1.47e+13 sin(21pi/2)= 0.9998667640418495 n= 157 t= 7.333724294246771e-14 Maksimalni član=7.99e+19 sin(31pi/2)= -5822.01852702401
U gornjem ispisu možemo primijetiti da primjerice za $x=\frac{31\pi}{2}$ dobijemo vrijednost koja prilično odstupa od one koju smo očekivali. Primijetimo da se u računanju nekih vrijednosti zbarajaju brojevi različitog reda veličine, o čemu će biti govora kasnij eu ovoj Jupyter bilježnici.
U računalu se ne pohranjuju uvijek "točne" vrijednosti!¶
Razlog tome je prikaz realnih brojeva u računalu. U računalu možemo prikazati samo konačno mnogo realnih brojeva. Dakle prikaziv je samo određeni raspon brojeva i fp-brojeva koji su aproksimacija određenog realnog broja ima konačno mnogo.
a=4./3
print("a=",a)
b=a-1.0
print("b=",b)
c=3*b
print("c=",c)
d=1.0-c
print("d=", d)
a= 1.3333333333333333 b= 0.33333333333333326 c= 0.9999999999999998 d= 2.220446049250313e-16
0.7/0.1
6.999999999999999