Live Coding Session: Modeling and Simulation Basics#
Objectives#
Work with vectors and matrices in Python.
Learn how to iterate through arrays and perform matrix operations.
Explore symbolic math using SymPy.
Create simple plots with Matplotlib.
Define functions
Section 1: Arrays and Matrices#
Step 1.1: Create a Row and Column Vector#
We start by creating a row vector and a column vector using NumPy.
[3]:
import numpy as np
# Make a row vector using Numpy
v_flat = np.array([1, 2, 3])
print("v_flat: ", v_flat)
# Make a column vector using Numpy
v_tall = np.array([[1], [2], [3]])
print("v_tall:\n ", v_tall)
v_flat: [1 2 3]
v_tall:
[[1]
[2]
[3]]
Step 1.2: Create a Matrix and perform matrix-vector multiplications#
We can also use Numpy to defind matrices and perform various mathematical operations on matrices and vectors
[9]:
# Create a matrix
M = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print("Matrix: \n", M)
# Multipy the matrix by a vector using Nympy's dot method
new_vector = np.dot(M, v_tall)
print("new vector:\n ", new_vector)
# Make a scalar by dotting the column vector, matrix and row vector
scalar = np.dot(np.dot(v_flat, M), v_tall)
print("scalar: ", scalar)
Matrix:
[[1 2 3]
[4 5 6]
[7 8 9]]
new vector:
[[14]
[32]
[50]]
scalar: [228]
Section 2: Arrays#
Step 2.1: Generating an array#
Our task is to generate an array of time instances from 0 to 10 seconds with 0.5 second time steps.
The linspace method takes the following arguments:
The starting value of the sequence
The end value of hte sequence
The number of samples to generate
[10]:
# Generate an array using Numpy's linspace method
step_size = 0.5
n_steps = int(10/0.5)+1
time_steps = np.linspace(0, 10, n_steps)
print(time_steps)
[ 0. 0.5 1. 1.5 2. 2.5 3. 3.5 4. 4.5 5. 5.5 6. 6.5
7. 7.5 8. 8.5 9. 9.5 10. ]
Step 2.2: Iterate through the array#
We will use a for-loop to iterate through the array we generated to print each time step
[11]:
# Iterate through the array and print something
for t in time_steps:
print("time is: ", t)
time is: 0.0
time is: 0.5
time is: 1.0
time is: 1.5
time is: 2.0
time is: 2.5
time is: 3.0
time is: 3.5
time is: 4.0
time is: 4.5
time is: 5.0
time is: 5.5
time is: 6.0
time is: 6.5
time is: 7.0
time is: 7.5
time is: 8.0
time is: 8.5
time is: 9.0
time is: 9.5
time is: 10.0
Section 3: Symbolic math#
Step 3.1: Defining variables and functions#
With symbolic math tools, we can define variables and do matematical operations on them symbolically. For example we may define functions and differentiate them.
[14]:
# Import diff, symbols and Matrix from sympy
from sympy import symbols, diff, Matrix, sin
# Define variables x1 and x2
x1, x2 = symbols("x1 x2")
# Define two functions f1 and f2
f1 = x1 ** 3 + 2*x2
f2 = x2 * sin(x1)
print(f1)
x1**3 + 2*x2
Step 3.2: Find Partial derivatives#
Finding partial derivatives is something we have to deal with often in this course, and often the expressions are not nice to work with by hand.
[16]:
# Find the partial derivatives of f1 and f2 wrt x1 and x2
df1_dx1 = diff(f1, x1)
df1_dx2 = diff(f1, x1)
df2_dx1 = diff(f1, x1)
df2_dx2 = diff(f1, x1)
print(df1_dx1)
3*x1**2
Step 3.3: Use the chain rule in sympy#
Given the function \(f(x_1(t), x_2(t))\) as an example, we have that \(\frac{df}{dt} = \frac{\partial f}{\partial x_1} \frac{dx_1}{dt} + \frac{\partial f}{\partial x_2} \frac{dx_2}{dt}\)
Let’s pretend like x1 and x2, defined above, are functions of time, and then try to find the time derivative of our funcitons f1 and f2
[17]:
# Define variables for time derivatives of x1 and x2
dx1, dx2 = symbols("dx1 dx2")
# Find the time derivative of f1 and f2
df1_dt = df1_dx1 * dx1 + df1_dx2 * dx2
print(df1_dt)
3*dx1*x1**2 + 3*dx2*x1**2
Step 3.4: Find the Jacobian for a Vector-Valued Function#
Given a function \(\boldsymbol{f}(\boldsymbol{x})\), where \(\boldsymbol{f}\) is an n-dimensional vector of functions and \(\boldsymbol{x}\) is an m-dimensional vector, the Jacobian is defined as:
We will find the Jacobian for \(f_1\) and \(f_2\).
[19]:
# Define the Jacobian for f1 and f2
functions = Matrix([f1, f2])
variables = Matrix([x1, x2])
jacobian = functions.jacobian(variables)
print(jacobian)
Matrix([[3*x1**2, 2], [x2*cos(x1), sin(x1)]])
Section 4: Plotting#
We will make a time array and plot teh function \(\sin t\) using the Python module Matplotlib
[9]:
# Make a time array from 0 to 2*pi
# Make an array for the value of sin(t) for each value of the time array
# Set up the plot
Section 5: Defining functions#
In Python (and MATLAB) you can define functions (methods). We will make an example here
[10]:
# Define a function to calculate the square root of an input, including handling of negative numbers
# Call the function and show the result
[ ]:
[ ]:
[ ]: