Vectoren: Vectorrekening in Python
Rekenen met vectoren
Optelling, scalaire vermenigvuldiging en lineaire combinatie Je kunt vectoren optellen, met een scalar vermenigvuldigen en combineren. Dit gaat op de manier die je zou mogen verwachten. Het enige opmerkelijke aan optelling, maar wat wel een prettige bijkomstigheid blijkt te zijn, is dat je ook een getal bij een vector mag optellen of aftrekken en dat dit dan als een vector van geschikte lengte met alleen maar dat gegeven getal wordt opgevat zodat de optelling betekenis heeft.
>>> u = np.array([1,2]); v = np.array([3,4])
>>> u+v
array([4, 6])
>>> 5*u
array([ 5, 10])
>>> 5*u-2*v
array([-1, 2])
>>> u+1
array([2, 3])
Vermenigvuldiging, inproduct, uitproduct en Hadamard product Tot nu toe zijn we het inproduct, het uitproduct en het Hadamard product tegengekomen. Python faciliteert deze berekeningen:
>>> u = np.array([1,2,3]); v = np.array([4,5,6])
>>> np.dot(u,v) # inproduct van vectoren
32
>>> u.dot(v) # alternatief
32
>>> np.cross(u,v) # uitproduct
array([-3, 6, -3])
>> u * v # Hadamard product
array([ 4, 10, 18])
Rekenkundige bewerkingen Met het vermenigvuldigingsteken *
geef je aan dat je vermenigvuldiging componentsgewijs wilt toepassen. Dit kan je ook met andere rekenkundige operatoren doen zoals deling en machtsverheffing. Op deze manier kun je ook snel vectoren construeren die gedefinieerd zijn door indexeringsfuncties of eenvoudig grafieken van functies maken. We geven wat voorbeelden ter illustratie
>>> u = np.array([3,4]); v = np.array([5,6])
>>> u / v
array([0.6 , 0.66666667])
>>> u**2
array([ 9, 16], dtype=int32)
>>> u*u
array([ 9, 16])
>>> np.sqrt(np.sum(u*u)) # berekening van de Euclidische norm van u
5.0
>>> i = np.arange(1,6); v = 1/(i+1); v # v_i = 1/(i+1)
array([0.5 , 0.33333333, 0.25 , 0.2 , 0.16666667])
>>> t = np.arange(0,np.pi, 0.01)
>>> s = np.sin(t)
>>> plt.plot(t,s, '-b', t, y, '-r'); # grafisch object
>>> plt.show() # toon de grafiek van sinus (in blauw) en veeltermfunctie (in rood)
Vectorisatie Het laatste voorbeeld van een sinusgrafiek illustreert ook dat Python 'begrijpt' dat de enige zinvolle toepassing van wiskundige functies op vectoren is dat ze componentsgewijs gebruikt worden. Deze manier van werken heet vectorisatie en maakt de Python taal zo bondig en helder. Je kunt ook eigengemaakte functies vectoriseren. We geven nog een paar voorbeelden ter illustratie.
>>> x = np.arange(1,6); print(x)
[1 2 3 4 5]
p.set_printoptions(precision=4 # format voor decimale getallen >>> y = np.sqrt(x); print(y) # componentsgewijs worteltrekken [1. 1.4142 1.7321 2. 2.2361] >>> y = np.log(x); print(y) # componentsgewijs natuurlijke logaritme toepassen [0. 0.6931 1.0986 1.3863 1.6094] >>> y = np.exp(x); print(y) # componentsgewijs exponentiele functie toepassen[ 2.7183 7.3891 20.0855 54.5982 148.4132]
>>> i = np.arange(1,7); v = (-1)**i/i; print('v =',v) # v_i=(-1)^i/i
v = [-1. 0.5 -0.3333 0.25 -0.2 0.1667]
>>> minmax = [np.min(v), np.max(v)]; print(minmax) # minimum en maximum [-1.0, 0.5]
>>> s = np.sum(v); print('%.4f' % s) # alle componenten sommeren -0.6167 >>> cs = np.cumsum(v); print(cs) # cummulatieve sommatie [-1. -0.5 -0.8333 -0.5833 -0.7833 -0.6167] >>> sv = np.sign(v); print(sv) # tekens van de componenten [-1. 1. -1. 1. -1. 1.] >>> dsv = np.diff(sv); print(dsv) # verschillen in opeenvolgende tekens [ 2. -2. 2. -2. 2.] >>> np.where(dsv>0) % indices met overging van - naar + teken in v (array([0, 2, 4], dtype=int64),) >>> def S(x): return (0 if x<0 else 1) # stapfunctie H >>> S_vec = np.vectorize(S)
>>> S(-1), S(0.5)
(0, 1)
>>> S(v) # # niet-gevectoriseerde versie gaat fout
Traceback (most recent call last):
...
ValueError: The truth value of an array with more than one element is ambiguous.
Use a.any() or a.all()
>>> S_vec(v) # gevectoriseerde versie werkt goed
array([0, 1, 0, 1, 0, 1])