{
"cells": [
{
"cell_type": "markdown",
"id": "db5748ac",
"metadata": {},
"source": [
"# Linear Algebra I\n",
"\n",
"Linear algebra is a core topic in modern applied mathematics. Essentially every important method in statistics, data science, and machine learning is built on linear algebra. Indeed, deep neural networks, which we will discuss shortly, are built on a foundation of matrix multiplication coupled with simple nonlinear functions. \n",
"\n",
"\n",
"\n",
"In this lecture, we'll see how to perform several important operations in linear algebra using our good friend, Numpy. These operations include: \n",
"\n",
"- Matrix multiplication. \n",
"- Exact and approximate solutions to linear systems. \n",
"- Singular value and eigenvalue-eigenvector decompositions. \n",
"\n",
"Along the way, we'll show several examples from statistics and applied mathematics, including simulation of partial differential equations; least-squares regression; and image compression. \n",
"\n",
"This is probably the lecture in which things will get \"the most mathematical.\" Comfort with concepts from Math 33A or equivalent will be helpful. If you're not familiar with these concepts, that's ok -- feel free to ask questions. We'll all get through this just fine. "
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "051120b9",
"metadata": {},
"outputs": [],
"source": [
"# no fancy packages this time! just our good friends numpy and matplotlib\n",
"import numpy as np\n",
"from matplotlib import pyplot as plt\n",
"np.random.seed(1234)"
]
},
{
"cell_type": "markdown",
"id": "4b5b3ff1",
"metadata": {},
"source": [
"## Basic Matrix Operations\n",
"\n",
"A *matrix* is a two-dimensional array of numbers. "
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "0155704f",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[4, 7, 6, 5, 9],\n",
" [2, 8, 7, 9, 1],\n",
" [6, 1, 7, 3, 1],\n",
" [6, 3, 7, 4, 8],\n",
" [1, 1, 4, 3, 4]])"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# random matrix data to play with\n",
"n = 5\n",
"A = np.random.randint(1, 10, size = (n, n))\n",
"A"
]
},
{
"cell_type": "markdown",
"id": "cedfe61e",
"metadata": {},
"source": [
"Matrices admit several standard operations, including: "
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "8fc6a898",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 8, 14, 12, 10, 18],\n",
" [ 4, 16, 14, 18, 2],\n",
" [12, 2, 14, 6, 2],\n",
" [12, 6, 14, 8, 16],\n",
" [ 2, 2, 8, 6, 8]])"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# scalar multiplication\n",
"2*A"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "cc59f510",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[4, 2, 6, 6, 1],\n",
" [7, 8, 1, 3, 1],\n",
" [6, 7, 7, 7, 4],\n",
" [5, 9, 3, 4, 3],\n",
" [9, 1, 1, 8, 4]])"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# transposition\n",
"A.T"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "74293632",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[4. , 4.5, 6. , 5.5, 5. ],\n",
" [4.5, 8. , 4. , 6. , 1. ],\n",
" [6. , 4. , 7. , 5. , 2.5],\n",
" [5.5, 6. , 5. , 4. , 5.5],\n",
" [5. , 1. , 2.5, 5.5, 4. ]])"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# application of transposition: a \"symmetrized\" version of A\n",
"# symmetric matrices satisfy A = A.T\n",
"(A + A.T)/2"
]
},
{
"cell_type": "markdown",
"id": "0ebb0d40",
"metadata": {},
"source": [
"Inversion is an especially important matrix operation. The inverse $\\mathbf{A}^{-1}$ of a square matrix $\\mathbf{A}$ satisfies $\\mathbf{A}\\mathbf{A}^{-1} = \\mathbf{I}$, where $\\mathbf{I}$ is the identity matrix. We'll see how to multiply matrices and check this in a sec. "
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "80fa14b2",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[-0.30292479, 0.12743733, -0.1810585 , 0.58704735, -0.47910864],\n",
" [ 0.38857939, -0.07381616, 0.19777159, -0.42200557, -0.06128134],\n",
" [ 0.48746518, -0.23955432, 0.5097493 , -0.84122563, 0.51810585],\n",
" [-0.65529248, 0.33774373, -0.51810585, 0.88370474, -0.24791086],\n",
" [-0.01740947, -0.02715877, -0.12534819, 0.13718663, 0.05292479]])"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# inverse of A\n",
"A_inv = np.linalg.inv(A) \n",
"A_inv"
]
},
{
"cell_type": "markdown",
"id": "ab81e0ea",
"metadata": {},
"source": [
"## Matrix multiplication"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "8be3aba9",
"metadata": {},
"outputs": [],
"source": [
"# random vector\n",
"b = np.random.randint(1, 5, size = n)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "82692921",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([98, 86, 52, 88, 47])"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# matrix-vector product\n",
"A.dot(b)\n",
"\n",
"# modern, convenient syntax -- same effect\n",
"A@b"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "e160aba8",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([ True, True, True, True, True])"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"A.dot(b) == A@b"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "ec830806",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[172, 91, 202, 149, 203],\n",
" [166, 89, 169, 108, 148],\n",
" [ 85, 56, 135, 90, 120],\n",
" [146, 86, 193, 145, 191],\n",
" [ 78, 42, 86, 74, 83]])"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# random matrix\n",
"B = np.random.randint(1, 10, size = (n, n))\n",
"\n",
"# matrix-matrix product (same as A.dot(B))\n",
"A@B"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "06a17aa4",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 1.00000000e+00, 2.77555756e-17, 8.32667268e-17,\n",
" -1.38777878e-16, -8.32667268e-17],\n",
" [-1.49186219e-16, 1.00000000e+00, -2.49800181e-16,\n",
" 8.32667268e-17, 5.55111512e-17],\n",
" [ 7.28583860e-17, -8.32667268e-17, 1.00000000e+00,\n",
" 8.32667268e-17, 0.00000000e+00],\n",
" [ 1.38777878e-16, -2.22044605e-16, -2.22044605e-16,\n",
" 1.00000000e+00, 2.22044605e-16],\n",
" [-4.16333634e-17, -1.11022302e-16, 0.00000000e+00,\n",
" 7.77156117e-16, 1.00000000e+00]])"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# checking our inverse from earlier\n",
"# observe--finite precision arithmetic! \n",
"A @ A_inv"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "dbc4f3f5",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
""
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"