# Scalar and vector¶

Marcos Duarte

Python handles very well all mathematical operations with numeric scalars and vectors and you can use Sympy for similar stuff but with symbols (algebra). Let's briefly review about scalars and vectors and show how to use Python for calculations.

## Scalar¶

A scalar is a one-dimensional physical quantity, which can be described by a single real number. For example, time, mass, and energy are examples of scalars.

### Scalar operations in Python¶

Simple arithmetic operations with scalars are indeed simple:

In [1]:
import math

a = 2
b = 3
print('a =', a, ', b =', b)
print('a + b =', a + b)
print('a - b =', a - b)
print('a * b =', a * b)
print('a / b =', a / b)
print('a ** b =', a ** b)
print('sqrt(b) =', math.sqrt(b))

a = 2 , b = 3
a + b = 5
a - b = -1
a * b = 6
a / b = 0.6666666666666666
a ** b = 8
sqrt(b) = 1.7320508075688772


If you have a set of numbers, or an array, it is probably better to use Numpy; it will be faster for large data sets, and combined with Scipy, has many more mathematical funcions.

In [2]:
import numpy as np

a = 2
b = [3, 4, 5, 6, 7, 8]
b = np.array(b)
print('a =', a, ', b =', b)
print('a + b =', a + b)
print('a - b =', a - b)
print('a * b =', a * b)
print('a / b =', a / b)
print('a ** b =', a ** b)
print('np.sqrt(b) =', np.sqrt(b))  # use numpy functions for numpy arrays

a = 2 , b = [3 4 5 6 7 8]
a + b = [ 5  6  7  8  9 10]
a - b = [-1 -2 -3 -4 -5 -6]
a * b = [ 6  8 10 12 14 16]
a / b = [ 0.66666667  0.5         0.4         0.33333333  0.28571429  0.25      ]
a ** b = [  8  16  32  64 128 256]
np.sqrt(b) = [ 1.73205081  2.          2.23606798  2.44948974  2.64575131  2.82842712]


Numpy performs the arithmetic operations of the single number in a with all the numbers of the array b. This is called broadcasting in computer science.
Even if you have two arrays (but they must have the same size), Numpy handles for you:

In [3]:
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
print('a =', a, ', b =', b)
print('a + b =', a + b)
print('a - b =', a - b)
print('a * b =', a * b)
print('a / b =', a / b)
print('a ** b =', a ** b)

a = [1 2 3] , b = [4 5 6]
a + b = [5 7 9]
a - b = [-3 -3 -3]
a * b = [ 4 10 18]
a / b = [ 0.25  0.4   0.5 ]
a ** b = [  1  32 729]


## Vector¶

A vector is a geometric quantity with magnitude (or length) and direction expressed numerically as an ordered list of values according to a coordinate reference system. For example, position, force, and torque are physical quantities defined by vectors.

For instance, consider the position of a point in space represented by a vector:

The position of the point (the vector) above can be represented as a tuple of values:

$$(x,\: y,\: z) \; \Rightarrow \; (1, 3, 2)$$

or in matrix form:

$$\begin{bmatrix} x \\y \\z \end{bmatrix} \;\; \Rightarrow \;\; \begin{bmatrix} 1 \\3 \\2 \end{bmatrix}$$

We can use the Numpy array to represent the components of vectors.
For instance, for the vector above is expressed in Python as:

In [4]:
a = np.array([1, 3, 2])
print('a =', a)

a = [1 3 2]


Exactly like the arrays in the last example for scalars, so all operations we performed will result in the same values, of course.
However, as we are now dealing with vectors, now some of the operations don't make sense. For example, for vectors there are no multiplication, division, power, and square root in the way we calculated.

A vector can also be represented as:

$$\mathbf{a} = a_x\mathbf{i}+a_y\mathbf{j}+a_z\mathbf{k}$$

Where $\mathbf{i,\: j,\: k}$ are unit vectors, each representing a direction and $a_x\mathbf{i},\: a_y\mathbf{j},\: a_z\mathbf{k}$ are the vector components of the vector $\mathbf{a}$.
A unit vector (or versor) is a vector whose length (or norm) is 1.
The unit vector of a non-zero vector $\mathbf{a}$ is the unit vector codirectional with $\mathbf{a}$:

$$\mathbf{\hat{u}} = \frac{\mathbf{a}}{||\mathbf{a}||} = \frac{a_x\:\mathbf{i} + a_y\:\mathbf{j} + a_z\:\mathbf{k}}{\sqrt{a_x^2+a_y^2+a_z^2}}$$

Where the symbol $||\;||$ denotes the norm (magnitude, length or Euclidean norm) of a vector and it is defined as:

$$||\mathbf{a}|| = \sqrt{a_x^2+a_y^2+a_z^2}$$

The function numpy.linalg.norm calculates the norm:

In [5]:
a = np.array([1, 2, 3])
np.linalg.norm(a)

Out[5]:
3.7416573867739413

Or we can use the definition and compute directly:

In [6]:
np.sqrt(np.sum(a*a))

Out[6]:
3.7416573867739413

Then, the versor for the vector $\mathbf{a} = (1, 2, 3)$ is:

In [7]:
a = np.array([1, 2, 3])
u = a/np.linalg.norm(a)
print('u =', u)

u = [ 0.26726124  0.53452248  0.80178373]


And we can verify its magnitude is indeed 1:

In [8]:
np.linalg.norm(u)

Out[8]:
1.0

But the representation of a vector as a tuple of values is only valid for a vector with its origin coinciding with the origin $(0, 0, 0)$ of the coordinate system we adopted. For instance, consider the following vector:

Such a vector cannot be represented by $(b_x, b_y, b_z)$ because this would be for the vector from the origin to the point B. To represent exactly this vector we need the two vectors $\mathbf{a}$ and $\mathbf{b}$. This fact is important when we perform some calculations in Mechanics.

The addition of two vectors is another vector:

$$\mathbf{a} + \mathbf{b} = (a_x\mathbf{i}+a_y\mathbf{j}+a_z\mathbf{k}) + (b_x\mathbf{i}+b_y\mathbf{j}+b_z\mathbf{k}) = (a_x+b_x)\mathbf{i} + (a_y+b_y)\mathbf{j} + (a_z+b_z)\mathbf{k}$$

The subtraction of two vectors is also another vector:

$$\mathbf{a} - \mathbf{b} = (a_x\mathbf{i}+a_y\mathbf{j}+a_z\mathbf{k}) + (b_x\mathbf{i}+b_y\mathbf{j}+b_z\mathbf{k}) = (a_x-b_x)\mathbf{i} + (a_y-b_y)\mathbf{j} + (a_z-b_z)\mathbf{k}$$

</div>

Consider two 2D arrays (rows and columns) representing the position of two objects moving in space. The columns represent the vector components and the rows the values of the position vector in different instants.
Once again, it's easy to perform addition and subtraction with these vectors:

In [9]:
import IPython
a = np.array([[1, 2, 3], [1, 1, 1]])
b = np.array([[4, 5, 6], [7, 8, 9]])
print('a =', a, '\nb =', b)
print('a + b =', a + b)
print('a - b =', a - b)

a = [[1 2 3]
[1 1 1]]
b = [[4 5 6]
[7 8 9]]
a + b = [[ 5  7  9]
[ 8  9 10]]
a - b = [[-3 -3 -3]
[-6 -7 -8]]


Numpy can handle a N-dimensional array with the size limited by the available memory in your computer.

And we can perform operations on each vector, for example, calculate the norm of each one.
First let's check the shape of the variable a using the method shape or the function numpy.shape:

In [10]:
print(a.shape)
print(np.shape(a))

(2, 3)
(2, 3)


This means the variable a has 2 rows and 3 columns.
We have to tell the function numpy.norm to calculate the norm for each vector, i.e., to operate through the columns of the variable a using the paraneter axis:

In [11]:
np.linalg.norm(a, axis=1)

Out[11]:
array([ 3.74165739,  1.73205081])

## Dot product¶

Dot product (or scalar product or inner product) between two vectors is a mathematical operation algebraically defined as the sum of the products of the corresponding components (maginitudes in each direction) of the two vectors. The result of the dot product is a single number (a scalar).
The dot product between vectors $\mathbf{a}$ and $\mathbf{b}$ is:

$$\mathbf{a} \cdot \mathbf{b} = (a_x\:\mathbf{i}+a_y\:\mathbf{j}+a_z\:\mathbf{k}) \cdot (b_x\:\mathbf{i}+b_y\:\mathbf{j}+b_z\:\mathbf{k}) = a_x b_x + a_y b_y + a_z b_z$$

Because by definition:

$$\mathbf{i} \cdot \mathbf{i} = \mathbf{j} \cdot \mathbf{j} = \mathbf{k} \cdot \mathbf{k} = 1 \;\;\;\; \text{and} \;\;\;\; \mathbf{i} \cdot \mathbf{j} = \mathbf{i} \cdot \mathbf{k} = \mathbf{j} \cdot \mathbf{k} = 0$$

The geometric equivalent of the dot product is the product of the magnitudes of the two vectors and the cosine of the angle between them:

$$\mathbf{a} \cdot \mathbf{b} = ||\mathbf{a}||\:||\mathbf{b}||\:cos(\theta)$$

Which is also eqivalent to state that the dot product between two vectors $\mathbf{a}$ and $\mathbf{b}$ is the magnitude of $\mathbf{a}$ times the magnitude of the component of $\mathbf{b}$ parallel to $\mathbf{a}$ (or the magnitude of $\mathbf{b}$ times the magnitude of the component of $\mathbf{a}$ parallel to $\mathbf{b}$).

The dot product between two vectors can be visualized in this interactive animation:

In [12]:
from IPython.display import HTML
'DotProduct.html width=100% height=420></iframe>')

Out[12]:

The Numpy function for the dot product is numpy.dot:

In [13]:
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
print('a =', a, '\nb =', b)
print('np.dot(a, b) =', np.dot(a, b))

a = [1 2 3]
b = [4 5 6]
np.dot(a, b) = 32


Or we can use the definition and compute directly:

In [14]:
np.sum(a*b)

Out[14]:
32

For 2D arrays, the numpy.dot function performs matrix multiplication rather than the dot product; so let's use the numpy.sum function:

In [15]:
a = np.array([[1, 2, 3], [1, 1, 1]])
b = np.array([[4, 5, 6], [7, 8, 9]])
np.sum(a*b, axis=1)

Out[15]:
array([32, 24])

## Vector product¶

Cross product or vector product between two vectors is a mathematical operation in three-dimensional space which results in a vector perpendicular to both of the vectors being multiplied and a length (norm) equal to the product of the perpendicular components of the vectors being multiplied (which is equal to the area of the parallelogram that the vectors span).
The cross product between vectors $\mathbf{a}$ and $\mathbf{b}$ is:

$$\mathbf{a} \times \mathbf{b} = (a_x\:\mathbf{i}+a_y\:\mathbf{j}+a_z\:\mathbf{k}) \times (b_x\:\mathbf{i}+b_y\:\mathbf{j}+b_z\:\mathbf{k}) = (a_yb_z-a_zb_y)\mathbf{i} + (a_zb_x-a_xb_z)\mathbf{j}+(a_xb_y-a_yb_x)\mathbf{k}$$

Because by definition:

$$\begin{array}{l l} \mathbf{i} \times \mathbf{i} = \mathbf{j} \times \mathbf{j} = \mathbf{k} \times \mathbf{k} = 0 \\ \mathbf{i} \times \mathbf{j} = \mathbf{k},\;\;\; \mathbf{j} \times \mathbf{k} = \mathbf{i},\;\;\; \mathbf{k} \times \mathbf{i} = \mathbf{j} \\ \mathbf{j} \times \mathbf{i} = -\mathbf{k},\;\;\; \mathbf{k} \times \mathbf{j} = -\mathbf{i},\;\;\; \mathbf{i} \times \mathbf{k} = -\mathbf{j} \end{array}$$

The direction of the vector resulting from the cross product between the vectors $\mathbf{a}$ and $\mathbf{b}$ is given by the right-hand rule.

The geometric equivalent of the cross product is:

The geometric equivalent of the cross product is the product of the magnitudes of the two vectors and the sine of the angle between them:

$$\mathbf{a} \times \mathbf{b} = ||\mathbf{a}||\:||\mathbf{b}||\:sin(\theta)$$

Which is also eqivalent to state that the cross product between two vectors $\mathbf{a}$ and $\mathbf{b}$ is the magnitude of $\mathbf{a}$ times the magnitude of the component of $\mathbf{b}$ perpendicular to $\mathbf{a}$ (or the magnitude of $\mathbf{b}$ times the magnitude of the component of $\mathbf{a}$ perpendicular to $\mathbf{b}$).

The definition above, also implies that the magnitude of the cross product is the area of the parallelogram spanned by the two vectors:

The cross product can also be calculated as the determinant of a matrix:

$$\mathbf{a} \times \mathbf{b} = \left| \begin{array}{ccc} \mathbf{i} & \mathbf{j} & \mathbf{k} \\ a_x & a_y & a_z \\ b_x & b_y & b_z \end{array} \right| = a_y b_z \mathbf{i} + a_z b_x \mathbf{j} + a_x b_y \mathbf{k} - a_y b_x \mathbf{k} -a_z b_y \mathbf{i} - a_x b_z \mathbf{j} \\ \mathbf{a} \times \mathbf{b} = (a_yb_z-a_zb_y)\mathbf{i} + (a_zb_x-a_xb_z)\mathbf{j}+(a_xb_y-a_yb_x)\mathbf{k}$$

The same result as before.

The cross product between two vectors can be visualized in this interactive animation:

In [16]:
from IPython.display import HTML
'CrossProduct.html width=100% height=420></iframe>')

Out[16]:

The Numpy function for the cross product is numpy.cross:

In [17]:
print('a =', a, '\nb =', b)
print('np.cross(a, b) =', np.cross(a, b))

a = [[1 2 3]
[1 1 1]]
b = [[4 5 6]
[7 8 9]]
np.cross(a, b) = [[-3  6 -3]
[ 1 -2  1]]


For 2D arrays with vectors in different rows:

In [18]:
a = np.array([[1, 2, 3], [1, 1, 1]])
b = np.array([[4, 5, 6], [7, 8, 9]])
np.cross(a, b, axis=1)

Out[18]:
array([[-3,  6, -3],
[ 1, -2,  1]])

## Problems¶

1. Given the vectors, $\mathbf{a}$=(1, 0, 0) and $\mathbf{b}$=(1, 1, 1), calculate the dot product.
2. Calculate two unit vectors for (2, −2, 3) and (3, −3, 2) and determine an orthogonal vector for the two.
3. Given the vectors $\mathbf{a}$=(1, 0, 0) and $\mathbf{b}$=(1, 1, 1), calculate $\mathbf{a} \times \mathbf{b}$ and verify that this vector is orthogonal to vectors $\mathbf{a}$ and $\mathbf{b}$. Also, calculate $\mathbf{b} \times \mathbf{a}$ and compare it with $\mathbf{a} \times \mathbf{b}$.

If you are new to scalars and vectors, you should solve these problems first by hand and then use Python to check the answers.