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)!}$$

In [3]:
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()
No description has been provided for this image

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)

In [4]:
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

In [6]:
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.

In [8]:
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
In [9]:
0.7/0.1
Out[9]:
6.999999999999999
In [ ]: