{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# MATH 4242 Python Lab 4: The four fundamental subspaces\n",
        "\n",
        "**Course sections:** 2.2--2.6\n",
        "\n",
        "This notebook accompanies LEAP Assignment 4. LEAP supplies your\n",
        "parameter values and grades your mathematical responses. Copy those\n",
        "values into the indicated cell below. Run a cell with **Shift+Enter**.\n",
        "\n",
        "The notebook is a computational scratchpad: your graded answers are\n",
        "entered in LEAP unless your instructor says otherwise.\n",
        "\n",
        "**Programming support:** Guided practice. Examples and function names are supplied; you complete short expressions marked `TODO`.\n",
        "\n",
        "A cell marked `TODO` is intentionally unfinished. Read the directions\n",
        "immediately above it before running it. Placeholders such as zero keep\n",
        "the notebook runnable, but their output is not an answer. If you are\n",
        "new to notebooks,\n",
        "complete `00_Getting_Started.ipynb` before this lab.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "\n",
        "np.set_printoptions(precision=6, suppress=True)\n",
        "print(\"NumPy version:\", np.__version__)\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## 1. Rank and row dependence\n",
        "\n",
        "The third row of the matrix is the sum of the first two. Copy your\n",
        "randomized `k` and `m` values and ask NumPy for the numerical rank.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# Replace these example values with your LEAP values.\n",
        "k = 2\n",
        "m = 3\n",
        "\n",
        "A = np.array([[1, 0, k],\n",
        "              [0, 1, m],\n",
        "              [1, 1, k + m]], dtype=float)\n",
        "\n",
        "# TODO: compute the rank.\n",
        "rank_A = 0  # TODO: replace 0 with np.linalg.matrix_rank(A)\n",
        "print(\"A =\\n\", A)\n",
        "print(\"rank(A) =\", rank_A)\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## 2. Right and left null vectors\n",
        "\n",
        "A right-null vector satisfies $Av=0$. A left-null vector satisfies\n",
        "$A^T w=0$. Construct the vectors suggested by the algebra in LEAP and\n",
        "verify both products.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# TODO: enter the right-null and left-null vectors.\n",
        "v = np.zeros(3)  # TODO: replace with your right-null vector\n",
        "w = np.zeros(3)  # TODO: replace with your left-null vector\n",
        "\n",
        "print(\"A @ v =\", A @ v)\n",
        "print(\"A.T @ w =\", A.T @ w)\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## 3. See the null space through the SVD\n",
        "\n",
        "In $A=U\\Sigma V^T$, a right singular vector associated with a zero\n",
        "singular value lies in the null space. Numerical computations rarely\n",
        "produce an exact zero, so inspect the scale of the singular values.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "U, s, Vt = np.linalg.svd(A)\n",
        "numerical_null_vector = Vt[-1, :]\n",
        "\n",
        "print(\"singular values:\", s)\n",
        "print(\"SVD null vector:\", numerical_null_vector)\n",
        "print(\"A @ SVD null vector:\", A @ numerical_null_vector)\n",
        "\n",
        "# TODO: compare its direction with v using a normalized dot product.\n",
        "# TODO: replace 0 using np.dot and np.linalg.norm as shown in the hint.\n",
        "direction_similarity = 0\n",
        "print(\"absolute direction similarity:\", direction_similarity)\n"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "name": "python",
      "version": "3",
      "mimetype": "text/x-python",
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "pygments_lexer": "ipython3",
      "nbconvert_exporter": "python",
      "file_extension": ".py"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 4
}
