A matrix is a $2$-dimensional (2D) array of numbers. This means that every element in the matrix is identified by two indices, commonly $i$ representing the row-index and $j$ representing the column-index.
Matrices are usually given uppercase variable names in bold, such as $\mathbf{A}$.
We use a colon “:” to represent all the elements across an axis. So, $\mathbf{A}_{i,:}$ identifies all the elements in the $i$th row and $\mathbf{A}_{:,j}$ identifies all the elements in the $j$th column. If a real-valued matrix (i.e. its elements are all real numbers) has $m$ rows and $n$ columns, we show the matrix dimensionality as $\mathbf{A} \in \mathbb{R}^{m \times n}$.
In Python, we can represent a matrix as a list of lists, however, it is more convenient to represent matrices and higher-order tensors in packages designed to handle them such as NumPy, TensorFlow or PyTorch.
A = np.array([[7, 4, 3, 2], [0, 8, 9, 5]])
# Python is zero-indexed so A[1,:] will give the second row in the matrix
print("First element of matrix A is {}".format(A[0,0]))
print("Second row of matrix A is {}".format(A[1,:]))
print("A is of type {}".format(type(A)))
print("A has shape {}".format(A.shape)) # 2 rows, 4 columns
First element of matrix A is 7
Second row of matrix A is [0 8 9 5]
A is of type <class 'numpy.ndarray'>
A has shape (2, 4)
NumPy allows us to do various matrix operations such as element-wise multiplication, matrix multiplication, dimensionality manipulation, broadcasting and more. Some examples can be found below.
# Create a 2x2 identitity matrix
B = np.identity(2)
print(B)
[[1. 0.]
[0. 1.]]
# Create a matrix of ones
B = np.ones(shape=(2, 4))
print(B)
[[1. 1. 1. 1.]
[1. 1. 1. 1.]]
# Element-wise multiplication by a scalar
B = 3*B
print(B)
[[3. 3. 3. 3.]
[3. 3. 3. 3.]]
# Multiplication of a vector and a matrix through broadcasting
x = np.array([7, 4, 3, 2])
B = x*B
print(B)
[[21. 12. 9. 6.]
[21. 12. 9. 6.]]
# Element-wise multiplication between two matrices of the same shape
C = A*B
print(C)
[[147. 48. 27. 12.]
[ 0. 96. 81. 30.]]
# Matrix multiplication between two matrices
C = A.dot(B.T) # We transpose B to get a multiplication between matrices of shapes (2, 4) x (4, 2) = (2, 2)
print(C)
[[234. 234.]
[207. 207.]]
# Modify a matrix element in-place
C[1,1] -= 5
print(C)
[[234. 234.]
[207. 202.]]
# We can also invert a square, non-singular matrix
C_inv = np.linalg.inv(C)
print(C_inv)
[[-0.17264957 0.2 ]
[ 0.17692308 -0.2 ]]
# Another way to do matrix inversion would be through the NumPy matrix object instead of using arrays
D = np.matrix([[234, 234], [207, 202]])
D_inv = D.I
print(D_inv)
[[-0.17264957 0.2 ]
[ 0.17692308 -0.2 ]]
# The multiplication of a matrix with its inverse should therefore give
# the Identity matrix (subject to floating-point inaccuracies)
E = D.dot(D_inv)
assert np.array_equal(E, np.identity(E.shape[0])), "E is not equal to the identity matrix of the same shape!"
print(E)
[[1. 0.]
[0. 1.]]
# Expand a matrix dimensions
print("Original matrix shape is", E.shape)
E = np.expand_dims(E, axis=1)
print("Matrix shape after expanding dimensions on axis 1 is", E.shape)
Original matrix shape is (2, 2)
Matrix shape after expanding dimensions on axis 1 is (2, 1, 2)
For more examples, see https://scipy-lectures.org/intro/numpy/operations.html
Source: https://github.com/maxbartolo/ml-index/blob/master/01-basic-math/01-linear-algebra/03-matrices.ipynb
Share this post
Twitter
Facebook
Reddit
LinkedIn
Google+
StumbleUpon
Pinterest
Email