{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "2a46114b",
   "metadata": {},
   "source": [
    "# Multiplication is rotation; roots of unity on the circle\n",
    "### Chapter 8 · the complex plane, rotation, roots of unity · **[PREDICT-FIRST]**\n",
    "\n",
    "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/MeiraDavidson/math_module1/blob/main/notebooks/notebook_8_1_complex_rotation_roots.ipynb)\n",
    "\n",
    "**What you'll see:** complex numbers as *arrows* in a plane — and watch multiplication\n",
    "literally **turn** them (distances multiply, angles add, exactly as you proved on\n",
    "paper). Then watch the $n$-th roots of unity snap into the corners of a perfect\n",
    "$n$-sided polygon.\n",
    "\n",
    "**Predict-first:** guess before you run each 🔮 cell."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "87fe2d56",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from ipywidgets import interact, FloatSlider, IntSlider\n",
    "\n",
    "def draw_arrow(ax, z, color, label=None):\n",
    "    ax.annotate(\"\", xy=(z.real, z.imag), xytext=(0, 0),\n",
    "                arrowprops=dict(arrowstyle=\"-|>\", color=color, lw=2))\n",
    "    if label:\n",
    "        ax.text(z.real*1.07, z.imag*1.07, label, color=color, fontsize=12)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "23518b1b",
   "metadata": {},
   "source": [
    "## 1. Multiplication turns the arrow\n",
    "\n",
    "We'll multiply a fixed number $z = 2 + i$ by a second number you control with\n",
    "sliders: its **distance** from the origin and its **angle**.\n",
    "\n",
    "🔮 **Predict first:** set the second number's angle to **90°** and its distance to\n",
    "**1**. *Before you run it*, predict where the product's arrow will point — and whether\n",
    "it will be longer, shorter, or the same length as the original."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2614ee01",
   "metadata": {},
   "outputs": [],
   "source": [
    "def multiply_demo(distance=1.0, angle_deg=90.0):\n",
    "    z = 2 + 1j                                   # the fixed arrow\n",
    "    theta = np.radians(angle_deg)\n",
    "    w = distance * (np.cos(theta) + 1j*np.sin(theta))  # the arrow you control\n",
    "    product = z * w\n",
    "\n",
    "    fig, ax = plt.subplots(figsize=(5.5, 5.5))\n",
    "    draw_arrow(ax, z, \"#999\", \"z = 2+i\")\n",
    "    draw_arrow(ax, product, \"#1A6FB0\", \"z × w\")\n",
    "    lim = 4\n",
    "    ax.set_xlim(-lim, lim); ax.set_ylim(-lim, lim); ax.set_aspect(\"equal\")\n",
    "    ax.axhline(0, color=\"#ccc\", lw=0.8); ax.axvline(0, color=\"#ccc\", lw=0.8)\n",
    "    ax.set_title(f\"multiply by w: distance {distance:.1f}, angle {angle_deg:.0f}°\")\n",
    "    plt.show()\n",
    "    print(f\"original distance {abs(z):.2f}, angle {np.degrees(np.angle(z)):.0f}°\")\n",
    "    print(f\"product  distance {abs(product):.2f}, angle {np.degrees(np.angle(product)):.0f}°\")\n",
    "\n",
    "interact(multiply_demo,\n",
    "         distance=FloatSlider(min=0.3, max=2.0, step=0.1, value=1.0),\n",
    "         angle_deg=FloatSlider(min=0, max=360, step=15, value=90));"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4e014646",
   "metadata": {},
   "source": [
    "Read the two printed lines: when you multiply, the **distances multiply** and the\n",
    "**angles add** — exactly the rule you proved. Multiplying by something at angle 90°\n",
    "and distance 1 is a pure **quarter-turn**, no stretching. *Multiplication and turning\n",
    "are the same act.*"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "74350e44",
   "metadata": {},
   "source": [
    "## 2. The roots of unity form a polygon\n",
    "\n",
    "The $n$-th **roots of unity** are the $n$ solutions of $x^n = 1$. On paper you found\n",
    "they sit at evenly spaced angles $\\tfrac{2\\pi k}{n}$ around the unit circle.\n",
    "\n",
    "🔮 **Predict first:** before you set $n = 6$, predict **how many points** you'll see\n",
    "and **what shape** they'll make."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cfb3d03c",
   "metadata": {},
   "outputs": [],
   "source": [
    "def roots_of_unity(n=3):\n",
    "    k = np.arange(n)\n",
    "    roots = np.exp(2j * np.pi * k / n)           # the n-th roots of 1\n",
    "\n",
    "    fig, ax = plt.subplots(figsize=(5.5, 5.5))\n",
    "    circle = np.exp(1j * np.linspace(0, 2*np.pi, 300))\n",
    "    ax.plot(circle.real, circle.imag, color=\"#ccc\", lw=1)\n",
    "    # connect them into a polygon\n",
    "    poly = np.append(roots, roots[0])\n",
    "    ax.plot(poly.real, poly.imag, color=\"#1A6FB0\", lw=1.8)\n",
    "    ax.plot(roots.real, roots.imag, \"o\", color=\"#1A6FB0\", ms=10)\n",
    "    ax.plot([1], [0], \"o\", color=\"#E8833A\", ms=11)   # the ordinary real root x=1\n",
    "    ax.text(1.08, 0.05, \"x = 1\", color=\"#E8833A\")\n",
    "    ax.set_aspect(\"equal\"); ax.set_xlim(-1.4, 1.5); ax.set_ylim(-1.4, 1.4)\n",
    "    ax.axhline(0, color=\"#eee\", lw=0.8); ax.axvline(0, color=\"#eee\", lw=0.8)\n",
    "    ax.set_title(f\"the {n} roots of unity\")\n",
    "    plt.show()\n",
    "    for r in roots:\n",
    "        print(f\"  angle {np.degrees(np.angle(r)) % 360:6.1f}°   ->   {r.real:+.3f} {r.imag:+.3f}i\")\n",
    "\n",
    "interact(roots_of_unity, n=IntSlider(min=2, max=12, step=1, value=3));"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e8f079a9",
   "metadata": {},
   "source": [
    "## What just happened\n",
    "\n",
    "You *proved* on paper that \"multiplication adds angles\" and that \"the roots of unity\n",
    "form a regular polygon.\" Here you watched the arrows **actually rotate** and the\n",
    "polygon **actually form** — and you could test values of $n$ you'd never compute by\n",
    "hand.\n",
    "\n",
    "For any $n$, the roots are the $n$ corners of a regular $n$-gon on the unit circle,\n",
    "with one corner always sitting on the ordinary real root $x=1$. Chapter 4's promise —\n",
    "that $x^n - 1$ factors into roots arranged on a circle — computed with your own\n",
    "hands. The walker, the rotation, and the polygon were a complex number all along."
   ]
  }
 ],
 "metadata": {
  "colab": {
   "provenance": []
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
