%reload_ext rubberize
from rubberize.config import config
The rendering of numpy.ndarray type is supported by Rubberize.
Creating Arrays
Arrays created using array() are rendered as the resulting array:
Append _mat or _vec to the variable name to render them in bold font, as in textbooks.
%%tap --grid
import numpy as np
a_mat = np.array([1, 2, 3])
b_mat = np.array([[1, 2], [3, 4]])
c_mat = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
\( \displaystyle
\mathbf{a} = \begin{bmatrix}
1 \\ 2 \\ 3
\end{bmatrix}
\)
\( \displaystyle
\mathbf{b} = \begin{bmatrix}
1 & 2 \\ 3 & 4
\end{bmatrix}
\)
\( \displaystyle
\mathbf{c} = \begin{bmatrix}
\begin{bmatrix}
1 & 2 \\ 3 & 4
\end{bmatrix} \\ \begin{bmatrix}
5 & 6 \\ 7 & 8
\end{bmatrix}
\end{bmatrix}
\)
Array Delimiters
@array_delimiter controls the appearance of delimiters used in an array. Use "pmatrix" for parentheses and "bmatrix" for square brackets.
%%tap --grid @array_delimiter="pmatrix"
a_mat; b_mat; c_mat
\( \displaystyle
\mathbf{a} = \begin{bmatrix}
1 \\ 2 \\ 3
\end{bmatrix}
\)
\( \displaystyle
\mathbf{b} = \begin{bmatrix}
1 & 2 \\ 3 & 4
\end{bmatrix}
\)
\( \displaystyle
\mathbf{c} = \begin{bmatrix}
\begin{bmatrix}
1 & 2 \\ 3 & 4
\end{bmatrix} \\ \begin{bmatrix}
5 & 6 \\ 7 & 8
\end{bmatrix}
\end{bmatrix}
\)
Array Creation Routines
The following array creation routines are also supported:
%%tap
A_mat = np.eye(2,3,1)
B_mat = np.identity(2)
\( \displaystyle
\mathbf{A} = \mathbf{I}_{2 \times 3}^{\left( 1 \right)} = \begin{bmatrix}
0.00 & 1.00 & 0.00 \\ 0.00 & 0.00 & 1.00
\end{bmatrix}
\)
\( \displaystyle
\mathbf{B} = \mathbf{I}_{2} = \begin{bmatrix}
1.00 & 0.00 \\ 0.00 & 1.00
\end{bmatrix}
\)
%%tap
C_mat = np.ones((3,2))
C_mat_star = np.ones(3)
D_mat = np.ones_like(B_mat)
\( \displaystyle
\mathbf{C} = \mathbf{1}_{3 \times 2} = \begin{bmatrix}
1.00 & 1.00 \\ 1.00 & 1.00 \\ 1.00 & 1.00
\end{bmatrix}
\)
\( \displaystyle
\mathbf{C}^{*} = \mathbf{1}_{1 \times 3} = \begin{bmatrix}
1.00 \\ 1.00 \\ 1.00
\end{bmatrix}
\)
\( \displaystyle
\mathbf{D} = \mathbf{1}_{\mathbf{B}} = \begin{bmatrix}
1.00 & 1.00 \\ 1.00 & 1.00
\end{bmatrix}
\)
%%tap
E_mat = np.zeros((3,2))
E_mat_star = np.zeros(2)
F_mat = np.zeros_like(A_mat)
\( \displaystyle
\mathbf{E} = \mathbf{0}_{3 \times 2} = \begin{bmatrix}
0.00 & 0.00 \\ 0.00 & 0.00 \\ 0.00 & 0.00
\end{bmatrix}
\)
\( \displaystyle
\mathbf{E}^{*} = \mathbf{0}_{1 \times 2} = \begin{bmatrix}
0.00 \\ 0.00
\end{bmatrix}
\)
\( \displaystyle
\mathbf{F} = \mathbf{0}_{\mathbf{A}} = \begin{bmatrix}
0.00 & 0.00 & 0.00 \\ 0.00 & 0.00 & 0.00
\end{bmatrix}
\)
%%tap
G_mat = np.full((2,1), 69.0)
H_mat = np.full_like(E_mat, 420.0)
\( \displaystyle
\mathbf{G} = 69.00 \cdot \mathbf{1}_{2 \times 1} = \begin{bmatrix}
69.00 \\ 69.00
\end{bmatrix}
\)
\( \displaystyle
\mathbf{H} = 420.00 \cdot \mathbf{1}_{\mathbf{E}} = \begin{bmatrix}
420.00 & 420.00 \\ 420.00 & 420.00 \\ 420.00 & 420.00
\end{bmatrix}
\)
1D Arrays
@show_1d_as_col specifies whether to render 1-dimension arrays vertically or horizontally:
%%tap --grid
a_mat # @show_1d_as_col=False
a_mat # @show_1d_as_col=True
\( \displaystyle \mathbf{a} = \begin{bmatrix} 1 & 2 & 3 \end{bmatrix} \)
\( \displaystyle
\mathbf{a} = \begin{bmatrix}
1 \\ 2 \\ 3
\end{bmatrix}
\)
Accessing Elements
Element access is rendered like other collection types:
%%tap
b_mat
b_mat[0][1]
b_mat[0, 1] # Tuple access
b_mat[:, 0] # Slice access
\( \displaystyle
\mathbf{b} = \begin{bmatrix}
1 & 2 \\ 3 & 4
\end{bmatrix}
\)
\( \displaystyle \mathbf{b}_{\left( 0,\, 1 \right)} = 2 \)
\( \displaystyle \mathbf{b}_{\left( 0,\, 1 \right)} = 2 \)
Tuple access
\( \displaystyle
\mathbf{b}_{\left( : ,\, 0 \right)} = \begin{bmatrix}
1 \\ 3
\end{bmatrix}
\)
Slice access
Array Operations
Common array operations are supported:
Arithmetic Operations
%%tap
d_mat = np.array([[5, 6], [7, 8]])
b_mat + d_mat
b_mat * d_mat
b_mat / d_mat
\( \displaystyle
\mathbf{d} = \begin{bmatrix}
5 & 6 \\ 7 & 8
\end{bmatrix}
\)
\( \displaystyle
\mathbf{b} + \mathbf{d} = \begin{bmatrix}
1 & 2 \\ 3 & 4
\end{bmatrix} + \begin{bmatrix}
5 & 6 \\ 7 & 8
\end{bmatrix} = \begin{bmatrix}
6 & 8 \\ 10 & 12
\end{bmatrix}
\)
\( \displaystyle
\mathbf{b}\,\mathbf{d} = \begin{bmatrix}
1 & 2 \\ 3 & 4
\end{bmatrix}\,\begin{bmatrix}
5 & 6 \\ 7 & 8
\end{bmatrix} = \begin{bmatrix}
5 & 12 \\ 21 & 32
\end{bmatrix}
\)
\( \displaystyle
\frac{\mathbf{b}}{\mathbf{d}} = \frac{\begin{bmatrix}
1 & 2 \\ 3 & 4
\end{bmatrix}}{\begin{bmatrix}
5 & 6 \\ 7 & 8
\end{bmatrix}} = \begin{bmatrix}
0.20 & 0.33 \\ 0.43 & 0.50
\end{bmatrix}
\)
Scalar Operations
%%tap
1 + d_mat
2 * d_mat
3 / d_mat
\( \displaystyle
1 + \mathbf{d} = 1 + \begin{bmatrix}
5 & 6 \\ 7 & 8
\end{bmatrix} = \begin{bmatrix}
6 & 7 \\ 8 & 9
\end{bmatrix}
\)
\( \displaystyle
2\,\mathbf{d} = 2\,\begin{bmatrix}
5 & 6 \\ 7 & 8
\end{bmatrix} = \begin{bmatrix}
10 & 12 \\ 14 & 16
\end{bmatrix}
\)
\( \displaystyle
\frac{3}{\mathbf{d}} = \frac{3}{\begin{bmatrix}
5 & 6 \\ 7 & 8
\end{bmatrix}} = \begin{bmatrix}
0.60 & 0.50 \\ 0.43 & 0.38
\end{bmatrix}
\)
Array Transpose
%%tap
b_mat.transpose()
np.transpose(b_mat)
np.linalg.matrix_transpose(b_mat)
b_mat.T # Substituted form not displayed
\( \displaystyle
\mathbf{b}^{\intercal} = \begin{bmatrix}
1 & 2 \\ 3 & 4
\end{bmatrix}^{\intercal} = \begin{bmatrix}
1 & 3 \\ 2 & 4
\end{bmatrix}
\)
\( \displaystyle
\mathbf{b}^{\intercal} = \begin{bmatrix}
1 & 2 \\ 3 & 4
\end{bmatrix}^{\intercal} = \begin{bmatrix}
1 & 3 \\ 2 & 4
\end{bmatrix}
\)
\( \displaystyle
\mathbf{b}^{\intercal} = \begin{bmatrix}
1 & 2 \\ 3 & 4
\end{bmatrix}^{\intercal} = \begin{bmatrix}
1 & 3 \\ 2 & 4
\end{bmatrix}
\)
\( \displaystyle
\mathbf{b}^{\intercal} = \begin{bmatrix}
1 & 3 \\ 2 & 4
\end{bmatrix}
\)
Substituted form not displayed
Matrix Multiplication
Matrix multiplication always uses a center dot (\(\cdot\)) as the multiplication symbol.
%%tap
e_mat = np.array([[9, 10], [11, 12]])
d_mat @ e_mat
d_mat.dot(e_mat)
np.dot(d_mat, e_mat)
np.matmul(d_mat, e_mat)
np.linalg.matmul(d_mat, e_mat)
\( \displaystyle
\mathbf{e} = \begin{bmatrix}
9 & 10 \\ 11 & 12
\end{bmatrix}
\)
\( \displaystyle
\mathbf{d} \cdot \mathbf{e} = \begin{bmatrix}
5 & 6 \\ 7 & 8
\end{bmatrix} \cdot \begin{bmatrix}
9 & 10 \\ 11 & 12
\end{bmatrix} = \begin{bmatrix}
111 & 122 \\ 151 & 166
\end{bmatrix}
\)
\( \displaystyle
\mathbf{d} \cdot \mathbf{e} = \begin{bmatrix}
5 & 6 \\ 7 & 8
\end{bmatrix} \cdot \begin{bmatrix}
9 & 10 \\ 11 & 12
\end{bmatrix} = \begin{bmatrix}
111 & 122 \\ 151 & 166
\end{bmatrix}
\)
\( \displaystyle
\mathbf{d} \cdot \mathbf{e} = \begin{bmatrix}
5 & 6 \\ 7 & 8
\end{bmatrix} \cdot \begin{bmatrix}
9 & 10 \\ 11 & 12
\end{bmatrix} = \begin{bmatrix}
111 & 122 \\ 151 & 166
\end{bmatrix}
\)
\( \displaystyle
\mathbf{d} \cdot \mathbf{e} = \begin{bmatrix}
5 & 6 \\ 7 & 8
\end{bmatrix} \cdot \begin{bmatrix}
9 & 10 \\ 11 & 12
\end{bmatrix} = \begin{bmatrix}
111 & 122 \\ 151 & 166
\end{bmatrix}
\)
\( \displaystyle
\mathbf{d} \cdot \mathbf{e} = \begin{bmatrix}
5 & 6 \\ 7 & 8
\end{bmatrix} \cdot \begin{bmatrix}
9 & 10 \\ 11 & 12
\end{bmatrix} = \begin{bmatrix}
111 & 122 \\ 151 & 166
\end{bmatrix}
\)
Cross Product
Associativity rules are accounted for when rendering cross products:
%%tap
Q_mat = np.array([[1, 2, 3], [4, 5, 6]])
W_mat = np.array([[7, 8, 9], [10, 11, 12]])
E_mat = np.array([[7, 8, 9], [10, 11, 12]])
np.cross(Q_mat, W_mat)
np.cross(np.cross(Q_mat, W_mat), E_mat)
np.cross(Q_mat, np.cross(W_mat, E_mat))
\( \displaystyle
\mathbf{Q} = \begin{bmatrix}
1 & 2 & 3 \\ 4 & 5 & 6
\end{bmatrix}
\)
\( \displaystyle
\mathbf{W} = \begin{bmatrix}
7 & 8 & 9 \\ 10 & 11 & 12
\end{bmatrix}
\)
\( \displaystyle
\mathbf{E} = \begin{bmatrix}
7 & 8 & 9 \\ 10 & 11 & 12
\end{bmatrix}
\)
\( \displaystyle
\mathbf{Q} \times \mathbf{W} = \begin{bmatrix}
1 & 2 & 3 \\ 4 & 5 & 6
\end{bmatrix} \times \begin{bmatrix}
7 & 8 & 9 \\ 10 & 11 & 12
\end{bmatrix} = \begin{bmatrix}
-6 & 12 & -6 \\ -6 & 12 & -6
\end{bmatrix}
\)
\( \displaystyle
\left( \mathbf{Q} \times \mathbf{W} \right) \times \mathbf{E} = \left(
\begin{bmatrix}
1 & 2 & 3 \\ 4 & 5 & 6
\end{bmatrix} \times \begin{bmatrix}
7 & 8 & 9 \\ 10 & 11 & 12
\end{bmatrix}
\right) \times \begin{bmatrix}
7 & 8 & 9 \\ 10 & 11 & 12
\end{bmatrix} = \begin{bmatrix}
156 & 12 & -132 \\ 210 & 12 & -186
\end{bmatrix}
\)
\( \displaystyle
\mathbf{Q} \times \left( \mathbf{W} \times \mathbf{E} \right) = \begin{bmatrix}
1 & 2 & 3 \\ 4 & 5 & 6
\end{bmatrix} \times \left(
\begin{bmatrix}
7 & 8 & 9 \\ 10 & 11 & 12
\end{bmatrix} \times \begin{bmatrix}
7 & 8 & 9 \\ 10 & 11 & 12
\end{bmatrix}
\right) = \begin{bmatrix}
0 & 0 & 0 \\ 0 & 0 & 0
\end{bmatrix}
\)
Inner Product
%%tap
np.inner(Q_mat, W_mat)
\( \displaystyle
\left\langle \mathbf{Q},\, \mathbf{W} \right\rangle = \left\langle \begin{bmatrix}
1 & 2 & 3 \\ 4 & 5 & 6
\end{bmatrix},\, \begin{bmatrix}
7 & 8 & 9 \\ 10 & 11 & 12
\end{bmatrix} \right\rangle = \begin{bmatrix}
50 & 68 \\ 122 & 167
\end{bmatrix}
\)
Outer Product
%%tap
u_vec = np.array([1, 2, 3])
v_vec = np.array([4, 5])
np.outer(u_vec, v_vec)
np.linalg.outer(u_vec, v_vec)
\( \displaystyle
\mathbf{u} = \begin{bmatrix}
1 \\ 2 \\ 3
\end{bmatrix}
\)
\( \displaystyle
\mathbf{v} = \begin{bmatrix}
4 \\ 5
\end{bmatrix}
\)
\( \displaystyle
\mathbf{u} \otimes \mathbf{v} = \begin{bmatrix}
1 \\ 2 \\ 3
\end{bmatrix} \otimes \begin{bmatrix}
4 \\ 5
\end{bmatrix} = \begin{bmatrix}
4 & 5 \\ 8 & 10 \\ 12 & 15
\end{bmatrix}
\)
\( \displaystyle
\mathbf{u} \otimes \mathbf{v} = \begin{bmatrix}
1 \\ 2 \\ 3
\end{bmatrix} \otimes \begin{bmatrix}
4 \\ 5
\end{bmatrix} = \begin{bmatrix}
4 & 5 \\ 8 & 10 \\ 12 & 15
\end{bmatrix}
\)
Norm
%%tap
np.linalg.vector_norm(a_mat)
np.linalg.matrix_norm(b_mat)
np.linalg.matrix_norm(b_mat, ord="nuc")
\( \displaystyle
\left\| \mathbf{a} \right\| = \begin{Vmatrix}
1 \\ 2 \\ 3
\end{Vmatrix} = 3.74
\)
\( \displaystyle
\left\| \mathbf{b} \right\|_{F} = \begin{Vmatrix}
1 & 2 \\ 3 & 4
\end{Vmatrix}_{F} = 5.48
\)
\( \displaystyle
\left\| \mathbf{b} \right\|_{*} = \begin{Vmatrix}
1 & 2 \\ 3 & 4
\end{Vmatrix}_{*} = 5.83
\)
Power
%%tap
np.linalg.matrix_power(b_mat, 3)
\( \displaystyle
\mathbf{b}^{3} = \begin{bmatrix}
1 & 2 \\ 3 & 4
\end{bmatrix}^{3} = \begin{bmatrix}
37 & 54 \\ 81 & 118
\end{bmatrix}
\)
Determinant
%%tap
np.linalg.det(b_mat)
\( \displaystyle
\det \left( \mathbf{b} \right) = \det \begin{pmatrix}
1 & 2 \\ 3 & 4
\end{pmatrix} = -2.00
\)
Rank
%%tap
np.linalg.matrix_rank(b_mat)
\( \displaystyle
\operatorname{rank} \left( \mathbf{b} \right) = \operatorname{rank} \begin{pmatrix}
1 & 2 \\ 3 & 4
\end{pmatrix} = 2
\)
Trace
%%tap
np.trace(b_mat)
np.linalg.trace(b_mat)
\( \displaystyle
\operatorname{Tr} \left( \mathbf{b} \right) = \operatorname{Tr} \begin{pmatrix}
1 & 2 \\ 3 & 4
\end{pmatrix} = 5
\)
\( \displaystyle
\operatorname{Tr} \left( \mathbf{b} \right) = \operatorname{Tr} \begin{pmatrix}
1 & 2 \\ 3 & 4
\end{pmatrix} = 5
\)
Inverse and Pseudo-inverse
%%tap
np.linalg.inv(b_mat)
np.linalg.pinv(b_mat)
\( \displaystyle
\mathbf{b}^{-1} = \begin{bmatrix}
1 & 2 \\ 3 & 4
\end{bmatrix}^{-1} = \begin{bmatrix}
-2.00 & 1.00 \\ 1.50 & -0.50
\end{bmatrix}
\)
\( \displaystyle
\mathbf{b}^{+} = \begin{bmatrix}
1 & 2 \\ 3 & 4
\end{bmatrix}^{+} = \begin{bmatrix}
-2.00 & 1.00 \\ 1.50 & -0.50
\end{bmatrix}
\)
Solving Systems of Equations
%%tap @show_1d_as_col=True
# **Define stiffness matrix**
k_1, k_2, k_3 = 10, 15, 20 # Example stiffness values
K_mat = np.array([[k_1 + k_2, -k_2],
[-k_2, k_2 + k_3]])
# **Force vector**
F_mat = np.array([100, 150]) # Example forces
u_mat = np.linalg.inv(K_mat) @ F_mat # Solve for displacements
Define stiffness matrix
\( \displaystyle k_{1},\, k_{2},\, k_{3} = \left( 10,\, 15,\, 20 \right) \)
Example stiffness values
\( \displaystyle
\mathbf{K} = \begin{bmatrix}
k_{1} + k_{2} & -k_{2} \\ -k_{2} & k_{2} + k_{3}
\end{bmatrix} = \begin{bmatrix}
10 + 15 & -15 \\ -15 & 15 + 20
\end{bmatrix} = \begin{bmatrix}
25 & -15 \\ -15 & 35
\end{bmatrix}
\)
Force vector
\( \displaystyle
\mathbf{F} = \begin{bmatrix}
100 \\ 150
\end{bmatrix}
\)
Example forces
\( \displaystyle
\mathbf{u} = \mathbf{K}^{-1} \cdot \mathbf{F} = \begin{bmatrix}
25 & -15 \\ -15 & 35
\end{bmatrix}^{-1} \cdot \begin{bmatrix}
100 \\ 150
\end{bmatrix} = \begin{bmatrix}
8.85 \\ 8.08
\end{bmatrix}
\)
Solve for displacements
Or using numpy.linalg.solve():
%%tap @show_1d_as_col=True
u_mat_alt = np.linalg.solve(K_mat, F_mat)
\( \displaystyle
\mathbf{u}_{\mathrm{alt}} = \underbracket{\mathbf{K}^{-1} \cdot \mathbf{F}}_{\text{via LAPACK}} = \underbracket{\begin{bmatrix}
25 & -15 \\ -15 & 35
\end{bmatrix}^{-1} \cdot \begin{bmatrix}
100 \\ 150
\end{bmatrix}}_{\text{via LAPACK}} = \begin{bmatrix}
8.85 \\ 8.08
\end{bmatrix}
\)