SVD: Singular Value Decomposition#
The Singular Value Decomposition (SVD
) solver object can be used for computing a partial SVD of a rectangular matrix, and other related problems. It provides uniform and efficient access to several specific SVD solvers included in SLEPc, and also gives the possibility to compute the decomposition via the eigensolvers provided in the EPS
package.
In many aspects, the user interface of SVD
resembles that of EPS
. For this reason, this chapter and chapter EPS: Eigenvalue Problem Solver have a very similar structure.
Mathematical Background#
This section provides some basic concepts about the singular value decomposition and other related problems. The objective is to set up the notation and also to justify some of the solution approaches, particularly those based on the EPS
object. As in the case of eigensolvers, some of the implemented methods are described in detail in the SLEPc technical reports.
For background material about the SVD, see for instance [Bai et al., 2000, ch. 6]. Many other books such as [Björck, 1996] or [Hansen, 1998] present the SVD from the perspective of its application to the solution of least squares problems and other related linear algebra problems.
The (Standard) Singular Value Decomposition (SVD)#
The singular value decomposition (SVD) of an \(m\times n\) matrix \(A\) can be written as
where \(U=[u_1,\ldots,u_m]\) is an \(m\times m\) unitary matrix (\(U^*U=I\)), \(V=[v_1,\ldots,v_n]\) is an \(n\times n\) unitary matrix (\(V^*V=I\)), and \(\Sigma\) is an \(m\times n\) diagonal matrix with real diagonal entries \(\Sigma_{ii}=\sigma_i\) for \(i=1,\ldots,\min\{m,n\}\). If \(A\) is real, \(U\) and \(V\) are real and orthogonal. The vectors \(u_i\) are called the left singular vectors, the \(v_i\) are the right singular vectors, and the \(\sigma_i\) are the singular values.
Scheme of the thin SVD of a rectangular matrix \(A\).#
In the following, we will assume that \(m\geq n\). If \(m<n\) then \(A\) should be replaced by \(A^*\) (note that in SLEPc this is done transparently as described later in this chapter and the user need not worry about this). In the case that \(m\geq n\), the top \(n\) rows of \(\Sigma\) contain \(\mathrm{diag}(\sigma_1,\ldots,\sigma_n)\) and its bottom \(m-n\) rows are zero. The relation equation (1) may also be written as \(AV=U\Sigma\), or
and also as \(A^*U=V\Sigma^*\), or
The last left singular vectors corresponding to equation (4) are often not computed, especially if \(m\gg n\). In that case, the resulting factorization is sometimes called the thin SVD, \(A=U_n\Sigma_n V_n^*\), and is depicted in figure Scheme of the thin SVD of a rectangular matrix A.. This factorization can also be written as
Each \((\sigma_i,u_i,v_i)\) is called a singular triplet.
The singular values are real and nonnegative, \(\sigma_1\geq\sigma_2\geq\ldots\geq\sigma_r>\sigma_{r+1}=\ldots=\sigma_n=0\), where \(r=\mathrm{rank}(A)\). It can be shown that \(\{u_1,\ldots,u_r\}\) span the range of \(A\), \(\mathcal{R}(A)\), whereas \(\{v_{r+1},\ldots,v_n\}\) span the null space of \(A\), \(\mathcal{N}(A)\).
If the zero singular values are dropped from the sum in equation (5), the resulting factorization, \(A=\sum_{i=1}^{r}\sigma_iu_iv_i^*\), is called the compact SVD, \(A=U_r\Sigma_r V_r^*\).
In the case of a very large and sparse \(A\), it is usual to compute only a subset of \(k\leq r\) singular triplets. We will refer to this decomposition as the truncated SVD of \(A\). It can be shown that the matrix \(A_k=U_k\Sigma_k V_k^*\) is the best rank-\(k\) approximation to matrix \(A\), in the least squares sense.
In general, one can take an arbitrary subset of the summands in equation (5), and the resulting factorization is called the partial SVD of \(A\). As described later in this chapter, SLEPc allows the computation of a partial SVD corresponding to either the \(k\) largest or smallest singular triplets.
Equivalent Eigenvalue Problems#
It is possible to formulate the problem of computing the singular triplets of a matrix \(A\) as an eigenvalue problem involving a Hermitian matrix related to \(A\). There are two possible ways of achieving this:
With the cross product matrix, either \(A^*A\) or \(AA^*\).
With the cyclic matrix, \(H(A)=\left[\begin{smallmatrix}0&A\\A^*&0\end{smallmatrix}\right]\).
In SLEPc, the computation of the SVD is usually based on one of these two alternatives, either by passing one of these matrices to an EPS
object or by performing the computation implicitly.
By pre-multiplying equation (2) by \(A^*\) and then using equation (3), the following relation results
that is, the \(v_i\) are the eigenvectors of matrix \(A^*A\) with corresponding eigenvalues equal to \(\sigma_i^2\). Note that after computing \(v_i\) the corresponding left singular vector, \(u_i\), is readily available through equation (2) with just a matrix-vector product, \(u_i=\frac{1}{\sigma_i}Av_i\).
Alternatively, one could first compute the left vectors and then the right ones. For this, pre-multiply equation (3) by \(A\) and then use equation (2) to get
In this case, the right singular vectors are obtained as \(v_i=\frac{1}{\sigma_i}A^*u_i\).
The two approaches represented in equations (6) and (7) are very similar. Note however that \(A^*A\) is a square matrix of order \(n\) whereas \(AA^*\) is of order \(m\). In cases where \(m\gg n\), the computational effort will favor the \(A^*A\) approach. On the other hand, the eigenproblem equation (6) has \(n-r\) zero eigenvalues and the eigenproblem equation (7) has \(m-r\) zero eigenvalues. Therefore, continuing with the assumption that \(m\geq n\), even in the full rank case the \(AA^*\) approach may have a large null space resulting in difficulties if the smallest singular values are sought. In SLEPc, this will be referred to as the cross product approach and will use whichever matrix is smaller, either \(A^*A\) or \(AA^*\).
Computing the SVD via the cross product approach may be adequate for determining the largest singular triplets of \(A\), but the loss of accuracy can be severe for the smallest singular triplets. The cyclic matrix approach is an alternative that avoids this problem, but at the expense of significantly increasing the cost of the computation. Consider the eigendecomposition of
which is a Hermitian matrix of order \((m+n)\). It can be shown that \(\pm\sigma_i\) is a pair of eigenvalues of \(H(A)\) for \(i=1,\ldots,r\) and the other \(m+n-2r\) eigenvalues are zero. The unit eigenvectors associated with \(\pm\sigma_i\) are \(\frac{1}{\sqrt{2}}\left[\begin{smallmatrix}\pm u_i\\v_i\end{smallmatrix}\right]\). Thus it is possible to extract the singular values and the left and right singular vectors of \(A\) directly from the eigenvalues and eigenvectors of \(H(A)\). Note that in this case the singular values are not squared, and therefore the computed values will be more accurate (especially the small ones). The drawback in this case is that small eigenvalues are located in the interior of the spectrum.
The Generalized Singular Value Decomposition (GSVD)#
An extension of the SVD to the case of two matrices is the generalized singular value decomposition (GSVD), which can be applied in constrained least squares problems, among others. An overview of the problem can be found in [Golub and van Loan, 1996, 8.7.3].
Consider two matrices, \(A\in\mathbb{C}^{m\times n}\) with \(m\geq n\) and \(B\in\mathbb{C}^{p\times n}\). Note that both matrices must have the same column dimension. Then there exist two unitary matrices \(U\in\mathbb{C}^{m\times m}\) and \(V\in\mathbb{C}^{p\times p}\) and an invertible matrix \(X\in\mathbb{C}^{n\times n}\) such that
where \(C=\mathrm{diag}(c_1,\dots,c_n)\) and \(S=\mathrm{diag}(s_{n-q+1},\dots,s_n)\) with \(q=\min(p,n)\). The values \(c_i\) and \(s_i\) are real and nonnegative, and the ratios define the generalized singular values,
and if \(p<n\) we can consider that the first \(n-p\) generalized singular values are infinite, as if \(s_1=\dots=s_{n-p}=0\). Note that if \(B\) is the identity matrix, \(X\) can be taken to be unitary and then we recover the standard SVD, \(\sigma(A,I)=\sigma(A)\), that is why equation (9) is considered a generalization of the SVD.
The diagonal matrices \(C\) and \(S\) satisfy \(C^*C+S^*S=I\), and are related to the CS decomposition [Golub and van Loan, 1996, 2.6.4] associated with the orthogonal factor of the QR factorization of matrices \(A\) and \(B\) stacked, that is, if
then \(C\) and \(S\) can be obtained from the singular values of \(Q_1\) and \(Q_2\), respectively. The matrix \(Z\) is relevant for algorithms and is often built explicitly.
Scheme of the thin GSVD of two matrices \(A\) and \(B\), for the case \(p < n\).#
The above description assumes that matrix \(Z\) has full column rank, and the rank of \(B\) is also \(q\). In the general case where these assumptions do not hold, the structure of matrices \(C\) and \(S\) is a bit more complicated. This includes also the case where \(m<n\). A detailed description of those cases can be found in [Anderson et al., 1999, 2.3.5.3].
As in the case of the SVD, one can consider thin, compact, truncated, and partial versions of the GSVD. A pictorial representation of the thin GSVD is shown in figure Scheme of the thin GSVD of two matrices A and B, for the case p < n..
The columns of \(X\), \(x_i\), are called the (right) generalized singular vectors. The left vectors in this case would correspond to the columns of \(U\) and \(V\). In SLEPc, the user interface will provide these vectors stacked on top of each other, as a single \((m+p)\)-vector \(\begin{bmatrix}u_i\\v_i\end{bmatrix}\).
Equivalent Eigenvalue Problems#
In the GSVD it is also possible to formulate the problem as an eigenvalue problem, which opens the door to approach its solution via EPS
. The columns of \(X\) satisfy
and so if \(s_i\neq 0\) then \(A^*Ax_i=\sigma_i^2B^*Bx_i\), a generalized eigenvalue problem for the matrix pair \((A^*A,B^*B)\). This is the analog of the cross product matrix eigenproblem of equation (6).
The formulation that is analog to the eigenproblem associated with the cyclic matrix equation (8) is to solve the generalized eigenvalue problem defined by any of the matrix pairs
The Hyperbolic Singular Value Decomposition (HSVD)#
The hyperbolic singular value decomposition (HSVD) was introduced in [Onn et al., 1991], motivated by some signal processing applications such as the so-called covariance differencing problem. The formulation of the HSVD is similar to that of the SVD, except that \(U\) is orthogonal with respect to a signature matrix,
where \(\Omega=\mathrm{diag}(\pm 1)\) is an \(m\times m\) signature matrix provided by the user, while \(\tilde\Omega\) is another signature matrix obtained as part of the solution. Sometimes \(U\) is said to be a hyperexchange matrix, or also an \((\Omega,\tilde\Omega)\)-orthogonal matrix. Note that in the problem definition normally found in the literature it is \(V\) that is \((\Omega,\tilde\Omega)\)-orthogonal and not \(U\). We choose this definition for consistency with respect to the generalized HSVD of two matrices. If the user wants to compute the HSVD according to the alternative definition, then it suffices to (conjugate) transpose the input matrix \(A\), using for instance MatHermitianTranspose.
As in the case of the SVD, the solution of the problem consists in singular triplets \((\sigma_i,u_i,v_i)\), with \(\sigma_i\) real and nonnegative and sorted in nonincreasing order. Note that these quantities are different from those of section The (Standard) Singular Value Decomposition (SVD), even though we use the same notation here. With each singular triplet, there is an associated sign \(\tilde\omega_i\) (either 1 or \(-1\)), the corresponding diagonal element of \(\tilde\Omega\). In SLEPc, this value is not returned by the user interface, but if required it can be easily computed as \(u_i^*\Omega u_i\).
The relations between left and right singular vectors are slightly different from those of the standard SVD. We have \(AV=U\Sigma\) and \(A^*\Omega U=V\Sigma^*\tilde\Omega\), so for \(m\geq n\) the following relations hold, together with equation (2):
In SLEPc we will compute a partial HSVD consisting of either the largest or smallest hyperbolic singular triplets. Note that the sign \(\tilde\omega_i\) is not used when sorting for largest or smallest \(\sigma_i\).
Equivalent Eigenvalue Problems#
Once again, we can derive cross and cyclic schemes to compute the decomposition by solving an eigenvalue problem. The cross product matrix approach has two forms, to be selected depending on whether \(m\geq n\) or not, as discussed in section The (Standard) Singular Value Decomposition (SVD). The first form,
is derived by pre-multiplying equation (2) by \(A^*\Omega\) and then using equation (15). This eigenproblem can be solved as a HEP (cf. section Defining the Problem) and may have both positive and negative eigenvalues, corresponding to \(\tilde\omega_i=1\) and \(\tilde\omega_i=-1\), respectively. Once the right vector \(v_i\) has been computed, the corresponding left vector can be obtained using equation (2) with just a matrix-vector product, \(u_i=\sigma_i^{-1}Av_i\).
The second form of cross computes the left vectors first, by pre-multiplying equation (15) by \(A\) and then using equation (2),
In this case, the right singular vectors are obtained as \(v_i=(\sigma_i\tilde\omega_i)^{-1}A^*\Omega u_i\). The coefficient matrix of (18) is non-Hermitian, so the eigenproblem has to be solved as non-Hermitian, or alternatively it can be formulated as a generalized eigenvalue problem of GHIEP type (cf. section Defining the Problem) for the indefinite pencil \((AA^*,\Omega)\),
with \(\hat{u}_i=\Omega u_i\). The eigenvectors obtained from equation (18) or equation (19) must be normalized so that \(U^*\Omega U=\tilde\Omega\) holds.
Finally, in the cyclic matrix approach for the HSVD we must solve a generalized eigenvalue problem defined by the matrices of order \((m+n)\)
As in the case of equation (19), this pencil is Hermitian-indefinite and hence it may have complex eigenvalues. However, it can be shown that nonzero eigenvalues of the pencil \((H(A),\hat\Omega)\) are either real (equal to \(\pm\sigma_i\) for a certain hyperbolic singular value \(\sigma_i\)) or purely imaginary (equal to \(\pm\sigma_ij\) for a certain \(\sigma_i\) with \(j=\sqrt{-1}\)). The associated eigenvectors are \(\left[\begin{smallmatrix}\varsigma_i u_i\\v_i\end{smallmatrix}\right]\), where \(\varsigma_i\) is either \(\pm 1\) or \(\pm j\).
Basic Usage#
From the perspective of the user interface, the SVD
package is very similar to EPS
, with some differences that will be highlighted shortly.
SVD svd; /* SVD solver context */
Mat A; /* problem matrix */
Vec u, v; /* singular vectors */
PetscReal sigma; /* singular value */
PetscInt j, nconv;
PetscReal error;
SVDCreate( PETSC_COMM_WORLD, &svd );
SVDSetOperators( svd, A, NULL );
SVDSetProblemType( svd, SVD_STANDARD );
SVDSetFromOptions( svd );
SVDSolve( svd );
SVDGetConverged( svd, &nconv );
for (j=0; j<nconv; j++) {
SVDGetSingularTriplet( svd, j, &sigma, u, v );
SVDComputeError( svd, j, SVD_ERROR_RELATIVE, &error );
}
SVDDestroy( &svd );
The basic steps for computing a partial SVD with SLEPc are illustrated in figure Example code for basic solution with SVD.. The steps are more or less the same as those described in chapter EPS: Eigenvalue Problem Solver for the eigenvalue problem. First, the solver context is created with SVDCreate
. Then the problem matrices have to be specified with SVDSetOperators
and the type of problem can be selected via SVDSetProblemType
. Then, a call to SVDSolve
invokes the actual solver. After that, SVDGetConverged
is used to determine how many solutions have been computed, which are retrieved with SVDGetSingularTriplet
. Finally, SVDDestroy
gets rid of the object.
If one compares this example code with the EPS
example in figure Example code for basic solution with EPS, the most outstanding differences are the following:
The singular value is a PetscReal, not a PetscScalar.
Each singular vector is defined with a single Vec object, not two as was the case for eigenvectors.
Defining the Problem#
Defining the problem consists in specifying the problem matrix \(A\) (and also a second matrix \(B\) in case of the GSVD), the problem type, and the portion of the spectrum to be computed.
The problem matrices are provided with the following function SVDSetOperators
SVDSetOperators(SVD svd,Mat A,Mat B);
where A
can be any matrix, not necessarily square, stored in any allowed PETSc format including the matrix-free mechanism (see section Supported Matrix Types for a detailed discussion), and B
is generally set to NULL
except in the case of computing the GSVD. If the problem is hyperbolic (section The Hyperbolic Singular Value Decomposition (HSVD)) then in addition a signature matrix \(\Omega\) must be provided with SVDSetSignature
SVDSetSignature(SVD svd,Vec omega);
Note that \(\Omega\) is represented as a vector containing values equal to 1 or \(-1\).
The problem type can be specified with the function SVDSetProblemType
SVDSetProblemType(SVD svd,SVDProblemType type);
Note that in SVD
calling it is currently not strictly required, since the problem type can be deduced from the information passed by the user: if only one matrix is passed to SVDSetOperators
the problem type will default to a standard SVD (or hyperbolic SVD if a signature has been provided), while if two matrices are passed then it defaults to GSVD. Still, it is recommended to always call SVDSetProblemType
. Table Problem types considered in SVD. lists the supported problem types.
Problem Type |
Command line key |
|
---|---|---|
Standard SVD |
|
|
Generalized SVD (GSVD) |
|
|
Hyperbolic SVD (HSVD) |
|
It is important to note that all SVD solvers in SLEPc make use of both \(A\) and \(A^*\), as suggested by the description in section The (Standard) Singular Value Decomposition (SVD). \(A^*\) is not explicitly passed as an argument to SVDSetOperators
, therefore it will have to stem from \(A\). There are two possibilities for this: either \(A\) is transposed explicitly and \(A^*\) is created as a distinct matrix, or \(A^*\) is handled implicitly via MatMultTranspose (or MatMultHermitianTranspose in the complex case) operations whenever a matrix-vector product is required in the algorithm. The default is to build \(A^*\) explicitly, but this behavior can be changed with SVDSetImplicitTranspose
SVDSetImplicitTranspose(SVD svd,PetscBool impl);
In section The (Standard) Singular Value Decomposition (SVD), it was mentioned that in SLEPc the cross product approach chooses the smallest of the two possible cases \(A^*A\) or \(AA^*\), that is, \(A^*A\) is used if \(A\) is a tall, thin matrix (\(m\geq n\)), and \(AA^*\) is used if \(A\) is a fat, short matrix (\(m<n\)). In fact, what SLEPc does internally is that if \(m<n\) the roles of \(A\) and \(A^*\) are reversed. This is equivalent to transposing all the SVD factorization, so left singular vectors become right singular vectors and vice versa. This is actually done in all singular value solvers, not only the cross product approach. The objective is to simplify the number of cases to be treated internally by SLEPc, as well as to reduce the computational cost in some situations. Note that this is done transparently and the user need not worry about transposing the matrix, only to indicate how the transpose has to be handled, as explained above.
The user can specify how many singular values and vectors to compute. The default is to compute only one singular triplet. The function SVDSetDimensions
SVDSetDimensions(SVD svd,PetscInt nsv,PetscInt ncv,PetscInt mpd);
allows the specification of the number of singular values to compute, nsv
. The next argument can be set to prescribe the number of column vectors to be used by the solution algorithm, ncv
, that is, the largest dimension of the working subspace. These two parameters can also be set at run time with the options -svd_nsv
and -svd_ncv
. For example, the command line
$ ./program -svd_nsv 10 -svd_ncv 24
requests 10 singular values and instructs to use 24 column vectors. Note that ncv
must be at least equal to nsv
, although in general it is recommended (depending on the method) to work with a larger subspace, for instance \(\mathtt{ncv}\geq2\cdot\mathtt{nsv}\) or even more. As in the case of the EPS
object, the last argument, mpd
, can be used to limit the maximum dimension of the projected problem, as discussed in section Computing a Large Portion of the Spectrum. Using this parameter is especially important in the case that a large number of singular values are requested.
Command line key |
Sorting criterion |
|
---|---|---|
|
Largest \(\sigma\) |
|
|
Smallest \(\sigma\) |
For the selection of the portion of the spectrum of interest, there are only two possibilities in the case of SVD: largest and smallest singular values, see table Available possibilities for selection of the singular values of interest.. The default is to compute the largest ones, but this can be changed with SVDSetWhichSingularTriplets
SVDSetWhichSingularTriplets(SVD svd,SVDWhich which);
which can also be specified at the command line. This criterion is used both for configuring how the algorithm seeks singular values and also for sorting the computed values. In contrast to the case of EPS
, computing singular values located in the interior part of the spectrum is difficult, the only possibility is to use an EPS
object combined with a spectral transformation (this possibility is explained in detail in the next section). Note that in this case, the value of which
applies to the transformed spectrum.
Using a threshold to specify wanted singular values#
In some applications, the number of wanted singular values is not known a priori. For instance, suppose that matrix \(A\) is known to have low rank, and we want to approximate it by a truncated SVD containing the leading singular values. The goal is to have a good approximation, that is, discard only small singular values. The numerical rank \(k\) might be difficult to estimate, due to discretization error or other reasons. But since we assume that singular values decay abruptly around some unknown value \(k\), we can configure SLEPc to detect this decay.
The threshold \(\delta\) can be set with SVDSetThreshold
SVDSetThreshold(SVD svd,PetscReal thres,PetscBool rel);
When rel
is PETSC_TRUE, the solver will compute \(k\) singular values, with \(\sigma_j\geq\delta\cdot\sigma_1\), for \(j=1,\dots,k-1\), where \(k\) is computed internally. In this case, the threshold is relative to the largest singular value \(\sigma_1\), i.e., the matrix norm. It can be interpreted as a percentage, for instance \(\delta=0.8\) means compute singular values that are at least 80% of the matrix norm. Alternatively, an absolute threshold can be used by setting rel
to PETSC_FALSE
Illustration of threshold usage with the singular values of the rdb200
matrix. The red line represents a threshold of \(\delta=0.8\).#
In the low-rank example suggested above, the singular values will decay fast for a relatively small \(k\), so a relative threshold \(\delta=0.5\) or less could do the job. But care must be taken in matrices whose singular values decay progressively, as in the example of figure Illustration of threshold usage with the singular values of the rdb200
matrix, since a small \(\delta\) would imply computing many singular triplets and hence a very high cost, both computationally and in memory. Since the number of computed singular values is not known a priori, the solver will need to reallocate the basis of vectors internally, to have enough room to accommodate all the singular vectors, so this option must be used with caution to avoid out-of-memory problems. The recommendation is to set the value of ncv
to be larger than the estimated number of singular values, to minimize the number of reallocations. You can also use the nsv
parameter in combination with the threshold to stop in case the number of computed singular triplets exceeds that value.
An absolute threshold is also available when computing smallest singular values, in which case the solver will compute the \(k\) smallest singular values, where \(\sigma_j<\delta\), \(j=n-k+1,\dots,n\).
Selecting the SVD Solver#
The available methods for computing the partial SVD are shown in table List of solvers available in the SVD module. In the column of supported problems, ‘G’ means GSVD and ‘H’ means HSVD (the standard SVD is supported by all solvers).. These methods can be classified in the following categories:
Solvers based on
EPS
. These solvers set up anEPS
object internally, thus using the available eigensolvers for solving the SVD problem. The two possible approaches in this case are the cross product matrix and the cyclic matrix, as described in section Mathematical Background.Specific SVD solvers. These are typically eigensolvers that have been adapted algorithmically to exploit the structure of the SVD or GSVD problems. There are two Lanczos-type solvers in this category: Lanczos and thick-restart Lanczos, see Hernandez et al. [2007] for a detailed description of these methods. In this category, we could also add the randomized SVD (RSVD), a special solver that does not compute individual singular vectors accurately, but rather a low-rank approximation of \(A\) by means of randomized techniques.
The LAPACK solver. This is an interface to some LAPACK routines, analog of those in the case of eigenproblems. These routines operate in dense mode with only one processor and therefore are suitable only for moderate size problems. This solver should be used only for debugging purposes.
External packages: ScaLAPACK and ELEMENTAL are dense packages and compute the complete SVD, while PRIMME offers Davidson-type methods to compute only a few singular triplets.
The default solver is the one that uses the cross product matrix (cross
), usually the fastest and most memory-efficient approach, at least for the standard SVD. See a more detailed explanation below.
Method |
Options Database Name |
Supported Problems |
Default |
|
---|---|---|---|---|
Cross Product |
|
|
G,H |
\(\star\) |
Cyclic Matrix |
|
|
G,H |
|
Lanczos |
|
|
||
Thick-restart Lanczos |
|
|
G,H |
|
Randomized SVD (RSVD) |
|
|
||
LAPACK solver |
|
|
G |
|
Wrapper to ScaLAPACK |
|
|
||
Wrapper to KSVD |
|
|
||
Wrapper to ELEMENTAL |
|
|
||
Wrapper to PRIMME |
|
|
The solution method can be specified procedurally or via the command line. The application programmer can set it by means of the command SVDSetType
SVDSetType(SVD svd,SVDType method);
while the user writes the options database command -svd_type
followed by the name of the method (see table List of solvers available in the SVD module. In the column of supported problems, ‘G’ means GSVD and ‘H’ means HSVD (the standard SVD is supported by all solvers).).
Note that not all solvers in the SVD
module support non-standard problems (sections The Generalized Singular Value Decomposition (GSVD)-The Hyperbolic Singular Value Decomposition (HSVD)). Table List of solvers available in the SVD module. In the column of supported problems, ‘G’ means GSVD and ‘H’ means HSVD (the standard SVD is supported by all solvers). indicates which solvers can be used for these.
The EPS
-based solvers deserve some additional comments. These SVD solvers work by creating an EPS
object internally and setting up an eigenproblem of type EPS_HEP
(or EPS_GHEP
in the case of the GSVD, or EPS_GHIEP
in the case of the HSVD). These solvers implement the cross product matrix and the cyclic matrix approaches as described in section Mathematical Background. Therefore, the operator matrix associated with the EPS
object will be \(A^*A\) in the case of the cross
solver and \(H(A)\) in the case of the cyclic
solver (with variations in the case of non-standard problems).
In the case of the cross
solver, the matrix \(A^*A\) is not built explicitly by default, since the resulting matrix may be much less sparse than the original matrix. By default, a shell matrix is created internally in the SVD
object and passed to the EPS
object. Still, the user may choose to force the computation of \(A^*A\) explicitly, by means of PETSc’s sparse matrix-matrix product subroutines. This is set with SVDCrossSetExplicitMatrix
SVDCrossSetExplicitMatrix(SVD svd,PetscBool explicit);
In the cyclic
solver the user can also choose between handling \(H(A)\) implicitly as a shell matrix (the default), or forming it explicitly, that is, storing its elements in a distinct matrix. The function for setting this option is SVDCyclicSetExplicitMatrix
SVDCyclicSetExplicitMatrix(SVD svd,PetscBool explicit);
The EPS
object associated with the cross
and cyclic
SVD solvers is created with a set of reasonable default parameters. However, it may sometimes be necessary to change some of the EPS
options such as the eigensolver. To allow application programmers to set any of the EPS
options directly within the code, the following routines are provided to extract the EPS
context from the SVD
object, SVDCrossGetEPS
SVDCyclicGetEPS
SVDCrossGetEPS(SVD svd,EPS *eps);
SVDCyclicGetEPS(SVD svd,EPS *eps);
A more convenient way of changing EPS
options is through the command-line. This is achieved simply by prefixing the EPS
options with -svd_cross_
or -svd_cyclic_
as in the following example:
$ ./program -svd_type cross -svd_cross_eps_type gd
At this point, one may consider changing also the options of the ST
object associated with the EPS
object in cross
and cyclic
SVD solvers, for example to compute singular values located at the interior of the spectrum via a shift-and-invert transformation. This is indeed possible, but some considerations have to be taken into account. When \(A^*A\) or \(H(A)\) are managed as shell matrices, then the potential of the spectral transformation is limited seriously, because some of the required operations will not be defined if working with implicit matrices (this is discussed briefly in sections Supported Matrix Types and Explicit Computation of Coefficient Matrix). The following example illustrates the computation of interior singular values with the cyclic
solver with explicit \(H(A)\) matrix:
$ ./program -svd_type cyclic -svd_cyclic_explicitmatrix
-svd_cyclic_st_type sinvert -svd_cyclic_eps_target 12.0
-svd_cyclic_st_ksp_type preonly -svd_cyclic_st_pc_type lu
Similarly, in the case of GSVD the thick-restart Lanczos solver uses a KSP solver internally, that can be configured by accessing it with SVDTRLanczosGetKSP
SVDTRLanczosGetKSP(SVD svd,KSP *ksp);
or with the corresponding command-line options prefixed with -svd_trlanczos_
. This KSP object is used to solve a linear least squares problem at each Lanczos step with coefficient matrix \(Z\) equation (11), which by default is a shell matrix but the user can choose to create it explicitly with the function SVDTRLanczosSetExplicitMatrix
.
Retrieving the Solution#
Once the call to SVDSolve
is complete, all the data associated with the computed partial SVD is kept internally in the SVD
object. This information can be obtained by the calling program by means of a set of functions described below.
As in the case of eigenproblems, the number of computed singular triplets depends on the convergence and, therefore, it may be different from the number of solutions requested by the user. So the first task is to find out how many solutions are available, with SVDGetConverged
SVDGetConverged(SVD svd,PetscInt *nconv);
Usually, the number of converged solutions, nconv
, will be equal to nsv
, but in general it can be a number ranging from 0 to ncv
(here, nsv
and ncv
are the arguments of function SVDSetDimensions
).
Normally, the user is interested in the singular values only, or the complete singular triplets. The function SVDGetSingularTriplet
SVDGetSingularTriplet(SVD svd,PetscInt j,PetscReal *sigma,Vec u,Vec v);
returns the \(j\)-th computed singular triplet, \((\sigma_j,u_j,v_j)\), where both \(u_j\) and \(v_j\) are normalized to have unit norm[1]. Typically, this function is called inside a loop for each value of j
from 0 to nconv
–1. Note that singular values are ordered according to the same criterion specified with function SVDSetWhichSingularTriplets
for selecting the portion of the spectrum of interest.
In some applications, it may be enough to compute only the right singular vectors. This is especially important in cases in which memory requirements are critical (remember that both \(U_k\) and \(V_k\) are dense matrices, and \(U_k\) may require much more storage than \(V_k\), see figure Scheme of the thin SVD of a rectangular matrix A.). In SLEPc, there is no general option for specifying this, but the default behavior of some solvers is to compute only right vectors and allocate/compute left vectors only in the case that the user requests them. This is done in the cross
solver and in some special variants of other solvers such as one-sided Lanczos (consult the Hernandez et al. [2007] technical report for specific solver options).
In the case of the GSVD, the sigma
argument of SVDGetSingularTriplet
contains \(\sigma_i=c_i/s_i\) and the second Vec argument (v
) contains the right singular vectors (\(x_i\)), while the first Vec argument (u
) contains the other vectors of the decomposition stacked on top of each other, as a single \((m+p)\)-vector: \(\left[\begin{smallmatrix}u_i\\v_i\end{smallmatrix}\right]\).
Reliability of the Computed Solution#
In SVD computations, a-posteriori error bounds are much the same as in the case of Hermitian eigenproblems, due to the equivalence discussed in section The (Standard) Singular Value Decomposition (SVD). The residual vector is defined in terms of the cyclic matrix, \(H(A)\), so its norm is
where \(\tilde{\sigma}\), \(\tilde{u}\) and \(\tilde{v}\) represent any of the nconv
computed singular triplets delivered by SVDGetSingularTriplet
.
Given the above definition, the following relation holds
where \(\sigma\) is an exact singular value. The associated error can be obtained in terms of \(\|r_\mathrm{SVD}\|_2\) with the following function: SVDComputeError
SVDComputeError(SVD svd,PetscInt j,SVDErrorType type,PetscReal *error);
In the case of the GSVD, the function SVDComputeError
will compute a residual norm based on the two relations equation (9),
where \(\tilde{x}\), \(\tilde{u}\), \(\tilde{v}\) are the computed singular vectors corresponding to \(\tilde{\sigma}\), and \(\tilde{c}\), \(\tilde{s}\) are obtained from \(\tilde{\sigma}\) as \(\tilde{s}=1/\sqrt{1+\tilde{\sigma}^2}\) and \(\tilde{c}=\tilde{\sigma}\tilde{s}\). See [Alvarruiz et al., 2024] for details.
Similarly, in the HSVD we employ a modified residual
where \(\tilde\omega\) is the corresponding element of the signature \(\tilde\Omega\) of the definition equation (14).
Controlling and Monitoring Convergence#
Similarly to the case of eigensolvers, in SVD
the number of iterations carried out by the solver can be determined with SVDGetIterationNumber
, and the tolerance and maximum number of iterations can be set with SVDSetTolerances
. Also, convergence can be monitored with command-line keys -svd_monitor
, -svd_monitor_all
, -svd_monitor_conv
, or graphically with -svd_monitor draw::draw_lg
, or alternatively with -svd_monitor_all draw::draw_lg
. See section Controlling and Monitoring Convergence for additional details.
Convergence criterion |
Command line key |
Error bound |
|
---|---|---|---|
Absolute |
|
\(|r|\) |
|
Relative to eigenvalue |
|
\(|r|/|\lambda|\) |
|
Relative to matrix norms |
|
\(|r|/|Z|\) |
|
Fixed number of iterations |
|
\(\infty\) |
|
User-defined |
|
user function |
As in the case of eigensolvers, the user can choose different convergence tests, based on an error bound obtained from the computed residual norm, \(\|r\|\). Table Available possibilities for the convergence criterion, with Z=A in the standard SVD or as defined in equation eq:qr for the GSVD. lists the available options. It is worth mentioning the SVD_CONV_MAXIT
convergence criterion, which is a bit special. With this criterion, the solver will not compute any residual norms and will stop with a successful status when the maximum number of iterations is reached. This is intended for the SVDRANDOMIZED
solver in cases when a low-rank approximation of a matrix needs to be computed instead of accurate singular vectors.
Viewing the Solution#
There is support for different kinds of viewers for the solution, as in the case of eigensolvers. One can for instance use -svd_view_values
, -svd_view_vectors
, -svd_error_relative
, or -svd_converged_reason
. See the description in section Viewing the Solution.
Footnotes
F. Alvarruiz, C. Campos, and J. E. Roman. Thick-restarted joint Lanczos bidiagonalization for the GSVD. Journal of Computational and Applied Mathematics, 440:115506, 2024. doi:10.1016/j.cam.2023.115506.
E. Anderson, Z. Bai, C. Bischof, L. S. Blackford, J. Demmel, J. Dongarra, J. Du Croz, A. Greenbaum, S. Hammarling, A. McKenney, and D. Sorensen. LAPACK Users' Guide. Society for Industrial and Applied Mathematics, Philadelphia, PA, third edition, 1999.
Z. Bai, J. Demmel, J. Dongarra, A. Ruhe, and H. van der Vorst, editors. Templates for the Solution of Algebraic Eigenvalue Problems: A Practical Guide. Society for Industrial and Applied Mathematics, Philadelphia, PA, 2000.
Å. Björck. Numerical Methods for Least Squares Problems. Society for Industrial and Applied Mathematics, Philadelphia, 1996.
G. H. Golub and C. F. van Loan. Matrix Computations. The Johns Hopkins University Press, Baltimore, MD, third edition, 1996.
Per Christian Hansen. Rank-Deficient and Discrete Ill-Posed Problems: Numerical Aspects of Linear Inversion. Society for Industrial and Applied Mathematics, Philadelphia, PA, 1998.
V. Hernandez, J. E. Roman, and A. Tomas. Restarted Lanczos Bidiagonalization for the SVD in SLEPc. Technical Report STR-8, Universitat Politècnica de València, 2007. Available at https://slepc.upv.es.
R. Onn, A. O. Steinhardt, and A. Bojanczyk. The hyperbolic singular value decomposition and applications. IEEE Transactions on Signal Processing, 39(7):1575–1588, 1991. doi:10.1109/78.134396.