{
  "schemaVersion": 1,
  "lessonId": "internals-02",
  "contentHash": "b4c3b8720c5f59e80a50216fbd223c61ea013199a86108a3d73205efb94fc75a",
  "rendererHash": "a1bd5b648f4731ae5d5f0a24811c2540d1a0a132149ce589d17c4113509cbedf",
  "kind": "executed",
  "generatedAt": "2026-10-20T10:46:36.318127+00:00",
  "provenance": "recorded_cpu_computation",
  "environment": {
    "backend": "cpu",
    "deviceCount": 1,
    "jax": "0.9.2",
    "numpy": "2.4.4",
    "matplotlib": "3.10.8"
  },
  "stdout": "Jacobian: [[-0.7         0.4       ]\n [ 0.92106099 -1.4       ]]\nJVP: [-0.96        1.52527319] VJP: [ 1.49212199 -2.6       ] adjoint pair: 2.570546385606924 2.570546385606924\nHessian-vector product: [ 1.74991568 -3.38303348]\n",
  "data": {
    "panels": [
      {
        "kind": "bar",
        "labels": [
          "output 0",
          "output 1"
        ],
        "ylabel": "directional output change",
        "series": [
          {
            "label": "JAX JVP",
            "y": [
              -0.96,
              1.525273192803462
            ]
          },
          {
            "label": "analytic J v",
            "y": [
              -0.96,
              1.525273192803462
            ]
          }
        ]
      },
      {
        "kind": "bar",
        "labels": [
          "input 0",
          "input 1"
        ],
        "ylabel": "input cotangent",
        "series": [
          {
            "label": "JAX VJP",
            "y": [
              1.4921219880057701,
              -2.5999999999999996
            ]
          },
          {
            "label": "analytic transpose J u",
            "y": [
              1.4921219880057701,
              -2.5999999999999996
            ]
          }
        ]
      }
    ]
  },
  "diagram": {
    "title": "JVP and VJP use different vector spaces",
    "prediction": "Does a VJP simply return the same vector as a JVP?",
    "reading": "The top row pushes a three-component direction into two output components. The bottom pulls a two-component sensitivity back to three inputs. Shapes disambiguate the two products even when a square worked example would not. The adjoint identity checks their relationship.",
    "alt": "The top row pushes a three-component direction into two output components. The bottom pulls a two-component sensitivity back to three inputs. Shapes disambiguate the two products even when a square worked example would not. The adjoint identity checks their relationship.",
    "scope": "Architecture and dataflow mechanism diagram.",
    "height": 3.5,
    "panel": {
      "kind": "table",
      "headers": [
        "Mode",
        "Input",
        "Linear map",
        "Result"
      ],
      "rows": [
        [
          "JVP",
          "direction: (3,)",
          "J: (2, 3)",
          "Jv: (2,)"
        ],
        [
          "VJP",
          "sensitivity: (2,)",
          "J\u1d40: (3, 2)",
          "J\u1d40u: (3,)"
        ]
      ]
    }
  }
}
