{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Quickstart\n",
    "\n",
    "BrainEvent connects two ideas: **Data** describes how neural connectivity is stored or generated, while **Events** describes sparse, discrete activity and the operations driven by it. This notebook takes you from those concepts to a visible spike pattern and a first event-driven matrix multiplication. For setup instructions, see [Installation](installation.rst).\n",
    "\n",
    "## What BrainEvent Computes\n",
    "\n",
    "A `BinaryArray` wraps boolean or 0/1 activity. When it participates in matrix multiplication, BrainEvent processes the active entries as events while preserving the numerical result of ordinary dense multiplication.\n",
    "\n",
    "## Why Event-Driven Computation?\n",
    "\n",
    "Event-driven kernels can avoid work associated with inactive entries. The benefit depends on event density, matrix shape, backend, hardware, compilation state, and memory behavior; sparsity alone does not guarantee a speedup."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Import BrainEvent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import brainevent\n",
    "import brainstate\n",
    "import jax\n",
    "import jax.numpy as jnp\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "print(f\"BrainEvent {brainevent.__version__}\")\n",
    "print(f\"JAX backend: {jax.default_backend()}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Create and Visualize Binary Events\n",
    "\n",
    "Create 80 time steps for 20 neurons. Each active entry represents a spike."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "brainstate.random.seed(7)\n",
    "spike_train = brainstate.random.bernoulli(0.12, size=(80, 20))\n",
    "events = brainevent.BinaryArray(spike_train)\n",
    "\n",
    "print(\"event shape:\", events.shape)\n",
    "print(\"total active events:\", int(spike_train.sum()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "time_index, neuron_index = jnp.nonzero(spike_train)\n",
    "fig, ax = plt.subplots(figsize=(8, 3))\n",
    "ax.scatter(time_index, neuron_index, s=8)\n",
    "ax.set(xlabel=\"time step\", ylabel=\"neuron\", title=\"Binary spike events\")\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Run Your First Event-Driven Matrix Multiplication\n",
    "\n",
    "Multiply the event batch by dense connectivity weights. The ordinary JAX product provides a correctness reference."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "weights = jnp.linspace(-0.5, 0.5, 60, dtype=jnp.float32).reshape(20, 3)\n",
    "event_output = events @ weights\n",
    "dense_output = spike_train @ weights\n",
    "\n",
    "print(\"output shape:\", event_output.shape)\n",
    "print(\"matches dense result:\", bool(jnp.allclose(event_output, dense_output)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Use BrainEvent with JAX Transformations\n",
    "\n",
    "BrainEvent arrays compose with JAX transformations. The compiled function below performs the same event-driven multiplication."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "@jax.jit\n",
    "def apply_events(binary_events, matrix):\n",
    "    return binary_events @ matrix\n",
    "\n",
    "compiled_output = apply_events(events, weights)\n",
    "print(\"compiled result matches:\", bool(jnp.allclose(compiled_output, dense_output)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Summary and Next Steps\n",
    "\n",
    "You created binary spike events, visualized their activity, and verified an event-driven matrix multiplication against dense JAX computation. Continue with [Data](../tutorials/data-structures/index.rst) for CSR/CSC, fixed-count, and just-in-time connectivity; [Events](../tutorials/events/index.rst) for event representations and event-triggered updates; or [Custom operators](../tutorials/custom-operators/index.rst) to extend BrainEvent with new kernels."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.11"
  },
  "mystnb": {
   "execution_mode": "force",
   "execution_timeout": 120
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
