The Gram-Schmidt calculator above takes a list of vectors and returns an orthonormal basis for the subspace they span. It shows each projection as it is subtracted, so you can follow the construction rather than only see the result, and it names any vector that turns out to be a linear combination of the ones before it instead of returning a zero vector or a page of NaN.
Arb Digital publishes this as the process page. Gram-Schmidt is a construction, and the point of a construction is the steps. Our QR decomposition calculator covers the closely related factorisation, and the boundary between the two pages is worth stating up front: Gram-Schmidt produces only the orthonormal vectors, works on any list including a dependent one, and shows the geometry; QR produces the pair of factors Q and R for a matrix, where R records the very coefficients this page subtracts, and in practice is computed by a different and more stable algorithm entirely.
What This Gram-Schmidt Calculator Does
It processes the vectors in the order you give them. The first is simply normalised to unit length. Each subsequent vector has its component along every earlier basis vector removed, and what is left — the residual, which is perpendicular to everything before it by construction — is normalised in turn.
Where a residual comes out shorter than the tolerance, the vector lies in the span of its predecessors and contributes nothing new. The tool says which vector this happened to and continues with the rest, which is what you want: the output is still a valid orthonormal basis for the span, just with fewer vectors in it than you entered. The number of basis vectors produced is the rank of the set.
It also reports the largest absolute dot product between distinct output vectors. That figure should be at rounding level. When it is not, the input was numerically close to dependent, and the result is worth distrusting no matter how clean the numbers look. This is the single most useful diagnostic on the page and it is why the classical and modified variants are both offered.
How to Use It
- Enter one vector per line with components separated by spaces or commas. All vectors must have the same number of components.
- Note that order matters. The first output vector is always a scalar multiple of the first input, so reordering the input changes the basis you get, though not the subspace it spans.
- Pick the variant. Modified is the default and is what you should use for anything numerical; classical is there because it is the form written in most textbooks.
- Check the dependent count. If it is non-zero, the tool names which vectors were redundant in its working line.
- Read the largest off-diagonal dot product before trusting the basis. It is the verification, not decoration.
The Formula and How It Is Calculated
Given vectors v₁ through vₖ, the construction is uₖ = vₖ − ∑j<k (vₖ · ej) ej followed by eₖ = uₖ ÷ ||uₖ||. Each subtracted term is the orthogonal projection of the new vector onto an existing basis direction, and removing all of them leaves the part that is perpendicular to the whole existing basis.
Work the default through by hand. Take v₁ = (1, 1, 0), v₂ = (1, 0, 1) and v₃ = (0, 1, 1). The norm of v₁ is √2, so e₁ = (0.70711, 0.70711, 0).
For v₂, the dot product with e₁ is 1 ÷ √2 = 0.70711, and subtracting 0.70711 times e₁ gives u₂ = (1, 0, 1) − (0.5, 0.5, 0) = (0.5, −0.5, 1). Its norm is √1.5 = 1.22474, so e₂ = (0.40825, −0.40825, 0.81650).
For v₃, the dot with e₁ is 0.70711 and the dot with e₂ is −0.40825 + 0.81650 = 0.40825. Subtracting both projections gives (0, 1, 1) − (0.5, 0.5, 0) − (0.16667, −0.16667, 0.33333) = (−0.66667, 0.66667, 0.66667), with norm 1.15470, so e₃ = (−0.57735, 0.57735, 0.57735). Checking, e₃ · e₁ = (−0.57735 + 0.57735) × 0.70711 = 0 exactly, which is what the verification line reports. Wolfram MathWorld's page on Gram-Schmidt orthonormalization gives the same construction in the general inner-product setting.
Why the Modified Variant Exists
The two variants are algebraically identical and numerically very different, which is one of the cleanest illustrations in numerical analysis of why algebraic equivalence is not enough.
Classical Gram-Schmidt computes every projection coefficient against the original vector, then subtracts all of them at once. Modified Gram-Schmidt subtracts one projection at a time and computes the next coefficient against the partially updated vector. In exact arithmetic the two give the same answer, because the updates do not change the dot products with the earlier basis vectors. In floating point they do change them slightly, and the classical version keeps computing against a stale vector while rounding error accumulates.
The consequence is measurable. On a well-conditioned set both are fine. On an ill-conditioned set — one where the vectors are nearly parallel — the classical version can produce output vectors whose mutual dot products are far from zero, sometimes catastrophically so, while the modified version degrades gracefully. Switch the variant selector on a nearly dependent input and watch the largest off-diagonal dot product change. That is the whole argument, visible in one number.
Neither variant is what a numerical library actually uses for QR. Householder reflections are backward stable without qualification and are the standard choice, at the cost of not producing the basis vectors one at a time. Gram-Schmidt survives because it is incremental, which matters when vectors arrive one by one, and because it is the version you can follow by hand.
Order Changes the Answer
This surprises people, so it is worth stating plainly: Gram-Schmidt is not symmetric in its inputs. The first output vector is always the normalised first input. Swap the first two vectors and you get a different orthonormal basis for exactly the same subspace.
Both bases are correct. A subspace has infinitely many orthonormal bases and the process picks one, determined entirely by the order you supplied. If you are comparing your result against a textbook or another tool and the vectors differ, check the input order before assuming an error — and check the signs, because a basis vector and its negative are equally valid and different implementations make different choices.
Order also affects which vector gets flagged as dependent. In a set where the third vector is the sum of the first two, moving it to the front means the first two are processed after it and one of them is flagged instead. The rank is unchanged; the labelling is not. Our matrix rank calculator gives the rank directly by row reduction if that is all you need.
Where Orthonormal Bases Earn Their Keep
The reason to do this work at all is that orthonormal bases make several hard problems easy. In a general basis, finding the coordinates of a vector means solving a linear system. In an orthonormal basis each coordinate is just a dot product, which is why the construction pays for itself the moment you need to expand more than a couple of vectors.
Least squares fitting is the standard application. Projecting a data vector onto the column space of a design matrix is the whole of linear regression, and doing it through an orthonormal basis avoids forming the normal equations, whose condition number is the square of the original matrix's. Signal processing uses the same idea for basis expansion, and the Legendre and Hermite families of orthogonal polynomials are literally what Gram-Schmidt produces when you apply it to the powers of x under an integral inner product.
If you want the individual operations rather than the whole construction, our dot product calculator gives the inner products, the vector calculator handles projection of one vector onto another, and the matrix calculator multiplies and transposes so you can verify that Q transpose times Q is the identity. MIT's OpenCourseWare linear algebra course covers orthogonality and the least squares application in full.
Arb Digital builds free tools that report the residual error alongside the answer instead of hiding it.
Browse All Free Tools Talk To Our TeamCommon Mistakes to Avoid
- Forgetting to normalise — subtracting projections gives an orthogonal set, not an orthonormal one, and the two are used interchangeably far too often.
- Projecting onto the original vectors instead of the new basis — the projections must be taken against the already-orthonormalised vectors, or the result is not orthogonal at all.
- Assuming a different order gives a wrong answer — it gives a different valid basis for the same subspace, and so does flipping the sign of any output vector.
- Trusting the classical variant on nearly parallel vectors — it can lose orthogonality badly while still returning a clean-looking set of numbers.
- Ignoring the verification figure — a largest off-diagonal dot product well above rounding level means the answer is unreliable regardless of how it looks.
Related Free Tools From Arb Digital
Get the full factorisation with the QR decomposition calculator, compute inner products with the dot product calculator, project one vector onto another with the vector calculator, find the rank directly with the matrix rank calculator, or verify the result with the matrix calculator. The full free online tools hub lists every linear algebra tool we publish.
Frequently Asked Questions
It converts a list of vectors into an orthonormal basis for the same span, by subtracting from each vector its projection onto every basis vector already built and then normalising what is left.
The residual for the redundant vector comes out at zero length. The tool names that vector, skips it, and carries on, so the output is still a correct orthonormal basis for the span with fewer vectors than you entered.
Yes. The first output vector is always the normalised first input, so a different order gives a different orthonormal basis. Both bases span the same subspace and both are correct.
Classical computes all projection coefficients against the original vector and subtracts them together; modified subtracts one at a time and recomputes against the updated vector. They agree in exact arithmetic and differ substantially in floating point.
Gram-Schmidt produces only the orthonormal vectors and shows the projections. QR produces a matrix pair where R holds those projection coefficients, and practical QR is normally computed by Householder reflections rather than by this process.
Because rounding error accumulates in the subtracted projections, so on nearly parallel vectors the output can fail to be orthogonal. The modified variant reduces the effect considerably but does not eliminate it.
Yes, and that is the correct behaviour. The number of output vectors is the rank of the input set, and any shortfall means some of your vectors were combinations of the others.
Every distinct pair of output vectors should have a dot product of zero and every vector should have length one. The tool reports the largest deviation from the first of those conditions.
This page explains a numerical linear algebra construction for educational purposes. Results are computed in double-precision floating point, so a nearly dependent input set may produce a basis that looks clean while having lost orthogonality.