# 198812 Session 1: Vector algebra

Math to code mapping.

The purpose of the document it to show how mathematical conpects learned in the Computer Programming Prerequisites course could be implemented in a programming language. This supplementary material should help you to transfer theoretical concepts to programming. If you have programming skills you may use the material during the course. If not, just come back to it, once you are advanced enough in programming.

- This document is basesd on the
**lecture notes**by Sébastien Court. It structured in the same way as the lecture notes. It consists only of sections, where numeric examples were given. - It provides
**code**in Python and R for examples used there. The code serves only demonstration purposes to show a possible implementation. We assumed the correctness of input data. - For multiple
**examples**of the same calculation, only one is taken. You can easily adapt code for missing calculations.

For this session, code in basic **Python**, Python with **NumPy** package and in **R** is given. Vector and matrix algebra is relatively easy to implement using `numpy`

(some courses from module 3) or R (198803). In most of the cases just by calling dedicated functions. In basic Python (198801), the required functionality in many cases must be implemented from scratch.

# 1 Definitions and basic operations

## 1.1 Definitions

Defining example vectors `v`

(a column vector) and `w`

(a row vector).

`v = (1, 6, 0, 3)`

`w = (3, 1, 4, 8, 2)`

We define them as lists.

```
= [1, 6, 0, 3]
v = [3, 1, 4, 8, 2] w
```

If we use `numpy`

, we define them as arrays.

```
import numpy
= numpy.array([3, 1, 4, 8, 2])
V = numpy.array([1, 6, 0, 3]) W
```

We define them as vectors.

```
<- c(1, 6, 0, 3)
v <- c(3, 1, 4, 8, 2) w
```

## 1.2 Basic operations

### * Multiplication by scalar

`3 * v = 3 * (1, 6, 0, 3) = (3, 18, 0, 9)`

We have to define a for-loop to create a new list with results.

```
= []
result for n in v:
3*n)
result.append(print(result)
```

`[3, 18, 0, 9]`

We may use the multiplication operator `*`

.

`3*V `

```
array([[ 3],
[18],
[ 0],
[ 9]])
```

We may use the multiplication operator `*`

.

`3*v `

`[1] 3 18 0 9`

### * Sum of two vectors

`v + w = (3, 2, 7, 9) + (1, 4, 2, 12) = (4, 6, 9, 21)`

We have to use a for-loop.

```
= len(v)
number_of_elements = []
result for i in range(number_of_elements):
+ w[i])
result.append(v[i] print(result)
```

`[4, 6, 9, 21]`

We may use the addition operator `+`

or the `numpy.add()`

function.

`+ W V `

`array([ 4, 6, 9, 21])`

` numpy.add(V, W)`

`array([ 4, 6, 9, 21])`

We may use the addition operator `+`

.

`+ w v `

`[1] 4 6 9 21`

### * The subtraction

Let us subtract the same, two vectors, `v`

and `w`

.

`v - w = (3, 2, 7, 9) - (1, 4, 2, 12) = (2, -2, 5, -3)`

We have to use a for-loop.

```
= len(v)
number_of_elements = []
result for i in range(number_of_elements):
- w[i])
result.append(v[i] print(result)
```

`[2, -2, 5, -3]`

We may use the subtraction operator `-`

or the `subtract()`

function.

`- W V `

`array([ 2, -2, 5, -3])`

` numpy.subtract(V, W) `

`array([ 2, -2, 5, -3])`

We may use the subtraction operator `-`

.

`- w v `

`[1] 2 -2 5 -3`

### * Componentwise product of two vectors

For the same two vectors, we will get.

`v * w = (3, 2, 7, 9) * (1, 4, 2, 12) = (3, 8, 14, 108)`

We have to use a for-loop.

```
= len(v)
number_of_elements = []
result for i in range(number_of_elements):
* w[i])
result.append(v[i] print(result)
```

`[3, 8, 14, 108]`

We may use the multiplication operator `*`

or the `numpy.multiply()`

function.

`* W V `

`array([ 3, 8, 14, 108])`

` numpy.multiply(V, W) `

`array([ 3, 8, 14, 108])`

We may use the multiplication operator `*`

.

`* w v `

`[1] 3 8 14 108`

# 2 Subsetting and notation

## 2.1 When numbering starts at 0

The convention of indexing is notation/language-dependent.

Numbering starts from 1.

`v = (1, 6, 0, 6)`

For `v`

, we have the following indices.

`1, 2, 3, 4`

For example, the first element we get with v[1] and obtain 1. In general, we have

```
v[1] = 1
v[2] = 6
v[3] = 0
v[4] = 6
```

Numbering starts from 0.

`v = [1, 6, 0, 6]`

For `v`

, we have the following indices.

`0, 1, 2, 3`

We may also count backward with negative indices.

`-4, -3, -2, -1`

Thus, we may access elements as follows.

```
v[0] = v[-4] = 1
v[1] = v[-3] = 6
v[2] = v[-2] = 0
v[3] = v[-1] = 6
```

For arrays, it is just analogues as for lists (see the previous tab).

We may access elements as follows.

```
V[0] = V[-4] = 1
V[1] = V[-3] = 6
V[2] = V[-2] = 0
V[3] = V[-1] = 6
```

Numbering starts from 1, like in math.

`v <- c( 1, 6, 0, 6 )`

For `v`

, we have the following indices.

`1, 2, 3, 4`

We may access elements as follows.

```
v[1] = 1
v[2] = 6
v[3] = 0
v[4] = 6
```

## 2.2 Subsetting several elements

We may pick up several elements using indices.

`w = (3, 1, 4, 8, 2)`

`w[1:3] = (3, 1, 4)`

`w[(1,3,5)] = [3, 4, 2]`

For our list

` w`

`[3, 1, 4, 8, 2]`

we may use slicing.

`0:3] # for indices 0, 1, 2 w[`

`[3, 1, 4]`

To select a discontinuous list the elements from the original list, we need to construct a new list explicitly.

`0], w[2], w[4]] [w[`

`[3, 4, 2]`

For our array

` W`

`array([3, 1, 4, 8, 2])`

we may use slicing.

`0:3] # for indices 0, 1, 2 W[`

`array([3, 1, 4])`

We may also select a discontinuous list of the elements from the original array.

`0, 2, 4]] W[[`

`array([3, 4, 2])`

For our vector

` w`

`[1] 3 1 4 8 2`

we may use slicing.

`1:3] # for indices 1, 2, 3 w[`

`[1] 3 1 4`

We may also select a discontinuous list of the elements from the original vector.

`c(1, 3, 5)] w[`

`[1] 3 4 2`

Negative indices might be used to exclude elements.

`-1] # all but the first w[`

`[1] 1 4 8 2`

`-c(1, 3, 5)] # all but listed w[`

`[1] 1 8`

## 2.3 Notation of summation

We may sum all elements of a vector.

`v = (1, 6, 0, 6)`

`sum(v) = 13`

We may use the built-in `sum()`

function.

`sum(v)`

`13`

We may use the `numpy.sum()`

function or just built-in `sum()`

function.

`sum(V) numpy.`

`13`

`sum(V)`

`13`

We may use the built-in `sum()`

function.

`sum(v)`

`[1] 13`

# 3 Scalar product and norm

## 3.1 The scalar product

We may calculate the scalar product of two vectors.

```
v · w = (-2, 6, 9, 2) · (4, -1, 3, 7) =
= (-2) x 4 + 6 x (-1) + 9 x 3 + 2 x 7 =
= 27
```

We need to use a for-loop.

```
= len(v)
number_of_elements = 0
result for i in range(number_of_elements):
= result + v[i] * w[i]
result result
```

`27`

We have the `dot()`

function.

` numpy.dot(V, W)`

`27`

Alternatively, we may use multiplication and summation.

`sum(V*W) numpy.`

`27`

We use `%*%`

operator.

`%*% w v `

```
[,1]
[1,] 27
```

## 3.2 The Euclidean norm

Let us calculate the Euclidean norm for the following vector.

```
norm(v) = norm((1, 2)) =
= sqrt(1^2 + 2^2) =
= sqrt(5) =
= 2.23606797749979
```

We have to use a for-loop.

```
= 0
result for n in v:
= result + n**2
result ** 0.5 result
```

`2.23606797749979`

We use the `norm()`

function from `numpy.linalg`

subpackage.

` numpy.linalg.norm(V)`

`2.23606797749979`

We have to use the `sqrt()`

(square root) function and the `sum()`

function.

`sqrt(sum(v^2))`

`[1] 2.236068`

## 3.3 Other norms

The *p* values and meaning of the norms.

*p*= 0 for the number of non-zero components.

*p*= 1 for the sum of absolute values.*p*= 2 for the Euclidean distance (earlier example).*p*= infinity for the maximal absolute value.

We would need to use for-loops, but let us calculate different norms using list comprehension to make the code shorter.

`sum([n > 0 for n in v]) # p = 0 `

`2`

`sum([abs(n) for n in v]) # p = 1`

`3`

`max([abs(n) for n in v]) # p = infinity `

`2`

The other norms may be calculated using different values for *p*. The `numpy.linalg.norm()`

function has a named parameter `ord`

- order of the norm (*p*).

`ord=0) numpy.linalg.norm(V, `

`2.0`

`ord=1) numpy.linalg.norm(V, `

`3.0`

`ord=numpy.Inf) numpy.linalg.norm(V, `

`2.0`

We use the built-in `sum()`

, `abs()`

, and `max()`

function.

`sum(v > 0) # p = 0 `

`[1] 2`

`sum(abs(v)) # p = 1`

`[1] 3`

`max(abs(v)) # p = infinity `

`[1] 2`

# 5 Geometric aspects

## 5.3 Determining the position of a point with respect to a straight line

Given are three points.

`A = (0, 1)`

`B = (0, 4)`

`M = (-2, 1)`

The task is to determine on which side the point M is located, with respect to this directed by the vector v = AB.

We calculate (geometrical) vectors `AB`

and `AM`

.

`= [b[i] - a[i] for i in range(len(a))]; ab ab `

`[0, 3]`

`= [m[i] - a[i] for i in range(len(a))]; am am `

`[-2, 0]`

Next, we calculate their 2D cross product.

`= ab[0] * am[1] - ab[1] * am[0]; p p `

`6`

The final step is to determine the sign.

```
= 0
sign if p > 0:
= 1
sign elif p < 0:
= -1
sign sign
```

`1`

For the last step, optionally, we may use the `copysign()`

function from the `math`

package.

```
import math
1, p) math.copysign(
```

`1.0`

We calculate (geometrical) vectors `AB`

and `AM`

.

`= B - A; AB AB `

`array([0, 3])`

`= M - A; AM AM `

`array([-2, 0])`

Next, we determine the sign of their cross product.

` numpy.sign(numpy.cross(AB, AM)) `

`1`

We calculate (geometrical) vectors `AB`

and `AM`

.

`= B - A; AB AB `

```
[,1] [,2]
[1,] 0 3
```

`= M - A; AM AM `

```
[,1] [,2]
[1,] -2 0
```

Next, we determine the sign of their cross product.

`sign(crossprod(AB, AM)) `

```
[,1] [,2]
[1,] 0 0
[2,] -1 0
```