Software tutorial/Vectors and arrays
Contents
In this section we will focus on containers for your numbers: vectors and arrays. For the purposes of this section you should use this terminology:
 Vector
 A onedimensional list of numbers
 Array
 A multidimensional arrangement of numbers
 Matrix
 A twodimensional array
In this course we will mainly use vectors and matrices, however, arrays are extremely prevalent in process modelling.
Creating vectors
We will create these vectors:
 \(a = [4.0, \, 5, \,6, \,2,\, 3, \text{NaN}, \infty]\)
 \(b = [0, 0, \ldots, 0]\) with 300 columns of zeros, one row
 \(c = [1, 1, \ldots, 1]^T\) with 300 rows of ones in a single column
 \(d = [2.6, 2.6, \ldots, 2.6]^T\) with 300 entries of 2.6 in one column
 \(e = [4.5, 4.6, 4.7, \ldots, 10.5] \), equispaced entries
 \(f = \) 26 equispaced entries starting from 3.0, going down 4.0
MATLAB  Python 

a = [4, 5, 6, 2, 3, NaN, inf];
b = zeros(1, 300);
c = ones(300, 1);
d = ones(300, 1) .* 2.6;
e = 4.5:0.1:10.5;
f = linspace(3.0, 4.0, 26);
>> size(a)
ans =
1 7
>> size(c)
ans =
300 1
>> size(f)
ans =
1 26
In MATLAB, everything is an array, even a scalar is just a \(1 \times 1\) array, and vectors are either a \(1 \times n\) or \(n \times 1\) array. 
import numpy as np
a = np.array([4, 5, 6, 2, 3, np.nan, np.inf])
b = np.zeros((1, 300)) # note the extra brackets!
c = np.ones((300, 1))
d = np.ones((300, 1)) * 2.6
e = np.arange(4.5, 10.5001, 0.1); # type help(np.arange) to understand why
f = np.linspace(3.0, 4.0, 26)
>>> a.shape
(7,)
>>> c.shape
(300, 1)
>>> f.shape
(26,)
The NumPy library in Python supports two different data containers: arrays and matrices. We will not use NumPy matrices in this course, because they cannot deal with multiple dimensions (e.g. 3 dimensional arrays). And even though we will probably not use multidimensional arrays in this course, it is not worth learning about NumPy matrices, because they are fairly limited. So we will focus on NumPy arrays, which while a bit harder to get used to, are much more powerful than NumPy matrices. A NumPy array is roughly equivalent to a MATLAB array. One difference though with MATLAB, is that a Numpy array with one dimension, in other words a vector, has a shape property of (n,): indicating the vector has nelements. It is not like MATLAB where one of the dimensions is a 1 (one). If you require the vector to be either a row vector or a column vector, then you must do so explicitly. The following code demonstrates this: np.zeros(300).shape # (300,) a general vector
np.zeros((300, 1)).shape # (300, 1) a column vector
np.zeros((1, 300)).shape # (1, 300) a row vector

Creating arrays
We will create these arrays:
 \(a = \left(\begin{array}{cccc} 1 & 1 & 1 & 2 \\ 4 & 1 & 2 & 3 \\ \end{array} \right)\)
 \(b = \left(\begin{array}{cccc} 0 & 0 & \dots & 0 \\ \vdots & & & \vdots \\ 0 & 0 & \dots & 0 \\\end{array} \right)\), a \( 5 \times 8\) array of zeros
 \(c = \left(\begin{array}{cccc} 1 & 2 & \dots & 10 \\ 11 & 12 & \ldots & 20 \\ \vdots & \vdots & & \vdots \\ 61 & 62 & \dots & 70 \\\end{array} \right)\), a \( 7 \times 10\) array of sequence integers
MATLAB  Python 

a = [1, 1, 1, 2; 4, 1, 2, 3];
b = zeros(5,8);
c = reshape(1:70, 10, 7)'
The last line requires a bit more explanation. It first creates a vector with 70 integers, starting from 1 and ending at 70. Then it reshapes that vector into a matrix, with 10 rows and 7 columns. Then it transposes the array into the desired \(7 \times 10\) result. What would have been the result if you wrote: reshape(1:70, 7, 10): can you explain why? See more on manipulating vectors and arrays below. 
a = np.array([[1, 1, 1, 2], [4, 1, 2, 3]])
b = np.zeros((5, 8))
c = np.reshape(np.arange(1,71), (7, 10))
In Python, when you write something like [5, 2, 7, 2] you are creating a list; in this case a list of numbers. If you write [[1, 1, 1, 2], [4, 1, 2, 3]], then that is a list of lists. An array is nothing more than a list of lists, where the inner list a vector. So a list of lists is a 2D array, i.e. a matrix, while a list of lists of lists is a 3dimensional array. You would not normally write these by hand, but the reason for the seemingly complex notation is that arrays are usually created from Excel files, or other data sources. When these are loaded into Python they are presented as a list of lists. So it is easy to create NumPy arrays from these data sources: something like np.array(data_from_excel_file). 
Array addition and subtraction
Array addition and subtraction work as you would expect, as long as the arrays are of the same size. You can add and subtract two \(N\)dimensional arrays in MATLAB or in Python as long as the corresponding dimensions are the same on both arrays. This is called elementbyelement addition or subtraction. In MATLAB and Python, imagine you have arrays A and B of the same dimension, then you simply write A + B or A  B. This elementbyelement operation also works if one of the arrays is a scalar.
Array multiplication and matrix multiplication
We will look at two types of multiplication: array multiplication and matrix multiplication. This table outlines the difference:
Multiplication type  MATLAB  Python 

Array multiplication (elementbyelement multiplication) 
A .* B 
A * B 
Matrix multiplication (as used in linear algebra) 
A * B 
np.dot(A, B) 
Since MATLAB considers variables to be matrices, it defines the multiplication operator, *, to be for matrix multiplication. NumPy's native data structure is the array, so it defines the * operator as array multiplication (i.e. elementbyelement multiplication).
You cannot use * in MATLAB for \(N\)dimensional arrays, when \(N>2\), since that operation is undefined. The arrays (matrices) A and B in the above table must obviously have consistent dimensions for matrix multiplication.
Example: Given the two matrices, \(A\) and \(B\) calculate the matrix (dot) product, \(A \cdot B\), or often just written as \(AB\). Also calculate the array (elementbyelement) product of \(A\) and \(B^T\)
 A = \(\left(\begin{array}{cccc} 1 & 3 & 5 \\ 7 & 9 & 11 \\ \end{array} \right)\)
 B = \(\left(\begin{array}{cccc} 0 & 2 \\4 & 6 \\ 8 & 10 \\ \end{array} \right)\)
MATLAB  Python 

A = [1, 3, 5; 7, 9, 11];
B = [0, 2; 4, 6; 8, 10];
>> A*B
ans =
52 70
124 178
>> A .* B'
ans =
0 12 40
14 54 110

A = np.array([[1, 3, 5], [7, 9, 11]])
B = np.array([[0, 2], [4, 6], [8, 10]])
>>> np.dot(A, B)
array([[ 52, 70],
[124, 178]])
>>> A * B.T
array([[ 0, 12, 40],
[ 14, 54, 110]])

Solving a system of linear algebra equations \( Ax = b\)
As our course progresses we will go into the details of how MATLAB and Python solve the common linear system of equations, \(Ax = b\), where \(A\) is an \(N \times N\) matrix, and \(b\) is an \(N \times 1\) vector.
For now though, you can simply use the commands in MATLAB or Python:
MATLAB  Python 

x = A \ b; % is the operator form
x = mldivide(A, b); % is the function form

x = np.linalg.solve(A, b) # only available in function form
