A 3D lattice is the set of all integer linear combinations of three linearly independent basis vectors . Any matrix — i.e., any integer matrix with — gives an equally valid description of the same lattice:
There are infinitely many such , hence infinitely many cells for a single lattice. Niggli (1928), building on Eisenstein (1851), defined a canonical choice: the Niggli reduced cell, which is unique up to the symmetry operations of the lattice itself.
| Paper | Contribution |
|---|---|
| Niggli (1928) | Defines the algebraic conditions for a unique reduced cell |
| Buerger (1957) | First iterative numerical procedure (does not always reach the unique Niggli cell) |
| Gruber (1973), Acta Cryst. A29, 433–440 | Alternative Buerger-reduction algorithm; classifies 28 unique Niggli type families; introduces what become steps N1–N3, B1–B5 |
| Křivý & Gruber (1976), Acta Cryst. A32, 297–298 | Modified algorithm (8 steps A1–A8) that reaches the unique Niggli cell |
| Zuo et al. (1995), Acta Cryst. A51, 943–945 | Optimizes iteration count |
| Grosse-Kunstleve, Sauter & Adams (2004), Acta Cryst. A60, 1–6 | Numerically stable implementation with tolerance ; proves the naive implementation has ~1% infinite-loop failure rate; derives change-of-basis matrices for each step |
All geometry of the unit cell is encoded in the metric tensor , the Gram matrix of the basis vectors:
Under a basis change , the metric tensor transforms as:
This is the fundamental operation underlying Niggli reduction — every step is a congruence transformation of .
Gruber (1973) and Křivý & Gruber (1976) use the following notation:
So the metric tensor becomes:
The factors of 2 in (rather than the cosines themselves) simplify all the expressions that follow. Note:
The volume of the cell is , and the positivity condition is required for the cell to be non-degenerate.
A cell is Niggli-reduced if and only if all of the following conditions hold simultaneously. They come from §9.3.2 of International Tables for Crystallography, Vol. A, and are derived directly from Niggli (1928):
These enforce that is the shortest, the second shortest, the third shortest, in a suitably constrained sense:
The last three mean that no off-diagonal entry of can exceed the smaller of the two diagonal entries in the same row/column. This is the Minkowski reduction condition: must be among the shortest vectors in the lattice.
Even after the main conditions are satisfied, there is still residual freedom in choosing signs of the off-diagonal elements. The Niggli conditions eliminate this by requiring all angles to be simultaneously of the same type:
Type I (all obtuse/right):
Type II (all acute/right):
and then additional tie-breaking conditions that kick in at the boundaries:
At equalities in M1–M4, additional strict inequalities resolve ambiguity:
And one more for the body-diagonal case:
Conditions D1–D6 are the tie-breaking rules that distinguish among otherwise metrically equivalent choices and make the cell truly unique.
The Křivý–Gruber (1976) algorithm starts from an arbitrary primitive cell of a three-dimensional Bravais lattice and reaches the Niggli form requisite for lattice type determination. The algorithm is iterative: you apply steps A1–A8 in order, and whenever a step fires (its condition is true), you apply the corresponding transformation and restart from A1. The algorithm terminates when one complete pass through A1–A8 fires no step.
Before describing the steps, we introduce helper variables for the signs:
where we use the convention if , if , if . In practice with tolerance : if , if , else ; similarly for .
Condition: , OR ( AND )
The first clause simply sorts lengths. The second handles the degenerate case : by condition D1, we need , so if this is violated we swap.
Action — swap :
This matrix simultaneously swaps and and flips , so that the cell remains right-handed (). After this, update all six Niggli parameters:
(and is unaffected because which is symmetric in ; but the flip of leaves sign-unchanged because both involve ). More precisely the tensor transformation gives:
After firing: go to A1 (restart).
Condition: , OR ( AND )
This enforces and, when , enforces D2: .
Action — swap :
The parameter update from gives:
More carefully (the entries in flip signs): , , , , and acquires sign changes from the two diagonal factors: (two flips cancel).
After firing: go to A1 (must re-sort, since may now be violated).
Condition:
This means exactly one or all three of are positive. In other words, the signs are not all negative/zero (Type I would be with all nonpositive). If we are not yet pure Type I or II — we have a “mixed” situation with an odd number of positive signs but at least one negative.
Wait — let’s be more precise. The condition occurs when: all three are positive (, pure Type II, which is fine), OR exactly two are negative and one positive (, which is not a pure type). So the real intent of A3 is to handle the case where the product is positive but not all are positive (two negatives, one positive), by flipping signs to make them all positive. When all three are positive, the product is also , but in that case we want to make which does nothing. The step fires and does no harm.
Action — diagonal sign flip:
This flips the sign of any basis vector that has a negative off-diagonal inner product contribution. Effect on parameters:
More simply: , , , since the diagonal sign changes cancel in (each squared) but flip the signs of appropriately. After A3 in this case, all three off-diagonal parameters become positive (Type II).
After firing: go to A4.
Condition: NOT ( AND AND ) AND ( OR )
This step handles the case where the angles are not yet all the same sign, and specifically forces them toward a consistent type. The goal is: if we can’t have all positive, make them all non-positive (Type I).
Action:
Initialize and a reference variable pointing to nothing.
The logic: for any angle that is currently positive (acute), flip it to negative (obtuse). If after doing so the product comes out , it means flipping all positive ones left an odd number of negative signs overall — so we pick one of the zero-angle directions (pointed to by ) and flip that too, to bring the parity back.
This step converts any mixed sign pattern to either all-negative (Type I) or all-zero-or-negative. After A4, , , .
After firing: go to A1 (lengths may have changed).
Condition: , OR ( AND ), OR ( AND )
This enforces (condition M2). The secondary clauses handle the tie-breaking conditions D3.
Action:
This replaces , which is equivalent to the operation that reduces . The tensor update is:
(with unchanged). In the Gruber (1973) algorithm this is a full-reduction step using , reducing in one shot; in the Křivý–Gruber version, only the sign step is used (requiring more iterations but simpler logic).
After firing: go to A1.
Condition: , OR ( AND ), OR ( AND )
This enforces (condition M3), with tie-breaking for D4.
Action:
This replaces . Update:
(with unchanged).
After firing: go to A1.
Condition: , OR ( AND ), OR ( AND )
This enforces (condition M4), with tie-breaking for D5.
Action:
This replaces . Update:
(with unchanged).
After firing: go to A1.
Condition: , OR ( AND )
This enforces the final boundary condition D6. The quantity appears because it equals , which must be non-negative (any vector in the lattice has non-negative squared length). If it is negative, the vector is shorter than and needs to replace it. The tie-breaking clause handles the boundary case.
Action:
This replaces . The tensor update:
(with unchanged).
After firing: go to A1.
Initialize C_total = I (3×3 identity)
LOOP:
Compute l, m, n from current ξ, η, ζ
A1: if (A > B) OR (A≈B AND |ξ|>|η|):
apply C_A1 → update A,B,C,ξ,η,ζ and C_total
GOTO A1
A2: if (B > C) OR (B≈C AND |η|>|ζ|):
apply C_A2 → update
GOTO A1
A3: if lmn = 1 (odd number negative or all positive):
apply C_A3 → update
GOTO A4
A4: if lmn = 0 or -1 (not all negative):
apply C_A4 → update
GOTO A1
A5: if |ξ| > B or boundary violation:
apply C_A5 → update
GOTO A1
A6: if |η| > A or boundary violation:
apply C_A6 → update
GOTO A1
A7: if |ζ| > A or boundary violation:
apply C_A7 → update
GOTO A1
A8: if ξ+η+ζ+A+B < 0 or boundary violation:
apply C_A8 → update
GOTO A1
If no step fired in A1–A8: DONE
The final cell is Niggli-reduced. The accumulated product is the change-of-basis matrix, which can be used to transform atomic coordinates, symmetry operations, orientation matrices, etc.
Each step in the Křivý–Gruber algorithm consists of testing for a condition, followed by an action. The actions are given by Křivý & Gruber as reassignments of the parameters . A mathematically equivalent definition is given by the tensor transformation with a transformation matrix acting on the metric tensor.
All eight matrices explicitly:
where .
All matrices shown above have determinant . Each matrix could also be replaced by the matrix product since any lattice exhibits a center of inversion at the origin. However, the choices above ensure that the final matrix has determinant . This is a very useful property because otherwise a determinant of would result in the transformation of a right-handed system into a left-handed system (and vice versa). With the definitions above, the final change-of-basis matrix is directly suitable for transforming symmetry operations, atomic coordinates, orientation matrices or other crystallographic parameters.
The accumulated change-of-basis matrix is built by left-multiplying at each step:
To make the iterative reduction algorithm numerically stable, a tolerance is used in all comparisons. This tolerance accounts for the uncertainties implicitly introduced by the use of finite-precision algebra.
The recommended tolerance is:
where is the cell volume and in practice. The factor scales with cell dimensions (it is exact for cubic cells). All comparisons in steps A1–A8 use this tolerance:
| Exact comparison | Implementation with |
|---|---|
Why is this necessary? Practical application of the algorithms of Gruber (1973), Křivý & Gruber (1976) and Zuo et al. (1995) reveals that rounding errors owing to floating-point arithmetic can lead to infinite loops given typical experimentally observed cell parameters. In approximately 14,000 trials with reasonable unit-cell parameters, the algorithm enters infinite loops approximately 100 times (i.e., the failure rate is 0.7%).
A special consideration for A3/A4: Using the exact less-than comparison is the correct approach for the sign function evaluations in steps A5, A6, and A7, because the values involved are first compared (using the tolerance) with the parameters or , which must be strictly greater than zero because the unit cell is degenerate otherwise. To further maximize the numerical stability, the expression in step A3 is treated in a special way: each parameter is tested individually, counting the number of positive and negative values, then using those integer counts to decide whether . All evaluations in the reduction procedure are implemented using only additions and subtractions — floating-point multiplications are completely avoided.
The algorithm terminates because each transformation that fires strictly decreases a non-negative definite quantity. The key insight is:
Since (bounded below by the AM-GM inequality on lattice vectors), and each firing step decreases it by a computable amount, the number of steps is finite.
Once you have the Niggli-reduced parameters , the lattice type is read off from a table of 44 lattice characters (also called Niggli types). These 44 different lattice characters arise because continuous deformations within a Bravais type are possible only within each character; to move between characters you must pass through special metric relationships. Each can be recognized from the relations between the elements of the reduced form.
The 44 types are classified by:
Here is the complete classification table (Niggli 1928, as tabulated in International Tables, §9.3.2). Each row gives the Niggli type number, the metric conditions on , and the Bravais lattice it corresponds to:
| Type | Conditions | Bravais Lattice |
|---|---|---|
| 1 | ; (all equal, Type II) | cF |
| 2 | ; (all equal, Type I) | cI |
| 3 | ; | cP or hR |
| 4 | ; , all | hR |
| 5 | ; , all | hR |
| 6 | ; , all | hR |
| 7 | ; , , others | hR |
| 8 | ; , | oI or mI |
| 9 | ; | tP or oP |
| 10 | ; , , | hR |
| 11 | ; , | hP |
| 12 | ; , | oC (or oA) |
| 13 | ; , all | oI |
| 14 | ; , , | mI |
| 15 | ; , , all | tI |
| 16 | ; , | tP or oP |
| 17 | ; , | hR (obverse) |
| 18 | ; , , | oF |
| 19 | ; , , all | oI |
| 20 | ; , , general, Type I | mI |
| 21 | ; , , | hR |
| 22 | ; , | oC |
| 23 | ; general Type II | mC |
| 24 | ; | oP |
| 25 | ; , | mP |
| 26 | ; , , all | oC |
| 27 | ; , others | mC |
| 28 | ; , , | mP |
| 29 | ; , , | mP |
| 30 | ; , | mP |
| 31 | ; , | mP |
| 32 | ; general Type I (all ) | aP |
| 33 | ; one of , others | mP |
| 34 | ; , Type I | mI |
| 35–44 | Various specific Type I/II combinations for with mixed constraints | aP, mP, mI, oF, etc. |
(The exact table runs to 44 entries with conditions becoming increasingly specific; the full table is in International Tables, Table 9.3.1 and in Gruber 1973, Table 1.)
The key point: once you have the Niggli-reduced in exact arithmetic, exactly one of these 44 patterns is satisfied, which uniquely determines the Bravais lattice type. In practice with experimental data, metric symmetry searching (Le Page, 1982) is more robust than a direct lookup.
Let us reduce a triclinic cell with:
Initialize Niggli parameters:
.
Pass 1:
The transformation gives:
New state: , , , , , .
Now , . Type I. Go to A1.
Pass 2:
Done. The Niggli-reduced cell is:
In conventional parameters:
Wait — note that changed from to because we flipped . The physical lattice is the same; we’ve just made all angles obtuse (Type I), which is the canonical form.
Change-of-basis matrix:
This matches Niggli type 32 (general triclinic, , all off-diagonal , Type I) → Bravais lattice aP (primitive triclinic).
It’s worth distinguishing clearly:
Buerger-reduced cell (1957): A cell satisfying only the main conditions M1–M4 (lengths sorted, off-diagonal bounded). This is not unique — Gruber (1973) showed there can be up to 5 Buerger-reduced cells for the same lattice.
Gruber (1973) algorithm (steps N1–N3, B1–B5): A refinement of Buerger reduction. Steps N1–N3 handle the main conditions (sorting and sign normalization) using the integer-rounding function (nearest integer) rather than just the sign, which reduces in one shot rather than incrementally. Steps B1–B5 correspond to A4–A8 above. This reaches a Buerger cell, which may not be the unique Niggli cell.
Křivý–Gruber (1976) algorithm (steps A1–A8): Adds the tie-breaking conditions to reach the unique Niggli cell. The key additional logic is in A1 and A2 (the secondary conditions involving vs , etc.) and in the boundary clauses of A5–A8.
The parameter updates in A5–A7 use in Křivý–Gruber, but use or (the nearest-integer division) in Gruber (1973). The nearest-integer version reduces in one step; the sign version needs multiple passes but is simpler to analyze.
Primitive cell requirement: Niggli reduction is defined only for primitive cells. If you start with a centered cell (e.g., body-centered cubic, face-centered, -centered), you must first transform to the primitive setting:
Then reduce the primitive cell; after reduction, look up the Niggli type to identify the Bravais lattice and transform back to the conventional setting.
Comparison of cells from different codes: Two cells describe the same lattice if and only if they reduce to the same Niggli cell. This is why Niggli reduction is the right tool when comparing a cell output from Mantid’s peak indexing against a published ICSD or NOMAD result — reduce both and check equality of within experimental tolerance.
ISODISTORT supercell identification: ISODISTORT works from the primitive parent cell. If your RMCProfile supercell looks geometrically different from the published conventional cell, reduce both primitive cells with Niggli and verify they match before assuming an error.
Indexing software: DICVOL, TREOR, and N-TREOR all internally reduce candidate cells to Niggli form before comparing with observed -spacings, which is why two candidate cells that are related by a unimodular transformation appear as duplicates and get de-duplicated at the Niggli comparison stage.