London South Bank University
Foundations of Cal, Statistics, and Optimisation
WEEK 5_Tutorial notes_Task
Hannah Oh • November 2025
Keywords : Norm, Distance, Vectors independent, Angle, Orthogonality
1. Week 5
Week 5’s tutorial covers three main linear algebra concepts that are essential for under-
standing matrix operations:
• Norm of a Vector: Vector Length
• Angle Between Two Vectors: Vector Relationships
• Rotation Matrices: Linear Transformations
PART 1: Importing the necessary libraries for this tutorial
(a) import numpy as np : Check the previous tutorial notes
(b) import [Link] as LA :
• [Link] is a submodule of NumPy that provides functions for linear
algebra operations. It’s specifically designed for matrix and vector compu-
1
Statistical Analysis and Modelling Tutorial
tations commonly used in mathematics, physics, engineering, and data
science.
• Click 1
• Click 2
(c) import [Link] as plt :
• [Link] is a plotting library that creates 2D visualisations
(graphs, charts, plots). It’s the standard tool for data visualisation in
Python.
• Click 1
• Click 2
• Click 3
PART 2: Norm - 5 methods
A norm on a vector space V is a function which assigns each vector x its length.
The Euclidean norm corresponds to the distance of x from the origin.
v
uX
u n
√ √
∥x∥2 = t x2
i = x · x = x⊤ x
i=1
1.1 1st Method: Basic Norm Calculation
1 # Creates a 1 D NumPy array representing a 2 D vector
2 u = np . array ([2 , 5])
3
4 # 1 st Method
5 u_squared = u **2
6 sum_u_squared = np . sum ( u_squared )
7 u_norm_1 = np . sqrt ( sum_u_squared )
8
9 print ( " u_squared = " , u_squared )
10 print ( " sum_u_squared = " , sum_u_squared )
11 print ( " || " , u , " || = " , u_norm_1 )
• u_squared = u**2
– Operation ** : Element-wise squaring (raises each component to power of 2)
– Expected output: [22 , 52 ] = [4, 25]
– Actual output( print("u_squared =",u_squared) ): “u_squared = [ 4 25]”
• sum_u_squared = [Link](u_squared)
– [Link]() adds all elements in the array
P 2
– Purpose: Finds the sum needed for the norm formula( ni=1 ui )
– Actual output( print("sum_u_squared = ",sum_u_squared) ): “sum_u_squared
= 29”
2
Statistical Analysis and Modelling Tutorial
• u_norm_1 = [Link](sum_u_squared)
– [Link]() calculates the square root
√
– Calculation: 29
qP
– Purpose: Completes the norm formula: ∥u∥2 = n 2
i=1 ui
– Actual output( print("||", u, "|| =",u_norm_1) ): “|| [2 5] ||
= 5.385164807134504”
– It means the distance from the origin (0,0) to the point (2,5)
1.2 2nd Method: Condensed Norm Calculation
1 # second method . same as the first one but in one row .
2 u_norm_2_way = np . sqrt ( np . sum ( u **2) )
3 print ( " || " , u , " || = " , u_norm_2_way )
• From the 2nd Method, we combine all previous steps into one line.
• Execution order (nested functions):
– u**2 → [4, 25]
– [Link](...) → 29
– [Link](...) →≈ 5.385
• Advantage: More compact and fewer intermediate variables
• Actual output( print("||", u, "|| =",u_norm_2_way) ): “|| [2 5] ||
= 5.385164807134504”
1.3 3rd Method: Norm Using Dot Product
1 # third method .
2 u_norm_3_way = np . sqrt ( np . dot (u , u ) )
3 print ( " || " , u , " || = " , u_norm_3_way )
• [Link](u, u) computes the dot product u·u
• u · u = u1 2 + u 2 2 = ∥ u ∥ 2
– Expecter output: (2×2) + (5×5) = 4 + 25 = 29
– [Link](29) →≈ 5.385
– Actual output( print("||", u, "|| =",u_norm_3_way) ): “|| [2 5] ||
= 5.385164807134504”
• Dot product of vector with itself gives squared norm
1.4 4th Method: Norm Using Transpose
1 # fourth method .
2 u_norm_4_way = np . sqrt ( np . dot ( u .T , u ) )
3 print ( " || " , u , " || = " , u_norm_4_way )
• u.T : Transpose of vector u
3
Statistical Analysis and Modelling Tutorial
– For 1D array [2, 5], transpose still gives [2, 5]
– ∥ u ∥ = (uT u) where uT is transpose of u
p
• [Link](u.T, u) : Performs dot product (same as u · u)
– Expecter output: 29
– [Link](29) →≈ 5.385
– Actual output( print("||", u, "|| =",u_norm_4_way) ): “|| [2 5] ||
= 5.385164807134504”
• Better for 2D matrices where transpose actually changes dimensions
1.5 5th Method: Norm Using Linear Algebra Library (Method 5)
1 # fifth method .
2 import numpy . linalg as LA
3
4 u_norm_5_way = LA . norm ( u )
5 print ( " || " , u , " || = " , u_norm_5_way )
• Remind: Imports the linear algebra module from NumPy
– Functions for norms, matrix operations, eigenvalues, etc.
• u_norm_5_way = [Link](u)
– [Link]() calculates vector norm directly
– Default: Computes L2 norm (Euclidean norm)
– Actual output( print("||", u, "|| =",u_norm_5_way) ): “|| [2 5] ||
= 5.385164807134504”
PART 3: Angle between two vectors-Calculating the angle between vectors
One of the many uses of the dot product is to calculate the angle between two
non-zero vectors:
u·v
ω = arc cos
∥u∥ ∥v∥
Note that if u · v = 0, it follows that = π/2. In other words, if the dot product of two
non-null vectors is zero, it means that they are orthogonal. Let’s use this formula
to calculate the angle between u and v(in radians):
4
Statistical Analysis and Modelling Tutorial
1.6 PART ONE: Basic Angle Calculation
1 # PART ONE
2 v = np . array ([3 ,1])
3 cos_omega = np . dot (u , v ) / ( LA . norm ( u ) * LA . norm ( v ) )
4 omega = np . arccos ( cos_omega )
5
6 print ( " Angle = " , omega , " radians " )
7 print ( " = " , omega * 180 / np . pi , " degrees " )
• v = [Link]([3,1])
– Creates a second vector v = [3, 1]
– We need another vector BECAUSE we calculate angle between u = [2, 5] and v
= [3, 1]
• cos_omega = [Link](u,v) / ([Link](u) * [Link](v))
u·v
cos(ω) =
∥u∥ × ∥v∥
– [Link](u,v) : Computes dot product
* Calculation: (2×3) + (5×1) = 6 + 5 = 11
– [Link](u) : Calculates ∥ u ∥
√
* Result: 29 ≈ 5.385
– [Link](v) : Calculates ∥ v ∥
√
* Result: 10 ≈ 3.162
– Division: 11/(5.385 × 3.162) ≈ 0.649
• omega = [Link](cos_omega)
– [Link]() computes inverse cosine (arccos), that is, the angle in radians be-
tween the two vectors
– Input: cos_omega ≈ 0.649
– Output:
* print("Angle =", omega, "radians") : “Angle = 0.8685393952858896
radians”
* print(" =", omega * 180 / [Link], "degrees") : “= 49.76364169072618
degrees”
* Converts radians to degrees: ω(180/π) = 0.8685 × (180/3.14159) ≈ 49.76◦
5
Statistical Analysis and Modelling Tutorial
1.7 PART TWO: Handling Floating-Point Errors
1 # PART TWO
2 # same as before but with cos_omega clipped
3 v = np . array ([3 ,1])
4 cos_omega = np . dot (u , v ) / ( LA . norm ( u ) * LA . norm ( v ) )
5 omega = np . arccos ( np . clip ( cos_omega , -1 , 1) ) # clipped
6
7 print ( " Angle = " , omega , " radians " )
8 print ( " = " , omega * 180 / np . pi , " degrees " )
• cos_omega = [Link](u,v) / ([Link](u) * [Link](v))
– Recalculates cos_omega
– Same calculation as the previous cell
• omega = [Link]([Link](cos_omega,-1, 1))
– [Link](value, min, max) : Constrains value within range [min, max]
* If value < -1, returns -1
* If value > 1, returns 1
* Otherwise, returns the original value
– Why needed?
* Due to floating-point arithmetic errors, cos_omega might be slightly outside
[-1, 1]
* Example: cos_omega could be 1.0000001 or -1.0000001
· arccos() only accepts values in [-1, 1]
· Without clipping, arccos() would return NaN (not a number)
– cos_omega ≈ 0.649 (already valid), so clipping has no effect
1.8 PART THREE: Demonstrating the Clipping Problem
1 # PART THREE
2 # An example of what would happend if cos_omega were out of the [ -1 ,1] range
3 cos_omega = -1.0001
4 omega = np . arccos ( cos_omega )
5
6 # As expcted , a warning was issued .
7 # So we need to clip the cosine first , as follows :
8 np . clip ( cos_omega , -1 , 1)
9 omega = np . arccos ( np . clip ( cos_omega , -1 , 1) )
10 print ( " Angle = " , omega , " radians " )
11 print ( " = " , omega * 180 / np . pi , " degrees " )
• cos_omega = -1.0001 : We set cos_omega to -1.0001 (outside valid range)
• [Link](cos_omega) : Attempts to compute arccos(-1.0001)
• Output
– RuntimeWARNING: invalid value encountered in arccos”
– RuntimeWarning issued because arccos() cannot process this value
6
Statistical Analysis and Modelling Tutorial
– omega becomes “NaN (not a number)”
• omega = [Link]([Link](cos_omega,-1, 1))
– [Link](cos_omega,-1, 1) : Clips -1.0001 to -1.0
– [Link]() : arccos(-1.0) = π radians
– No warning because -1.0 is valid
• Output: “ Angle = 3.141592653589793 radians = 180.0 degrees”
– It means two vectors pointing in opposite directions (180◦ apart)
PART 4: Rotation matrices
We saw that the multiplication by a matrix A ∈ R(m×n) can be interpreted as a
linear transformation (function) from a space V to a space W that maps a vector x
onto a vector y = Ax.
One particular kind of linear transformation is rotation. A rotation matrix has the
effect of rotating the vector x and can be defined as follows:
" #
cos(ω) −sin(ω)
A=
sin(ω) cos(ω)
The effect of the matrix above, is to rotate any vector in the plane by an angle ω
counterclockwise.
1 # Create the matrix A to rotate vectors in the plane by 45 degrees
counterclockwise .
2 omega = np . radians (45)
3 print ( omega )
4 print ( np . pi /4)
5
6 c = np . cos ( omega )
7 s = np . sin ( omega )
8 #c , s = np . cos ( omega ) , np . sin ( omega )
9 A = np . array ((( c , -s ) , (s , c ) ) )
10 print ( A )
11
12 e1 = np . array ([1 ,0])
13 np . matmul (A , e1 )
• omega = [Link](45)
– [Link]() converts degrees to radians
* Input: 45 degrees
* Calculation → 45 × (π/180) = π/4 ≈ 0.7854 radians
• print([Link]/4) shows π/4 ≈ 0.7853981633974483
• So, we can confirm that they(omega ,[Link]/4 )are the same value.
• c = [Link](omega)
– Calculation → cos(45◦ ) ≈ 0.7071
– Used in the rotation matrix formula
7
Statistical Analysis and Modelling Tutorial
• s = [Link](omega)
– Calculation → sin(45◦ ) ≈ 0.7071
– Used in the rotation matrix formula
• An alternative way in Python to define c and s simultaneously
– c, s = [Link](omega), [Link](omega)
• A = [Link](((c, -s), (s, c)))
– Creates rotation matrix A using the formula
" #
cos(ω) −sin(ω)
A=
sin(ω) cos(ω)
– ((c, -s), (s, c)) : Tuple of tuples
* First row: (c, -s) = (0.7071, -0.7071)
* Second row: (s, c) = (0.7071, 0.7071)
– [Link]() : Converts tuple structure into 2D NumPy array
• Output print(A)
– [[0.70710678, −0.70710678],
[0.70710678, 0.70710678]]
• Output e1 = [Link]([1,0])
– Creates unit vector e1 pointing right (along x-axis)
– Why? Simple vector to demonstrate rotation effect
• [Link](A,e1)
– [Link]() performs matrix multiplication
– Calculation → A × e1
– Original vector [1,0] rotated 45◦ counterclockwise becomes [0.7071, 0.7071]
– Both components equal because 45◦ is midway between x and y axes
8
Statistical Analysis and Modelling Tutorial
Figure 1: The workflow for the tasks
1.9 TASKS
**The code is based on the sample solution the lecturer provided.
(a) QUESTION 1: Given the following vectors: [5,1], [10, 2], find the angle be-
tween the two vectors
1 # Import libraries
2 import numpy as np
3 import numpy . linalg as LA
4 import matplotlib . pyplot as plt
5
6 # Given vectors : u = [5 , 1] , v = [10 , 2]
7 # Find the angle between the two vectors
8 u = np . array ([5 , 1])
9 v = np . array ([10 , 2])
10
11 # Angle ( in radians and degrees )
12 cos_omega = np . dot (u , v ) / ( LA . norm ( u ) * LA . norm ( v ) )
13 omega = np . arccos ( np . clip ( cos_omega , -1 , 1) )
14
15 print ( " Angle between [5 ,1] and [10 ,2]: " )
16 print ( " = " , omega , " radians " )
17 print ( " = " , omega * 180 / np . pi , " degrees \ n " )
18
19 ---------------------------------------
20 # OUTPUT /
21 Angle between [5 ,1] and [10 ,2]:
22 = 0.0 radians
23 = 0.0 degrees
Example 1: Angle Between Vectors
9
Statistical Analysis and Modelling Tutorial
(b) QUESTION 2: Are the vectors independent? Why? Do NOT use the elim-
ination method to check the independence. You can use the elimination
method to double check your answer.
1 # Are the vectors independent ?
2 # The vectors [5 ,1] and [10 ,2] are scalar multiples :
3 # v = 2 * u they are linearly dependent
4 print ( " Independence check : " )
5 ratio = v [0] / u [0] if u [0] != 0 else None
6 print ( " v = " , ratio , " * u ? " )
7 print ( " Yes , because [10 ,2] = 2 * [5 ,1] Dependent \ n " )
8
9 ---------------------------------------
10 # OUTPUT /
11 Independence check :
12 v = 2.0 * u ?
13 Yes , because [10 ,2] = 2 * [5 ,1] Dependent
Example 2: Linear Independence (First Pair)
(c) QUESTION 3: What about the vectors [1,2,3] and [-2,0,4]? Are these vectors
independent? Do NOT use the elimination method to check the indepen-
dence. You can use the elimination method to double check your answer.
1 # Vectors [1 ,2 ,3] and [ -2 ,0 ,4]
2 a = np . array ([1 ,2 ,3])
3 b = np . array ([ -2 ,0 ,4])
4
5 # Check if one is a scalar multiple of the other
6 # ( i . e . , if b = k * a for some k )
7 # We ' ll compare the ratios of nonzero elements
8 ratios = []
9 for ai , bi in zip (a , b ) :
10 if ai != 0:
11 ratios . append ( bi / ai )
12 ratios_unique = set ( np . round ( ratios , 6) ) # round to remove floating errors
13
14 print ( " Independence check for [1 ,2 ,3] and [ -2 ,0 ,4]: " )
15 print ( " Ratios = " , ratios_unique )
16 if len ( ratios_unique ) == 1:
17 print ( " They are scalar multiples Dependent " )
18 else :
19 print ( " Ratios differ Independent \ n " )
20
21 # Double - check with rank method
22 M = np . column_stack (( a , b ) )
23 rank = np . linalg . matrix_rank ( M )
24 print ( " Matrix rank = " , rank , " Independent " if rank == 2 else "
Dependent " )
25 print ()
26
27 ---------------------------------------
28 # OUTPUT /
29 Independence check for [1 ,2 ,3] and [ -2 ,0 ,4]:
30 Ratios = {0.0 , 1.333333 , -2.0}
10
Statistical Analysis and Modelling Tutorial
31 Ratios differ Independent
32 Matrix rank = 2 Independent
Example 3: Linear Independence (Second Pair)
(d) QUESTION 4: Given the vector [10, 2], which is its l2 norm?
1 # Given vector [10 , 2] , find its l2 norm
2 x = np . array ([10 , 2])
3 l2_norm = LA . norm ( x )
4 print ( " l2 norm of [10 ,2] = " , l2_norm , " \ n " )
5
6 ---------------------------------------
7 # OUTPUT /
8 l2 norm of [10 ,2] = 10.198039027185569
Example 4: L2 Norm
(e) QUESTION 5: How can you compute the l1 norm of the same vector? Note
that the easiest approach it to apply a function (to be defined) from the
[Link] library. You can look up the documentation online to find out
what is the function to be applied.
1 # Compute l1 norm ( sum of absolute values )
2 l1_norm = LA . norm (x , 1)
3 print ( " l1 norm of [10 ,2] = " , l1_norm , " \ n " )
4
5 ---------------------------------------
6 # OUTPUT /
7 l1 norm of [10 ,2] = 12.0
Example 5: L1 Norm
(f) QUESTION 6: How can you get a vector that points in the same direction as
[10, 2] but whose norm is 1? What is this vector?
1 # Get a vector pointing in the same direction as [10 , 2]
2 # but whose norm is 1 ( unit vector )
3 x_unit = x / LA . norm ( x )
4 print ( " Unit vector in direction of [10 ,2]: " , x_unit )
5 print ( " Norm of unit vector = " , LA . norm ( x_unit ) , " \ n " )
6
7 ---------------------------------------
8 # OUTPUT /
9 Unit vector in direction of [10 ,2]: [0.98058068 0.19611614]
10 Norm of unit vector = 1.0
Example 6: Unit Vector
(g) QUESTION 7: What is the matrix that rotate a two-dimensional vector by
60 degrees clockwise? Choose a two-dimensional vector to be rotated and
rotate the vector by applying the rotation matrix to rotate by 60 degrees
clockwise. Plot the original vector and the rotated vector.
1 # Rotation matrix : 60 degrees clockwise
2 # Clockwise = negative angle in standard math rotation
3 theta = np . radians ( -60) # - for clockwise
11
Statistical Analysis and Modelling Tutorial
4 c , s = np . cos ( theta ) , np . sin ( theta )
5 R = np . array ([[ c , -s ] ,
6 [s , c ]])
7
8 print ( " Rotation matrix for 60 clockwise :\ n " , R , " \ n " )
9
10 # Choose a vector to rotate ( you can change this )
11 v_original = np . array ([4 , 2])
12 v_rotated = R @ v_original
13
14 print ( " Original vector : " , v_original )
15 print ( " Rotated vector : " , np . round ( v_rotated , 4) )
16
17 # Plot original and rotated vector
18 plt . figure ( figsize =(6 ,6) )
19 origin = np . array ([[0 ,0] ,[0 ,0]]) # origin point
20
21 plt . quiver (* origin , [ v_original [0] , v_rotated [0]] ,
22 [ v_original [1] , v_rotated [1]] ,
23 angles = ' xy ' , scale_units = ' xy ' , scale =1 ,
24 color =[ ' blue ' , ' red ' ])
25
26 plt . xlim ( -5 ,5) # Sets X - axis limits ( -5 to 5)
27 plt . ylim ( -5 ,5) # Sets Y - axis limits ( -5 to 5)
28 plt . axhline (0 , color = ' black ' , linewidth =0.8)
29 plt . axvline (0 , color = ' black ' , linewidth =0.8)
30 plt . gca () . set_aspect ( ' equal ' , adjustable = ' box ')
31 plt . title ( " Blue : Original vector | Red : Rotated 60 clockwise " )
32 plt . grid ( True )
33 plt . show ()
34
35 ---------------------------------------
36 # OUTPUT /
37 7. Rotation matrix for 60 clockwise :
38 [[ 0.5 0.8660254]
39 [ -0.8660254 0.5 ]]
40
41 Original vector : [4 2]
42 Rotated vector : [ 3.7321 -2.4641]
Example 7: Rotation Matrix(60◦ Clockwise) and Plotting
12
Statistical Analysis and Modelling Tutorial
Figure 2: Plot result
13