Polar Decomposition
Polar decomposition is the mathematical trick that makes O(1) on-chain verification possible. Instead of tracking the full n-dimensional reserve vector, the contract only needs two scalar values.
The Decomposition
We write the reserve vector as:
where:
- v = (1/√n, 1/√n, ..., 1/√n) is the unit vector along the equal-price direction
- α = (∑ᵢ xᵢ)/√n is the projection of x onto v
- w = x − αv is the component orthogonal to v
Geometrically, α measures "how far along the equal-price axis" the pool is, while w captures the "imbalance" — how far from equal prices the pool has moved.
Deriving α
The projection of x onto v is:
This is just the sum of reserves, scaled by √n. The contract tracks ∑ᵢxᵢ directly, so α is free to compute.
The Orthogonal Component
The squared norm of w is:
= ‖x‖² − 2α(x · v) + α²‖v‖²
= ‖x‖² − 2α² + α² (since ‖v‖² = 1 and x · v = α)
= ‖x‖² − α²
Substituting α = (∑xᵢ)/√n:
This is the variance formula! ‖w‖² measures how "spread out" the reserves are from their mean. When all reserves are equal, ‖w‖² = 0.
Why This Matters
The contract stores only two values:
sumX = ∑ᵢxᵢsumXSq = ∑ᵢxᵢ²
From these, it can compute:
‖w‖² = sumXSq − sumX²/n
This is O(1) state — constant size regardless of how many tokens are in the pool. Without this decomposition, the contract would need to store all n reserves explicitly.
Trading in Polar Coordinates
A swap of Δxᵢ tokens (selling token i) changes the state as follows:
sumXSq' = sumXSq + (xᵢ + Δxᵢ)² − xᵢ² + (xⱼ − Δxⱼ)² − xⱼ²
The contract verifies that the new state satisfies the torus invariant. The actual trade computation (solving for Δxⱼ given Δxᵢ) happens off-chain in the SDK.
Connection to the Sphere
The sphere invariant can be rewritten in polar coordinates:
nr² − 2r·sumX + sumXSq = r²
sumXSq − 2r·sumX + (n−1)r² = 0
This form is what the contract actually checks — it's algebraically equivalent to the sphere equation but uses the tracked values directly.
Key insight: Polar decomposition turns an n-dimensional problem into a 2-dimensional one. The contract never sees the full reserve vector — only its projection (α) and its orthogonal norm (‖w‖).