2.2. Arrays and Matrices#

2.2.1. Learning Goals#

After this notebook, you will be able to:

  1. Generate an manipulate python lists

  2. Import numpy package

  3. Use numpy arrays

  4. Use numpy matrices

2.2.2. Lists#

The python native version of an array is called a list. A list contains multiple elements and can be of various data types. There are multiple ways to initialize a list. We will start by investigating how one initializes a list.

2.2.2.1. Initializing lists#

# initialize list
a = [1,2,3]
print("a= ", a,type(a))
print("a[0] = ", a[0],type(a[0]))
print("a[1] = ", a[1],type(a[1]))
print("a[2] = ", a[2],type(a[2]))
a=  [1, 2, 3] <class 'list'>
a[0] =  1 <class 'int'>
a[1] =  2 <class 'int'>
a[2] =  3 <class 'int'>

In the above code we created a list called a with three elements. The first element is the integer value 1, the second element is the integer value 2, the third element is integer value 3.

Python is a C-based language so indexing of lists starts at 0. So the first element the list is a[0]

We will now look at ways of adding to lists

# initialize an empty list
a = []
print("a = ", a)
# append a value to a
a.append(3)
print("a = ", a)
# append another value to a
a.append(6)
print("a = ",  a)
a =  []
a =  [3]
a =  [3, 6]

2.2.2.2. Data types within lists#

Lists can have various data types

# initialize a list of varying data types
a = [1,2.0,3]
print(a,type(a))
print("a[0] = ", a[0],type(a[0]))
print("a[1] = ", a[1],type(a[1]))
print("a[2] = ", a[2],type(a[2]))
[1, 2.0, 3] <class 'list'>
a[0] =  1 <class 'int'>
a[1] =  2.0 <class 'float'>
a[2] =  3 <class 'int'>
a = [1,2.0,str(3)]
print(a,type(a))
print("a[0] = ", a[0],type(a[0]))
print("a[1] = ", a[1],type(a[1]))
print("a[2] = ", a[2],type(a[2]))
[1, 2.0, '3'] <class 'list'>
a[0] =  1 <class 'int'>
a[1] =  2.0 <class 'float'>
a[2] =  3 <class 'str'>

2.2.2.3. Useful functions on lists#

There are various attributes of list objects and functions applied to lists that might be useful.

a = [1,2,3]
print(a)
print("Length of a:", len(a))
[1, 2, 3]
Length of a: 3

2.2.3. Numpy#

Lists can be useful but when we want to perform vector and matrix math they can be quite cumberson. Python is a very common coding language and is actively developed in a variety of areas. As such it has a number of ‘’libraries’’ or bits of code to do common things that are already written. If we import those libraries we can utilize these functions. The most common example it the numpy library (http://www.numpy.org/). This library contains a lot of functions to perform vector, matrix and other common mathematical manipulations. The first step is to

import numpy as np.

import numpy as np

2.2.3.1. Vectors#

# defining an array/vector
a = np.array([2,3,1])
print("a = ", a, type(a))
a =  [2 3 1] <class 'numpy.ndarray'>
# vectors have some attributes that might be of interest
print("Size of array a:", a.size)
print("Data type of array a:", a.dtype)
Size of array a: 3
Data type of array a: int64

For a list of all attributes of arrays see: https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.ndarray.html

# vector manipulations
# for this I start by defining another vector in R3:
b = np.array([-1,0,7])
print("a=",a)
print("b=",b)
print("a+b=",a+b)
print("2a+3b=",2*a+3*b)
print("a*b=",a*b)
print("a*b=",np.dot(a,b))
# what are the differences between the last two lines?
print("a x b =",np.cross(a,b))
a= [2 3 1]
b= [-1  0  7]
a+b= [1 3 8]
2a+3b= [ 1  6 23]
a*b= [-2  0  7]
a*b= 5
a x b = [ 21 -15   3]

2.2.3.2. Matrices#

We can define a matrix in a number of ways. The first is to cast a list of lists as a numpy matrix.

# defining a matrix - these are just 2D arrays
a = np.matrix([[1,2],[3,4]])
b = np.matrix([[1,2],[3,4]],dtype=float)
c = np.matrix([[5,6],[-1,0]],dtype=float)
print(a)
print(b)
print(c)
[[1 2]
 [3 4]]
[[1. 2.]
 [3. 4.]]
[[ 5.  6.]
 [-1.  0.]]

We can also declare the matrices and populate them element by element.

a = np.empty((3,3),dtype=float)   # declare an empty matrix of size 3x3 and type float
for i in range(3):
    for j in range(3):
        a[i,j] = i+j              # place the value of i+j into the i,jth element of the matrix
print(a)
[[0. 1. 2.]
 [1. 2. 3.]
 [2. 3. 4.]]

Elements in a matrix can be accessed by square brackets and the integer indeces

print("a[0,0]=",a[0,0])
print("a[1,2]=",a[1,2])
a[0,0]= 0.0
a[1,2]= 3.0

2.2.3.3. Manipulating Matrices#

Numpy has a lot of built in functions to manipulate or assess a matrix.

# trace
print("Tr(a)=",np.trace(a))
# determinant
print("|a|=det(a)=",np.linalg.det(a))
# transpose
print("a^T=",a.T)
Tr(a)= 6.0
|a|=det(a)= 0.0
a^T= [[0. 1. 2.]
 [1. 2. 3.]
 [2. 3. 4.]]

More complicated matrix manipulations such as inverses and diagonalizations can also be done

# inverse
np.linalg.inv(a)
---------------------------------------------------------------------------
LinAlgError                               Traceback (most recent call last)
/var/folders/td/dll8n_kj4vd0zxjm0xd9m7740000gq/T/ipykernel_29582/1624788978.py in <module>
      1 # inverse
----> 2 np.linalg.inv(a)

~/opt/anaconda3/lib/python3.9/site-packages/numpy-1.25.0-py3.9-macosx-10.9-x86_64.egg/numpy/linalg/linalg.py in inv(a)
    559     signature = 'D->D' if isComplexType(t) else 'd->d'
    560     extobj = get_linalg_error_extobj(_raise_linalgerror_singular)
--> 561     ainv = _umath_linalg.inv(a, signature=signature, extobj=extobj)
    562     return wrap(ainv.astype(result_t, copy=False))
    563 

~/opt/anaconda3/lib/python3.9/site-packages/numpy-1.25.0-py3.9-macosx-10.9-x86_64.egg/numpy/linalg/linalg.py in _raise_linalgerror_singular(err, flag)
    110 
    111 def _raise_linalgerror_singular(err, flag):
--> 112     raise LinAlgError("Singular matrix")
    113 
    114 def _raise_linalgerror_nonposdef(err, flag):

LinAlgError: Singular matrix
Note that not all matrices are invertible!
# eigenvalues and eigenvectors
e,v = np.linalg.eig(a)
print("Eigenvalues:",e)
print("Eigenvectors:",v)
Eigenvalues: [ 6.87298335e+00 -8.72983346e-01 -3.17588043e-16]
Eigenvectors: [[-0.30646053 -0.8598926   0.40824829]
 [-0.54384383 -0.19382266 -0.81649658]
 [-0.78122713  0.47224729  0.40824829]]