The Gram Schmidt algorithm


This page describes how to generate collections of vectors upon which the Gram Schmidt algorithm may be run where none of the intermediate vectors have more than one digit to the right of the decimal point (which will be described as "nice"), and where intermediate calculations of the inner product and 2-norm require at most two digits to the right of the decimal point. In some cases, we will look at vectors where there are at most two digits beyond the decimal point, and these will be described as "almost nice". We will start by describing the algorithm, then look at orthogonal or tall orthogonal matrices that we will use to generate our problems, and we conclude by running our algorithm on each of the given matrices.

Creating problems

Given a set of $n$ orthonormal $m$-dimensional vectors, we will proceed as follows:

  1. Create the $m \times n$ matrix $A$ of the $n$ orthonormal $m$-dimensional vectors as columns, thus creating either an orthogonal or a tall orthogonal matrix where $A^\top A = I_n$.
  2. If the matrix is square (orthogonal), transpose it 50% of the time.
  3. Randomly permute the columns of this matrix $A$.
  4. Randomly permute the rows of this matrix $A$.
  5. Multiply each column of $A$ by $\pm 1$, where the sign is chosen randomly.
  6. Multiply each row of $A$ by $\pm 1$, where the sign is chosen randomly.

The form of the matrix at this point is the solution the student will be finding; however, to create the set of vectors to which the student will apply the algorithm, we continue:

  1. For each column, starting with the right-most first, and incrementally moving to the first:
    replace each column with an integer linear combination of that column and all columns to the left of it.

You will observe that the last operation mulitplies the first column by a scalar, thus making it a unnormalized vector.

The coefficients of that linear combination will either be the inner products calculated during the Gram Schmidt algorithm or will be the norms of the orthogonal vectors that must then be normalized. The multiplier of the column being replaced should be a positive integer, and preferably something more straight-forward, especially if this is being done on a blackboard or by students not using calculators, such as $2, 4, 5, 10, \ldots$.

In the section below, we provide code in Matlab that does this automatically. Next, however, we will look at orthogonal and tall orthogonal matrices in two, three, four, and five dimensions.

Two (2) dimensions

In two dimensions, there are only two "nice" orthogonal matrices: $$\left(\begin{array}{rr} 1 & 0 \\ 0 & 1 \end{array}\right)$$ and $$\left(\begin{array}{rr} 0.6 & 0.8 \\ 0.8 & -0.6 \end{array}\right)$$

Another "almost nice" (requiring intermediate results with two digits beyond the decimal point) orthogonal matrix is: $$\left(\begin{array}{rr} 0.28 & 0.96 \\ 0.96 & -0.28 \end{array}\right)$$.

You will notice that all of the above matrices are isometric (orthogonal) and self-adjoint (symmetric), and thus, all matricies equals their own inverse: $A = A^\top = A^{-1}$. Of course, once permutations and multiplications of random rows or columns by $-1$ are applied, this may no longer be the case.

Here are these three matrices in Matlab, but you can click here to view this matrix in C/C++, Maple, Matlab, Python and Mathematica.

A21 = [1 0
       0 1];

A22 = [0.6  0.8
       0.8 -0.6];

A23 = [0.28  0.96
       0.96 -0.28];

Three (3) dimensions

There are literally no "nice" non-trivial three $3$-dimensional normalized vectors that have only one digit following the decimal point, so we are reduced to starting with the orthonormal vectors in lower dimensions embedded into $\textbf{R}^3$ with matrices such as:

$$\left( \begin{array}{rrr} 1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{array}\right)$$ and $$\left( \begin{array}{rrr} 1\phantom{.0} & 0\phantom{.0} & 0\phantom{.0} \\ 0\phantom{.0} & 0.6 & 0.8 \\ 0\phantom{.0} & 0.8 & -0.6 \end{array}\right)$$.

There are two examples of "almost nice" orthogonal matrices where there are three orthonormal vectors with at most two digits after the decimal point: $$\left( \begin{array}{rrr} 0\phantom{.00} & 0.6\phantom{0} & 0.8\phantom{0} \\ 0.6\phantom{0} & -0.64 & 0.48 \\ 0.8\phantom{0} & 0.48 & -0.36 \end{array}\right)$$ and $$\left( \begin{array}{rrr} 1 & 0\phantom{.00} & 0\phantom{.00} \\ 0 & 0.28 & 0.96 \\ 0 & 0.96 & -0.28 \end{array}\right)$$ .

Again, you will notice that all of of the above matrices are isometric (orthogonal) and self-adjoint (symmetric), and thus, all matricies equals their own inverse: $A = A^\top = A^{-1}$.

Here are these four matrices in Matlab, but you can click here to view these matricies in C/C++, Maple, Matlab, Python and Mathematica.

A31 = [1 0 0
       0 1 0
       0 0 1];

A32 = [1  0    0
       0  0.6  0.8
       0  0.8 -0.6];

A33 = [0     0.6   0.8
       0.6  -0.64  0.48
       0.8   0.48 -0.36];

A34 = [1  0     0
       0  0.28  0.96
       0  0.96 -0.28];

Four (4) dimensions

A number of instructors seem to be averse to going to four dimensions, but there are some really nice examples. There are exactly five normalized vectors (up to signs and permutations) where each entry has one digit beyond the decimal point:

$$\left( \begin{array}{r} 0.5 \\ 0.5 \\ 0.5 \\ 0.5 \end{array}\right), \left( \begin{array}{r} 0.2 \\ 0.4 \\ 0.4 \\ 0.8 \end{array}\right), \left( \begin{array}{r} 0.1 \\ 0.1 \\ 0.7 \\ 0.7 \end{array}\right), \left( \begin{array}{r} 0.1 \\ 0.5 \\ 0.5 \\ 0.7 \end{array}\right), \textrm{ and } \left( \begin{array}{r} 0.1 \\ 0.3 \\ 0.3 \\ 0.9 \end{array}\right).$$

Given any one of these vectors, one can generate an orthogonal matrix as follows: $$\left( \begin{array}{rrrr} \alpha & \beta & \gamma & \delta \\ \beta & -\alpha & \delta & -\gamma \\ \gamma & -\delta & -\alpha & \beta \\ \delta & \gamma & -\beta & -\alpha \end{array}\right)$$

However, there is one further orthogonal matrix that is "nice": $$\left( \begin{array}{r} 0.5 & 0.5 & 0.1 & 0.7 \\ 0.5 & 0.5 & -0.1 & -0.7 \\ 0.5 & -0.5 & -0.7 & 0.1 \\ 0.5 & -0.5 & 0.7 & -0.1 \end{array}\right).$$

However, even in this special case, having permutations of the same vector appearing in the solution may be seen to be sub-optimal, and may appear to be contrived (which, of course, it is). Unfortunately, however, there are no "nice" orthogonal collections of three or four vectors where the entries are different.

Here are these six matrices in Matlab, but you can click here to view these matricies in C/C++, Maple, Matlab, Python and Mathematica.

A41 = [0.5  0.5  0.1  0.7
       0.5  0.5 -0.1 -0.7
       0.5 -0.5 -0.7  0.1
       0.5 -0.5  0.7 -0.1];

A42 = [0.5  0.5  0.5  0.5
       0.5 -0.5  0.5 -0.5
       0.5 -0.5 -0.5  0.5
       0.5  0.5 -0.5 -0.5];

A43 = [0.2  0.4  0.4  0.8
       0.4 -0.2  0.8 -0.4
       0.4 -0.8 -0.2  0.4
       0.8  0.4 -0.4 -0.2];

A44 = [0.1  0.1  0.7  0.7
       0.1 -0.1  0.7 -0.7
       0.7 -0.7 -0.1  0.1
       0.7  0.7 -0.1 -0.1];

A45 = [0.1  0.5  0.5  0.7
       0.5 -0.1  0.7 -0.5
       0.5 -0.7 -0.1  0.5
       0.7  0.5 -0.5 -0.1];

A46 = [0.1  0.3  0.3  0.9
       0.3 -0.1  0.9 -0.3
       0.3 -0.9 -0.1  0.3
       0.9  0.3 -0.3 -0.1];

Five (5) dimensions

A number of instructors seem to fear going to five dimensions, as well, but there are even nicer examples. There are exactly six normalized vectors (up to signs and permutations) where each entry has one digit beyond the decimal point:

$$\left( \begin{array}{r} 0.1 \\ 0.1 \\ 0.1 \\ 0.4 \\ 0.9 \end{array}\right), \left( \begin{array}{r} 0.1 \\ 0.1 \\ 0.3 \\ 0.5 \\ 0.8 \end{array}\right), \left( \begin{array}{r} 0.1 \\ 0.3 \\ 0.4 \\ 0.5 \\ 0.7 \end{array}\right), \left( \begin{array}{r} 0.3 \\ 0.3 \\ 0.3 \\ 0.3 \\ 0.8 \end{array}\right), \left( \begin{array}{r} 0.3 \\ 0.4 \\ 0.5 \\ 0.5 \\ 0.5 \end{array}\right), \textrm{ and } \left( \begin{array}{r} 0.4 \\ 0.4 \\ 0.4 \\ 0.4 \\ 0.6 \end{array}\right).$$

Of these, there are two triplets that form an orthonormal set and thus these tall orthogonal matrix: $$ \left( \begin{array}{rrr} 0.1 & 0.1 & 0.1 \\ 0.1 & -0.1 & -0.5 \\ 0.1 & -0.5 & -0.7 \\ 0.4 & 0.8 & -0.4 \\ 0.9 & -0.3 & 0.3 \end{array}\right)$$

and $$ \left( \begin{array}{rrr} 0.1 & 0.3 & 0.5 \\ 0.1 & 0.7 & 0.3 \\ 0.3 & -0.1 & -0.5 \\ 0.5 & 0.5 & -0.5 \\ 0.8 & -0.4 & 0.4 \end{array}\right)$$

Of the vectors that remain, there are two doublets that form an orthonormal set and thus these tall orthogonal matrix: $$ \left( \begin{array}{rrr} 0.1 & 0.4 \\ 0.3 & 0.4 \\ 0.5 & -0.4 \\ 0.7 & 0.4 \\ 0.4 & -0.6 \end{array}\right)$$

and $$ \left( \begin{array}{rrr} 0.3 & 0.4 \\ 0.3 & 0.4 \\ 0.3 & 0.4 \\ 0.3 & 0.4 \\ 0.8 & -0.6 \end{array}\right)$$

If we allow ourselves to include "nice" lower dimensional unit vectors into $\textbf{R}^5$, then there are exactly two "nice" $5 \times 5$ orthogonal matrices (up to multiplying rows or columns by $-1$ and swapping rows or columns) where no two columns contain the same digits:

$$\left(\begin{array}{rrrrr} 0.1 & 0.1 & 0.1 & 0.4 & 0.9 \\ 0.1 & -0.1 & -0.5 & 0.8 & -0.3 \\ 0.1 & -0.5 & -0.7 & -0.4 & 0.3 \\ 0.4 & 0.8 & -0.4 & -0.2 & 0\phantom{.0} \\ 0.9 & -0.3 & 0.3 & 0\phantom{.0} & -0.1 \end{array}\right)$$ $$\left(\begin{array}{rrrrr} 0.1 & 0.1 & 0.3 & 0.5 & 0.8 \\ 0.1 & -0.5 & 0.7 & 0.3 & -0.4 \\ 0.3 & -0.7 & -0.1 & -0.5 & 0.4 \\ 0.5 & 0.5 & 0.5 & -0.5 & 0\phantom{.0} \\ 0.8 & 0\phantom{.0} & -0.4 & 0.4 & -0.2 \end{array}\right)$$

You will notice that the first matrix is both isometric (orthogonal) and self-adjoint (symmetric), and thus, that matrix equals its inverse: $A = A^\top = A^{-1}$.

Here are these six matrices in Matlab, but you can click here to view these matrices in C/C++, Maple, Matlab, Python and Mathematica.

A51 = [0.1  0.1  0.5
       0.1  0.5  0.7
       0.1 -0.1 -0.1
       0.4 -0.8  0.4
       0.9  0.3 -0.3];

A52 = [0.1  0.3  0.5
       0.1  0.7  0.3
       0.3 -0.1 -0.5
       0.5  0.5 -0.5
       0.8 -0.4  0.4];

A53 = [0.1  0.4
       0.3  0.4
       0.5 -0.4
       0.7  0.4
       0.4 -0.6];

A54 = [0.3  0.4
       0.3  0.4
       0.3  0.4
       0.3  0.4
       0.8 -0.6];

A55 = [0.1  0.1  0.1  0.4  0.9
       0.1 -0.1 -0.5  0.8 -0.3
       0.1 -0.5 -0.7 -0.4  0.3
       0.4  0.8 -0.4 -0.2  0.0
       0.9 -0.3  0.3  0.0 -0.1];

A56 = [0.1  0.1  0.3 0.5   0.8
       0.1 -0.5  0.7  0.3 -0.4
       0.3 -0.7 -0.1 -0.5  0.4
       0.5  0.5  0.5 -0.5  0.0
       0.8  0.0 -0.4  0.4 -0.2];

Creating a "nice" Gram-Schmidt problem

This is most nicely done in Matlab:

% Start with an orthonormal collection of vectors:
V = [0.5  0.5  0.1  0.7
     0.5  0.5 -0.1 -0.7
     0.5 -0.5 -0.7  0.1
     0.5 -0.5  0.7 -0.1];
[dim, n_vec] = size( V );
% This verifies that the vectors form an orthonormal collection
assert( norm( V'*V - eye( n_vec ) ) < 1e-10 );

% If the matrix is square (orthogonal),
% with a 50/50 chance, transpose it
if (dim == n_vec) && (randi( 2 ) == 2)
   V = V';
end
% Rearrange the vectors
V = V(:, randperm(n_vec));
% Rearrange the entries
V = V(randperm(dim), :);
% Multiply random vectors by -1
V .* ((-1).^randi( 0:1, 1, n_vec ) );
% Multiply random entries in all vectors by -1
V .* ((-1).^randi( 0:1, dim, 1  ) );
display( 'The solution will be these orthonormal vectors:' );
V

U = zeros(dim, n_vec);

% Generate a set of 'n_vec' linearly independent vectors that satisfy:
%  - The inner products calculate to integers from -6, ..., 6.
%  - The norms are either 2, 3, 4, 5, or 10.
poss_ips = (-6:6)';
n_ips = length( poss_ips );

poss_norms = [2 3 4 5 10];
n_norms = length( poss_norms );
assert( all( poss_norms > 0 ) );  % Ensure the norms are positive

for k = n_vec:-1:1
  U(:,k) = poss_norms(randi( n_norms ))*V(:,k) + V(:,1:(k - 1))*poss_ips(randi( n_ips, (k - 1), 1 ));
  % If you want the inner products to calculate to half-integers
  % values -6, -5.5, -5, ..., 5, 5.5, 6, use this line instead:
  % U(:,k) = poss_norms(randi(n_norms))*V(:,k) + V(:,1:(k - 1))*randi([-12,12],(k - 1),1)/2;
end

display( 'The vectors upon which Gram Schmidt are to be applied are:' );
U

Example executions

Given the matrix A21 we get:

     The solution will be these orthonormal vectors:
        V =
           0  1
           1  0

     The vectors upon which Gram Schmidt are to be applied are:
        U =
           0  3
           5 -6

Given the matrix A22 we get:

     The solution will be these orthonormal vectors:
        V =
           0.8  0.6
          -0.6  0.8

     The vectors upon which Gram Schmidt are to be applied are:
        U =
            3.2   1.2
           -2.4  11.6

Given the matrix A23 we get:

     The solution will be these orthonormal vectors:
        V =
          -0.28  0.96
           0.96  0.28

     The vectors upon which Gram Schmidt are to be applied are:
        U =
          -0.84  1.76
           2.88  4.68

Given the matrix A31 we get:

     The solution will be these orthonormal vectors:
        V =
           0  0  1
           1  0  0
           0  1  0

     The vectors upon which Gram Schmidt are to be applied are:
        U =
           0  0  3
           5 -5 -1
           0  4  6

Given the matrix A32 we get:

     The solution will be these orthonormal vectors:
        V =
           0    0    1
          -0.6  0.8  0
           0.8  0.6  0

     The vectors upon which Gram Schmidt are to be applied are:
        U =
           0    0    2
          -2.4  4.6 -1
           3.2  2.2  3

Given the matrix A33 we get:

     The solution will be these orthonormal vectors:
        V =
          -0.36  0.48  0.8
           0.8   0.6   0
           0.48 -0.64  0.6

     The vectors upon which Gram Schmidt are to be applied are:
        U =
           -0.72  0 10.4
            1.6   5 -2
            0.96  0  2.8

Given the matrix A34 we get:

     The solution will be these orthonormal vectors:
        V =
           0     1  0
           0.96  0 -0.28
           0.28  0  0.96

     The vectors upon which Gram Schmidt are to be applied are:
        U =
           0     4     0
           3.84 -0.96 -4.96
           1.12 -0.28  2.72

Given the matrix A41 we get:

     The solution will be these orthonormal vectors:
        V =
           0.7 -0.1  0.5 -0.5
          -0.1 -0.7  0.5  0.5
          -0.7  0.1  0.5 -0.5
           0.1  0.7  0.5  0.5

     The vectors upon which Gram Schmidt are to be applied are:
        U =
           1.4 -4.5 -3.5 -6.1
          -0.2 -6.5 -0.5  3.3
          -1.4  4.5  5.5  0.1
           0.2  6.5  2.5 -3.3

Given the matrix A42 we get:

     The solution will be these orthonormal vectors:
        V =
          -0.5 -0.5  0.5  0.5
          -0.5  0.5  0.5 -0.5
           0.5 -0.5  0.5 -0.5
           0.5  0.5  0.5  0.5

     The vectors upon which Gram Schmidt are to be applied are:
        U =
          -2.5 -8  1.5 -1.5
          -2.5  2 -0.5 -0.5
           2.5 -2  5.5 -0.5
           2.5  8  3.5  4.5

Given the matrix A43 we get:

     The solution will be these orthonormal vectors:
        V =
           0.8 -0.4 -0.2  0.4
           0.4 -0.2  0.4 -0.8
           0.4  0.8 -0.4 -0.2
           0.2  0.4  0.8  0.4

     The vectors upon which Gram Schmidt are to be applied are:
        U =
           1.6 -4.8 -5.6  3.6
           0.8 -2.4 -0.8  1.8
           0.8  7.6  2   -0.2
           0.4  3.8  5    7.4

Given the matrix A44 we get:

     The solution will be these orthonormal vectors:
        V =
           0.7 -0.1 -0.1  0.7
           0.1  0.7  0.7  0.1
          -0.1 -0.7  0.7  0.1
          -0.7  0.1 -0.1  0.7

     The vectors upon which Gram Schmidt are to be applied are:
        U =
           2.8 -0.4  0  7.5
           0.4  2.8  5  2.5
          -0.4 -2.8  9 -1.9
          -2.8  0.4 -2  6.7

Given the matrix A45 we get:

     The solution will be these orthonormal vectors:
        V =
           0.5 -0.5 -0.1  0.7
           0.1  0.7  0.5  0.5
           0.5  0.5 -0.7 -0.1
           0.7 -0.1  0.5 -0.5

     The vectors upon which Gram Schmidt are to be applied are:
        U =
           2   -2   -0.5 -1.6
           0.4  3.6  4.3  6.2
           2    3   -7.5 -2.2
           2.8  0.2  5.1  0.4

Given the matrix A46 we get:

     The solution will be these orthonormal vectors:
        V =
           0.3 -0.1  0.9 -0.3
          -0.9  0.3  0.3 -0.1
           0.3  0.9  0.1  0.3
          -0.1 -0.3  0.3  0.9

     The vectors upon which Gram Schmidt are to be applied are:
        U =
           3  0  0.2  2.8
          -9  0  5.4 -5.4
           3  3  2.6 -1
          -1 -1 -0.2  4

Given the matrix A51 we get:

     The solution will be these orthonormal vectors:
        V =
          -0.8  0.4  0.4
           0.1  0.5  0.1
          -0.1 -0.1  0.1
           0.3 -0.3  0.9
           0.5  0.7  0.1

     The vectors upon which Gram Schmidt are to be applied are:
        U =
          -2.4  5.6  4.4
           0.3  0.4  3.2
          -0.3  0.4 -0.2
           0.9 -2.4  0.6
           1.5 -1.6  4

Given the matrix A52 we get:

     The solution will be these orthonormal vectors:
        V =
           0.3 -0.1 -0.5
           0.1  0.3  0.5
           0.5  0.5 -0.5
           0.1  0.7  0.3
           0.8 -0.4  0.4

     The vectors upon which Gram Schmidt are to be applied are:
        U =
           3 -1.9 -2.5
           1  0.7  1.5
           5 -0.5 -2.5
           1  2.3  1.3
           8 -5.6 -1.6

Given the matrix A53 we get:

     The solution will be these orthonormal vectors:
        V =
           0.5 -0.4
           0.7  0.4
           0.4 -0.6
           0.1  0.4
           0.3  0.4

     The vectors upon which Gram Schmidt are to be applied are:
        U =
           1.5 -3.7
           2.1 -2.3
           1.2 -3.8
           0.3  0.7
           0.9 -0.3

Given the matrix A54 we get:

     The solution will be these orthonormal vectors:
        V =
           0.3  0.4
           0.3  0.4
           0.8 -0.6
           0.3  0.4
           0.3  0.4

     The vectors upon which Gram Schmidt are to be applied are:
        U =
           0.6  2
           0.6  2
           1.6  2
           0.6  2
           0.6  2

Given the matrix A55 we get:

     The solution will be these orthonormal vectors:
        V =
           0.1 -0.4  0.3 -0.5 -0.7
           0.1  0.4  0.9  0.1  0.1
           0.4 -0.2  0    0.8 -0.4
           0.9  0   -0.1 -0.3  0.3
           0.1  0.8 -0.3 -0.1 -0.5

     The vectors upon which Gram Schmidt are to be applied are:
        U =
           0.4 -2.1 -1.1 -2.4  0.4
           0.4  1.9  5.3 -4.8  3.2
           1.6 -1.4 -2.2  2.2 -3
           3.6 -0.9 -3.1 -4.4  5.2
           0.4  3.9  2.5 -2    1.6

Given the matrix A56 we get:

     The solution will be these orthonormal vectors:
        V =
           0.3 -0.7 -0.5 -0.1  0.4
           0.1  0.1  0.5  0.3  0.8
           0.5  0.5 -0.5  0.5  0
           0.1 -0.5  0.3  0.7 -0.4
           0.8  0    0.4 -0.4 -0.2

     The vectors upon which Gram Schmidt are to be applied are:
        U =
           0.6 -7 -0.7 -1.9  6.1
           0.2  1  2.1  1.7 -0.3
           1    5 -1.5  9.5 -2.5
           0.2 -5  1.9  0.5 -3.1
           1.6  0  3.2  2    2.2