A forward matrix product packages a finite history of linear updates into one matrix. For a sequence of square matrices \(A_0,A_1,A_2,\ldots\), this project writes
\[ P_A(k)=A_{k-1}\cdots A_1A_0 \]when \(k\) is positive, and sets \(P_A(0)=I\). The convention is designed for column vectors. Starting from \(x_0=x\), the recurrence
\[ x_{j+1}=A_jx_j \]gives \(x_k=P_A(k)x\). The earliest matrix acts first, even though it appears furthest to the right in the written product. The newest matrix acts last and therefore appears on the left.
That reversal between reading order and action order is the central fact to remember. It follows from composition, not from a typographical preference. Transition and fundamental matrices in finite-dimensional linear dynamics use the same chronological logic (Coppel).
The first four horizons
The safest way to learn the convention is to expand the first few cases:
\[ \begin{aligned} P_A(0)&=I,\\ P_A(1)&=A_0,\\ P_A(2)&=A_1A_0,\\ P_A(3)&=A_2A_1A_0. \end{aligned} \]Applied to a column vector \(x\), these become
\[ \begin{aligned} P_A(0)x&=x,\\ P_A(1)x&=A_0x,\\ P_A(2)x&=A_1(A_0x),\\ P_A(3)x&=A_2(A_1(A_0x)). \end{aligned} \]The horizon \(k\) counts factors, not the largest time index. Thus \(P_A(3)\) uses the factors with indices \(0,1,2\). This zero-based convention matches the natural-number recursion used in Lean.
The empty product must be the identity. It makes the state at time zero equal to its initial value, makes concatenation valid when either block is empty, and makes a constant family agree with the zeroth matrix power.
The defining recursion
The project defines the product recursively:
def forwardProduct (A : ℕ → Matrix ι ι 𝕜) : ℕ → Matrix ι ι 𝕜
| 0 => 1
| k + 1 => A k * forwardProduct A k
The successor equation says to prepend the newest factor:
\[ P_A(k+1)=A_kP_A(k). \]This direction matters because matrices generally do not commute. Replacing the right side by \(P_A(k)A_k\) would define a different product and would reverse chronological action on column vectors.
Only modest algebra is needed. The index type \(\iota\) is finite and has decidable equality so that matrix multiplication is a finite sum. The scalar type \(\mathbb K\) is a semiring, which supplies zero, one, addition, multiplication, distributivity, and associativity. The definition does not need subtraction, division, an order, a topology, a norm, or probability.
The index type may be empty. There is still one empty square matrix, and its identity and multiplication are well-defined. Empty dimension becomes a separate issue only when a normalized operator norm is requested.
Splitting a history after a chosen time
Let the first block contain \(m\) steps and the second contain \(k\) steps. Define the shifted sequence by
\[ A^{(m)}_j=A_{m+j}. \]Then the checked split law is
\[ P_A(m+k)=P_{A^{(m)}}(k)P_A(m). \]The earlier block is on the right because it acts first. The later, shifted block is on the left because it acts second. For example, taking \(m=2\) and \(k=3\) gives
\[ \begin{aligned} P_A(5) &=A_4A_3A_2A_1A_0\\ &=(A_4A_3A_2)(A_1A_0)\\ &=P_{A^{(2)}}(3)P_A(2). \end{aligned} \]This is the discrete-time analogue of composing a transition from time zero to time \(m\) with a transition from time \(m\) to time \(m+k\). It is also the finite algebraic skeleton of a cocycle law. The current module does not define a base dynamical system or prove a random-cocycle theorem.
Constant systems recover powers
If every factor is the same matrix \(B\), the nonautonomous product reduces to an ordinary power:
\[ P_{j\mapsto B}(k)=B^k. \]The first cases agree:
\[ I=B^0,\qquad B=B^1,\qquad BB=B^2. \]If every factor is the identity, every forward product is the identity. These facts are calibration tests. They show that the time-dependent definition extends the familiar autonomous iteration \(x_{j+1}=Bx_j\).
A two-dimensional example where order matters
Consider
\[ A_0= \begin{bmatrix} 1&1\\ 0&1 \end{bmatrix}, \qquad A_1= \begin{bmatrix} 2&0\\ 0&1 \end{bmatrix}, \qquad x= \begin{bmatrix} 0\\ 1 \end{bmatrix}. \]The first update shears the vector:
\[ A_0x= \begin{bmatrix} 1\\ 1 \end{bmatrix}. \]The second update stretches its first coordinate:
\[ A_1(A_0x)= \begin{bmatrix} 2\\ 1 \end{bmatrix}. \]Accordingly, \(P_A(2)=A_1A_0\). Reversing the factors gives
\[ A_0(A_1x)= \begin{bmatrix} 1\\ 1 \end{bmatrix}, \]which is different. A harmless-looking order reversal therefore changes the dynamics.
The checked Lean interface
forwardProduct A (k + 1) = A k * forwardProduct A kforwardProductis the project definition for this precise order convention.A : ℕ → Matrix ι ι 𝕜is a time-indexed family of square matrices.k + 1is the successor horizon. It counts \(k+1\) factors, whose indices run from \(0\) through \(k\).A kis the newest factor at that horizon.*is matrix multiplication. Its order is meaningful because this multiplication generally does not commute.forwardProduct A kis the earlier block, placed on the right so it acts first on a column vector.- The zero branch lives in the definition as
forwardProduct A 0 = 1; here1is the identity matrix.
The algebraic part of the module publishes nine declarations:
| Declaration | Meaning |
|---|---|
forwardProduct | Defines the ordered product at every natural horizon |
forwardProduct_zero | The zero-horizon product is the identity |
forwardProduct_succ | The newest factor is prepended on the left |
forwardProduct_add | Splits a history into a shifted later block and an earlier block |
forwardProduct_one | The one-step product is the time-zero factor |
forwardProduct_const | A constant sequence gives ordinary matrix powers |
forwardProduct_const_one | An identity sequence stays at the identity |
forwardProduct_mulVec_zero | The zero-horizon product fixes every column vector |
forwardProduct_mulVec_succ | Product action is chronological iteration |
The last theorem uses Mathlib’s compatibility between matrix multiplication
and matrix-vector multiplication, Matrix.mulVec_mulVec
(Mathlib contributors). It turns the matrix
recursion directly into the state recursion.
Type the noncommutative example locally
This worksheet models two-by-two integer matrices and column vectors with
Std only. Save it as ForwardProductTutorial.lean:
import Std
structure Mat2 where
a00 : Int
a01 : Int
a10 : Int
a11 : Int
deriving Repr, DecidableEq
structure Vec2 where
x0 : Int
x1 : Int
deriving Repr, DecidableEq
def Mat2.mul (A B : Mat2) : Mat2 :=
{ a00 := A.a00 * B.a00 + A.a01 * B.a10
a01 := A.a00 * B.a01 + A.a01 * B.a11
a10 := A.a10 * B.a00 + A.a11 * B.a10
a11 := A.a10 * B.a01 + A.a11 * B.a11 }
def Mat2.mulVec (A : Mat2) (x : Vec2) : Vec2 :=
{ x0 := A.a00 * x.x0 + A.a01 * x.x1
x1 := A.a10 * x.x0 + A.a11 * x.x1 }
def shear : Mat2 :=
{ a00 := 1, a01 := 1, a10 := 0, a11 := 1 }
def stretch : Mat2 :=
{ a00 := 2, a01 := 0, a10 := 0, a11 := 1 }
def initial : Vec2 := { x0 := 0, x1 := 1 }
#eval shear.mulVec initial
#eval stretch.mulVec (shear.mulVec initial)
#eval shear.mulVec (stretch.mulVec initial)
#eval stretch.mul shear
#eval shear.mul stretch
example : stretch.mulVec (shear.mulVec initial) =
{ x0 := 2, x1 := 1 } := by decide
example : shear.mulVec (stretch.mulVec initial) =
{ x0 := 1, x1 := 1 } := by decide
example : stretch.mul shear ≠ shear.mul stretch := by decide
Run it with the installed pinned toolchain:
elan run leanprover/lean4:v4.32.0 lean ForwardProductTutorial.lean
The first three outputs are \((1,1)\), \((2,1)\), and \((1,1)\). The last two outputs are distinct matrix products. The kernel-certified examples then make both trajectories and noncommutativity explicit. This miniature checks the finite arithmetic and order convention, not Mathlib’s generic matrix API.
The authoritative source is
formalization/NonlinearDynamics/Random/MatrixProducts/FiniteProducts.lean.
In a clone with the repository’s pinned Lean and Mathlib dependencies
installed, a human can type:
import NonlinearDynamics.Random.MatrixProducts.FiniteProducts
#check NonlinearDynamics.Random.MatrixProducts.forwardProduct
#check NonlinearDynamics.Random.MatrixProducts.forwardProduct_zero
#check NonlinearDynamics.Random.MatrixProducts.forwardProduct_succ
#check NonlinearDynamics.Random.MatrixProducts.forwardProduct_add
#check NonlinearDynamics.Random.MatrixProducts.forwardProduct_const
#check NonlinearDynamics.Random.MatrixProducts.forwardProduct_mulVec_succ
These checks expose the definition, identity horizon, successor order, block split, constant-sequence calibration, and chronological vector action. The full-project command below checks the pinned project module and Mathlib dependencies with the repository’s pinned dependencies installed.
cd formalization
lake env lean -DwarningAsError=true NonlinearDynamics/Random/MatrixProducts/FiniteProducts.leanResource note: this exact file uses the repository's
pinned Lean and Mathlib dependencies. Initial project setup can require
substantial disk space and build time. For a lightweight first step on
macOS or Linux, use the page's standalone Lean-core or Std
tutorial.
What the definition does not say
The phrase forward product fixes an order and an empty-product convention. It does not by itself say that the factors are random, measurable, independent, stationary, invertible, or identically distributed. It does not supply a base flow, a cocycle over that flow, or an infinite product.
It also makes no growth claim. A product may expand some vectors, contract others, or alternate between both behaviors. The companion induced infinity operator norm entry explains one finite-horizon upper-bound mechanism. Such an upper bound is not automatically an equality, a sharp rate, a Lyapunov exponent, or a stability theorem.
In nonlinear dynamics, products of derivative matrices describe linearized perturbation propagation along an orbit. That application motivates the interface, but the present Lean module contains no differentiable map, no Jacobian identification, and no theorem connecting a nonlinear orbit to this matrix sequence.
Random products are another major destination. Oseledets’ multiplicative ergodic theorem classically organizes long-time exponential growth rates under substantial dynamical and integrability hypotheses (Oseledets). Nothing in the finite recursive definition proves those hypotheses or conclusions.
Exercises
- Expand \(P_A(4)x\) with parentheses showing chronological action.
- Check the split law for \(m=1\) and \(k=3\) by writing every factor.
- Explain why \(P_A(m+k)=P_A(m)P_{A^{(m)}}(k)\) is generally false.
- For the matrices in the worked example, compute both \(A_1A_0\) and \(A_0A_1\).
- Prove on paper by induction that a constant family gives \(B^k\). Identify why the successor-power convention must match left multiplication.
- Describe the unique forward product when the matrix index type is empty. Which parts of the algebraic interface still make sense?
Where to continue
Ordered Finite Matrix Products and Operator-Norm Growth develops all thirteen public declarations in the module, including the exact assumption ledger and finite-horizon product, power, and orbit bounds.
The next checked layer evaluates the factors at one outcome, proves exact finite-prefix measurability, and forms a pushforward law. Begin with the finite random-matrix product entry, then climb Measurable Finite Random-Matrix Products and Proof-Carrying Pushforward Laws.
Read the induced infinity operator norm entry before interpreting those bounds. The Hermitian Frobenius geometry entry explains a different, entrywise Euclidean matrix norm. The earlier Finite Product Probability Spaces and Independent Gaussian Fields uses product for a product probability measure. That commutative measure construction should not be confused with an ordered, generally noncommutative matrix product.
References
Mathlib contributors. Matrix-vector multiplication, Mathlib 4 documentation. This official interface supplies the compatibility between matrix multiplication and successive action on a column vector.
W. A. Coppel. Dichotomies in Stability Theory, Lecture Notes in Mathematics, Springer, 1978. This monograph supplies the classical stability motivation for transition matrices and products in linear evolution problems. The page’s exact indexing convention is fixed by the Lean definition above.
V. I. Oseledets. A multiplicative ergodic theorem. Characteristic Ljapunov exponents of dynamical systems, Transactions of the Moscow Mathematical Society 19 (1968), 197-231. This primary source identifies the long-time random-dynamical destination. Its ergodic hypotheses and asymptotic conclusions are not formalized in the finite-product module.
The exact upstream Lean source audited for this entry is Mathlib commit
81a5d257,
the revision pinned by formalization/lake-manifest.json.
