Eigen-Contrib  5.0.1
 
Loading...
Searching...
No Matches
Eigen::DiagonalPlusLowRank< Scalar_, Size_, Rank_ > Class Template Reference

#include <contrib/Eigen/src/StructuredMatrices/DiagonalPlusLowRank.h>

Detailed Description

template<typename Scalar_, int Size_, int Rank_>
class Eigen::DiagonalPlusLowRank< Scalar_, Size_, Rank_ >

An n x n operator \( D + U V^H \): a diagonal matrix plus a rank-k correction, stored as its diagonal and the two n x k factors.

Products cost O(nk) instead of O(n^2). Linear systems are solved in O(nk^2) through the Woodbury identity [1] \( (D + UV^H)^{-1} = D^{-1} - D^{-1} U (I_k + V^H D^{-1} U)^{-1} V^H D^{-1} \), factoring only the k x k capacitance matrix (solve). The determinant follows from the matrix determinant lemma [2] \( \det(D)\,\det(I_k + V^H D^{-1} U) \) (determinant), and the class is closed under inverse, transpose, conjugate and adjoint.

The rank-k correction may have k = 0 (a plain diagonal operator). k is not required to be small, but every advantage over a dense matrix vanishes as k approaches n.

The operator stores its own copies of the diagonal and the factors and derives from EigenBase. Because operator* returns an Eigen product expression, a DiagonalPlusLowRank also drops into the matrix-free iterative solvers, and it can be assigned to a dense matrix when an explicit representation is needed. As with any matrix-free operator, the iterative solvers must be instantiated with IdentityPreconditioner (e.g. GMRES<DiagonalPlusLowRank<double>,IdentityPreconditioner>): the default preconditioners read individual coefficients through col() or InnerIterator, which the structured operators do not expose.

Template Parameters
Scalar_the scalar type, real or complex.
Size_the dimension at compile time, or Dynamic (the default).
Rank_the correction rank at compile time, or Dynamic (the default).
See also
makeDiagonalPlusLowRank()
+ Inheritance diagram for Eigen::DiagonalPlusLowRank< Scalar_, Size_, Rank_ >:

Public Member Functions

DiagonalPlusLowRank adjoint () const
 
CapacitanceType capacitance () const
 
Scalar coeff (Index row, Index col) const
 
DiagonalPlusLowRank conjugate () const
 
Index correctionRank () const
 
Scalar determinant () const
 
const DiagonalVector & diagonal () const
 
template<typename DDerived, typename UDerived, typename VDerived>
 DiagonalPlusLowRank (const MatrixBase< DDerived > &d, const MatrixBase< UDerived > &U, const MatrixBase< VDerived > &V)
 
const FactorType & factorU () const
 
const FactorType & factorV () const
 
DiagonalPlusLowRank inverse () const
 
template<typename Rhs>
Product< DiagonalPlusLowRank, Rhs > operator* (const MatrixBase< Rhs > &v) const
 
template<typename Rhs>
Matrix< Scalar, Size_, Rhs::ColsAtCompileTime > solve (const MatrixBase< Rhs > &b) const
 
DiagonalPlusLowRank transpose () const
 

Constructor & Destructor Documentation

◆ DiagonalPlusLowRank()

template<typename Scalar_, int Size_, int Rank_>
template<typename DDerived, typename UDerived, typename VDerived>
Eigen::DiagonalPlusLowRank< Scalar_, Size_, Rank_ >::DiagonalPlusLowRank ( const MatrixBase< DDerived > & d,
const MatrixBase< UDerived > & U,
const MatrixBase< VDerived > & V )
inline

Builds the operator diag(d) + U*V.adjoint(). The factors must have the same number of columns (the correction rank k, possibly zero) and as many rows as d has entries.

Member Function Documentation

◆ adjoint()

template<typename Scalar_, int Size_, int Rank_>
DiagonalPlusLowRank Eigen::DiagonalPlusLowRank< Scalar_, Size_, Rank_ >::adjoint ( ) const
inline
Returns
the adjoint of *this, itself a DiagonalPlusLowRank operator: \( (D + UV^H)^H = \bar D + V U^H \).

◆ capacitance()

template<typename Scalar_, int Size_, int Rank_>
CapacitanceType Eigen::DiagonalPlusLowRank< Scalar_, Size_, Rank_ >::capacitance ( ) const
inline
Returns
the capacitance matrix \( I_k + V^H D^{-1} U \) of the Woodbury identity. Every consumer of the triple product – solve, inverse and determinant – forms it through this one method. With extreme factor magnitudes the product can overflow even when the capacitance itself is representable.
Warning
The diagonal must have no zero entries.

◆ coeff()

template<typename Scalar_, int Size_, int Rank_>
Scalar Eigen::DiagonalPlusLowRank< Scalar_, Size_, Rank_ >::coeff ( Index row,
Index col ) const
inline
Returns
the coefficient at row row and column col.

◆ conjugate()

template<typename Scalar_, int Size_, int Rank_>
DiagonalPlusLowRank Eigen::DiagonalPlusLowRank< Scalar_, Size_, Rank_ >::conjugate ( ) const
inline
Returns
the complex conjugate of *this, itself a DiagonalPlusLowRank operator.

◆ correctionRank()

template<typename Scalar_, int Size_, int Rank_>
Index Eigen::DiagonalPlusLowRank< Scalar_, Size_, Rank_ >::correctionRank ( ) const
inline
Returns
the correction rank k.

◆ determinant()

template<typename Scalar_, int Size_, int Rank_>
Scalar Eigen::DiagonalPlusLowRank< Scalar_, Size_, Rank_ >::determinant ( ) const
inline
Returns
the determinant through the matrix determinant lemma [2]: \( \det(D)\,\det(I_k + V^H D^{-1} U) \), in O(nk^2 + k^3) operations. Both factors are accumulated in the balanced form m * 2^e (the split fraction/exponent determinant convention of LINPACK's xGEDI [3]) – the diagonal entries and the LU pivots of the capacitance matrix are renormalized to unit magnitude one at a time [4], with the powers of two tracked in a shared exponent – so neither ordinary determinant on its own can overflow or underflow when the combined determinant is representable, whatever the ordering and magnitudes of the entries. Genuinely out-of-range determinants still saturate to (signed) zero or infinity. The capacitance entries themselves are formed in plain arithmetic (see capacitance): at extreme factor magnitudes such as d = 1e-200, U = 1e-200, V = 1e200 they, and with them the determinant, overflow although the determinant (~1) is representable.
Warning
The diagonal must have no zero entries (use the lemma symmetrically or a dense fallback for that case), and, as with solve and inverse, its reciprocals must be finite: a subnormal diagonal entry overflows \( D^{-1} \) – and with it the capacitance entries – to infinity.

◆ diagonal()

template<typename Scalar_, int Size_, int Rank_>
const DiagonalVector & Eigen::DiagonalPlusLowRank< Scalar_, Size_, Rank_ >::diagonal ( ) const
inline
Returns
the diagonal vector d.

◆ factorU()

template<typename Scalar_, int Size_, int Rank_>
const FactorType & Eigen::DiagonalPlusLowRank< Scalar_, Size_, Rank_ >::factorU ( ) const
inline
Returns
the left factor U.

◆ factorV()

template<typename Scalar_, int Size_, int Rank_>
const FactorType & Eigen::DiagonalPlusLowRank< Scalar_, Size_, Rank_ >::factorV ( ) const
inline
Returns
the right factor V.

◆ inverse()

template<typename Scalar_, int Size_, int Rank_>
DiagonalPlusLowRank Eigen::DiagonalPlusLowRank< Scalar_, Size_, Rank_ >::inverse ( ) const
inline
Returns
the inverse of *this, itself a DiagonalPlusLowRank operator: by the Woodbury identity [1], \( (D + UV^H)^{-1} = D^{-1} + U' V'^H \) with \( U' = -D^{-1} U (I_k + V^H D^{-1} U)^{-1} \) and \( V' = D^{-H} V \).
Warning
Same invertibility requirements as solve.

◆ operator*()

template<typename Scalar_, int Size_, int Rank_>
template<typename Rhs>
Product< DiagonalPlusLowRank, Rhs > Eigen::DiagonalPlusLowRank< Scalar_, Size_, Rank_ >::operator* ( const MatrixBase< Rhs > & v) const
inline
Returns
the product expression (*this) * v, evaluated at O(nk) operations without forming the matrix. The expression carries the default product tag, so assigning it behaves like any dense product: a temporary resolves aliasing between the destination and v, and .noalias() skips it.

◆ solve()

template<typename Scalar_, int Size_, int Rank_>
template<typename Rhs>
Matrix< Scalar, Size_, Rhs::ColsAtCompileTime > Eigen::DiagonalPlusLowRank< Scalar_, Size_, Rank_ >::solve ( const MatrixBase< Rhs > & b) const
inline
Returns
the solution of (*this) * x = b through the Woodbury identity [1], factoring only the k x k capacitance matrix: O(nk^2 + k^3) setup and O(nk) per right-hand side. Supports multiple right-hand sides.
Warning
Requires an invertible diagonal and an invertible capacitance matrix (equivalently, an invertible operator); this is not checked beyond the NaN/Inf propagation of the arithmetic itself.
The Woodbury splitting routes the solution through \( D^{-1} b \): when max|1/d| greatly exceeds the norm of the operator's inverse, the correction cancels most of those amplified digits and the achievable accuracy degrades accordingly, even for a well-conditioned operator [5].

◆ transpose()

template<typename Scalar_, int Size_, int Rank_>
DiagonalPlusLowRank Eigen::DiagonalPlusLowRank< Scalar_, Size_, Rank_ >::transpose ( ) const
inline
Returns
the transpose of *this, itself a DiagonalPlusLowRank operator: \( (D + UV^H)^T = D + \bar V \bar U^H \).

The documentation for this class was generated from the following file: