Quickstart#

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.

What BrainEvent Computes#

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.

Why Event-Driven Computation?#

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.

Import BrainEvent#

import brainevent
import brainstate
import jax
import jax.numpy as jnp
import matplotlib.pyplot as plt

print(f"BrainEvent {brainevent.__version__}")
print(f"JAX backend: {jax.default_backend()}")
BrainEvent 0.2.1
JAX backend: cpu

Create and Visualize Binary Events#

Create 80 time steps for 20 neurons. Each active entry represents a spike.

brainstate.random.seed(7)
spike_train = brainstate.random.bernoulli(0.12, size=(80, 20))
events = brainevent.BinaryArray(spike_train)

print("event shape:", events.shape)
print("total active events:", int(spike_train.sum()))
event shape: (80, 20)
total active events: 175
time_index, neuron_index = jnp.nonzero(spike_train)
fig, ax = plt.subplots(figsize=(8, 3))
ax.scatter(time_index, neuron_index, s=8)
ax.set(xlabel="time step", ylabel="neuron", title="Binary spike events")
plt.tight_layout()
plt.show()
../_images/04315630b3c72ec28cd1c25f001537219a159f44256c750fb4c600973bf27973.png

Run Your First Event-Driven Matrix Multiplication#

Multiply the event batch by dense connectivity weights. The ordinary JAX product provides a correctness reference.

weights = jnp.linspace(-0.5, 0.5, 60, dtype=jnp.float32).reshape(20, 3)
event_output = events @ weights
dense_output = spike_train @ weights

print("output shape:", event_output.shape)
print("matches dense result:", bool(jnp.allclose(event_output, dense_output)))
output shape: (80, 3)
matches dense result: True

Use BrainEvent with JAX Transformations#

BrainEvent arrays compose with JAX transformations. The compiled function below performs the same event-driven multiplication.

@jax.jit
def apply_events(binary_events, matrix):
    return binary_events @ matrix

compiled_output = apply_events(events, weights)
print("compiled result matches:", bool(jnp.allclose(compiled_output, dense_output)))
compiled result matches: True

Summary and Next Steps#

You created binary spike events, visualized their activity, and verified an event-driven matrix multiplication against dense JAX computation. Continue with Data for CSR/CSC, fixed-count, and just-in-time connectivity; Events for event representations and event-triggered updates; or Custom operators to extend BrainEvent with new kernels.