{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "0ad1d698",
   "metadata": {},
   "source": [
    "# DCT Laboratory — Volume I, Chapter 2\n",
    "## Enterprise Systems and Transformation\n",
    "**Seed `26102`** · Companion to the chapter and AXIOM Module **AXIOM-02**\n",
    "\n",
    "The chapter's four formal moves, made computational: the enterprise as an **open\n",
    "system** $S = (\\mathcal{X}, \\mathcal{U}, \\mathcal{W}, \\mathcal{Y}, f, g, \\mathbf{x}_0)$,\n",
    "the **boundary** as a modeling decision, **feedback** ($u_k = \\varphi(x_k)$) against the\n",
    "environment's pull, and transformation as a designed steering process. The\n",
    "deterministic core is mirrored in `DCT_V1_Ch02_Lab.xlsx`; validation at the end."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2765fd5e",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-13T21:47:43.584986Z",
     "iopub.status.busy": "2026-07-13T21:47:43.584782Z",
     "iopub.status.idle": "2026-07-13T21:47:44.449919Z",
     "shell.execute_reply": "2026-07-13T21:47:44.448727Z"
    }
   },
   "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 = 26102\n",
    "DT, N = 1/12, 60\n",
    "A_PULL, B_GAIN, K_FB = 0.8, 0.5, 1.6\n",
    "X0, X_ENV, X_STAR = 68.0, 60.0, 75.0\n",
    "\n",
    "def simulate(feedback, x0=X0, n=N):\n",
    "    x = np.empty(n+1); x[0] = x0\n",
    "    for k in range(n):\n",
    "        u = K_FB*(X_STAR - x[k]) if feedback else 0.0\n",
    "        x[k+1] = x[k] + DT*(A_PULL*(X_ENV - x[k]) + B_GAIN*u)\n",
    "    return x\n",
    "\n",
    "def mc_fan(n_paths=200, sigma=0.9):\n",
    "    rng = np.random.default_rng(SEED)\n",
    "    out = np.empty((n_paths, N+1))\n",
    "    for p in range(n_paths):\n",
    "        x = X0\n",
    "        out[p,0] = x\n",
    "        for k in range(N):\n",
    "            u = K_FB*(X_STAR - x)\n",
    "            x = x + DT*(A_PULL*(X_ENV - x) + B_GAIN*u) + sigma*np.sqrt(DT)*rng.standard_normal()\n",
    "            out[p,k+1] = x\n",
    "    return out\n",
    "\n",
    "# Boundary panel: 4 subsystem efficiency states; two boundary choices = weights\n",
    "SUBS = np.array([72.0, 61.0, 58.0, 80.0])   # Industrial, Digital, Shared-services, Ventures\n",
    "W_B1 = np.array([0.45, 0.30, 0.25, 0.00])   # ventures outside the boundary\n",
    "W_B2 = np.array([0.40, 0.27, 0.22, 0.11])   # ventures inside\n",
    "\n",
    "def reference_values():\n",
    "    op, cl = simulate(False), simulate(True)\n",
    "    return {\n",
    "        \"open_loop_t5.0\":  round(op[-1], 4),\n",
    "        \"closed_loop_t5.0\":round(cl[-1], 4),\n",
    "        \"feedback_gap_t5.0\": round(cl[-1]-op[-1], 4),\n",
    "        \"closed_loop_t1.0\": round(cl[12], 4),\n",
    "        \"aggregate_B1\": round(float(W_B1 @ SUBS), 4),\n",
    "        \"aggregate_B2\": round(float(W_B2 @ SUBS), 4),\n",
    "        \"boundary_shift\": round(float((W_B2-W_B1) @ SUBS), 4),\n",
    "    }\n",
    "if __name__ == \"__main__\":\n",
    "    [print(f\"{k:22s} {v}\") for k,v in reference_values().items()]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7549c309",
   "metadata": {},
   "source": [
    "## Panel 1 — Open loop vs. feedback\n",
    "Operational efficiency $x_5$ with the environment pulling toward $x_e = 60$.\n",
    "Without control the enterprise drifts to its environment; the feedback law\n",
    "$u_k = K(x^* - x_k)$ (Definition: enterprise feedback) holds it near target.\n",
    "Feedback acts on **inputs**; adaptation (not simulated here) acts on the **rule**."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "522ff590",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-13T21:47:44.452603Z",
     "iopub.status.busy": "2026-07-13T21:47:44.451715Z",
     "iopub.status.idle": "2026-07-13T21:47:44.829232Z",
     "shell.execute_reply": "2026-07-13T21:47:44.828495Z"
    }
   },
   "outputs": [],
   "source": [
    "op, cl = simulate(False), simulate(True)\n",
    "t = np.arange(N+1)/12\n",
    "fig, ax = plt.subplots(figsize=(8,4.2))\n",
    "ax.plot(t, op, color=\"#8A8F8B\", lw=2.2, label=\"open loop (u = 0)\")\n",
    "ax.plot(t, cl, color=\"#C8A24B\", lw=2.4, label=\"state feedback u = K(x* − x)\")\n",
    "ax.axhline(X_ENV, ls=\":\", c=\"#8A8F8B\", lw=1); ax.axhline(X_STAR, ls=\":\", c=\"#C8A24B\", lw=1)\n",
    "ax.set(xlabel=\"years\", ylabel=\"$x_5$ operational efficiency\",\n",
    "       title=\"The open enterprise: environment pull vs. feedback (seed 26102)\")\n",
    "ax.legend(frameon=False); ax.grid(alpha=.25); plt.tight_layout(); plt.show()\n",
    "print(\"gap at t=5:\", round(cl[-1]-op[-1],4))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "04e8a1ca",
   "metadata": {},
   "source": [
    "## Panel 2 — The seeded fan under disturbance\n",
    "The environment channel $\\mathcal{W}$ made stochastic: 200 disturbed closed-loop\n",
    "paths, seed `26102`. Feedback doesn't remove uncertainty — it shapes where the\n",
    "distribution settles."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b7f14e93",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-13T21:47:44.831867Z",
     "iopub.status.busy": "2026-07-13T21:47:44.831319Z",
     "iopub.status.idle": "2026-07-13T21:47:45.713420Z",
     "shell.execute_reply": "2026-07-13T21:47:45.712719Z"
    }
   },
   "outputs": [],
   "source": [
    "paths = mc_fan()\n",
    "fig, ax = plt.subplots(figsize=(8,4.2))\n",
    "ax.plot(t, paths.T, color=\"#1B6B52\", alpha=.05)\n",
    "ax.plot(t, simulate(True), color=\"#0B3D2E\", lw=2.5, label=\"deterministic core\")\n",
    "q10,q90 = np.quantile(paths,[.1,.9],axis=0)\n",
    "ax.plot(t,q10,\"--\",c=\"#0B3D2E\",lw=1); ax.plot(t,q90,\"--\",c=\"#0B3D2E\",lw=1,label=\"10–90% band\")\n",
    "ax.set(xlabel=\"years\", ylabel=\"$x_5$\", title=\"Closed loop under disturbance (n=200)\")\n",
    "ax.legend(frameon=False); ax.grid(alpha=.25); plt.tight_layout(); plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "38ba0345",
   "metadata": {},
   "source": [
    "## Panel 3 — The boundary is a modeling decision\n",
    "Four subsystems; two defensible boundaries. $B_1$ leaves Ventures outside; $B_2$\n",
    "brings it in. The **same enterprise** reports a different aggregate state under\n",
    "each — nothing is wrong, and the difference is exactly what the Boundary\n",
    "Consistency Theorem disciplines."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "71ae8952",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-13T21:47:45.728082Z",
     "iopub.status.busy": "2026-07-13T21:47:45.727515Z",
     "iopub.status.idle": "2026-07-13T21:47:45.735167Z",
     "shell.execute_reply": "2026-07-13T21:47:45.734143Z"
    }
   },
   "outputs": [],
   "source": [
    "names=[\"Industrial\",\"Digital\",\"Shared services\",\"Ventures\"]\n",
    "for nm,s,w1,w2 in zip(names,SUBS,W_B1,W_B2):\n",
    "    print(f\"{nm:16s} state={s:5.1f}   weight B1={w1:.2f}  B2={w2:.2f}\")\n",
    "print(\"\\naggregate under B1:\", round(float(W_B1@SUBS),4))\n",
    "print(\"aggregate under B2:\", round(float(W_B2@SUBS),4))\n",
    "print(\"boundary shift    :\", round(float((W_B2-W_B1)@SUBS),4))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7f2d9f6b",
   "metadata": {},
   "source": [
    "## Validation — agrees with `DCT_V1_Ch02_Lab.xlsx`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f4cee215",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-13T21:47:45.736912Z",
     "iopub.status.busy": "2026-07-13T21:47:45.736726Z",
     "iopub.status.idle": "2026-07-13T21:47:45.743048Z",
     "shell.execute_reply": "2026-07-13T21:47:45.742009Z"
    }
   },
   "outputs": [],
   "source": [
    "ref = reference_values()\n",
    "expected = {\"open_loop_t5.0\":60.1274,\"closed_loop_t5.0\":67.5001,\"feedback_gap_t5.0\":7.3727,\n",
    " \"closed_loop_t1.0\":67.5898,\"aggregate_B1\":65.2,\"aggregate_B2\":66.83,\"boundary_shift\":1.63}\n",
    "for k,v in expected.items():\n",
    "    assert abs(ref[k]-v)<5e-4, f\"MISMATCH {k}\"\n",
    "    print(f\"PASS  {k:22s} {ref[k]}\")\n",
    "print(\"\\nAll checkpoints agree — seed 26102.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "49bc6546",
   "metadata": {},
   "source": [
    "**Next**: Exercises 2.9–2.12 (Part C) extend this laboratory; AXIOM-02's boundary designer makes Panel 3 draggable. Solutions: IM Ch. 2."
   ]
  }
 ],
 "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
}
