brainevent.fcnmm_dt2t#
- brainevent.fcnmm_dt2t = <NameScope(brainevent.fcnmm_dt2t)>#
Batched per-synapse element-wise product of dense vectors and fixed-connection weights.
Batched generalization of
fcnmv_dt2t(): for each batch elementband stored connection slot(i, k)of the fixed-connection-number (ELL) structure, computesout[b, i, k] = weights[b, i, k] * y[b, i]whentranspose=Falseorout[b, i, k] = weights[b, i, k] * y[b, indices[i, k]]whentranspose=True. Bothweightsandycarry a shared leading batch axis, and the result has shape(n_batch, *indices.shape).This is the fixed-connection-number analog of
brainevent.csrmm_dt2t()and follows the sametransposeconvention as that operator: the flag selects whetheryis indexed by the leading (row) axis or by the storedindices(column) axis. Note this is the opposite sense of thetransposeflag inbrainevent.fcnmv()/brainevent.fcnmm().This operation implements the \(D^t \epsilon^{t-1}\) term of the D-RTRL eligibility-trace update \(\epsilon^t \approx D^t \epsilon^{t-1} + \mathrm{diag}(D_f^t) \otimes x^t\) for a batch of samples:
yholds the batched per-neuron factor \(D^t\) andweightsholds the batched per-synapse trace \(\epsilon^{t-1}\) stored in the ELL grid.The operator is a plain element-wise / gather-multiply, so it is fully differentiable through JAX autodiff with respect to both
weightsandy; no custom differentiation rule is required. It is alsojit- andvmap-compatible.- Parameters:
weights (
Array|Quantity) – Batched per-synapse values. Either a scalar / size-1 array (homogeneous) or a(n_batch, rows, n_conn)array whose trailing axes matchindices(heterogeneous). Must be a floating-point dtype.indices (
Array) – Integer ELL index array of shape(rows, n_conn).y (
Array|Quantity) – Batch of dense vectors. Shape(n_batch, shape[0])whentranspose=Falseor(n_batch, shape[1])whentranspose=True.shape (
Tuple[int,int]) – Two-element(rows_dim, cols_dim)logical shape of the ELL operand.transpose (
bool) – IfFalse, indexyby the leading (row) axis (broadcast over the connection axis). IfTrue, indexybyindices(gather).
- Returns:
out – Batched per-synapse result of shape
(n_batch, *indices.shape). The output unit isunit(weights) * unit(y).- Return type:
Array|Quantity- Raises:
ValueError – If
indicesis not 2-D.ValueError – If
shapeis not length-2.ValueError – If
weightsis not a floating-point dtype.ValueError – If
weightsis neither size-1 nor shaped(n_batch, rows, n_conn).ValueError – If
yis not 2-D.ValueError – If
ydoes not have the trailing dimension required bytransposeandshape.
See also
fcnmv_dt2tUnbatched (single-vector) variant of this operator.
csrmm_dt2tCSR equivalent of this operator.
fcnmmFixed-connection sparse matrix–matrix product.
Notes
Unlike
brainevent.csrmm_dt2t()(which dropsy’s physical unit), this operator keeps both units, consistent withfcnmv_dt2t()and with the mathematics of a product.Mixed floating dtypes between
weightsandyare promoted following JAX’s standard promotion rules (e.g.float32 * float64 -> float64); no equal-dtype constraint is imposed.Empty structures are supported: an
indicesarray withrows == 0orn_conn == 0, or aywith zero batch elements, returns an array of the corresponding (empty) shape.This operation is memory-bandwidth-bound and maps to a fused XLA broadcast-multiply (
transpose=False) or gather-multiply (transpose=True); it is therefore implemented in pure JAX rather than as a custom kernel.Examples
>>> import jax.numpy as jnp >>> from brainevent import fcnmm_dt2t >>> # n_batch=2, rows=2, n_conn=2 >>> weights = jnp.array([[[0.5, 1.0], [1.5, 2.0]], ... [[1.0, 1.0], [1.0, 1.0]]]) >>> indices = jnp.array([[0, 1], [1, 2]]) >>> y = jnp.array([[10.0, 20.0], [100.0, 200.0]]) # (n_batch=2, rows=2) >>> fcnmm_dt2t(weights, indices, y, shape=(2, 3), transpose=False) Array([[[ 5., 10.], [ 30., 40.]], [[100., 100.], [200., 200.]]], dtype=float32) >>> # transpose=True gathers y by the stored column indices >>> y_post = jnp.array([[1.0, 2.0, 3.0], [10.0, 20.0, 30.0]]) >>> fcnmm_dt2t(weights, indices, y_post, shape=(2, 3), transpose=True) Array([[[ 0.5, 2. ], [ 3. , 6. ]], [[10. , 20. ], [20. , 30. ]]], dtype=float32)