Projected Gauss-Seidel for LCP
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
Projected Gauss-Seidel, often shortened to PGS, is a simple iterative method for solving linear complementarity problems. It is widely used in contact mechanics and rigid-body simulation because it is easy to implement and often good enough for large sparse systems where exact solvers are too expensive.
What Problem PGS Solves
A linear complementarity problem asks for vectors x and w such that:
- '
w = Mx + q' - every entry of
xis non-negative - every entry of
wis non-negative - for each index, at least one of
x[i]orw[i]is zero
That last rule is the complementarity condition. In contact simulation, it matches the physical idea that a contact can either apply force or have a separating gap, but not both in the active sense at the same time.
The Core PGS Update
Ordinary Gauss-Seidel updates one variable at a time using the newest available values. Projected Gauss-Seidel adds one extra step: after computing the unconstrained update, it projects the value back onto the feasible region by clamping it to be non-negative.
For each component, the update is conceptually:
- compute the residual using the current iterate
- divide by the diagonal entry of
M - clamp the result with
max(0, value)
That projection is what makes the method suitable for an LCP.
A Runnable Python Implementation
The following NumPy example solves a small LCP and checks the complementarity conditions:
This code is intentionally small, but it captures the standard PGS pattern used in larger solvers.
Why PGS Is Popular
PGS has three practical advantages.
First, it is cheap per iteration. You do not need to factor the whole matrix, which matters when the system changes every frame in a physics engine.
Second, it works well with sparse matrices. Many LCPs from contacts or constraints are sparse and structured, so each sweep is fast.
Third, it is easy to warm start. If yesterday's or the previous frame's solution is close to today's, you can initialize with that guess and reduce the iteration count.
These advantages explain why PGS appears so often in real-time simulation code even when more sophisticated methods have better theoretical guarantees.
Where It Struggles
PGS is still only an iterative approximation. Convergence can be slow when the matrix is poorly conditioned or when the coupling between variables is strong. It can also behave badly if diagonal entries are zero or too small, because each update divides by M[i, i].
In practice, convergence depends heavily on problem structure. Well-scaled systems with reasonable diagonal dominance tend to behave far better than arbitrary dense matrices.
Some solvers improve PGS with relaxation factors, ordering heuristics, or block updates. Those changes can help, but they do not remove the basic limitations.
Common Pitfalls
The first pitfall is applying PGS to an LCP that does not meet the assumptions your implementation relies on, especially positive diagonal entries.
The second is checking only the iterate difference and ignoring feasibility. A small change in x does not automatically mean the complementarity conditions are satisfied well enough.
The third is expecting high-accuracy solutions from very few iterations. In many real-time applications PGS is chosen because approximate answers are acceptable, not because it is the most accurate solver.
Summary
- Projected Gauss-Seidel solves LCPs by combining Gauss-Seidel updates with a non-negativity projection.
- It is popular in contact and constraint problems because each iteration is cheap and easy to implement.
- Sparse, well-scaled systems are where PGS tends to work best.
- Convergence can be slow or unreliable on poorly conditioned problems.
- Always verify feasibility and complementarity, not just whether the iterate stopped moving.
Related reading
- pronounceability algorithm
- Proof by Induction of Pseudo Code
- Proof of correctness Algorithm for diameter of a tree in graph theory
- Proof of detecting the start of cycle in linked list
- Proof that Fowler's money allocation algorithm is correct
- Properly formatted multiplication table
- Proof of optimality of a greedy solution to job sequencing
- Proposing an algorithm for arbitrary shape Bit Matrix Transposition with BDD-like structure

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.