Vectors: Vector calculus in Python
Computing with vectors
Addition, scalar multiplication and linear combination You can add vectors, multiply them by a scalar, and you can combine them. This is done in the way you might expect. The only remarkable thing about addition, but what turns out to be a pleasant side effect, is that you can also add/subtract a number to a vector by considering the number as a vector of appropriate length with all values equal to the given number so that the addition/subtraction has meaning.
>>> 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])
Multiplication, dot product, cross product, and the Hadamard product So far we have seen in the theory pages the inner product, the cross product and the Hadamard product. Python facilitates these calculations:
>>> u = np.array([1,2,3]); v = np.array([4,5,6])
>>> np.dot(u,v) # inner product of vector
32
>>> u.dot(v) # alternative
32
>>> np.cross(u,v) # cross product
array([-3, 6, -3])
>> u * v # Hadamard product
array([ 4, 10, 18])
Arithmetic operations With the multiplication symbol *
, you indicate that you want to apply multiplication componentwise. You can also do other arithmetic operators like division and involution. This way you can quickly construct vectors that are defined by making indexing functions or simple graphs of functions. We give some examples to illustrate
>>> 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)) # computation of the Euclidean norm of 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'); # graphical object
>>> plt.show() # displaygraph of sine (blue) and of a polynomial function (red)
Vectorization The previous example of a sine graph also illustrates that Python "understands" that the only meaningful use of mathematical functions on vectors is that they are used componentwise. This working style is called vectorization and makes the Python language concise and clear. We give a few examples to illustrate this.
>>> x = np.arange(1,6); print(x)
[1 2 3 4 5]
p.set_printoptions(precision=4 # format for decimal numbers >>> y = np.sqrt(x); print(y) # componentwise extraction of roots [1. 1.4142 1.7321 2. 2.2361] >>> y = np.log(x); print(y) # componentwise application of the natural logarithm [0. 0.6931 1.0986 1.3863 1.6094] >>> y = np.exp(x); print(y) # componentwise application of the exponential function [ 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 and maximum [-1.0, 0.5]
>>> s = np.sum(v); print('%.4f' % s) # summation of all components -0.6167 >>> cs = np.cumsum(v); print(cs) # cumulative summation [-1. -0.5 -0.8333 -0.5833 -0.7833 -0.6167] >>> sv = np.sign(v); print(sv) # signs of the components [-1. 1. -1. 1. -1. 1.] >>> dsv = np.diff(sv); print(dsv) # differences in consecutive signs [ 2. -2. 2. -2. 2.] >>> np.where(dsv>0) % indices with transition from - to + sign in v (array([0, 2, 4], dtype=int64),) >>> def S(x): return (0 if x<0 else 1) # step function S >>> S_vec = np.vectorize(S) # vectorized version of step function S
>>> S(-1), S(0.5)
(0, 1)
>>> S(v) # non-vectorized version goes wrong
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) # vectorized version works fine
array([0, 1, 0, 1, 0, 1])