VerifiedarXiv:2111.0039636 min
Architecture · Sequence models

S4: Efficiently Modeling Long Sequences with Structured State Spaces

A linear state space layer that keeps 64 numbers of state per channel and solved a 16,384-step task every earlier model failed.

The layer is a linear differential equation from control theory. The paper's contribution is an algorithm that builds a convolution kernel as long as the input sequence without ever raising the state matrix to a power.

Explaining the paperEfficiently Modeling Long Sequences with Structured State SpacesGu, Goel, Ré · Stanford · ICLR 2022 · arXiv:2111.00396 ↗

Path-X hands a model 16,384 pixels one at a time and asks whether two circles in the picture are joined by a path. Every model benchmarked on it before S4 scored 50%, the rate of guessing. S4 scored 96.35%.

Path-X is the hardest task in the Long Range Arena benchmark (Tay et al., 2020). The input is a 128×128 black-and-white image with two small circles and a tangle of dashed curves, and the label says whether one curve connects the circles. A convolutional network handed the 2-D image would find this easy. The benchmark does not hand over the image: it flattens it row by row into a sequence of 16,384 pixel values and feeds the model one value per position, so any 2-D structure has to be recovered from the sequence.

Flattening makes the task long. Two pixels directly above and below each other in the picture sit 128 positions apart in the sequence, and the two circles can be thousands of positions apart. Drag the teal circle in the figure and the strip below the picture shows the gap in tokens; one step down in the picture costs a full row.

Figure 1 · Path-X as a sequence
The same puzzle at three sizes. The picture is equally easy to read at each, but the flattened sequence gets 16× longer from 32×32 to 128×128. At 32×32 several Transformer variants clear 70%; at 128×128 every model published before S4 scored 50.00, which is chance. Drag the teal circle to see the token gap follow it.

The paper by Gu, Goel and Ré is mostly a numerical linear algebra paper. It takes the state space model, which control engineers have used since the 1960s, observes that nobody could compute it fast enough to train as a deep learning layer, and spends most of its length on an algorithm that does. That algorithm, and the initialization it was built to make affordable, are the starting point of the state space family that includes Mamba and Mamba-2.

The page follows the paper's order: what a state space model computes, how a step size turns it into a recurrence, which state matrix makes it remember long histories, why that matrix defeats the standard speed-up, the decomposition and algorithm that get around it, and then the layer, its cost, and the results.

Why sequence length is the hard part

To relate a token to one 16,000 positions earlier, the two standard architectures each have a problem. Attention scores every position against every other, so any token can read any earlier token directly, at any distance. The cost is L2L^2 scores per head per layer. At L=16,384L = 16{,}384 that is 268,435,456 scores, and a matrix of that size to store. FlashAttention later removed the storage by never materializing the matrix; the 268 million multiply-adds remain. The efficient-Transformer variants in Long Range Arena approximate the quadratic term with sparsity or low-rank structure. All of them scored 50.00 on Path-X, some because they ran out of memory or compute and some because they trained and did not learn the task.

A recurrent network carries a fixed-size hidden state forward and does a constant amount of work per step, so memory does not grow with length. For an input at step 1 to affect the output at step 16,000, its signal has to pass through 16,000 applications of the recurrent update, and the gradient back to it is a product of 16,000 Jacobians. A product that long either shrinks toward zero or blows up unless every factor stays very close to norm one, which is the vanishing and exploding gradient problem.

S4 is a recurrence too, but a linear one whose state matrix is chosen so that the decay over many steps is slow and controlled, and whose linearity lets the whole recurrence be computed as one convolution during training.

How a state space model works

The state space model is two equations:

x′(t)=Ax(t)+Bu(t),y(t)=Cx(t)+Du(t)x'(t) = \bm{A}x(t) + \bm{B}u(t), \qquad y(t) = \bm{C}x(t) + \bm{D}u(t)
(1)

u(t)u(t) is a scalar input signal that changes over continuous time. x(t)x(t) is a vector of NN numbers, the state. y(t)y(t) is a scalar output. The first equation gives the rate of change of each state coordinate: a linear combination of the current state through the N×NN \times N matrix A\bm{A}, plus the current input scaled by the N×1N \times 1 vector B\bm{B}. The second reads the output off the state with the 1×N1 \times N vector C\bm{C}, plus a direct copy of the input scaled by the number D\bm{D}.

In control theory a state is a sufficient summary of the past: given x(t)x(t) and the inputs after time tt, the earlier inputs are never needed again. The NN numbers are therefore neither a window over recent inputs nor a cache of them. They are a fixed-size compression of the entire history, and the model can only use what survives the compression. S4 sets N=64N = 64 for the Long Range Arena experiments.

Du\bm{D}u bypasses the state, so the paper sets D=0\bm{D} = 0 in the exposition and treats it as a skip connection. The released code adds it back as a trained per-channel parameter.

Two properties of (1) drive the rest of the paper. It is linear: the response to the sum of two inputs is the sum of the two responses, because nothing in the equations is a gate, a tanh⁡\tanh, or any other nonlinearity. And it is time-invariant: A,B,C\bm{A}, \bm{B}, \bm{C} do not depend on tt or on the input, so a spike at step 10 produces the same response as a spike at step 5,000, shifted by 4,990 steps. A system with both properties is called linear time-invariant, or LTI.

An LTI system computes a convolution. Write the input as a sum of single spikes, one per time step, each scaled by the input value there. By linearity the output is the sum of the responses to the individual spikes. By time-invariance each of those responses is one fixed shape, shifted to the spike's position and scaled by its value. Adding up shifted, scaled copies of one shape is convolution with that shape, which signal processing calls the impulse response.

To compute it, turn the ODE into a recurrence over discrete steps (the next section derives A‾,B‾,C‾\bm{\overline{A}}, \bm{\overline{B}}, \bm{\overline{C}}) and unroll it from a zero initial state:

xk=A‾xk−1+B‾uk,yk=C‾xk,x−1=0x_k = \bm{\overline{A}}x_{k-1} + \bm{\overline{B}}u_k, \qquad y_k = \bm{\overline{C}}x_k, \qquad x_{-1} = 0
(3)
yk=∑j=0kC‾ A‾ jB‾  uk−j=(K‾∗u)ky_k = \sum_{j=0}^{k} \bm{\overline{C}}\,\bm{\overline{A}}^{\,j}\bm{\overline{B}}\;u_{k-j} = (\bm{\overline{K}} * u)_k
(4)
K‾=(C‾B‾, C‾A‾B‾, …, C‾A‾L−1B‾)\bm{\overline{K}} = \big(\bm{\overline{C}}\bm{\overline{B}},\ \bm{\overline{C}}\bm{\overline{A}}\bm{\overline{B}},\ \dots,\ \bm{\overline{C}}\bm{\overline{A}}^{L-1}\bm{\overline{B}}\big)
(5)

The bars mark discretized quantities. Each entry C‾A‾iB‾\bm{\overline{C}}\bm{\overline{A}}^{i}\bm{\overline{B}} is a 1×N1 \times N row times an N×NN \times N matrix power times an N×1N \times 1 column, so it is a single number, and K‾\bm{\overline{K}} is a filter of LL numbers, as long as the sequence. Feed in a 1 followed by zeros and the output is K‾\bm{\overline{K}} itself.

No approximation happens between (3) and (4). With the initial state at zero, which the paper assumes and the code does, the recurrence and the convolution compute the same function. S4 uses both: during training the whole sequence is available, so it computes all LL outputs at once with the convolution; during generation the next input does not exist yet, so it runs the recurrence at a fixed cost per token. The figure runs a two-state system both ways. Switch between the recurrent and convolutional views and compare the output rows digit by digit.

Figure 2 · one system, three ways to run it
A hand-picked two-state system, run three ways. Recurrent carries the state along and fills the output boxes one at a time. Convolutional lays the fixed kernel K̄ over the inputs and produces every output in one pass. The two output rows agree to the last printed digit. Hover or tap an output box to pick a position.

The smallest version can be computed by hand, with the HiPPO matrix introduced two sections below. Take N=2N = 2, step size Δ=1\Delta = 1, and a readout that takes the first state coordinate:

A=[−10−3−2],B=[13],C=[10]\bm{A} = \begin{bmatrix} -1 & 0 \\ -\sqrt{3} & -2\end{bmatrix}, \quad \bm{B} = \begin{bmatrix} 1 \\ \sqrt{3}\end{bmatrix}, \quad \bm{C} = \begin{bmatrix} 1 & 0\end{bmatrix}

The discretization formula of the next section gives

A‾=[1/30−1/30],B‾=[2/31/3]\bm{\overline{A}} = \begin{bmatrix} 1/3 & 0 \\ -1/\sqrt{3} & 0\end{bmatrix}, \qquad \bm{\overline{B}} = \begin{bmatrix} 2/3 \\ 1/\sqrt{3}\end{bmatrix}

Since C=[1 0]\bm{C} = [1\ 0], the output is the first coordinate, whose update is xk=13xk−1+23ukx_k = \tfrac13 x_{k-1} + \tfrac23 u_k, so the kernel is the geometric sequence K‾i=23(13)i\bm{\overline{K}}_i = \tfrac23(\tfrac13)^i:

K‾=(0.6667,  0.2222,  0.0741,  0.0247,  0.0082,  … )\bm{\overline{K}} = (0.6667,\; 0.2222,\; 0.0741,\; 0.0247,\; 0.0082,\; \dots)

Feed it the pulse u=(1,1,1,1,0,0,0,0)u = (1,1,1,1,0,0,0,0). Unrolling the recurrence, convolving directly, or convolving by FFT all give

y=(0.667, 0.889, 0.963, 0.988, 0.329, 0.110, 0.037, 0.012)y = (0.667,\ 0.889,\ 0.963,\ 0.988,\ 0.329,\ 0.110,\ 0.037,\ 0.012)

While the pulse is on, the output climbs toward 1; after it ends, the output falls by a factor of 3 per step. This is a leaky running average of recent input. At N=64N = 64 and L=16,384L = 16{,}384, computing K‾\bm{\overline{K}} this way would mean 16,383 multiplications by a 64×64 matrix, which is the problem the rest of the paper solves.

Discretization and the step size Δ

Equation (1) is written in continuous time, and a sequence model receives u0,u1,u2,…u_0, u_1, u_2, \dots. The bridge is one number, the step size Δ\Delta, which says how much continuous time passes between consecutive tokens: uk=u(kΔ)u_k = u(k\Delta). The data does not determine Δ\Delta, so S4 learns it, one value per channel.

The simplest discretization is forward Euler, which replaces the derivative with a finite difference:

xk=xk−1+Δ(Axk−1+Buk),A‾=I+ΔAx_k = x_{k-1} + \Delta\big(\bm{A}x_{k-1} + \bm{B}u_k\big), \qquad \bm{\overline{A}} = \bm{I} + \Delta\bm{A}

S4 uses the bilinear transform (Tustin, 1947) instead, which averages the derivative at both ends of the step, as the trapezoidal rule does:

A‾=(I−Δ2A)−1(I+Δ2A),B‾=(I−Δ2A)−1ΔB,C‾=C\bm{\overline{A}} = \Big(\bm{I}-\tfrac{\Delta}{2}\bm{A}\Big)^{-1}\Big(\bm{I}+\tfrac{\Delta}{2}\bm{A}\Big), \qquad \bm{\overline{B}} = \Big(\bm{I}-\tfrac{\Delta}{2}\bm{A}\Big)^{-1}\Delta\bm{B}, \qquad \bm{\overline{C}} = \bm{C}
(3)

This display carries the same number as the recurrence above because the paper prints them together as one equation group. The factor I+Δ2A\bm{I}+\tfrac{\Delta}{2}\bm{A} is a forward half-step, and the inverse (I−Δ2A)−1(\bm{I}-\tfrac{\Delta}{2}\bm{A})^{-1} is a backward half-step.

Why not Euler? Both discretizations are rational functions of A\bm{A}, so each eigenvalue λ\lambda of A\bm{A} maps to an eigenvalue of A‾\bm{\overline{A}} by the same scalar formula:

Euler: λ↦1+Δλ,bilinear: λ↦1+Δ2λ1−Δ2λ\text{Euler: } \lambda \mapsto 1 + \Delta\lambda, \qquad \text{bilinear: } \lambda \mapsto \frac{1+\tfrac{\Delta}{2}\lambda}{1-\tfrac{\Delta}{2}\lambda}

A continuous system is stable when every eigenvalue has negative real part. A discrete recurrence is stable when every eigenvalue of A‾\bm{\overline{A}} has magnitude below 1; otherwise that mode is multiplied by more than 1 at every step and grows without bound. The bilinear map sends the whole left half-plane into the open unit disk, for every Δ>0\Delta > 0. Euler sends λ=−n\lambda = -n to 1−Δn1 - \Delta n, which leaves the disk once Δ>2/n\Delta > 2/n.

The HiPPO matrix of the next section has eigenvalues exactly −1,−2,…,−N-1, -2, \dots, -N. At N=64N = 64 and Δ=0.1\Delta = 0.1, the top of S4's initialization range, Euler sends λ=−64\lambda = -64 to 1−6.4=−5.41 - 6.4 = -5.4; that mode is multiplied by 5.4 per token, about 1073210^{732} over 1,000 tokens. The bilinear transform sends it to (1−3.2)/(1+3.2)=−0.524(1-3.2)/(1+3.2) = -0.524. At the small end, λ=−1\lambda = -1 with Δ=0.1\Delta = 0.1 goes to 0.9048. In the figure, the shaded band is the stable region. Sweep Δ\Delta and switch NN: the amber Euler points fall out of the band once Δ\Delta passes 2/N2/N, while the teal bilinear points stay inside at every setting.

Figure 3 · forward Euler against the bilinear transform
0.10
Each mode n of equation (2) has continuous eigenvalue −n. Forward Euler maps it to 1 − Δn and leaves the stable band when Δ > 2/n; the verdict row counts the modes outside and how much the worst one grows in 1,000 steps. The bilinear transform keeps every mode inside at every Δ. The slider runs from Δ = 0.0001 to 1, covering both S4 initialization ranges.

Besides stability, Δ\Delta sets how far back the layer looks. The slowest mode of the HiPPO matrix has λ=−1\lambda = -1, and the bilinear map sends it to approximately e−Δe^{-\Delta}, so it decays by a factor of ee over about 1/Δ1/\Delta tokens. The released code initializes one Δ\Delta per channel, drawn log-uniformly from [0.001, 0.1][0.001,\ 0.1], which spreads those horizons from about 10 to about 1,000 tokens across the channels of a single layer.

The continuous-time view also explains a Speech Commands result. The dataset is recorded at 16 kHz. An S4 model trained at that rate scores 96.30% on test audio resampled to 8 kHz, with no retraining, after its Δ\Delta is doubled. Halving the sample rate doubles the real time between samples, and doubling Δ\Delta makes the discretization use that spacing, while the learned A,B,C\bm{A}, \bm{B}, \bm{C} describe the same continuous system as before. The rescale is manual: someone has to know the new sample rate and change Δ\Delta.

The HiPPO matrix

Everything so far holds for any A\bm{A}, and most choices of A\bm{A} train badly. The LSSL, the paper's immediate predecessor, reports 62% on permuted MNIST with a random, suitably normalized A\bm{A}, against 98.76% with the matrix below.

That matrix comes from HiPPO (Gu et al., 2020), which asked a different question: with a budget of NN numbers, what is the best summary of a signal's history, and can it be updated online as new input arrives? HiPPO's answer is a running least-squares polynomial approximation. Keep the NN coefficients of the best polynomial approximation of the history so far, in an orthogonal polynomial basis. HiPPO proves that those coefficients obey a linear ODE, so they can be updated by integrating the ODE instead of refitting. For the scaled Legendre measure (LegS) the matrix is:

Ank=−{(2n+1)1/2(2k+1)1/2if n>kn+1if n=k0if n<k,Bn=(2n+1)1/2\bm{A}_{nk} = -\begin{cases}(2n+1)^{1/2}(2k+1)^{1/2} & \text{if } n > k\\ n+1 & \text{if } n = k\\ 0 & \text{if } n < k\end{cases}, \qquad \bm{B}_n = (2n+1)^{1/2}
(2)

The square roots normalize the Legendre polynomials. The lower-triangular shape means coefficient nn is driven by the lower-degree coefficients 0,…,n−10, \dots, n-1. The diagonal entry −(n+1)-(n+1) is the decay rate of coefficient nn, so higher-degree coefficients, which carry finer detail, decay faster. Because the matrix is triangular its eigenvalues are its diagonal entries, −1,−2,…,−N-1, -2, \dots, -N, the eigenvalues used in Figure 3.

S4 changes one thing about how HiPPO uses this matrix, and the change alters what the state remembers. HiPPO's LegS system is time-varying. Written with the A\bm{A} and B\bm{B} of (2), it is

ddtx(t)=1tAx(t)+1tBu(t)\frac{d}{dt}x(t) = \frac{1}{t}\bm{A}x(t) + \frac{1}{t}\bm{B}u(t)

where the 1/t1/t stretches the approximation window as time passes, so the coefficients always summarize the whole history from 0 to tt with uniform weight. S4 keeps the matrix and drops the 1/t1/t, which gives back equation (1) with a constant A\bm{A}: the system becomes time-invariant, which is what the convolution requires. Run equation (2) as a fixed linear system and its impulse response has a closed form,

(etAB)n=2n+1  Pn ⁣(2e−t−1) e−t\big(e^{t\bm{A}}\bm{B}\big)_n = \sqrt{2n+1}\;P_n\!\big(2e^{-t}-1\big)\,e^{-t}

where PnP_n is the degree-nn Legendre polynomial. Its argument is e−te^{-t}, not tt: the time-invariant system fits polynomials to the past in a warped time variable in which recent history is stretched out and receives most of the resolution, and distant history is squeezed toward zero. The memory fades smoothly with age instead of weighting all of history equally. The S4 paper does not discuss the change; the closed form was worked out in the follow-up paper How to Train Your HiPPO.

The figure draws the input history on that warped axis, with "now" at the right edge and older input compressed toward the left. Raise NN from 1 and watch which part of the history the reconstruction resolves first.

Figure 4 · what N numbers can remember
time →
N = 8
Amber is the input history on the exponentially warped axis the state uses: the last 50 steps take most of the width, and 400 steps back is a sliver on the left. Teal is the history rebuilt from the state's N numbers. At N = 1 it is a single weighted average. Press play and each event drifts left and flattens as it ages.

The matrix also never amplifies the state, even briefly. Let Pn=(2n+1)1/2\bm{P}_n = (2n+1)^{1/2}, the same vector as B\bm{B}. The symmetric part of (2) is

12(A+A⊤)=−12I−12PP⊤⪯−12I\tfrac12\big(\bm{A}+\bm{A}^{\top}\big) = -\tfrac12\bm{I}-\tfrac12\bm{P}\bm{P}^{\top} \preceq -\tfrac12\bm{I}

and a symmetric part bounded by −12I-\tfrac12\bm{I} gives ∥etA∥2≤e−t/2\lVert e^{t\bm{A}}\rVert_2 \le e^{-t/2} for every t≥0t \ge 0. The norm of the state falls monotonically from any starting point. Many non-normal matrices first amplify the state by a large factor before it decays, which wrecks a recurrence in floating point; this one cannot. The vector P\bm{P} returns two sections below as the low-rank part of the decomposition.

Why diagonalizing the HiPPO matrix fails

Building K‾\bm{\overline{K}} from (5) directly takes LL successive multiplications by an N×NN \times N matrix: O(N2L)O(N^2L) operations, and O(NL)O(NL) memory to keep the intermediate states for backpropagation. The LSSL used N=256N = 256, and at that size it needed orders of magnitude more memory than an RNN or CNN of similar size, which kept it from being run at the sizes it needed.

The textbook speed-up is diagonalization. If A=VΛV−1\bm{A} = \bm{V}\bm{\Lambda}\bm{V}^{-1} with Λ\bm{\Lambda} diagonal, then Ai=VΛiV−1\bm{A}^i = \bm{V}\bm{\Lambda}^i\bm{V}^{-1}, and a power of a diagonal matrix is NN scalar powers. The change of basis costs nothing in the model. The paper's Lemma 3.1 states that

(A, B, C)  ∼  (V−1AV, V−1B, CV)(\bm{A},\ \bm{B},\ \bm{C}) \;\sim\; (\bm{V}^{-1}\bm{A}\bm{V},\ \bm{V}^{-1}\bm{B},\ \bm{C}\bm{V})

compute the same map from uu to yy, because in CV(V−1AV)iV−1B\bm{C}\bm{V}(\bm{V}^{-1}\bm{A}\bm{V})^i\bm{V}^{-1}\bm{B} every VV−1\bm{V}\bm{V}^{-1} pair cancels.

Equation (2) is diagonalizable. Its eigenvalues −1,…,−N-1, \dots, -N are real and distinct, distinct eigenvalues guarantee a full set of independent eigenvectors, and Lemma 3.2 even gives the eigenvector matrix in closed form, Vij=(i+ji−j)\bm{V}_{ij} = \binom{i+j}{i-j}.

In floating point it fails anyway. The eigenvectors are independent but nearly parallel, so V\bm{V} is badly ill-conditioned: writing an ordinary vector in that basis takes huge coordinates of opposite sign that nearly cancel, and float64 keeps about 16 significant digits, so the cancellation destroys the result. Lemma 3.2 bounds the entries of V\bm{V} by 24N/32^{4N/3}, about 4.9×10254.9 \times 10^{25} at N=64N = 64. The condition number of V\bm{V}, which we computed in 260-digit arithmetic because float64 cannot measure it, is about 7.7×1047.7\times10^4 at N=8N=8, 8.3×10108.3\times10^{10} at N=16N=16, 1.2×10231.2\times10^{23} at N=32N=32, and 3.2×10473.2\times10^{47} at N=64N=64. A condition number of 3.2×10473.2\times10^{47} means about 158 bits of precision are needed to diagonalize at S4's size, and float64 has 53.

Nothing overflows, the matrix is not defective, and the eigenvalues stay exact at every NN; only the computed eigenvectors lose relative precision. The figure's meter shows it directly: it takes the left matrix apart into its exactly known eigenvalues and eigenvectors, multiplies them back together in float64, and reports the relative error. Move NN up and watch the error pass 100% at about N=26N = 26.

Figure 5 · a diagonalizable matrix that cannot be diagonalized in float64
N = 16
Left, equation (2): lower triangular, eigenvalues exactly −1 … −N, and far from normal. Right, the same matrix plus ½PPᵀ: the picture turns antisymmetric around a constant diagonal, the normality defect is exactly zero, and every eigenvalue moves to the line Re = −½. The meter rebuilds the left matrix from its own eigenvalues and eigenvectors in float64; past N ≈ 26 the rebuilt matrix is off by more than 100%.

The matrices that diagonalize safely form a known class. A matrix is normal when it commutes with its conjugate transpose, AA∗=A∗A\bm{A}\bm{A}^{*} = \bm{A}^{*}\bm{A}. The spectral theorem says a matrix can be diagonalized by a unitary V\bm{V} (a rotation, with condition number 1, so nothing is lost to rounding) exactly when it is normal. Symmetric and skew-symmetric matrices are normal; equation (2) is not, and the figure's "not normal" readout measures by how much.

Normal plus low-rank

Requiring A\bm{A} to be normal would rule out the HiPPO matrix. The paper asks for less: a normal matrix plus a low-rank correction. It calls this form NPLR, normal plus low-rank. After the unitary change of basis that diagonalizes the normal part it becomes DPLR, diagonal plus low-rank, which is the form S4 stores:

A=VΛV∗−PQ⊤=V(Λ−(V∗P)(V∗Q)∗)V∗\bm{A} = \bm{V}\bm{\Lambda}\bm{V}^{*} - \bm{P}\bm{Q}^{\top} = \bm{V}\big(\bm{\Lambda} - (\bm{V}^{*}\bm{P})(\bm{V}^{*}\bm{Q})^{*}\big)\bm{V}^{*}
(6)

For the HiPPO matrix the correction has rank one, and the decomposition is exact. With Pn=(2n+1)1/2\bm{P}_n = (2n+1)^{1/2}, add 12PP⊤\tfrac12\bm{P}\bm{P}^{\top} to equation (2) and check the three kinds of entry. Above the diagonal, where A\bm{A} is zero, the sum is half the outer-product entry, 12PnPk\tfrac12\bm{P}_n\bm{P}_k. Below the diagonal it is

−(2n+1)1/2(2k+1)1/2+12(2n+1)1/2(2k+1)1/2=−12(2n+1)1/2(2k+1)1/2-(2n+1)^{1/2}(2k+1)^{1/2} + \tfrac12(2n+1)^{1/2}(2k+1)^{1/2} = -\tfrac12(2n+1)^{1/2}(2k+1)^{1/2}

which is the mirror entry with the opposite sign. On the diagonal it is −(n+1)+12(2n+1)=−12-(n+1) + \tfrac12(2n+1) = -\tfrac12 in every row. So

A+12PP⊤=−12I+S,S⊤=−S\bm{A} + \tfrac12\bm{P}\bm{P}^{\top} = -\tfrac12\bm{I} + \bm{S}, \qquad \bm{S}^{\top} = -\bm{S}

A skew-symmetric matrix has purely imaginary eigenvalues and is normal, and adding a multiple of the identity keeps it normal and shifts every eigenvalue by that multiple. Every eigenvalue of the corrected matrix is therefore −12+iω-\tfrac12 + i\omega for some real ω\omega. At N=8N = 8 they are −0.5±19.857i-0.5 \pm 19.857i, −0.5±5.354i-0.5 \pm 5.354i, −0.5±1.958i-0.5 \pm 1.958i and −0.5±0.427i-0.5 \pm 0.427i. All modes of the normal part decay at the same rate and differ only in how fast they oscillate. In the DPLR basis, Λ\bm{\Lambda} holds these eigenvalues on its diagonal, and the original eigenvalues −1,…,−N-1, \dots, -N are recovered only once the rank-one term is subtracted back.

The trainable parameters of one S4 channel are Λ,P,Q,B,C\bm{\Lambda}, \bm{P}, \bm{Q}, \bm{B}, \bm{C}, five complex vectors of length NN, which the paper counts as 5N5N parameters. The released code differs in ways that matter when reading it: Q\bm{Q} is tied to P\bm{P} (the Λ−PP∗\bm{\Lambda} - \bm{P}\bm{P}^{*} form from the SaShiMi paper), only one member of each complex conjugate pair is stored, and Δ\Delta and D\bm{D} are trained as well, outside the 5N5N. The kernel K‾\bm{\overline{K}} is never a parameter; it is recomputed from these vectors on every forward pass. At Path-X scale, with H=256H = 256 channels, roughly 66,000 stored numbers generate a 256×16,384256 \times 16{,}384 filter bank, 4,194,304 taps.

How S4 computes the kernel

Storing A=Λ−PQ∗\bm{A} = \bm{\Lambda} - \bm{P}\bm{Q}^{*} does not by itself make (5) cheap, because powers of a diagonal-plus-rank-one matrix do not stay diagonal plus rank one. Expand the square:

(Λ−PQ∗)2=Λ2−ΛPQ∗−PQ∗Λ+P(Q∗P)Q∗(\bm{\Lambda}-\bm{P}\bm{Q}^{*})^2 = \bm{\Lambda}^2 - \bm{\Lambda}\bm{P}\bm{Q}^{*} - \bm{P}\bm{Q}^{*}\bm{\Lambda} + \bm{P}(\bm{Q}^{*}\bm{P})\bm{Q}^{*}

The part that is not Λ2\bm{\Lambda}^2 has columns in the span of P\bm{P} and ΛP\bm{\Lambda}\bm{P}, so it has rank two. In general the off-diagonal part of the kk-th power lives in the span of P,ΛP,…,Λk−1P\bm{P}, \bm{\Lambda}\bm{P}, \dots, \bm{\Lambda}^{k-1}\bm{P}, so its rank grows by one per multiplication until it reaches NN and the matrix is effectively dense again. The paper puts it as "powering up this sum is still slow".

Inverses behave the opposite way. The Woodbury identity says that a rank-pp change to a matrix changes its inverse by rank pp, and the only new inverse needed is p×pp \times p:

(A+UV∗)−1=A−1−A−1U(Ip+V∗A−1U)−1V∗A−1(\bm{A}+\bm{U}\bm{V}^{*})^{-1} = \bm{A}^{-1} - \bm{A}^{-1}\bm{U}\big(\bm{I}_p + \bm{V}^{*}\bm{A}^{-1}\bm{U}\big)^{-1}\bm{V}^{*}\bm{A}^{-1}

At p=1p = 1 the inner inverse is one scalar division. The figure computes both in float64 on an 8×8 example, M=Λ−PQ∗\bm{M} = \bm{\Lambda} - \bm{P}\bm{Q}^{*} with a real scalar ss: singular values of the off-diagonal part of Mk\bm{M}^k on the left, and of the off-diagonal part of (sI−M)−1(s\bm{I} - \bm{M})^{-1} on the right. Step kk up and one more singular value rises above the rounding floor each time; move ss and the right panel keeps a single bar.

Figure 6 · powers spread the low-rank term, inverses keep it rank one
3
1.50
M = Λ − pqᵀ with N = 8. Each bar is a singular value, scaled so the largest is 1, on a log axis; bars below the dashed 10⁻¹² line are rounding noise. Left: the off-diagonal part of Mᵏ has rank min(k, 8). Right: the off-diagonal part of (sI − M)⁻¹ has rank 1 at every s. Drag the power k from 1 to 16.

So S4 rewrites the kernel in terms of an inverse, using a generating function: put the LL kernel values into the coefficients of a polynomial in zz and evaluate the polynomial instead of computing the coefficients:

K^L(z)=∑i=0L−1C‾∗A‾iB‾ zi=C‾∗(I−A‾LzL)(I−A‾z)−1B‾\hat{\mathcal{K}}_L(z) = \sum_{i=0}^{L-1} \bm{\overline{C}}^{*}\bm{\overline{A}}^{i}\bm{\overline{B}}\, z^i = \bm{\overline{C}}^{*}\big(\bm{I} - \bm{\overline{A}}^{L}z^{L}\big)\big(\bm{I}-\bm{\overline{A}}z\big)^{-1}\bm{\overline{B}}
(11)

The right side is the finite geometric series, ∑i<Lri\textstyle\sum_{i<L} r^i equal to (1−rL)/(1−r)(1-r^L)/(1-r), with the matrix A‾z\bm{\overline{A}}z in place of rr, valid wherever the inverse exists. The LL powers of A‾\bm{\overline{A}} have become one inverse and one fixed power A‾L\bm{\overline{A}}^L. Two choices make the right side cheap to evaluate.

First, evaluate at the LL-th roots of unity, zk=e−2πik/Lz_k = e^{-2\pi i k/L}. At those points the values of K^L\hat{\mathcal{K}}_L are exactly the discrete Fourier transform of K‾\bm{\overline{K}}, so one inverse FFT recovers the LL kernel values with nothing lost. Also at those points zL=1z^L = 1, so the factor I−A‾LzL\bm{I}-\bm{\overline{A}}^{L}z^{L} becomes the constant I−A‾L\bm{I}-\bm{\overline{A}}^{L} and can be absorbed into the output vector once:

C~=(I−A‾L)∗C‾\bm{\tilde{C}} = \big(\bm{I}-\bm{\overline{A}}^{L}\big)^{*}\bm{\overline{C}}

S4 learns C~\bm{\tilde{C}} directly and never computes A‾L\bm{\overline{A}}^L.

Second, expand the remaining inverse with Woodbury. With A=Λ−PQ∗\bm{A} = \bm{\Lambda} - \bm{P}\bm{Q}^{*}, the bilinear A‾\bm{\overline{A}}, and the substitution

s=2Δ⋅1−z1+z,R(z)=(sI−Λ)−1s = \frac{2}{\Delta}\cdot\frac{1-z}{1+z}, \qquad \bm{R}(z) = (s\bm{I} - \bm{\Lambda})^{-1}

the generating function at each root of unity reduces to

K^(z)=21+z[C~∗RB−C~∗RP(1+Q∗RP)−1Q∗RB]\hat{K}(z) = \frac{2}{1+z}\Big[\bm{\tilde{C}}^{*}\bm{R}\bm{B} - \bm{\tilde{C}}^{*}\bm{R}\bm{P}\big(1+\bm{Q}^{*}\bm{R}\bm{P}\big)^{-1}\bm{Q}^{*}\bm{R}\bm{B}\Big]

All four bracketed quantities have the form v∗Rw\bm{v}^{*}\bm{R}\bm{w}, and since Λ\bm{\Lambda} is diagonal, each one is a sum of NN divisions:

v∗R(z) w=∑j=1Nvj‾ wjs−λj\bm{v}^{*}\bm{R}(z)\,\bm{w} = \sum_{j=1}^{N} \frac{\overline{v_j}\,w_j}{s - \lambda_j}

Evaluating such a sum at LL points is multiplication by a Cauchy matrix, the matrix with entries 1/(si−λj)1/(s_i - \lambda_j), and numerical analysis has fast, stable algorithms for it. That is Theorem 3: the kernel reduces to four Cauchy multiplies, O~(N+L)\tilde{O}(N+L) operations and O(N+L)O(N+L) memory, against O(N2L)O(N^2L) and O(NL)O(NL) for the direct computation.

The divisions are also numerically safe. For z=e−iθz = e^{-i\theta} on the unit circle, the node is s=2iΔtan⁡(θ/2)s = \tfrac{2i}{\Delta}\tan(\theta/2), purely imaginary, and every λj\lambda_j has real part −12-\tfrac12. So ∣s−λj∣≥12\lvert s - \lambda_j\rvert \ge \tfrac12 and no denominator comes near zero.

The whole algorithm, in NumPy:

# Algorithm 1: the length-L kernel from N diagonal poles plus a rank-one term.
# Lam, P, B, Ct are complex vectors of length N. Ct is the learned C-tilde.

z = np.exp(-2j * np.pi * np.arange(L) / L)     # L-th roots of unity (minus sign)
s = (2 / dt) * (1 - z) / (1 + z)               # bilinear image: purely imaginary

def cauchy(v):                                 # sum_j v_j / (s - Lam_j), every s
    return (v[None, :] / (s[:, None] - Lam[None, :])).sum(-1)

k00 = cauchy(Ct.conj() * B)                    # the four Cauchy sums
k01 = cauchy(Ct.conj() * P)
k10 = cauchy(P.conj() * B)                     # released code ties Q = P
k11 = cauchy(P.conj() * P)

Khat = 2 / (1 + z) * (k00 - k01 / (1 + k11) * k10)   # Woodbury: one divide
K = np.fft.ifft(Khat).real                     # length-L kernel, time domain

Algorithm 1 prints the roots of unity as e+2πik/Le^{+2\pi i k/L}; paired with its own inverse FFT that returns the kernel reversed in time, a filter that looks at the future. Lemma C.2 and the released code use e−2πik/Le^{-2\pi i k/L}, as above. And when LL is even, one node is z=−1z = -1, where 2/(1+z)2/(1+z) divides by zero. The singularity is removable: ss goes to infinity there, the resolvent shrinks at the same rate, and the limit is C~∗(I+A‾)−1B‾\bm{\tilde{C}}^{*}(\bm{I}+\bm{\overline{A}})^{-1}\bm{\overline{B}}, so that node keeps a finite value.

The O~(N+L)\tilde{O}(N+L) of Theorem 3 assumes a fast-multipole Cauchy algorithm. Appendix A says those algorithms were not implemented for GPUs, and the release computes the Cauchy sums directly in O(NL)O(NL) time, with O(N+L)O(N+L) memory because the N×LN \times L matrix is never stored. At N=64N = 64 that is a modest cost, and it is paid once per batch, since the kernel does not depend on the input.

The figure runs the listing above in the browser, on the HiPPO initialization at N=64N = 64. The left panel is the resulting kernel; the right panel shows the 64 diagonal entries of Λ\bm{\Lambda} after the bilinear map, the poles of the four Cauchy sums. Drag Δ\Delta across the initialization range and past both ends. At small Δ\Delta the kernel stretches over more than a thousand taps and the poles bunch near z=1z = 1; at large Δ\Delta they spread around the circle and the kernel becomes a short, jagged burst. The poles stay strictly inside the circle at every Δ\Delta.

Figure 7 · the kernel S4 starts from
0.010
Left, the 2,048-tap kernel computed live by the four-Cauchy-sum algorithm at N = 64; the shaded region holds 90% of its energy. Right, the 64 poles of Λ after the bilinear map. The rank-one term moves the system's actual eigenvalues back to the real values (1 − Δn/2)/(1 + Δn/2) of Figure 3. Small Δ gives a long, slow filter; large Δ a short, jagged one. Max |z| stays below 1 throughout.

The recurrent view needs the same structure. Appendix C.2 writes the bilinear A‾\bm{\overline{A}} as a product of two factors: the forward half-step I+Δ2A\bm{I} + \tfrac{\Delta}{2}\bm{A}, which is diagonal plus rank one, and the backward half-step (I−Δ2A)−1(\bm{I} - \tfrac{\Delta}{2}\bm{A})^{-1}, which Woodbury also turns into diagonal plus rank one. Multiplying a vector by each factor costs O(N)O(N), so one generation step costs O(N)O(N) (Theorem 2). The readout during generation has to use C‾\bm{\overline{C}}, not the learned C~\bm{\tilde{C}}, which contains the (I−A‾L)(\bm{I}-\bm{\overline{A}}^L) factor meant only for the convolution. Recover it once by solving the definition of C~\bm{\tilde{C}} for C‾\bm{\overline{C}}, an N×NN \times N linear system. The factor is far from the identity: at Δ=0.001\Delta = 0.001, L=1024L = 1024, N=64N = 64, the norm of A‾L\bm{\overline{A}}^L is about 0.60.

# generation: the same parameters, run as a recurrence
AbarL = matrix_power(Abar, L)          # once, before generating
C = solve((I - AbarL).conj().T, Ct)   # undo C-tilde = (I - Abar^L)^* C
x = zeros(N, complex)                 # the whole memory of the past: N numbers
for u_k in stream:
    x = Abar @ x + Bbar * u_k         # O(N): Abar is a product of two DPLR factors
    y_k = (C.conj() @ x).real + D * u_k

The S4 layer and its cost

One SSM maps a scalar sequence to a scalar sequence, and a network layer has to transform HH features per position. S4 runs HH independent SSMs, one per channel, each with its own parameters and its own Δ\Delta; mixes the channels with a position-wise linear layer; and applies a nonlinearity. This is the structure of a depthwise-separable convolution, one filter per channel followed by a 1×11 \times 1 convolution across channels, and the code builds the mixer as a kernel-size-1 Conv1d.

S4's per-channel filters differ from a CNN's in three ways. They are as long as the sequence. They are generated from about 5N5N numbers per channel instead of stored tap by tap, so the parameter count does not grow with LL, and the same parameters can produce the filter at a different length or a different Δ\Delta. And each filter has an equivalent recurrence, which a CNN filter does not.

The state update has no gate. In xk=A‾xk−1+B‾ukx_k = \bm{\overline{A}}x_{k-1} + \bm{\overline{B}}u_k nothing depends on the input, so one fixed kernel can represent the layer. All of a deep S4 network's nonlinearity sits between SSM layers. Later S4 blocks add a GLU after the channel mixer, still outside the SSM. Mamba removes exactly this property: it makes the SSM's parameters depend on the input.

The convolution runs through FFTs, and the FFT computes a circular convolution, in which the end of the output wraps around and adds onto the beginning. Take K=(1,2)K = (1, 2) and u=(3,4)u = (3, 4). The linear convolution is (3,10,8)(3, 10, 8). The length-2 circular convolution is (11,10)(11, 10): the 8 wrapped around onto the 3. Zero-padding both signals to at least 2L−12L - 1 before the transform and keeping the first LL outputs gives the linear result; the code pads to 2L2L. Without the padding, each early output picks up contributions from inputs near the end of the sequence, an error as large as the signal itself. Here is one layer on a Path-X batch, with shapes:

# one S4 layer on a Path-X batch: B=32 sequences, H=256 channels, L=16384
u   = x.transpose(1, 2)               # (32, 256, 16384)  one scalar signal per channel
K   = kernel(Lam, P, B, Ct, dt, L)    # (256, 16384)      one length-L filter per channel
U_f = rfft(u, n=2*L)                  # zero-pad to 2L: FFT convolution is circular
K_f = rfft(K, n=2*L)
y   = irfft(U_f * K_f, n=2*L)[..., :L] + D[:, None] * u   # (32, 256, 16384)
y   = gelu(y)
out = W_mix @ y                       # (256 x 256) position-wise mix, a 1x1 conv

The gradient flows through every line of that listing and through Algorithm 1 into Λ,P,B,C~\bm{\Lambda}, \bm{P}, \bm{B}, \bm{\tilde{C}} and Δ\Delta, plus D\bm{D} and the mixer weights.

On cost: attention grows with the square of the length. The naive SSM was already linear in LL, so linearity was not S4's contribution. S4 removed the N2N^2 factor on the work and the NLNL of stored states. Slide the length in the figure and the three curves separate; switch to memory to see the naive SSM's problem.

Figure 8 · cost per layer as sequences get longer
2^14.0
Per layer, with N = 64. Attention is quadratic in length. The naive SSM and S4 are both linear, but the naive one carries N² work and holds NL numbers, while S4 carries 4N and holds N + L. Ticks mark the Long Range Arena lengths. Toggle to memory to see where the LSSL ran out.

Two qualifications on that chart. Training compute for S4 is O(Llog⁡L)O(L \log L) because of the FFT; only memory and the per-token generation cost are linear and constant. And the paper's complexity table (Table 1) leaves out the channel mixer, which costs Θ(BLH2)\Theta(BLH^2) and is the larger of S4's two terms at realistic widths. At B=32B = 32, H=256H = 256, L=16,384L = 16{,}384:

1.2×1010⏟FFT convolution+3.4×1010⏟mixer, BLH2  ≈  2% of 2.2×1012⏟attention, BL2H\underbrace{1.2\times10^{10}}_{\text{FFT convolution}} + \underbrace{3.4\times10^{10}}_{\text{mixer},\ BLH^2} \;\approx\; 2\%\ \text{of}\ \underbrace{2.2\times10^{12}}_{\text{attention},\ BL^2H}

Against the LSSL at layer width 512, S4 takes 29.6× less time per training step and 392× less memory (the introduction rounds these to 30× and 400×). Against efficient Transformers, parameter-matched at length 4,096 on one A100, S4 runs 5.19× as fast as a vanilla Transformer on 9.1% of its memory, in the same range as the Performer (3.79×, 8.6%) and the Linear Transformer (5.35×, 6.7%).

Results

On Long Range Arena, S4 has the best score on all six tasks and averages 86.09%; every baseline averages under 60%, the best being Luna-256 at 59.37%. On Path-X the baselines are at 50.00, the score of a coin flip, and S4 is at 96.35. Pick a task in the figure to see the full column.

Figure 9 · Long Range Arena, one task at a time
Accuracies from the paper's updated LRA table (Table 4), with the dashed line at chance for each task. On five tasks S4 (teal) leads by a wide margin. On Path-X, nine models were run and one learned the task.

The paper is inconsistent about the 86.09. Section 4.2 still says 80.48%, the average from the first arXiv version; Table 4 reports 86.09; and the appendix table prints both rows. Appendix D.5 explains that the table was refreshed with results from the S4D and How to Train Your HiPPO follow-ups, for the same model with minor hyperparameter changes, and asks readers to read it before citing. The Path-X change behind 88.10 to 96.35 is the Δ\Delta range, lowered from [0.001,0.1][0.001, 0.1] to [0.0001,0.01][0.0001, 0.01]. By the horizon estimate above, the slowest mode at Δ=0.0001\Delta = 0.0001 keeps e−1.64≈0.19e^{-1.64} \approx 0.19 of its value across all 16,384 tokens, while at Δ=0.001\Delta = 0.001 it keeps about 7.7×10−87.7 \times 10^{-8}. That calculation is our reading of why the change helps; the paper reports only the change and the score.

The other experiments test generality across data types:

The recurrent view makes generation fast. A Transformer producing token kk attends over all kk earlier tokens, so each token costs more than the last; S4 updates an NN-number state per channel at the same cost for every token. On WikiText-103 that gives 48,000 tokens per second against 800, a 60× speedup. On CIFAR the speedup ranges from 65.1× for the base model down to 10.5× for the large 2.85-bpd model. These are throughputs at the largest batch that fits on one A100, not single-sequence latency.

The ablation, S4D and Mamba

Section 4.4 asks which part of S4 produces the results, on sequential CIFAR-10 with models of at most 100K parameters. Random matrices in S4's NPLR form perform poorly. Training A\bm{A} improves every initialization, and with A\bm{A} trained every initialization reaches perfect training accuracy, yet their validation accuracies differ by more than 15 points. The models share a parameter count and an optimizer, so the starting matrix alone moves validation accuracy by that much. With 0.1 dropout added, the same trends hold, and full S4 with the HiPPO initialization reaches 84.27% test accuracy with 100K parameters. The paper concludes that the gains come mainly from the HiPPO initialization, not from the NPLR parameterization; NPLR makes that initialization affordable to compute.

Follow-up work simplified the parameterization within months. DSS (Gupta et al., 2022) and then S4D (Gu et al., 2022) dropped the low-rank term and kept only a diagonal Λ\bm{\Lambda} initialized from the HiPPO spectrum, and landed within about a point of S4 on the LRA average. A diagonal state matrix turns the kernel into a Vandermonde product and removes the Woodbury correction, the Cauchy sums, and most of Appendix C. The simplification costs something on the longest task: S4D-LegS averages 84.89 against S4's 86.09 and trails by 4.4 points on Path-X (91.95 against 96.35), and S4D-Lin, whose eigenvalues have linearly spaced imaginary parts, fails Path-X outright.

The larger change went the other way. Everything in this paper depends on time-invariance: the same A,B,C\bm{A}, \bm{B}, \bm{C} at every position, so one kernel represents the layer and one FFT computes it. A filter that applies the same weights at every position cannot down-weight one token or retain another based on its content, which is a plausible reason S4 trails Transformers on language. Mamba makes B\bm{B}, C\bm{C} and Δ\Delta functions of the input. With parameters that change at every token there is no single kernel to FFT, so Mamba replaces the convolution with a hardware-aware parallel scan, and it discretizes A‾\bm{\overline{A}} with the exact exponential eΔAe^{\Delta\bm{A}} instead of the bilinear transform. Mamba-2 restricts the state matrix to a scalar times the identity so the scan can be computed with matrix multiplications, and Mamba-3 brings back a trapezoid-rule discretization of the input term.

Provenance Verified against primary literatureHow we verify
HiPPO (Gu et al., 2020)Equation (2) and the theory of online polynomial memory it comes from. Its LegS ODE carries a 1/t factor that S4 drops.
LSSL (Gu et al., 2021)The predecessor: a deep SSM with trainable A at O(N²L) time and O(NL) space. Its Section 5.4 reports 62% on permuted MNIST with a random A.
Tustin (1947)The bilinear transform used to discretize the ODE.
Woodbury / Sherman-MorrisonThe rank-one inverse update behind Algorithm 1 and the O(N) recurrent step, via Golub & Van Loan.
Pan (2001, 2015, 2017)Fast, stable Cauchy-matrix algorithms behind the Õ(N+L) bound. Appendix A says these were not implemented for GPUs; the release uses an O(NL) Cauchy kernel in O(N+L) memory.
SaShiMi (Goel et al., 2022)The Λ − PP* form (Q tied to P) that the released S4 code uses.
S4D and How to Train Your HiPPO (2022)The refreshed LRA numbers in the v3 table (Appendix D.5), the Path-X Δ range [0.0001, 0.01], and the diagonal simplification.
state-spaces/s4, models/s4/s4.pyΔ initialized log-uniform in [0.001, 0.1]; D as a per-channel skip; FFT convolution padded to 2L and truncated; mixer as a kernel-size-1 Conv1d.
correctionFour checkable slips in the paper, each verified against the v3 arXiv source and the released code. (1) Appendix C.1 calls equation (2) "the HiPPO-LegT matrix"; it is HiPPO-LegS, which the same appendix restates later under that name. (2) The same appendix says A + ½PPᵀ equals ½I + S; the diagonal it computes is −½, so the identity is −½I + S, and +½ would put every eigenvalue in the right half-plane. (3) Algorithm 1 evaluates at exp(+2πik/L) and then applies an inverse FFT, which returns the kernel time-reversed; Lemma C.2 and the code use exp(−2πik/L). (4) Section 2.2 says the LSSL went "from 60% to 98%" on sequential MNIST by switching to equation (2); the LSSL paper reports 62% with a random A on permuted MNIST, against 98.76%. Separately, the Section 4.2 prose still gives the superseded 80.48% LRA average; Table 4 gives 86.09.

Questions you might still have

?

If the recurrence and the convolution give the same numbers, why keep both?
They cost differently. The convolution computes all L outputs in one pass with FFTs, which suits training, when the whole sequence is in hand. The recurrence produces one output at a time from an N-number state at constant cost, which suits generation, when the next token does not exist yet. The parameters are shared; only the schedule differs. For generation the readout uses C-bar, recovered once from the learned C-tilde.

?

Why the bilinear transform and not forward Euler?
Forward Euler maps an eigenvalue λ of A to 1 + Δλ. The HiPPO matrix has eigenvalues −1 to −N, so Euler is unstable once Δ exceeds 2/N, which at N = 64 is 0.031, inside S4's initialization range of 0.001 to 0.1. At Δ = 0.1 the fastest mode would be multiplied by 5.4 per token. The bilinear transform maps every eigenvalue with negative real part inside the unit circle at any Δ. Mamba later used the exact exponential exp(ΔA), which is also stable at any Δ.

?

Does S4 have a gate, like an LSTM or Mamba?
No. The state update is linear and its parameters do not depend on the input, which is what lets a single fixed kernel represent the layer. Later S4 blocks put a GLU after the channel mixer, outside the state space model. Input-dependent parameters are Mamba's change, and they remove the convolutional view.

?

What exactly gets trained?
Per channel: the diagonal Λ, the low-rank vector P (Q is tied to P in the released code), B, the convolution readout C-tilde, the step size Δ, and the skip weight D; plus the position-wise mixing weights between channels. The length-L kernel is recomputed from these on every forward pass, and gradients flow back through the Cauchy sums, the Woodbury correction and the inverse FFT.

?

Was all the low-rank machinery necessary?
Less than it seemed in 2021. DSS and S4D dropped the low-rank term and kept a diagonal state matrix, landing within about a point on the Long Range Arena average and replacing the Cauchy kernel with a Vandermonde product. The paper's own ablation pointed the same way: random matrices in NPLR form still did poorly, so the HiPPO initialization carried the result. The remaining gap is on Path-X, where S4D-LegS trails by 4.4 points (91.95 against 96.35) and the linearly spaced diagonal initialization does not solve the task.

?

Why does the paper quote 80.48% on Long Range Arena when its table says 86.09%?
The 80.48% in Section 4.2 is left over from the first arXiv version. Table 4 was refreshed for v3 with results from the S4D and How to Train Your HiPPO follow-ups, same model with minor hyperparameter changes, and the appendix table prints both rows. The paper asks readers to see Appendix D.5 before citing the table. The current figure is 86.09.

?

How can 64 numbers of state cover 16,000 steps?
The state holds coefficients of a polynomial approximation of the past, in a time variable that gives recent history most of the resolution and compresses older history. Fine detail from thousands of steps back is lost; the coarse shape survives. With Δ around 0.0001, the slowest mode still keeps about 19% of its value after 16,384 tokens, so information from the start of the sequence still reaches the end. Each layer also runs H independent channels (256 on Path-X), each with its own state and Δ, and the model stacks several layers.

Footnotes & further reading

  1. The paper: Gu, Goel, Ré, Efficiently Modeling Long Sequences with Structured State Spaces (Stanford, ICLR 2022). Code. Equations, tables and numbers on this page are from the v3 arXiv source; code claims are from models/s4/s4.py and src/models/hippo/hippo.py.
  2. The memory theory: Gu, Dao, Ermon, Rudra, Ré, HiPPO: Recurrent Memory with Optimal Polynomial Projections (2020), and its sequel How to Train Your HiPPO (2022), which works out the time-invariant version of HiPPO-LegS.
  3. The predecessor: Gu, Johnson, Goel, Saab, Dao, Rudra, Ré, Combining Recurrent, Convolutional, and Continuous-time Models with Linear State Space Layers (LSSL, 2021). The 62%-with-a-random-matrix figure is from its Section 5.4.
  4. The benchmark: Tay et al., Long Range Arena (2020). Path-X is the 128×128 version of Pathfinder. Tay et al. benchmarked eleven Transformer variants; Figure 9 shows the eight baselines the S4 paper carries into its LRA table (Table 4), three of which (FNet, Nyströmformer, Luna-256) postdate the benchmark paper.
  5. The simplifications: Gupta, Gu, Berant, Diagonal State Spaces are as Effective as Structured State Spaces (DSS, 2022), and Gu, Gupta, Goel, Ré, On the Parameterization and Initialization of Diagonal State Space Models (S4D, 2022), also the source of the refreshed LRA numbers and the Path-X step-size range.
  6. The parameterization the code uses: Goel, Gu, Donahue, Ré, It's Raw! Audio Generation with State-Space Models (SaShiMi, 2022), which introduced the Λ − PP* form.
  7. What came next: Mamba (Gu & Dao, 2023) makes the SSM parameters input-dependent and replaces the convolution with a parallel scan; Mamba-2 restricts the state matrix so the scan becomes matrix multiplication. The continuous-time framing connects to Neural ODEs, and the ODE-RNN baseline in the speech table comes from that line of work.