LinearAlgebra`Orthogonalization`
For most purposes, the most convenient type of basis for a vector space is orthonormal (i.e., the vectors are unit length and are pairwise orthogonal). The GramSchmidt procedure takes an arbitrary basis and generates an orthonormal one. It does this by sequentially processing the list of vectors and generating a vector perpendicular to the previous vectors in the list. For the process to succeed in producing an orthonormal set, the given vectors must be linearly independent. The function GramSchmidt assumes that this is the case. If the given vectors are not linearly independent, indeterminate or zero vectors may be produced. The Householder method of orthogonalization is restricted to numeric matrices and a dot inner product, but is numerically stable, unlike GramSchmidt, which may have problems with vectors that are nearly linearly dependent.
Vector operations using the usual inner product.
This loads the package.
In[1]:= <<LinearAlgebra`Orthogonalization`
This applies the GramSchmidt procedure to the given list of threedimensional vectors.
In[2]:= {w1, w2, w3} = GramSchmidt[ {{3,4,2}, {2,5,2}, {1,2,6}}]
Out[2]=
The result is an orthonormal basis, so the dot product of each pair of vectors is zero and each vector has unit length.
In[3]:= {w1 . w2, w2 . w3, w1 . w3, w1 . w1, w2 . w2, w3 . w3}
Out[3]=
A vector space is a generalization of the familiar notions of one, two, and threedimensional space. In these familiar spaces we know how to compute lengths of vectors and the angle between two vectors. The usual way of doing this uses the dot product. The length of a vector is simply Sqrt[v.v] and two vectors are perpendicular (or orthogonal) if v.w is zero. In a more general vector space, the dot product is replaced by an inner product. By setting the option InnerProduct, you can use GramSchmidt to produce a collection of vectors that are orthonormal with respect to your specified inner product.
Vector operations using a specified inner product.
The function you specify as the InnerProduct can be a pure function of two variables, with the variables given as #1 and #2. For example, the default InnerProduct > Dot could be expressed as InnerProduct > (#1.#2&). The parentheses around the formula for the function guarantee that Mathematica treats it as a single unit. For more information on pure functions, see The Mathematica Book.
The vectors here are functions, and the inner product is the integral of the product of two functions over the interval to .
In[4]:= GramSchmidt[{1, x, x^2, x^3, x^4}, InnerProduct > (Integrate[#1 #2,{x,1,1}]&)] //Simplify
Out[4]=
Here is the second Legendre polynomial normalized with respect to the same inner product. It is the same as the third element in the basis found using GramSchmidt.
In[5]:= Normalize[LegendreP[2,x], InnerProduct > (Integrate[#1 #2,{x,1,1}]&)]
Out[5]=
Generating orthogonal sets without normalizing.
The option Normalized is set to False.
In[6]:= {w1, w2} = GramSchmidt[{{3,4,3}, {2,3,6}}, Normalized > False]
Out[6]=
The resulting vectors are orthogonal, but they are not normalized.
In[7]:= {w1 . w1, w1 . w2}
Out[7]=
Housholder orthogonalization.
For the particular case of numeric vectors using Dot as the inner product, you may find Householder orthogonalization to be numerically more stable. Also, since this can be implemented in terms of the internal QRDecomposition routine, it may be much faster, even though the Householder method may theoretically take twice as many operations as the GramSchmidt method.
Here is a numeric matrix that is linearly dependent.
In[8]:= dat = {{0, 0, 1.}, {1., 0, 0}, {0.12988785514152842, 0.3997814966837186, 0.5468181006215335}, {1.013982920708332, 0.02721531177817664, 0.18567966396292607}};
The GramSchmidt routine doesn't catch the dependency.
In[9]:= GramSchmidt[dat]
Out[9]=
The Householder routine works as desired.
In[10]:= Householder[dat]
Out[10]=
The Householder function is restricted to numeric input, and returns only an orthonormal basis. It is not as flexible as GramSchmidt.
