Eigenvalue extraction with QR decomposition

Let M be a symmetric matrix (this is rather important). Perform a QR decomposition M=Q R, and create a new matrix

    \[M'=RQ\]

note that the order of the factors is reversed. It was noted that the off-diagonal matrix elements shrink in the process, but of course the eigenvalues and determinant are unchanged, since

    \[M'=RQ=(Q^TQ) RQ=Q^T(QR)Q=Q^T M Q=Q^{-1}MQ\]

and we know that orthogonal transformations do not alter the eigenvalues, and a matrix can be diagonalized by repeated orthogonal transformation.
Now QR decompose M' into M'=Q'R' and construct

    \[M''=R'Q'\]

Then

    \[M''=Q'^{-1} M' Q', \qquad M''=Q'^{-1} Q^{-1} M Q Q'=(QQ')^{-1} M (QQ')\]

This process can be continued, and under the right set of conditions (if M was a symmetric matrix), one eventually reaches a transformed M^{'\cdots '} that is approaching a diagonalized or triangularized state, as the off-diagonal (above, below the main diagonal or both) elements shrink to below machine precision. This is one of the most powerful and general diagonalization algorithms ever discovered.

The QR algorithm for eigenvalue extraction for a symmetric matrix is a repeated QR decomposition followed by a matrix multiplication

\bullet Perform the QR decomposition of M = M_0= Q_0R_0
\bullet create M_1=R_0 Q_0
\bullet Perform the QR decomposition of M_1= Q_1R_1
\bullet create M_2=R_1 Q_1
\bullet Continue this process: M_n=R_{n-1}Q_n and stop the process when the matrix elements of M_n below the main diagonal are smaller than \epsilon, or after N iterations.

# in julia, using CUDA to load onto the gpu
# use the QR decomposition in the LinearAlgebra library
using LinearAlgebra
using CUDA
# try it on a 256x256 array
b=rand(256,256);
b=b+b';
B=CuArray(b);
for j in 1:600
QR=qr(B)
B=QR.R * CuArray(QR.Q)
end
collect(B[j,j] for j in 1:256)
# Full eigenvalue extraction to 64 bits in 28 seconds on jetson nano

The only way to speed this up is to do it on the gpu, or to diminish the size of the matrix as you procede (deflation), or to improve convergence by shifting. Let I be the unit matrix

\bullet Create an empty list of eigenvalues.
\bullet Let c be the lower right corner diagonal entry of M and I be the unit matrix. Perform the QR decomposition of M-c_0I=Q_0R_0
\bullet Make M_1=R_0 Q_0+cI
\bullet Let c be the lower right corner diagonal entry of M_1. Perform the QR decomposition of M_1-cI=Q_1R_1
\bullet Make M_2=R_1 Q_1+cI
\bullet Continue this process until you get to some level M_m such that all matrix elements in the last row of M_m except for the one on the diagonal, the rightmost element, are smaller than \epsilon. Then add this last row rightmost element of M_m to the list of eigenvalues.
\bulletForm M'_m by removing the last row and column from M_m, and repeat the whole
process on the smaller array.
\bullet Do this until the array is deflated to a 1\times 1, then add its only element to the eigenvalue list.

# Implementation in R using Rmpfr multiple precision arrays
eigenval <- function(M,precision,iters){
  N <- ncol(M)
  cp <- Rmpfr::mpfrArray(rep(0,N^2),prec=64, dim = c(N, N))
  cp <- M
  eigs <- c()
  for (j in 1:iters){
    if (N==1){eigs <- c(eigs,cp)
              break}
    c<- cp[N,N]
    for (k in 1:N){cp[k,k]<- cp[k,k]-c}
    qr <- QR(cp)
    cp <- qrr%*%qrq
    for (k in 1:N){cp[k,k]<- cp[k,k]+c}
    if (max(abs(cp[N,-N]))<=precision) {
       eigs <- c(eigs,cp[N,N])
       cpn <- Rmpfr::mpfrArray(rep(0,(N-1)^2),prec=64, dim = c(N-1, N-1))
       cpn<- cp[1:(N-1),1:(N-1)]
       cp<- cpn
       N<-N-1 }
    }
    return(eigs)
    }

Convert this to julia and run it on the gpu, and we diagonalize the 256x256 in 2 seconds.

Any matrix M can be factored

    \[M=Q\cdot R\]

into the product of an orthogonal matrix Q and an upper-triangular matrix R, and Gram-Schmidt points the way. Think of it like this: the rows or columns of a non-singular matrix (one whose determinant is not zero) are a set of linearly independent vectors. These vectors can be transformed into a set of orthogonal unit vectors via GS.

Let’s do it then: start out with two linearly independent vectors \mathbf{u}_1=\left(\begin{array}{c} a\\ b\end{array}\right) and \mathbf{u}_2=\left(\begin{array}{c} c\\ d\end{array}\right) and create a matrix M=(\mathbf{u}_1, \mathbf{u}_2). Lets pick \mathbf{u}_1 and normalize it, r_1=|\mathbf{u}_1|=\sqrt{a^2+b^2} and use the result as \mathbf{v}_1={\mathbf{u}_1\over r_1}

    \[M=(\mathbf{u}_1, \mathbf{u}_2)=\left(\begin{array}{cc} a & c\\ b & d\end{array}\right)=\left(\begin{array}{cc} v_{11} & c\\ v_{12} & d\end{array}\right)\left(\begin{array}{cc} r_1 & 0\\ 0 & 1\end{array}\right)\]

Note that

(1)   \begin{eqnarray*}\left(\begin{array}{cc} a & c\\ b & d\end{array}\right)&=&\left(\begin{array}{cc} r_1 v_{11} & c\\ r_1 v_{12} & d\end{array}\right)\nonumber\\ &=&\left(\begin{array}{cc} v_{11} & c\\ v_{12} & d\end{array}\right)\left(\begin{array}{cc} r_1 & 0\\ 0 & 1\end{array}\right)\nonumber\\ &=&\left(\begin{array}{cc} v_{11} & c-a_1 v_{11}\\ v_{12} & d-a_1 v_{12}\end{array}\right)\left(\begin{array}{cc} 1 & a_1\\ 0 & 1\end{array}\right)\left(\begin{array}{cc} r_1 & 0\\ 0 & 1\end{array}\right), \quad \mbox{for any $a_1$}\end{eqnarray*}

so we pick a_1=\mathbf{u}_2\cdot\mathbf{v}_1. Note that the second column of the new matrix is \perp to the first column, so it must be r_2 \, \mathbf{v}_2, where r_2=|\mathbf{u}_2-a_1 \mathbf{v}_1|

(2)   \begin{eqnarray*}\left(\begin{array}{cc} a & c\\ b & d\end{array}\right)&=&\left(\begin{array}{cc} v_{11} & c-a_1 v_{11}\\ v_{12} & d-a_1 v_{12}\end{array}\right)\left(\begin{array}{cc} 1 & a_1\\ 0 & 1\end{array}\right)\left(\begin{array}{cc} r_1 & 0\\ 0 & 1\end{array}\right)\nonumber\\ &=&\left(\begin{array}{cc} v_{11} & v_{21}\\ v_{12} & v_{22}\end{array}\right)\left(\begin{array}{cc} 1 & 0\\ 0 & r_2\end{array}\right)\left(\begin{array}{cc} 1 & a_1\\ 0 & 1\end{array}\right)\left(\begin{array}{cc} r_1 & 0\\ 0 & 1\end{array}\right)\nonumber\\  \left(\begin{array}{cc} a & c\\ b & d\end{array}\right)&=&\left(\begin{array}{cc} v_{11} & v_{21}\\ v_{12} & v_{22}\end{array}\right)\left(\begin{array}{cc} r_1 & a_1\\ 0 & r_2\end{array}\right)\end{eqnarray*}

We began with an arbitrary matrix M and decomposed it into a product of an orthogonal matrix Q (made of orthogonal unit vectors \mathbf{v}_i) and an upper-triangular matrix R.

Let’s do it for three linearly independent vectors \mathbf{u}_1, \mathbf{u}_2,and \mathbf{u}_3, and make a matrix M out of them

    \[M=(\mathbf{u}_1, \mathbf{u}_2, \mathbf{u}_3)=\left(\begin{array}{ccc} u_{11} & u_{21} & u_{31}\\ u_{12} & u_{22} & u_{32}\\ u_{13} & u_{23} & u_{33}\end{array}\right)\]

Stage 0. Let r_1=|\mathbf{u}_1|, then

    \[M=(\mathbf{u}_1, \mathbf{u}_2, \mathbf{u}_3)=\left(\begin{array}{ccc} v_{11} & u_{21} & u_{31}\\ v_{12} & u_{22} & u_{32}\\ u_{13} & u_{23} & u_{33}\end{array}\right)\left(\begin{array}{ccc} r_1 & 0 & 0\\ 0 & 1 & 0\\ 0 & 0 & 1\end{array}\right)\]

Stage 1. Let a_1=\mathbf{v}_1\cdot\mathbf{u}_2, then

    \[M=(\mathbf{u}_1, \mathbf{u}_2, \mathbf{u}_3)=\left(\begin{array}{ccc} v_{11} & u_{21}-a_1v_{11} & u_{31}\\ v_{12} & u_{22}-a_1 v_{12} & u_{32}\\ u_{13} & u_{23}-a_1 v_{13} & u_{33}\end{array}\right)\left(\begin{array}{ccc} 1 & a_1 & 0\\ 0 & 1 & 0\\ 0 & 0 & 1\end{array}\right)\left(\begin{array}{ccc} r_1 & 0 & 0\\ 0 & 1 & 0\\ 0 & 0 & 1\end{array}\right)\]

let r_2=|\mathbf{u}_2-a_1 \mathbf{v}_1|, and \mathbf{v}_2={\mathbf{u}_2-a_1 \mathbf{v}_1\over r_2};

    \[M=\left(\begin{array}{ccc} v_{11} & v_{21} & u_{31}\\ v_{12} & v_{22} & u_{32}\\ u_{13} & v_{23} & u_{33}\end{array}\right)\left(\begin{array}{ccc} 1 & 0 & 0\\ 0 & r_2 & 0\\ 0 & 0 & 1\end{array}\right)\left(\begin{array}{ccc} 1 & a_1 & 0\\ 0 & 1 & 0\\ 0 & 0 & 1\end{array}\right)\left(\begin{array}{ccc} r_1 & 0 & 0\\ 0 & 1 & 0\\ 0 & 0 & 1\end{array}\right)\]

Final stage, let a_2=\mathbf{v}_1\cdot \mathbf{u}_3, and a_3=\mathbf{v}_2\cdot \mathbf{u}_3

    \[M=\left(\begin{array}{ccc}  v_{11} & v_{21} & u_{31}-a_2 v_{11}-a_3 v_{21}\\ v_{12} & v_{22} & u_{32}-a_2 v_{12}-a_3 v_{22}\\  u_{13} & v_{23} & u_{33}-a_2 v_{13}-a_3 v_{23}\end{array}\right)\left(\begin{array}{ccc} 1 & 0 & a_2\\ 0 & 1 & a_3\\ 0 & 0 & 1\end{array}\right)\]

    \[\cdot\left(\begin{array}{ccc} 1 & 0 & 0\\ 0 & r_2 & 0\\ 0 & 0 & 1\end{array}\right)\left(\begin{array}{ccc} 1 & a_1 & 0\\ 0 & 1 & 0\\ 0 & 0 & 1\end{array}\right)\left(\begin{array}{ccc} r_1 & 0 & 0\\ 0 & 1 & 0\\ 0 & 0 & 1\end{array}\right)\]

Call r_3=|\mathbf{u}_3-a_2 \mathbf{v}_1-a_3 \mathbf{v}_2|, and \mathbf{v}_3={\mathbf{u}_3-a_2 \mathbf{v}_1-a_3 \mathbf{v}_2\over r_3};

    \[M=\left(\begin{array}{ccc}  v_{11} & v_{21} & v_{31}\\ v_{12} & v_{22} & v_{32}\\  u_{13} & v_{23} & v_{33}\end{array}\right)\left(\begin{array}{ccc} 1 & 0 & 0\\ 0 & 1 & 0\\ 0 & 0 & r_3\end{array}\right)\left(\begin{array}{ccc} 1 & 0 & a_2\\ 0 & 1 & a_3\\ 0 & 0 & 1\end{array}\right)\]

    \[\cdot\left(\begin{array}{ccc} 1 & 0 & 0\\ 0 & r_2 & 0\\ 0 & 0 & 1\end{array}\right)\left(\begin{array}{ccc} 1 & a_1 & 0\\ 0 & 1 & 0\\ 0 & 0 & 1\end{array}\right)\left(\begin{array}{ccc} r_1 & 0 & 0\\ 0 & 1 & 0\\ 0 & 0 & 1\end{array}\right)\]

if you multiply it all out

    \[M=\left(\begin{array}{ccc}  v_{11} & v_{21} & v_{31}\\ v_{12} & v_{22} & v_{32}\\  u_{13} & v_{23} & v_{33}\end{array}\right)\left(\begin{array}{ccc} r_1 & a_1 & a_2\\ 0 & r_2 & a_3\\ 0 & 0 & r_3\end{array}\right)\]

a full QR decomposition of our original arbitrary 3\times 3 matrix.

Home 2.0
error: Content is protected !!