My Math Notes
  • Home
  • Calculus Notebooks
    • Backpropagation
    • Optimizing Functions of One Variable: Cost Minimization
    • Differentiation in Python: Symbolic, Numerical and Automatic
    • Optimization Using Gradient Descent: Linear Regression
    • Optimization Using Gradient Descent in One Variable
    • Optimization Using Gradient Descent in Two Variables
    • Neural Network with Two Layers
    • Regression with Perceptron
    • Classification with Perceptron
    • Optimization Using Newton's Method
    • Fitting the distribution of heights data
    • Gradient descent in a sandpit
    • The Sandpit - Part 2
    • The Sandpit
  • Deeplearning.ai
    • Calculus
    • Linear Algebra
    • Probability and Statistics
  • Imperial College
    • Linear Algebra
    • Multivariate Calculus
    • PCA
  • Linear Algebra Notebooks
    • Single Perceptron Neural Networks for Linear Regression
    • Single Perceptron Neural Networks for Linear Regression
    • Eigenvalues and Eigenvectors
    • Gram-Schmidt process
    • Identifying special matrices
    • PageRank
    • Reflecting Bear
    • Linear Transformations
    • Matrix Multiplication
    • Solving Linear Systems: 2 variables
    • Vector Operations: Scalar Multiplication, Sum and Dot Product of Vectors
  • PCA notebooks
    • Distances and Angles between Images
    • K nearest Neighbors Algorithm
    • Week 1: Mean/Covariance of a data set and effect of a linear transformation
    • Orthogonal Projections
    • Principal Component Analysis (PCA)
    • Demonstration of PCA
  • Previous
  • Next
  • Vector Operations: Scalar Multiplication, Sum and Dot Product of Vectors
  • Table of Contents
    • Packages
    • 1 - Scalar Multiplication and Sum of Vectors
    • 2 - Dot Product

Vector Operations: Scalar Multiplication, Sum and Dot Product of Vectors¶

In this lab you will use Python and NumPy functions to perform main vector operations: scalar multiplication, sum of vectors and their dot product. You will also investigate the speed of calculations using loop and vectorized forms of these main linear algebra operations

Table of Contents¶

  • 1 - Scalar Multiplication and Sum of Vectors
    • 1.1 - Visualization of a Vector $v\in\mathbb{R}^2$
    • 1.2 - Scalar Multiplication
    • 1.3 - Sum of Vectors
    • 1.4 - Norm of a Vector
  • 2 - Dot Product
    • 2.1 - Algebraic Definition of the Dot Product
    • 2.2 - Dot Product using Python
    • 2.3 - Speed of Calculations in Vectorized Form
    • 2.4 - Geometric Definition of the Dot Product
    • 2.5 - Application of the Dot Product: Vector Similarity

Packages¶

Load the NumPy package to access its functions.

In [1]:
Copied!
import numpy as np
import numpy as np

1 - Scalar Multiplication and Sum of Vectors¶

1.1 - Visualization of a Vector $v\in\mathbb{R}^2$¶

You already have seen in the videos and labs, that vectors can be visualized as arrows, and it is easy to do it for a $v\in\mathbb{R}^2$, e.g. $v=\begin{bmatrix} 1 & 3 \end{bmatrix}^T$

The following code will show the visualization.

In [2]:
Copied!
import matplotlib.pyplot as plt

def plot_vectors(list_v, list_label, list_color):
    _, ax = plt.subplots(figsize=(10, 10))
    ax.tick_params(axis='x', labelsize=14)
    ax.tick_params(axis='y', labelsize=14)
    ax.set_xticks(np.arange(-10, 10))
    ax.set_yticks(np.arange(-10, 10))
    
    
    plt.axis([-10, 10, -10, 10])
    for i, v in enumerate(list_v):
        sgn = 0.4 * np.array([[1] if i==0 else [i] for i in np.sign(v)])
        plt.quiver(v[0], v[1], color=list_color[i], angles='xy', scale_units='xy', scale=1)
        ax.text(v[0]-0.2+sgn[0], v[1]-0.2+sgn[1], list_label[i], fontsize=14, color=list_color[i])

    plt.grid()
    plt.gca().set_aspect("equal")
    plt.show()

v = np.array([[1],[3]])
# Arguments: list of vectors as NumPy arrays, labels, colors.
plot_vectors([v], [f"$v$"], ["black"])
import matplotlib.pyplot as plt def plot_vectors(list_v, list_label, list_color): _, ax = plt.subplots(figsize=(10, 10)) ax.tick_params(axis='x', labelsize=14) ax.tick_params(axis='y', labelsize=14) ax.set_xticks(np.arange(-10, 10)) ax.set_yticks(np.arange(-10, 10)) plt.axis([-10, 10, -10, 10]) for i, v in enumerate(list_v): sgn = 0.4 * np.array([[1] if i==0 else [i] for i in np.sign(v)]) plt.quiver(v[0], v[1], color=list_color[i], angles='xy', scale_units='xy', scale=1) ax.text(v[0]-0.2+sgn[0], v[1]-0.2+sgn[1], list_label[i], fontsize=14, color=list_color[i]) plt.grid() plt.gca().set_aspect("equal") plt.show() v = np.array([[1],[3]]) # Arguments: list of vectors as NumPy arrays, labels, colors. plot_vectors([v], [f"$v$"], ["black"])
No description has been provided for this image

The vector is defined by its norm (length, magnitude) and direction, not its actual position. But for clarity and convenience vectors are often plotted starting in the origin (in $\mathbb{R}^2$ it is a point $(0,0)$) .

1.2 - Scalar Multiplication¶

Scalar multiplication of a vector $v=\begin{bmatrix} v_1 & v_2 & \ldots & v_n \end{bmatrix}^T\in\mathbb{R}^n$ by a scalar $k$ is a vector $kv=\begin{bmatrix} kv_1 & kv_2 & \ldots & kv_n \end{bmatrix}^T$ (element by element multiplication). If $k>0$, then $kv$ is a vector pointing in the same direction as $v$ and it is $k$ times as long as $v$. If $k=0$, then $kv$ is a zero vector. If $k<0$, vector $kv$ will be pointing in the opposite direction. In Python you can perform this operation with a * operator. Check out the example below:

In [3]:
Copied!
plot_vectors([v, 2*v, -2*v], [f"$v$", f"$2v$", f"$-2v$"], ["black", "green", "blue"])
plot_vectors([v, 2*v, -2*v], [f"$v$", f"$2v$", f"$-2v$"], ["black", "green", "blue"])
No description has been provided for this image

1.3 - Sum of Vectors¶

Sum of vectors (vector addition) can be performed by adding the corresponding components of the vectors: if $v=\begin{bmatrix} v_1 & v_2 & \ldots & v_n \end{bmatrix}^T\in\mathbb{R}^n$ and
$w=\begin{bmatrix} w_1 & w_2 & \ldots & w_n \end{bmatrix}^T\in\mathbb{R}^n$, then $v + w=\begin{bmatrix} v_1 + w_1 & v_2 + w_2 & \ldots & v_n + w_n \end{bmatrix}^T\in\mathbb{R}^n$. The so-called parallelogram law gives the rule for vector addition. For two vectors $u$ and $v$ represented by the adjacent sides (both in magnitude and direction) of a parallelogram drawn from a point, the vector sum $u+v$ is is represented by the diagonal of the parallelogram drawn from the same point:

No description has been provided for this image

In Python you can either use + operator or NumPy function np.add(). In the following code you can uncomment the line to check that the result will be the same:

In [4]:
Copied!
v = np.array([[1],[3]])
w = np.array([[4],[-1]])

plot_vectors([v, w, v + w], [f"$v$", f"$w$", f"$v + w$"], ["black", "black", "red"])
# plot_vectors([v, w, np.add(v, w)], [f"$v$", f"$w$", f"$v + w$"], ["black", "black", "red"])
v = np.array([[1],[3]]) w = np.array([[4],[-1]]) plot_vectors([v, w, v + w], [f"$v$", f"$w$", f"$v + w$"], ["black", "black", "red"]) # plot_vectors([v, w, np.add(v, w)], [f"$v$", f"$w$", f"$v + w$"], ["black", "black", "red"])
No description has been provided for this image

1.4 - Norm of a Vector¶

The norm of a vector $v$ is denoted as $\lvert v\rvert$. It is a nonnegative number that describes the extent of the vector in space (its length). The norm of a vector can be found using NumPy function np.linalg.norm():

In [5]:
Copied!
print("Norm of a vector v is", np.linalg.norm(v))
print("Norm of a vector v is", np.linalg.norm(v))
Norm of a vector v is 3.1622776601683795

2 - Dot Product¶

2.1 - Algebraic Definition of the Dot Product¶

The dot product (or scalar product) is an algebraic operation that takes two vectors $x=\begin{bmatrix} x_1 & x_2 & \ldots & x_n \end{bmatrix}^T\in\mathbb{R}^n$ and
$y=\begin{bmatrix} y_1 & y_2 & \ldots & y_n \end{bmatrix}^T\in\mathbb{R}^n$ and returns a single scalar. The dot product can be represented with a dot operator $x\cdot y$ and defined as:

$$x\cdot y = \sum_{i=1}^{n} x_iy_i = x_1y_1+x_2y_2+\ldots+x_ny_n \tag{1}$$

2.2 - Dot Product using Python¶

The simplest way to calculate dot product in Python is to take the sum of element by element multiplications. You can define the vectors $x$ and $y$ by listing their coordinates:

In [6]:
Copied!
x = [1, -2, -5]
y = [4, 3, -1]
x = [1, -2, -5] y = [4, 3, -1]

Next, let’s define a function dot(x,y) for the dot product calculation:

In [7]:
Copied!
def dot(x, y):
    s=0
    for xi, yi in zip(x, y):
        s += xi * yi
    return s
def dot(x, y): s=0 for xi, yi in zip(x, y): s += xi * yi return s

For the sake of simplicity, let’s assume that the vectors passed to the above function are always of the same size, so that you don’t need to perform additional checks.

Now everything is ready to perform the dot product calculation calling the function dot(x,y):

In [8]:
Copied!
print("The dot product of x and y is", dot(x, y))
print("The dot product of x and y is", dot(x, y))
The dot product of x and y is 3

Dot product is very a commonly used operator, so NumPy linear algebra package provides quick way to calculate it using function np.dot():

In [9]:
Copied!
print("np.dot(x,y) function returns dot product of x and y:", np.dot(x, y))
print("np.dot(x,y) function returns dot product of x and y:", np.dot(x, y))
np.dot(x,y) function returns dot product of x and y: 3

Note that you did not have to define vectors $x$ and $y$ as NumPy arrays, the function worked even with the lists. But there are alternative functions in Python, such as explicit operator @ for the dot product, which can be applied only to the NumPy arrays. You can run the following cell to check that.

In [10]:
Copied!
print("This line output is a dot product of x and y: ", np.array(x) @ np.array(y))

print("\nThis line output is an error:")
try:
    print(x @ y)
except TypeError as err:
    print(err)
print("This line output is a dot product of x and y: ", np.array(x) @ np.array(y)) print("\nThis line output is an error:") try: print(x @ y) except TypeError as err: print(err)
This line output is a dot product of x and y:  3

This line output is an error:
unsupported operand type(s) for @: 'list' and 'list'

As both np.dot() and @ operators are commonly used, it is recommended to define vectors as NumPy arrays to avoid errors. Let's redefine vectors $x$ and $y$ as NumPy arrays to be safe:

In [11]:
Copied!
x = np.array(x)
y = np.array(y)
x = np.array(x) y = np.array(y)

2.3 - Speed of Calculations in Vectorized Form¶

Dot product operations in Machine Learning applications are applied to the large vectors with hundreds or thousands of coordinates (called high dimensional vectors). Training models based on large datasets often takes hours and days even on powerful machines. Speed of calculations is crucial for the training and deployment of your models.

It is important to understand the difference in the speed of calculations using vectorized and the loop forms of the vectors and functions. In the loop form operations are performed one by one, while in the vectorized form they can be performed in parallel. In the section above you defined loop version of the dot product calculation (function dot()), while np.dot() and @ are the functions representing vectorized form.

Let's perform a simple experiment to compare their speed. Define new vectors $a$ and $b$ of the same size $1,000,000$:

In [12]:
Copied!
a = np.random.rand(1000000)
b = np.random.rand(1000000)
a = np.random.rand(1000000) b = np.random.rand(1000000)

Use time.time() function to evaluate amount of time (in seconds) required to calculate dot product using the function dot(x,y) which you defined above:

In [13]:
Copied!
import time

tic = time.time()
c = dot(a,b)
toc = time.time()
print("Dot product: ", c)
print ("Time for the loop version:" + str(1000*(toc-tic)) + " ms")
import time tic = time.time() c = dot(a,b) toc = time.time() print("Dot product: ", c) print ("Time for the loop version:" + str(1000*(toc-tic)) + " ms")
Dot product:  249658.37079888294
Time for the loop version:371.7811107635498 ms

Now compare it with the speed of the vectorized versions:

In [14]:
Copied!
tic = time.time()
c = np.dot(a,b)
toc = time.time()
print("Dot product: ", c)
print ("Time for the vectorized version, np.dot() function: " + str(1000*(toc-tic)) + " ms")
tic = time.time() c = np.dot(a,b) toc = time.time() print("Dot product: ", c) print ("Time for the vectorized version, np.dot() function: " + str(1000*(toc-tic)) + " ms")
Dot product:  249658.37079888294
Time for the vectorized version, np.dot() function: 1.8706321716308594 ms
In [15]:
Copied!
tic = time.time()
c = a @ b
toc = time.time()
print("Dot product: ", c)
print ("Time for the vectorized version, @ function: " + str(1000*(toc-tic)) + " ms")
tic = time.time() c = a @ b toc = time.time() print("Dot product: ", c) print ("Time for the vectorized version, @ function: " + str(1000*(toc-tic)) + " ms")
Dot product:  249658.37079888294
Time for the vectorized version, @ function: 1.7764568328857422 ms

You can see that vectorization is extremely beneficial in terms of the speed of calculations!

2.4 - Geometric Definition of the Dot Product¶

In Euclidean space, a Euclidean vector has both magnitude and direction. The dot product of two vectors $x$ and $y$ is defined by:

$$x\cdot y = \lvert x\rvert \lvert y\rvert \cos(\theta),\tag{2}$$

where $\theta$ is the angle between the two vectors:

No description has been provided for this image

This provides an easy way to test the orthogonality between vectors. If $x$ and $y$ are orthogonal (the angle between vectors is $90^{\circ}$), then since $\cos(90^{\circ})=0$, it implies that the dot product of any two orthogonal vectors must be $0$. Let's test it, taking two vectors $i$ and $j$ we know are orthogonal:

In [ ]:
Copied!
i = np.array([1, 0, 0])
j = np.array([0, 1, 0])
print("The dot product of i and j is", dot(i, j))
i = np.array([1, 0, 0]) j = np.array([0, 1, 0]) print("The dot product of i and j is", dot(i, j))

2.5 - Application of the Dot Product: Vector Similarity¶

Geometric definition of a dot product is used in one of the applications - to evaluate vector similarity. In Natural Language Processing (NLP) words or phrases from vocabulary are mapped to a corresponding vector of real numbers. Similarity between two vectors can be defined as a cosine of the angle between them. When they point in the same direction, their similarity is 1 and it decreases with the increase of the angle.

Then equation $(2)$ can be rearranged to evaluate cosine of the angle between vectors:

$\cos(\theta)=\frac{x \cdot y}{\lvert x\rvert \lvert y\rvert}.\tag{3}$

Zero value corresponds to the zero similarity between vectors (and words corresponding to those vectors). Largest value is when vectors point in the same direction, lowest value is when vectors point in the opposite directions.

This example of vector similarity is given to link the material with the Machine Learning applications. There will be no actual implementation of it in this Course. Some examples of implementation can be found in the Natual Language Processing Specialization.

Well done, you have finished this lab!

In [ ]:
Copied!


Documentation built with MkDocs.

Keyboard Shortcuts

Keys Action
? Open this help
n Next page
p Previous page
s Search