2.4. Array operations#

The Python commands for the common operations on arrays are summarised in Table 2.2.

Table 2.2 Operations on NumPy arrays#

Operation

Description

Python syntax

\(A + B\)

addition of two arrays

A + B

\(A - B\)

subtracting an array

A - B

\(kA\)

multiplying an array by a scalar

k * A

\(A^\mathsf{T}\)

matrix transpose

A.T

\(A \odot B\)

element-wise matrix multiplication

A * B

\(A B\)

matrix multiplication

np.dot(A, B)

\(A B C\)

multiple matrix multiplication

np.linalg.multi_dot([A, B, C])

\(A^{\circ k}\)

raising elements of an array to a scalar power

A ** k

\(A^k\)

raising a square matrix to a power

np.linalg.matrix_power(A, k)

\(\det(A)\)

matrix determinant

np.linalg.det(A)

\(A^{-1}\)

matrix inverse

np.linalg.inv(A)

Enter the following code into your program (you may want to run your program after entering printing each result).

# Array operations
B = np.array([ [5, 6], [7, 8] ])

print(f"A = \n\n {A} \n")
print(f"B = \n\n {B} \n")

A_add_B = A + B
print(f"A + B =\n\n {A_add_B} \n")

A_sub_B = A - B
print(f"A - B =\n\n {A_sub_B} \n")

A2 = 2 * A
print(f"2A = \n\n {A2} \n")

AT = A.T
print(f"A^T = \n\n {AT} \n")

Run your program and your should see the following added to the console output.

A = 

 [[1 2]
 [3 4]] 

B = 

 [[5 6]
 [7 8]] 

A + B =

 [[ 6  8]
 [10 12]] 

A - B =

 [[-4 -4]
 [-4 -4]] 

2A = 

 [[2 4]
 [6 8]] 

A^T = 

 [[1 3]
 [2 4]] 

Here we have performed some basic arithmetic operations on the 2D arrays A and B.


2.4.1. Element-wise multiplication#

When dealing with multiplication of arrays we need to make sure we distinguish between multiplying the elements of two arrays and matrix multiplication. Element-wise multiplication of two matrices is defined by

\[ \begin{align*} [A \odot B]_{ij} = a_{ij} b_{ij}. \end{align*} \]

i.e., the corresponding elements are multipied together. Given the matrices

\[\begin{split} \begin{align*} A &= \begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix}, & B &= \begin{pmatrix} 5 & 6 \\ 7 & 8 \end{pmatrix}, \end{align*} \end{split}\]

we have

\[\begin{split} \begin{align*} A \odot B = \begin{pmatrix} 1(5) & 2(6) \\ 3(7) & 4(8) \end{pmatrix} = \begin{pmatrix} 5 & 12 \\ 21 & 32 \end{pmatrix}. \end{align*} \end{split}\]

Enter the following code into your program

AB_elementwise = A * B
print(f"A * B = \n\n {AB_elementwise} \n")

Run your program and your should see the following added to the console output.

A * B = 

[[ 5 12]
 [21 32]]

2.4.2. Matrix multiplication#

The other way which we multiply arrays is to use matrix multiplication which, for a \(m \times n\) matrix \(A\) and a \(p \times q\) matrix \(B\), is defined by

\[ \begin{align*} [AB]_{ij} = \sum_{k=1}^n a_{ik}b_{kj}. \end{align*} \]

So to multiply our matrices \(A\) and \(B\) using matrix multiplication we use

\[\begin{split} \begin{align*} AB &= \begin{pmatrix} 1 & 2 \\ 4 & 5 \end{pmatrix} \begin{pmatrix} 5 & 6 \\ 7 & 8 \end{pmatrix} \\ &= \begin{pmatrix} 1(5) + 2(7) & 1(6) + 2(8) \\ 3(5) + 4(7) & 3(6) + 4(8) \end{pmatrix} \\ &= \begin{pmatrix} 5 + 14 & 6 + 16 \\ 15 + 28 & 18 + 32 \end{pmatrix} \\ &= \begin{pmatrix} 19 & 22 \\ 43 & 50 \end{pmatrix}. \end{align*} \end{split}\]

To perform matrix multiplication of two NumPy arrays A and B we use the np.dot(A, B) command. Enter the following code into your program.

AB = np.dot(A, B)
print(f"AB = \n\n {np.dot(A, B)} \n")

Run your program and your should see the following added to the console output.

AB = 

[[19 22]
 [43 50]]

To calculate multiple matrix multiplications we can use the np.lingalg.multi_dot([A, B, C, ...]) command. Enter the following code into your program.

ABA = np.linalg.multi_dot([A, B, A])
print(f"ABA = \n\n {ABA} \n")

Run your program and your should see the following added to the console output.

ABA = 

 [[ 85 126]
 [193 286]] 

2.4.3. Element-wise power#

Element-wise power is defined by

\[ [A ^{\circ k}]_{ij} = a_{ij}^k, \]

so for the matrix \(A\) defined above

\[\begin{split} A^{\circ 2} = \begin{pmatrix} 1^2 & 2^2 \\ 3^2 & 4^2 \end{pmatrix} = \begin{pmatrix} 1 & 4 \\ 9 & 16 \end{pmatrix}.\end{split}\]

Enter the following code into your program.

A_pow_2_elementwise = A ** 2
print(f"A^2 (elementise) = \n\n {A_pow_2_elementwise} \n")

Run your program and your should see the following added to the console output.

A^2 (elementise) = 

 [[ 1  4]
 [ 9 16]] 

2.4.4. Matrix power#

The matrix power of a square matrix \(A\) is denoted by \(A^n\) and is defined by

\[ A^n = \underbrace{A \cdot A \cdots A}_{n \textsf{ times}}. \]

To calculate \(A^k\) we use the np.lingalg.matrix_power(A, k) command. Enter the following code into your program.

A_pow_2= np.linalg.matrix_power(A, 2)
print(f"A^2 = \n\n {A_pow_2} \n")

Run your program and your should see the following added to the console output.

A^2 = 

 [[ 7 10]
 [15 22]] 

2.4.5. Matrix determinant#

The determinant of an \(n \times n\) square matrix is a numerical value associated with the matrix. The NumPy command to calculate the determinant of the matrix A is np.linalg.det(A). Enter the following code into your program.

detA = np.linalg.det(A)
print(f"det(A) = {detA} \n")

Run your program and your should see the following added to the console output.

det(A) = -2.0000000000000004

2.4.6. Matrix inverse#

The inverse of a non-singular (a matrix with a non-zero determinant) square matrix \(A\), denoted by \(A^{-1}\), is a square matrix such that \(AA^{-1} = I\). The NumPy command to calculate the inverse of the matrix A is np.linalg.inv(A). Enter the following code into your program.

invA = np.linalg.inv(A)
print(f"inv(A) = \n\n {invA} \n")

Run your program and you should see the following added to the console output.

inv(A) = 

[[-2.   1. ]
 [ 1.5 -0.5]]

2.4.7. Exercise#

Exercise 2.3

Using the arrays defined in Exercise 2.1 to calculate the following:

  1. \(2\vec{a}\)

  2. \(B + D\)

  3. \(C^\mathsf{T}\)

  4. \(B \odot D\)

  5. \(DB\)

  6. \(DBB^\mathsf{T}\)

  7. \(D^{\circ 3}\)

  8. \(B^4\)

  9. \(\det(B)\)

  10. \(B^{-1}\)