{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# MATH 4242 Python Lab 5: Inner products, norms, and quadratic forms\n",
        "\n",
        "**Course sections:** 3.1--3.5\n",
        "\n",
        "This notebook accompanies LEAP Assignment 5. 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. Dot products and norms\n",
        "\n",
        "Copy `k` from LEAP. NumPy uses `np.dot(u, v)` (or `u @ v`) for the\n",
        "Euclidean inner product and `np.linalg.norm(u)` for its induced norm.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# Replace this example value with your LEAP value.\n",
        "k = 3\n",
        "\n",
        "u = np.array([1, k, -1], dtype=float)\n",
        "v = np.array([k, 1, 1], dtype=float)\n",
        "\n",
        "# TODO: compute the requested quantities.\n",
        "dot_uv = 0   # TODO: use np.dot(u, v)\n",
        "norm_u = 1   # TODO: use np.linalg.norm(u)\n",
        "norm_v = 1   # TODO: use np.linalg.norm(v)\n",
        "cosine = 0   # TODO: divide the dot product by both norms\n",
        "\n",
        "print(\"u dot v =\", dot_uv)\n",
        "print(\"||u|| =\", norm_u)\n",
        "print(\"||v|| =\", norm_v)\n",
        "print(\"cos(theta) =\", cosine)\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## 2. Check Cauchy--Schwarz\n",
        "\n",
        "Rather than checking only whether the inequality is true, compute its\n",
        "slack: $\\|u\\|\\|v\\|-|u^Tv|$. A positive slack means the vectors are not\n",
        "scalar multiples.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# TODO: calculate the Cauchy--Schwarz slack.\n",
        "slack = 0  # TODO: replace using norm_u, norm_v, abs, and dot_uv\n",
        "print(\"Cauchy--Schwarz slack:\", slack)\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## 3. A symmetric quadratic form\n",
        "\n",
        "For a real symmetric matrix, positive eigenvalues imply positive\n",
        "definiteness. Use `eigvalsh`, the symmetry-aware eigenvalue routine.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "Q = np.array([[2, 1],\n",
        "              [1, k + 2]], dtype=float)\n",
        "z = np.array([1, -1], dtype=float)\n",
        "\n",
        "# TODO: compute z^T Q z and the eigenvalues of Q.\n",
        "quadratic_value = 0       # TODO: use z @ Q @ z\n",
        "eigenvalues = np.zeros(2) # TODO: use np.linalg.eigvalsh(Q)\n",
        "\n",
        "print(\"z^T Q z =\", quadratic_value)\n",
        "print(\"eigenvalues of Q:\", eigenvalues)\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
}
