combination of both to produce a decomposition $B = U_B \Sigma V_B^T$. The complete SVD is then determined as $A = (Q_U U_B) 
\Sigma (Q_V V_B)^T$ during the backward transformation. These methods require significant algorithmic and programming effort to become robust and efficient while still suffering from a loss of relative accuracy [@demmel1992jacobi].

An alternative is the one-sided Jacobi method where all $n(n-1)/2$ pairs of columns are repeatedly orthogonalized in sweeps using plane rotations until all columns are mutually orthogonal. When the process converges (i.e., all columns are mutually orthogonal up to machine precision), the left singular vectors are the normalized columns of the modified matrix with the singular values as the norms of those columns. The right singular vectors can be computed either by accumulating the rotations or by solving a system of equations. Our application does not need the right vectors, so we omit the details of computing them. Algorithm \[alg:jacobi\] describes the one-sided Jacobi method. Since each pair of columns can be orthogonalized independently, the method is also easily parallelized. The simplicity and inherent parallelism of the method make it an attractive first choice for an implementation on the GPU.

\[b\]

$G = A_{ij}^T A_{ij}$ \[alg:jacobi:gram\] $R 