{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "3edbcd23",
   "metadata": {},
   "source": [
    "# Growth, decay, and the curve that decides\n",
    "### Chapter 5 · exponentials, the S-curve, the sigmoid · **[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_5_1_growth_decay_sigmoid.ipynb)\n",
    "\n",
    "**What you'll see:** drag the base of $b^x$ and watch growth *flip* into decay; race\n",
    "a runaway exponential against the S-curve that bends to a ceiling; and meet the\n",
    "**sigmoid**, the decision curve of an artificial neuron.\n",
    "\n",
    "This is a **predict-first** notebook. Each time you see 🔮, *say your guess out loud\n",
    "before you run the cell.* Guessing then checking is how the parameter gets into your\n",
    "bones."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bd62d028",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from ipywidgets import interact, FloatSlider"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "722f5c38",
   "metadata": {},
   "source": [
    "## 1. One knob flips growth into decay\n",
    "\n",
    "🔮 **Predict first:** the slider sets the base $b$ in $b^{\\,x}$. Right now it starts\n",
    "above 1. *Before you slide $b$ below 1, predict which way the curve will tilt.* Will\n",
    "it still rise to the right, or fall?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "88264603",
   "metadata": {},
   "outputs": [],
   "source": [
    "def show_base(b=2.0):\n",
    "    x = np.linspace(-4, 4, 400)\n",
    "    plt.figure(figsize=(7, 4))\n",
    "    plt.plot(x, b**x, color=\"#1A6FB0\", lw=2.5)\n",
    "    plt.axhline(0, color=\"#999\", lw=0.8)\n",
    "    plt.axvline(0, color=\"#999\", lw=0.8)\n",
    "    plt.title(f\"$b^x$  with  b = {b:.2f}   \" +\n",
    "              (\"(growth)\" if b > 1 else \"(decay)\" if b < 1 else \"(flat)\"))\n",
    "    plt.ylim(-1, 16); plt.xlabel(\"x\"); plt.show()\n",
    "\n",
    "interact(show_base, b=FloatSlider(min=0.3, max=3.0, step=0.05, value=2.0));"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "84b5c9c8",
   "metadata": {},
   "source": [
    "Did it match your guess? At exactly $b=1$ the curve goes **flat** — every power of\n",
    "1 is 1. Above 1 it grows; below 1 it decays. *Same machine, base flipped.*"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "919264c1",
   "metadata": {},
   "source": [
    "## 2. The exponential's lie: nothing grows forever\n",
    "\n",
    "A pure exponential (dashed) shoots to infinity. But in any *finite* world — a\n",
    "population, a market, an epidemic — growth runs out of room and bends into an\n",
    "**S-curve** (solid) that levels off at a ceiling.\n",
    "\n",
    "🔮 **Predict first:** the slider raises the **ceiling**. Before you drag it up,\n",
    "predict: does raising the ceiling change where the two curves *start* (on the left),\n",
    "or only where the S-curve ends up (on the right)?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4bf39445",
   "metadata": {},
   "outputs": [],
   "source": [
    "def show_scurve(ceiling=10.0):\n",
    "    x = np.linspace(0, 10, 400)\n",
    "    pure = 0.4 * np.exp(0.7 * x)                 # the runaway \"model\"\n",
    "    logistic = ceiling / (1 + np.exp(-1.1*(x-5)))  # the \"reality\"\n",
    "    plt.figure(figsize=(7, 4))\n",
    "    plt.plot(x, np.minimum(pure, ceiling*1.6), \"--\", color=\"#999\", lw=2, label=\"pure exponential (the model)\")\n",
    "    plt.plot(x, logistic, color=\"#1A6FB0\", lw=2.6, label=\"S-curve (reality)\")\n",
    "    plt.axhline(ceiling, color=\"#E8833A\", ls=\":\", lw=1.6, label=\"ceiling\")\n",
    "    plt.legend(); plt.xlabel(\"time\"); plt.title(\"The ceiling always bites\"); plt.show()\n",
    "\n",
    "interact(show_scurve, ceiling=FloatSlider(min=4, max=16, step=1, value=10));"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "55e1dcea",
   "metadata": {},
   "source": [
    "The two curves **start out identical** — the early, dangerous phase nobody sees\n",
    "coming looks exactly exponential. They only part ways once the ceiling starts to\n",
    "bite. *The real question is never \"how fast does it grow?\" but \"where is the\n",
    "ceiling, and when?\"*"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "65b4b06b",
   "metadata": {},
   "source": [
    "## 3. The sigmoid: a curve that decides\n",
    "\n",
    "Build this little machine from the decay $e^{-x}$:\n",
    "$$\\sigma(x) = \\frac{1}{1 + e^{-x}}$$\n",
    "\n",
    "🔮 **Predict first — before you run the next cell, guess all three:**\n",
    "- $\\sigma(0) = ?$\n",
    "- $\\sigma(\\text{a big positive number}) \\to ?$\n",
    "- $\\sigma(\\text{a big negative number}) \\to ?$\n",
    "\n",
    "Write your three guesses down, *then* run it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d3a96771",
   "metadata": {},
   "outputs": [],
   "source": [
    "def sigmoid(x):\n",
    "    return 1 / (1 + np.exp(-x))\n",
    "\n",
    "x = np.linspace(-8, 8, 400)\n",
    "plt.figure(figsize=(7, 4))\n",
    "plt.plot(x, sigmoid(x), color=\"#1A6FB0\", lw=2.6)\n",
    "plt.axhline(0, color=\"#999\", ls=\"--\", lw=1); plt.axhline(1, color=\"#999\", ls=\"--\", lw=1)\n",
    "plt.axhline(0.5, color=\"#E8833A\", ls=\":\", lw=1.2)\n",
    "plt.title(r\"$\\sigma(x) = 1/(1+e^{-x})$\"); plt.xlabel(\"x\"); plt.show()\n",
    "\n",
    "print(\"σ(0)      =\", round(sigmoid(0), 4), \"  <- exactly one half: 'unsure'\")\n",
    "print(\"σ(10)     =\", round(sigmoid(10), 6), \" <- basically 1: 'yes'\")\n",
    "print(\"σ(-10)    =\", round(sigmoid(-10), 6), \" <- basically 0: 'no'\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c7eda967",
   "metadata": {},
   "source": [
    "## What just happened\n",
    "\n",
    "The sigmoid takes **any** input on the whole number line — from minus infinity to\n",
    "plus infinity — and gently squashes it into the range between $0$ and $1$, passing\n",
    "through $\\tfrac12$ at the center. That's exactly how an artificial neuron *decides*:\n",
    "it turns a runaway input of any size into a bounded answer between $0$ (no) and $1$\n",
    "(yes), with $\\tfrac12$ as \"unsure.\"\n",
    "\n",
    "The curve that tames an epidemic and the curve that lets a neural network make up\n",
    "its mind are the **same curve** — and you just built it from $e^{-x}$, a reciprocal,\n",
    "and a $+1$. Everything in the modern machine is made of pieces you already have."
   ]
  }
 ],
 "metadata": {
  "colab": {
   "provenance": []
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
