Skip to main content

Subsection 11.3.2 Jacobi's method for computing the Spectral Decomposition

The oldest algorithm for computing the eigenvalues and eigenvectors of a (symmetric) matrix is due to Jacobi and dates back to 1846.

  • [23] C. G. J. Jacobi, Über ein leichtes Verfahren, die in der Theorie der Säkular-störungen vorkommenden Gleichungen numerisch aufzulösen, Crelle's Journal 30, 51-94 (1846).

If we recall correctly (it has been 30 years since we read the paper in German), the paper thanks Jacobi's student Seidel for performing the calculations for a \(5 \times 5 \) matrix, related to the orbits of the planets, by hand...

This is a method that keeps resurfacing, since it parallelizes easily. The operation count tends to be higher (by a constant factor) than that of reduction to tridiagonal form followed by the tridiagonal QR algorithm.

Jacobi's original idea went as follows:

  • We start with a symmetric matrix:

    \begin{equation*} A = \left( \begin{array}{c c c c} \alpha_{0,0} \amp \alpha_{0,1} \amp \alpha_{0,2} \amp \alpha_{0,3} \\ \alpha_{1,0} \amp \alpha_{1,1} \amp \alpha_{1,2} \amp \alpha_{1,3} \\ \alpha_{2,0} \amp \alpha_{2,1} \amp \alpha_{2,2} \amp \alpha_{2,3} \\ \alpha_{3,0} \amp \alpha_{3,1} \amp \alpha_{3,2} \amp \alpha_{3,3} \\ \end{array} \right). \end{equation*}
  • We find the off-diagonal entry with largest magnitude. Let's say it is \(\alpha_{3,1} \text{.}\)

  • We compute a Jacobi rotation so that

    \begin{equation*} \left( \begin{array}{c c} \gamma_{3,1} \amp \sigma_{3,1} \\ - \sigma_{3,1} \amp \gamma_{3,1} \end{array} \right) \left( \begin{array}{c c} \alpha_{1,1} \amp \alpha_{1,3} \\ \alpha_{3,1} \amp \alpha_{3,3} \end{array} \right) \left( \begin{array}{c c} \gamma_{3,1} \amp - \sigma_{3,1} \\ \sigma_{3,1} \amp \gamma_{3,1} \end{array} \right) = \left( \begin{array}{c c} \times \amp 0 \\ 0 \amp \times \end{array} \right), \end{equation*}

    where the \(\times\)s denote nonzero entries.

  • We now apply the rotation as a unitary similarity transformation from the left to the rows of \(A \) indexed with \(1 \) and \(3 \text{,}\) and from the right to columns \(1\) and \(3 \text{:}\)

    \begin{equation*} \begin{array}{l} \left( \begin{array}{c c c c} \alpha_{0,0} \amp \times \amp \alpha_{0,2} \amp \times \\ \times \amp \times \amp \times \amp 0 \\ \alpha_{2,0} \amp \times \amp \alpha_{2,2} \amp \times \\ \times \amp 0 \amp \times \amp \times \end{array} \right) = \\ \left( \begin{array}{c c c c} 1 \amp 0 \amp 0 \amp 0 \\ 0 \amp \gamma_{3,1} \amp 0 \amp \sigma_{3,1} \\ 0 \amp 0 \amp 1 \amp 0 \\ 0 \amp -\sigma_{3,1} \amp 0 \amp \gamma_{3,1} \end{array} \right) \left( \begin{array}{c c c c} \alpha_{0,0} \amp \alpha_{0,1} \amp \alpha_{0,2} \amp \alpha_{0,3} \\ \alpha_{1,0} \amp \alpha_{1,1} \amp \alpha_{1,2} \amp \alpha_{1,3} \\ \alpha_{2,0} \amp \alpha_{2,1} \amp \alpha_{2,2} \amp \alpha_{2,3} \\ \alpha_{3,0} \amp \alpha_{3,1} \amp \alpha_{3,2} \amp \alpha_{3,3} \\ \end{array} \right) \left( \begin{array}{c c c c} 1 \amp 0 \amp 0 \amp 0 \\ 0 \amp \gamma_{3,1} \amp 0 \amp -\sigma_{3,1} \\ 0 \amp 0 \amp 1 \amp 0 \\ 0 \amp \sigma_{3,1} \amp 0 \amp \gamma_{3,1} \end{array} \right). \end{array} \end{equation*}

    The \(\times\)s here denote elements of the matrix that are changed by the application of the Jacobi rotation.

  • This process repeats, reducing the off-diagonal element that is largest in magnitude to zero in each iteration.

Notice that each application of the Jacobi rotation is a unitary similarity transformation, and hence preserves the eigenvalues of the matrix. If this method eventually yields a diagonal matrix, then the eigenvalues can be found on the diagonal of that matrix. We do not give a proof of convergence here.

Homework 11.3.2.1.

Note: In the description of this homework, we index like Matlab does: starting at one. This is in contrast to how we usually index in these notes, starting at zero.

In Assignments/Week11/matlab, you will find the following files:

  • Jacobi_rotation.m: A function that computes a Jacobi rotation from a \(2 \times 2 \) symmetric matrix.

  • Seidel.m: A script that lets you apply Jacobi's method to a \(5 \times 5 \) matrix, much like Seidel did by hand. Fortunately, you only indicate the off-diagonal element to zero out. Matlab then does the rest.

Use this to gain insight into how Jacobi's method works. You will notice that finding the off-diagonal element that has largest magnitude is bothersome. You don't need to get it right every time.

Once you have found the diagonal matrix, restart the process. This time, zero out the off-diagonal elements in systematic "sweeps," zeroing the elements in the order.

( 2,1 ) - ( 3,1 ) - ( 4,1 ) - ( 5,1 ) -
          ( 3,2 ) - ( 4,2 ) - ( 5,2 ) - 
                    ( 4,3 ) - ( 5,3 ) - 
                              ( 5,4 )

and repeating this until convergence. A sweep zeroes every off-diagonal element exactly once (in symmetric pairs).

Solution

Hopefully you noticed that the matrix converges to a diagonal matrix, with the eigenvalues on its diagonal.

The key insight is that applying a Jacobi rotation to zero an element, \(\alpha_{i,j} \text{,}\) reduces the square of the Frobenius norm of the off-diagonal elements of the matrix by \(\alpha_{i,j}^2 \text{.}\) In other words, let \({\rm off}( A )\) equal the matrix \(A \) but with its diagonal elements set to zero. If \(J_{i,j} \) zeroes out \(\alpha_{i,j} \) (and \(\alpha_{j,i} \)), then

\begin{equation*} \| {\rm off}( J_{i,j}^T A J_{i,j} ) \|_F^2 = \| {\rm off}( A ) \|_F^2 - 2 \alpha_{i,j}^2 . \end{equation*}
Homework 11.3.2.2.

Partition matrix \(A \) like

\begin{equation*} \left( \begin{array}{c | c | c | c | c } A_{00} \amp \color{red}{ a_{10}} \amp A_{20}^T \amp \color{red}{ a_{30}} \amp A_{40}^T \\ \hline \color{red}{ a_{10}^T} \amp \color{blue}{ \alpha_{11}} \amp \color{red}{ a_{21}^T} \amp \color{blue}{ \alpha_{31}} \amp \color{red}{ a_{41}^T} \\ \hline A_{20} \amp \color{red}{ a_{21}} \amp A_{22} \amp \color{red}{ a_{32}} \amp A_{42}^T \\ \hline \color{red}{ a_{30}^T} \amp \color{blue}{ \alpha_{31}} \amp \color{red}{ a_{32}^T} \amp \color{blue}{ \alpha_{33}} \amp \color{red}{ a_{43}^T} \\ \hline A_{40} \amp \color{red}{ a_{41}} \amp A_{42} \amp \color{red}{ a_{43}} \amp A_{44} \end{array} \right) \end{equation*}

and let \(J \) equal the Jacobi rotation that zeroes the element denoted with \(\alpha_{31} \text{:}\)

\begin{equation*} \begin{array}{l} J^T A J = \\ ~~~ \begin{array}[t]{r c l} \left( \begin{array}{c | c | c | c | c } I \amp 0 \amp 0 \amp 0 \amp 0 \\ \hline 0 \amp \color{blue}{ \gamma_{11}} \amp 0 \amp \color{blue}{ \sigma_{31}} \amp 0 \\ \hline 0 \amp 0 \amp I \amp 0 \amp 0 \\ \hline 0 \amp \color{blue}{ -\sigma_{31}} \amp 0 \amp \color{blue}{ \gamma_{33}} \amp 0 \\ \hline 0 \amp 0 \amp 0 \amp 0 \amp I \end{array} \right) \amp \left( \begin{array}{c | c | c | c | c } A_{00} \amp \color{red}{ a_{10}} \amp A_{20}^T \amp \color{red}{ a_{30}} \amp A_{40}^T \\ \hline \color{red}{ a_{10}^T} \amp \color{blue}{ \alpha_{11}} \amp \color{red}{ a_{21}^T} \amp \color{blue}{ \alpha_{31}} \amp \color{red}{ a_{41}^T} \\ \hline A_{20} \amp \color{red}{ a_{21}} \amp A_{22} \amp \color{red}{ a_{32}} \amp A_{42}^T \\ \hline \color{red}{ a_{30}^T} \amp \color{blue}{ \alpha_{31}} \amp \color{red}{ a_{32}^T} \amp \color{blue}{ \alpha_{33}} \amp \color{red}{ a_{43}^T} \\ \hline A_{40} \amp \color{red}{ a_{41}} \amp A_{42} \amp \color{red}{ a_{43}} \amp A_{44} \end{array} \right) \amp \left( \begin{array}{c | c | c | c | c } I \amp 0 \amp 0 \amp 0 \amp 0 \\ \hline 0 \amp \color{blue}{ \gamma_{11}} \amp 0 \amp \color{blue}{ -\sigma_{13}} \amp 0 \\ \hline 0 \amp 0 \amp I \amp 0 \amp 0 \\ \hline 0 \amp \color{blue}{ \sigma_{31}} \amp 0 \amp \color{blue}{ \gamma_{33}} \amp 0 \\ \hline 0 \amp 0 \amp 0 \amp 0 \amp I \end{array} \right) \\ \\ ~~~= \amp\left( \begin{array}{c | c | c | c | c } A_{00} \amp \color{red}{\widehat a_{10}} \amp A_{20}^T \amp \color{red}{\widehat a_{30}} \amp A_{40}^T \\ \hline \color{red}{ \widehat a_{10}^T} \amp \color{blue}{ \widehat \alpha_{11}} \amp\color{red}{\widehat a_{21}^T} \amp \color{blue}{ 0} \amp \color{red}{ \widehat a_{41}^T} \\ \hline A_{20} \amp \color{red}{ \widehat a_{21}} \amp A_{22} \amp \color{red}{ \widehat a_{32}} \amp A_{42}^T \\ \hline \color{red}{ \widehat a_{30}^T} \amp \color{blue}{ 0} \amp \color{red}{ \widehat a_{32}^T} \amp \color{blue}{ \widehat \alpha_{33}} \amp \color{red}{ \widehat a_{43}^T} \\ \hline A_{40} \amp \color{red}{ \widehat a_{41}} \amp A_{42} \amp \color{red}{ \widehat a_{43}} \amp A_{44} \end{array} \right) \amp = \widehat A . \end{array} \end{array} \end{equation*}

Show that \(\| {\rm off}( \widehat A ) \|_F^2 = \| {\rm off}( A ) \|_F^2 - 2\alpha_{31}^2\text{.}\)

Solution

We notice that

\begin{equation*} \begin{array}{l} \| {\rm off}( A ) \|_F^2 =\\ \begin{array}[t]{lllllll} \phantom{+} \| {\rm off}( A_{00} ) \|_F^2 \amp + \| \color{red}{ a_{10}} \|_F^2 \amp + \| A_{20}^T \|_F^2 \amp + \| \color{red}{ a_{30}} \|_F^2 \amp + \| A_{40}^T \|_F^2\\ + \| \color{red}{ a_{10}^T} \|_F^2 \amp \amp + \| \color{red}{ a_{21}^T} \|_F^2 \amp + \color{blue}{ \alpha_{31}^2} \amp + \| \color{red}{ a_{41}^T} \|_F^2\\ + \| A_{20} \|_F^2 \amp + \| \color{red}{ a_{21}} \|_F^2 \amp + \| {\rm off}( A_{22} ) \|_F^2 \amp + \| \color{red}{ a_{32}} \|_F^2 \amp \| A_{42}^T \|_F^2\\ + \| \color{red}{ a_{30}^T} \|_F^2 \amp + \color{blue}{ \alpha_{31}^2} \amp + \| \color{red}{ a_{32}^T} \|_F^2 \amp \amp + \| \color{red}{ a_{43}^T} \|_F^2 \\ + \| A_{40} \|_F^2 \amp + \| \color{red}{ a_{41}} \|_F^2 \amp + \| A_{42} \|_F^2 \amp + \| \color{red}{ a_{43}} \|_F^2 \amp + \| {\rm off}( A_{44} )\|_F^2. \amp \end{array} \end{array} \end{equation*}

and

\begin{equation*} \begin{array}{l} \| {\rm off}( \widehat A ) \|_F^2 = \\ \begin{array}[t]{lllllll} \phantom{+} \| {\rm off}( A_{00} ) \|_F^2 \amp + \| \color{red}{ \widehat a_{10}} \|_F^2 \amp + \| A_{20}^T \|_F^2 \amp + \| \color{red}{ \widehat a_{30}} \|_F^2 \amp + \| A_{40}^T \|_F^2\\ + \| \color{red}{ \widehat a_{10}^T} \|_F^2 \amp \amp + \| \color{red}{ \widehat a_{21}^T} \|_F^2 \amp + ~~~~~ \color{blue} 0 \amp + \| \color{red}{ \widehat a_{41}^T} \|_F^2\\ + \| A_{20} \|_F^2 \amp + \| \color{red}{ \widehat a_{21}} \|_F^2 \amp + \| {\rm off}( A_{22} ) \|_F^2 \amp + \| \color{red}{ \widehat a_{32}} \|_F^2 \amp \| A_{42}^T \|_F^2\\ + \| \color{red}{ \widehat a_{30}^T} \|_F^2 \amp + ~~~~~ \color{blue} 0 \amp + \| \color{red}{ \widehat a_{32}^T} \|_F^2 \amp \amp + \| \color{red}{ \widehat a_{43}^T} \|_F^2 \\ + \| A_{40} \|_F^2 \amp + \| \color{red}{ \widehat a_{41}} \|_F^2 \amp + \| A_{42} \|_F^2 \amp + \| \color{red}{ \widehat a_{43}} \|_F^2 \amp + \| {\rm off}( A_{44} )\|_F^2. \amp \end{array} \end{array} \end{equation*}

All submatrices in black show up for \(\| {\rm off}( A ) \|_F^2 \) and \(\| {\rm off}( \widehat A ) \|_F^2 \text{.}\) The parts of rows and columns that show up in red and blue is what changes. We argue that the sum of the terms in red are equal for both.

Since a Jacobi rotation is unitary, it preserves the Frobenius norm of the matrix to which it applied. Thus, looking at the rows that are modified by applying \(J^T \) from the left, we find that

\begin{equation*} \begin{array}{l} \phantom{ \left( \begin{array}{c c} \color{blue}{ \gamma_{11}} \amp\color{blue}{ \sigma_{31}} \\ \color{blue}{ -\sigma_{31}} \amp \color{blue}{ \gamma_{33}} \end{array} \right) } \begin{array}{c c c c c } \phantom{+}\| \color{red}{ a_{10}^T} \|_F^2 \amp ~~ \amp + \| \color{red}{ a_{21}^T} \|_F^2 \amp ~~ \amp + \| \color{red}{ a_{41}^T} \|_F^2 \\ + \| \color{red}{ a_{30}^T} \|_F^2 \amp ~~ \amp + \| \color{red}{ a_{32}^T} \|_F^2 \amp ~~ \amp + \| \color{red}{ a_{43}^T} \|_F^2 \end{array} = \\ \phantom{ \left( \begin{array}{c c c c c} \color{blue}{ \gamma_{11}} \amp\color{blue}{ \sigma_{31}} \\ \color{blue}{ -\sigma_{31}} \amp \color{blue}{ \gamma_{33}} \end{array} \right) } \left\| \left( \begin{array}{c | c | c | c | c | c } \color{red}{ a_{10}^T} \amp ~~ \amp \color{red}{ a_{21}^T} \amp ~~ \amp \color{red}{ a_{41}^T} \\ \color{red}{ a_{30}^T} \amp ~~ \amp \color{red}{ a_{32}^T} \amp ~~ \amp \color{red}{ a_{43}^T} \end{array} \right) \right\|_F^2 = \\ \left\| \left( \begin{array}{c c c c c} \color{blue}{ \gamma_{11}} \amp\color{blue}{ \sigma_{31}} \\ \color{blue}{ -\sigma_{31}} \amp \color{blue}{ \gamma_{33}} \end{array} \right) \left( \begin{array}{c | c | c | c | c | c } \color{red}{ a_{10}^T} \amp ~~ \amp \color{red}{ a_{21}^T} \amp ~~ \amp \color{red}{ a_{41}^T} \\ \color{red}{ a_{30}^T} \amp ~~ \amp \color{red}{ a_{32}^T} \amp ~~ \amp \color{red}{ a_{43}^T} \end{array} \right) \right\|_F^2 = \\ \phantom{ \left( \begin{array}{c c c c c} \color{blue}{ \gamma_{11}} \amp\color{blue}{ \sigma_{31}} \\ \color{blue}{ -\sigma_{31}} \amp \color{blue}{ \gamma_{33}} \end{array} \right) } \left\| \left( \begin{array}{c | c | c | c | c | c} \color{red}{ \widehat a_{10}^T} \amp ~~ \amp \color{red}{ \widehat a_{21}^T} \amp ~~ \amp \color{red}{ \widehat a_{41}^T} \\ \color{red}{ \widehat a_{30}^T} \amp ~~ \amp \color{red}{ \widehat a_{32}^T} \amp ~~ \amp \color{red}{ \widehat a_{43}^T} \end{array} \right) \right\|_F^2 = \\ \phantom{ \left( \begin{array}{c c c c c} \color{blue}{ \gamma_{11}} \amp\color{blue}{ \sigma_{31}} \\ \color{blue}{ -\sigma_{31}} \amp \color{blue}{ \gamma_{33}} \end{array} \right) } \begin{array}{c c c c c } \phantom{+} \| \color{red}{ \widehat a_{10}^T} \|_F^2 \amp ~~ \amp + \| \color{red}{ \widehat a_{21}^T} \|_F^2 \amp ~~ \amp + \| \color{red}{ \widehat a_{41}^T} \|_F^2 \\ + \| \color{red}{ \widehat a_{30}^T} \|_F^2 \amp ~~ \amp + \| \color{red}{ \widehat a_{32}^T} \|_F^2 \amp ~~ \amp + \| \color{red}{ \widehat a_{43}^T} \|_F^2 . \end{array} \end{array} \end{equation*}

Similarly, looking at the columns that are modified by applying \(J^T \) from the right, we find that

\begin{equation*} \begin{array}{l} \begin{array}{c c c c c} \phantom{+} \| \color{red}{ a_{10} } \|_F^2 \amp + \| \color{red}{ a_{30} } \|_F^2 \\ ~ \amp ~ \\ + \| \color{red}{ a_{21} } \|_F^2 \amp + \| \color{red}{ a_{32} } \|_F^2 \\ ~ \amp ~ \\ + \| \color{red}{ a_{41} } \|_F^2 \amp + \| \color{red}{ a_{43} } \|_F^2 \end{array} = \left\| \left( \begin{array}{c c c c c} \color{red}{ a_{10} } \amp \color{red}{ a_{30} } \\ \hline ~ \amp ~ \\ \hline \color{red}{ a_{21} } \amp \color{red}{ a_{32} } \\ \hline ~ \amp ~ \\ \hline \color{red}{ a_{41} } \amp \color{red}{ a_{43} } \end{array} \right) \right\|_F^2 \\ = \left\| \left( \begin{array}{c c c c c} \color{red}{ a_{10} } \amp \color{red}{ a_{30} } \\ \hline ~ \amp ~ \\ \hline \color{red}{ a_{21} } \amp \color{red}{ a_{32} } \\ \hline ~ \amp ~ \\ \hline \color{red}{ a_{41} } \amp \color{red}{ a_{43} } \end{array} \right) \left( \begin{array}{c c} \color{blue}{ \gamma_{11}} \amp\color{blue}{ -\sigma_{31}} \\ \color{blue}{ \sigma_{31}} \amp \color{blue}{ \gamma_{33}} \end{array} \right) \right\|_F^2 = \left\| \begin{array}{c c c c c} \color{red}{ \widehat a_{10} } \amp \color{red}{ \widehat a_{30} } \\ \hline ~ \amp ~ \\ \hline \color{red}{ \widehat a_{21} } \amp \color{red}{ \widehat a_{32} } \\ \hline ~ \amp ~ \\ \hline \color{red}{ \widehat a_{41} } \amp \color{red}{ \widehat a_{43} } \end{array} \right\|_F^2 \\ = \begin{array}{c c c c c} \phantom{+} \| \color{red}{ \widehat a_{10} } \|_F^2 \amp + \| \color{red}{ \widehat a_{30} } \|_F^2 \\ ~ \amp ~ \\ + \| \color{red}{ \widehat a_{21} } \|_F^2 \amp + \| \color{red}{ \widehat a_{32} } \|_F^2 \\ ~ \amp ~ \\ + \| \color{red}{ \widehat a_{41} } \|_F^2 \amp + \| \color{red}{ \widehat a_{43} } \|_F^2 . \end{array} \end{array} \end{equation*}

We conclude that

\begin{equation*} {\rm off}( \widehat A ) = {\rm off}( A ) - 2 \alpha_{31}^2. \end{equation*}

From this exercise, we learn:

  • The good news: every time a Jacobi rotation is used to zero an off-diagonal element, \({\rm off} ( A )\) decreases by twice the square of that element.

  • The bad news: a previously introduced zero may become nonzero in the process.

The original algorithm developed by Jacobi searched for the largest (in absolute value) off-diagonal element and zeroed it, repeating this processess until all off-diagonal elements were small. The problem with this is that searching for the largest off-diagonal element in an \(m \times m \) matrix requires \(O( m^2) \) comparisons. Computing and applying one Jacobi rotation as a similarity transformation requires \(O(m) \) flops. For large \(m \) this is not practical. Instead, it can be shown that zeroing the off-diagonal elements by columns (or rows) also converges to a diagonal matrix. This is known as the column-cyclic Jacobi algorithm. Zeroing out every pair of off-diagonal elements once is called a sweep. We illustrate this in Figure 11.3.2.1. Typically only a few sweeps (on the order of five) are needed to converge sufficiently.

\begin{equation*} \begin{array}{c c c c c c c c} \amp \amp \mbox{Sweep 1} \amp \amp \amp \amp \amp\\ \hline \begin{array}{c c c c} \color{red} \times \amp \color{blue} 0 \amp \color{red} \times \amp \color{red} \times \\ \color{blue} 0 \amp \color{red} \times \amp \color{red} \times \amp \color{red} \times \\ \color{red} \times \amp \color{red} \times \amp \times \amp \times \\ \color{red} \times \amp \color{red} \times \amp \times \amp \times \\ \end{array} \amp \rightarrow \amp \begin{array}{c c c c} \color{red} \times \amp \color{red} \times \amp \color{blue} 0 \amp \color{red} \times \\ \color{red} \times \amp \times \amp \color{red} \times \amp \times \\ \color{blue} 0 \amp \color{red} \times \amp \color{red} \times \amp \color{red} \times \\ \color{red} \times \amp \times \amp \color{red} \times \amp \times \\ \end{array} \amp \rightarrow \amp \begin{array}{c c c c} \color{red} \times \amp \color{red} \times \amp \color{red} \times \amp\color{blue} 0 \\ \color{red} \times \amp \times \amp \times \amp \color{red} \times \\ \color{red} \times \amp \times \amp \times \amp \color{red} \times \\ \color{blue} 0 \amp \color{red} \times \amp \color{red} \times \amp \color{red} \times \\ \end{array} \amp \rightarrow \\ % \mbox{zero } (1,0) \amp \amp \mbox{zero } (2,0) \amp \amp \mbox{zero } (3,0) \\ \\ \begin{array}{c c c c} \times \amp \color{red} \times \amp \color{red} \times \amp \times \\ \color{red} \times \amp \color{red} \times \amp \color{blue} 0 \amp \color{red} \times \\ \color{red} \times \amp \color{blue} 0 \amp \color{red} \times \amp \color{red} \times \\ \times \amp \color{red} \times \amp \color{red} \times \amp \times \\ \end{array} \amp \rightarrow \amp \begin{array}{c c c c} \times \amp \color{red} \times \amp \times \amp \color{red} \times \\ \color{red} \times \amp \color{red} \times \amp \color{red} \times \amp\color{blue} 0 \\ \times \amp \color{red} \times \amp \times \amp \color{red} \times \\ \color{red} \times \amp \color{blue} 0 \amp \color{red} \times \amp \color{red} \times \\ \end{array} \amp \rightarrow \amp \begin{array}{c c c c} \times \amp \times \amp \color{red} \times \amp \color{red} \times \\ \times \amp \times \amp \color{red} \times \amp \color{red} \times \\ \color{red} \times \amp \color{red} \times \amp \color{red} \times \amp\color{blue} 0 \\ \color{red} \times \amp \color{red} \times \amp \color{blue} 0 \amp \color{red} \times \\ \end{array} \amp \rightarrow \\ \mbox{zero } (2,1) \amp \amp \mbox{zero } (3,1) \amp \amp \mbox{zero } (3,2) \end{array} \end{equation*}
\begin{equation*} \begin{array}{c c c c c c c c} \amp \amp \mbox{Sweep 2} \amp \amp \amp \amp \amp\\ \hline \begin{array}{c c c c} \color{red} \times \amp \color{blue} 0 \amp \color{red} \times \amp \color{red} \times \\ \color{blue} 0 \amp \color{red} \times \amp \color{red} \times \amp \color{red} \times \\ \color{red} \times \amp \color{red} \times \amp \times \amp \times \\ \color{red} \times \amp \color{red} \times \amp \times \amp \times \\ \end{array} \amp \rightarrow \amp \begin{array}{c c c c} \color{red} \times \amp \color{red} \times \amp \color{blue} 0 \amp \color{red} \times \\ \color{red} \times \amp \times \amp \color{red} \times \amp \times \\ \color{blue} 0 \amp \color{red} \times \amp \color{red} \times \amp \color{red} \times \\ \color{red} \times \amp \times \amp \color{red} \times \amp \times \\ \end{array} \amp \rightarrow \amp \begin{array}{c c c c} \color{red} \times \amp \color{red} \times \amp \color{red} \times \amp\color{blue} 0 \\ \color{red} \times \amp \times \amp \times \amp \color{red} \times \\ \color{red} \times \amp \times \amp \times \amp \color{red} \times \\ \color{blue} 0 \amp \color{red} \times \amp \color{red} \times \amp \color{red} \times \\ \end{array} \amp \rightarrow \\ \mbox{zero } (1,0) \amp \amp \mbox{zero } (2,0) \amp \amp \mbox{zero } (3,0) \\ \\ \begin{array}{c c c c} \times \amp \color{red} \times \amp \color{red} \times \amp \times \\ \color{red} \times \amp \color{red} \times \amp \color{blue} 0 \amp \color{red} \times \\ \color{red} \times \amp \color{blue} 0 \amp \color{red} \times \amp \color{red} \times \\ \times \amp \color{red} \times \amp \color{red} \times \amp \times \\ \end{array} \amp \rightarrow \amp \begin{array}{c c c c} \times \amp \color{red} \times \amp \times \amp \color{red} \times \\ \color{red} \times \amp \color{red} \times \amp \color{red} \times \amp\color{blue} 0 \\ \times \amp \color{red} \times \amp \times \amp \color{red} \times \\ \color{red} \times \amp \color{blue} 0 \amp \color{red} \times \amp \color{red} \times \\ \end{array} \amp \rightarrow \amp \begin{array}{c c c c} \times \amp \times \amp \color{red} \times \amp \color{red} \times \\ \times \amp \times \amp \color{red} \times \amp \color{red} \times \\ \color{red} \times \amp \color{red} \times \amp \color{red} \times \amp\color{blue} 0 \\ \color{red} \times \amp \color{red} \times \amp \color{blue} 0 \amp \color{red} \times \\ \end{array} \amp \rightarrow \\ \mbox{zero } (2,1) \amp \amp \mbox{zero } (3,1) \amp \amp \mbox{zero } (3,2) \end{array} \end{equation*}
Figure 11.3.2.1. Column-cyclic Jacobi algorithm.

We conclude by noting that the matrix \(Q \) such that \(A = Q \Lambda Q^H \) can be computed by accumulating all the Jacobi rotations (applying them to the identity matrix).