{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "2fb9376e",
   "metadata": {},
   "source": [
    "# DCT Laboratory — Volume I, Chapter 11\n",
    "## Enterprise Performance Architecture\n",
    "**Seed `26111`** · Companion to the chapter and AXIOM Module **AXIOM-11**\n",
    "\n",
    "Three instruments: the **aggregation reversal** (the top-ranked unit is a\n",
    "property of the weight vector — Performance Aggregation Theorem), the **Pareto\n",
    "performance frontier** of six units in (cost, quality), and first-order\n",
    "**performance dynamics** with an explicit half-life.\n",
    "Mirrored in `DCT_V1_Ch11_Lab.xlsx`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1d830eb7",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-13T22:53:07.124398Z",
     "iopub.status.busy": "2026-07-13T22:53:07.124209Z",
     "iopub.status.idle": "2026-07-13T22:53:07.648877Z",
     "shell.execute_reply": "2026-07-13T22:53:07.647683Z"
    }
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "plt.rcParams['figure.dpi']=110\n",
    "\n",
    "import numpy as np\n",
    "SEED = 26111\n",
    "UNITS = [\"U1\",\"U2\",\"U3\",\"U4\",\"U5\",\"U6\"]\n",
    "# dims: financial, customer, operational, innovation\n",
    "S = np.array([\n",
    " [82,55,70,40],\n",
    " [60,85,65,90],\n",
    " [75,70,60,80],\n",
    " [50,60,90,45],\n",
    " [68,72,75,62],\n",
    " [90,40,55,35]], dtype=float)\n",
    "W1 = np.array([0.70,0.10,0.10,0.10])   # finance-weighted\n",
    "W2 = np.array([0.05,0.35,0.10,0.50])   # customer/innovation-weighted\n",
    "\n",
    "# frontier data: (cost, quality) — cost lower-better, quality higher-better\n",
    "CQ = np.array([[60,70],[45,82],[55,88],[70,90],[50,75],[65,60]], dtype=float)\n",
    "\n",
    "P0, DRIV, RHO = 50.0, 80.0, 0.8\n",
    "\n",
    "def composites(w): return S @ w\n",
    "def pareto_efficient():\n",
    "    eff = []\n",
    "    for i,(c,q) in enumerate(CQ):\n",
    "        dominated = any((CQ[j,0] <= c) and (CQ[j,1] >= q) and (j != i)\n",
    "                        and ((CQ[j,0] < c) or (CQ[j,1] > q)) for j in range(6))\n",
    "        eff.append(not dominated)\n",
    "    return np.array(eff)\n",
    "\n",
    "def p_path(n=12):\n",
    "    p = np.empty(n+1); p[0] = P0\n",
    "    for k in range(n): p[k+1] = RHO*p[k] + (1-RHO)*DRIV\n",
    "    return p\n",
    "\n",
    "def reference_values():\n",
    "    c1, c2 = composites(W1), composites(W2)\n",
    "    eff = pareto_efficient()\n",
    "    return {\n",
    "        \"comp_U6_w1\": round(float(c1[5]),4), \"comp_U2_w1\": round(float(c1[1]),4),\n",
    "        \"comp_U2_w2\": round(float(c2[1]),4), \"comp_U6_w2\": round(float(c2[5]),4),\n",
    "        \"top_w1\": UNITS[int(np.argmax(c1))], \"top_w2\": UNITS[int(np.argmax(c2))],\n",
    "        \"n_pareto_efficient\": int(eff.sum()),\n",
    "        \"p_at_8\": round(float(p_path()[8]),4),\n",
    "        \"half_life\": round(float(np.log(2)/np.log(1/RHO)),4),\n",
    "    }\n",
    "if __name__ == \"__main__\":\n",
    "    [print(f\"{k:20s} {v}\") for k,v in reference_values().items()]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ed92c057",
   "metadata": {},
   "source": [
    "## Panel 1 — The aggregation reversal\n",
    "Six units scored on four dimensions. Weight scheme $w_1$ (finance-heavy) crowns\n",
    "**U6**; scheme $w_2$ (customer/innovation-heavy) crowns **U2** — with U6 falling\n",
    "to 41.5. Neither ranking is wrong; each is an *argument made numerical*. The\n",
    "theorem's demand: publish the weights with the ranking."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "57442ea6",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-13T22:53:07.651186Z",
     "iopub.status.busy": "2026-07-13T22:53:07.650869Z",
     "iopub.status.idle": "2026-07-13T22:53:07.657680Z",
     "shell.execute_reply": "2026-07-13T22:53:07.656684Z"
    }
   },
   "outputs": [],
   "source": [
    "c1, c2 = composites(W1), composites(W2)\n",
    "print(f\"{'unit':>5s} {'fin':>5s} {'cust':>5s} {'ops':>5s} {'innov':>6s} | {'w1 comp':>8s} {'w2 comp':>8s}\")\n",
    "for i,u in enumerate(UNITS):\n",
    "    print(f\"{u:>5s} {S[i,0]:5.0f} {S[i,1]:5.0f} {S[i,2]:5.0f} {S[i,3]:6.0f} | {c1[i]:8.2f} {c2[i]:8.2f}\")\n",
    "print(f\"\\ntop under w1 = {UNITS[np.argmax(c1)]}   top under w2 = {UNITS[np.argmax(c2)]}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "904728d4",
   "metadata": {},
   "source": [
    "## Panel 2 — The performance frontier\n",
    "The same six units in (cost, quality): three are Pareto-efficient, three are\n",
    "dominated. The Enterprise Performance Frontier Theorem: improvement without\n",
    "trade-off exists only for the dominated — on the frontier, every gain in one\n",
    "dimension is paid for in the other."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8834303d",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-13T22:53:07.659488Z",
     "iopub.status.busy": "2026-07-13T22:53:07.659297Z",
     "iopub.status.idle": "2026-07-13T22:53:07.932382Z",
     "shell.execute_reply": "2026-07-13T22:53:07.931010Z"
    }
   },
   "outputs": [],
   "source": [
    "eff = pareto_efficient()\n",
    "fig, ax = plt.subplots(figsize=(6.8,5.2))\n",
    "front = CQ[eff][np.argsort(CQ[eff][:,0])]\n",
    "ax.plot(front[:,0], front[:,1], c=\"#C8A24B\", lw=2, ls=\"--\", zorder=1)\n",
    "ax.scatter(CQ[~eff,0], CQ[~eff,1], c=\"#8A8F8B\", s=90, label=\"dominated\", zorder=2)\n",
    "ax.scatter(CQ[eff,0], CQ[eff,1], c=\"#0B3D2E\", s=110, label=\"Pareto-efficient\", zorder=3)\n",
    "for i,u in enumerate(UNITS):\n",
    "    ax.annotate(u, CQ[i], textcoords=\"offset points\", xytext=(8,4), fontsize=10)\n",
    "ax.set(xlabel=\"cost (lower better)\", ylabel=\"quality (higher better)\",\n",
    "       title=\"The performance frontier: 3 efficient, 3 dominated (seed 26111)\")\n",
    "ax.legend(frameon=False); ax.grid(alpha=.25); plt.tight_layout(); plt.show()\n",
    "for u,(c,q),e in zip(UNITS, CQ, eff):\n",
    "    print(f\"{u}: cost {c:4.0f}  quality {q:4.0f}  {'EFFICIENT' if e else 'dominated'}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cf30441c",
   "metadata": {},
   "source": [
    "## Panel 3 — Performance dynamics\n",
    "Performance responds to its drivers with inertia: $p_{k+1} = \\rho p_k +\n",
    "(1-\\rho)d$ with $\\rho = 0.8$. The gap to the driver level halves every\n",
    "$\\ln 2 / \\ln(1/\\rho) = 3.11$ quarters — Performance Evolves Dynamically\n",
    "(Prop.), with a number attached: today's initiative reads in the metrics three\n",
    "quarters later."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "74894878",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-13T22:53:07.934528Z",
     "iopub.status.busy": "2026-07-13T22:53:07.934337Z",
     "iopub.status.idle": "2026-07-13T22:53:08.111207Z",
     "shell.execute_reply": "2026-07-13T22:53:08.110131Z"
    }
   },
   "outputs": [],
   "source": [
    "p = p_path()\n",
    "t = np.arange(len(p))\n",
    "fig, ax = plt.subplots(figsize=(7.6,4.0))\n",
    "ax.plot(t, p, \"o-\", c=\"#C8A24B\", lw=2.2, ms=5)\n",
    "ax.axhline(DRIV, c=\"#0B3D2E\", ls=\":\", lw=1.2, label=f\"driver level {DRIV:.0f}\")\n",
    "ax.set(xlabel=\"quarter\", ylabel=\"performance p\", title=f\"Half-life of the gap: {np.log(2)/np.log(1/RHO):.4f} quarters\")\n",
    "ax.legend(frameon=False); ax.grid(alpha=.25); plt.tight_layout(); plt.show()\n",
    "print(f\"p at k=8: {p[8]:.4f}   half-life: {np.log(2)/np.log(1/RHO):.4f} quarters\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3e5521c8",
   "metadata": {},
   "source": [
    "## Validation — agrees with `DCT_V1_Ch11_Lab.xlsx`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "64c76237",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-13T22:53:08.113274Z",
     "iopub.status.busy": "2026-07-13T22:53:08.113065Z",
     "iopub.status.idle": "2026-07-13T22:53:08.119478Z",
     "shell.execute_reply": "2026-07-13T22:53:08.118496Z"
    }
   },
   "outputs": [],
   "source": [
    "ref = reference_values()\n",
    "expected = {\"comp_U6_w1\":76.0,\"comp_U2_w1\":66.0,\"comp_U2_w2\":84.25,\"comp_U6_w2\":41.5,\n",
    " \"n_pareto_efficient\":3,\"p_at_8\":74.9668,\"half_life\":3.1063}\n",
    "for k,v in expected.items():\n",
    "    assert abs(ref[k]-v)<5e-4, f\"MISMATCH {k}\"\n",
    "    print(f\"PASS  {k:20s} {ref[k]}\")\n",
    "assert ref[\"top_w1\"]==\"U6\" and ref[\"top_w2\"]==\"U2\"\n",
    "print(\"PASS  ranking reversal      U6 (w1) → U2 (w2)\")\n",
    "print(\"\\nAll checkpoints agree — seed 26111.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a879c436",
   "metadata": {},
   "source": [
    "**Next**: Exercises 11.9–11.12 (Part C) rebuild the frontier with your own weights; AXIOM-11's weighting console animates the reversal. Solutions: IM Ch. 11."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
