Eigen::BDCSVD< MatrixType_, Options_ > Class Template Reference

class Bidiagonal Divide and Conquer SVD More...

#include <BDCSVD.h>

+ Inheritance diagram for Eigen::BDCSVD< MatrixType_, Options_ >:

Public Types

enum  {
  Options = Options_ , QRDecomposition = Options & internal::QRPreconditionerBits , ComputationOptions = Options & internal::ComputationOptionsBits , RowsAtCompileTime = Base::RowsAtCompileTime ,
  ColsAtCompileTime = Base::ColsAtCompileTime , DiagSizeAtCompileTime = Base::DiagSizeAtCompileTime , MaxRowsAtCompileTime = Base::MaxRowsAtCompileTime , MaxColsAtCompileTime = Base::MaxColsAtCompileTime ,
  MaxDiagSizeAtCompileTime = Base::MaxDiagSizeAtCompileTime , MatrixOptions = Base::MatrixOptions
}
 
typedef MatrixType_ MatrixType
 
typedef Base::Scalar Scalar
 
typedef Base::RealScalar RealScalar
 
typedef NumTraits< RealScalar >::Literal Literal
 
typedef Base::Index Index
 
typedef Base::MatrixUType MatrixUType
 
typedef Base::MatrixVType MatrixVType
 
typedef Base::SingularValuesType SingularValuesType
 
typedef Matrix< Scalar, Dynamic, Dynamic, ColMajorMatrixX
 
typedef Matrix< RealScalar, Dynamic, Dynamic, ColMajorMatrixXr
 
typedef Matrix< RealScalar, Dynamic, 1 > VectorType
 
typedef Array< RealScalar, Dynamic, 1 > ArrayXr
 
typedef Array< Index, 1, DynamicArrayXi
 
typedef Ref< ArrayXrArrayRef
 
typedef Ref< ArrayXiIndicesRef
 
- Public Types inherited from Eigen::SVDBase< BDCSVD< MatrixType_, Options_ > >
enum  
 
typedef internal::traits< BDCSVD< MatrixType_, Options_ > >::MatrixType MatrixType
 
typedef MatrixType::Scalar Scalar
 
typedef NumTraits< typename MatrixType::Scalar >::Real RealScalar
 
typedef Eigen::internal::traits< SVDBase >::StorageIndex StorageIndex
 
typedef internal::make_proper_matrix_type< Scalar, RowsAtCompileTime, MatrixUColsAtCompileTime, MatrixOptions, MaxRowsAtCompileTime, MatrixUMaxColsAtCompileTime >::type MatrixUType
 
typedef internal::make_proper_matrix_type< Scalar, ColsAtCompileTime, MatrixVColsAtCompileTime, MatrixOptions, MaxColsAtCompileTime, MatrixVMaxColsAtCompileTime >::type MatrixVType
 
typedef internal::plain_diag_type< MatrixType, RealScalar >::type SingularValuesType
 
- Public Types inherited from Eigen::SolverBase< Derived >
enum  {
  RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime , ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime , SizeAtCompileTime = (internal::size_of_xpr_at_compile_time<Derived>::ret) , MaxRowsAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime ,
  MaxColsAtCompileTime = internal::traits<Derived>::MaxColsAtCompileTime , MaxSizeAtCompileTime , IsVectorAtCompileTime , NumDimensions
}
 
typedef EigenBase< Derived > Base
 
typedef internal::traits< Derived >::Scalar Scalar
 
typedef Scalar CoeffReturnType
 
typedef Transpose< const Derived > ConstTransposeReturnType
 
typedef std::conditional_t< NumTraits< Scalar >::IsComplex, CwiseUnaryOp< internal::scalar_conjugate_op< Scalar >, const ConstTransposeReturnType >, const ConstTransposeReturnTypeAdjointReturnType
 
- Public Types inherited from Eigen::EigenBase< Derived >
typedef Eigen::Index Index
 The interface type of indices. More...
 
typedef internal::traits< Derived >::StorageKind StorageKind
 

Public Member Functions

 BDCSVD ()
 Default Constructor. More...
 
 BDCSVD (Index rows, Index cols)
 Default Constructor with memory preallocation. More...
 
EIGEN_DEPRECATED BDCSVD (Index rows, Index cols, unsigned int computationOptions)
 Default Constructor with memory preallocation. More...
 
 BDCSVD (const MatrixType &matrix)
 Constructor performing the decomposition of given matrix, using the custom options specified with the Options template parameter. More...
 
EIGEN_DEPRECATED BDCSVD (const MatrixType &matrix, unsigned int computationOptions)
 Constructor performing the decomposition of given matrix using specified options for computing unitaries. More...
 
 ~BDCSVD ()
 
BDCSVDcompute (const MatrixType &matrix)
 Method performing the decomposition of given matrix. Computes Thin/Full unitaries U/V if specified using the Options template parameter or the class constructor. More...
 
EIGEN_DEPRECATED BDCSVDcompute (const MatrixType &matrix, unsigned int computationOptions)
 Method performing the decomposition of given matrix, as specified by the computationOptions parameter. More...
 
void setSwitchSize (int s)
 
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols () const EIGEN_NOEXCEPT
 
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows () const EIGEN_NOEXCEPT
 
- Public Member Functions inherited from Eigen::SVDBase< BDCSVD< MatrixType_, Options_ > >
BDCSVD< MatrixType_, Options_ > & derived ()
 
const BDCSVD< MatrixType_, Options_ > & derived () const
 
const MatrixUTypematrixU () const
 
const MatrixVTypematrixV () const
 
const SingularValuesTypesingularValues () const
 
Index nonzeroSingularValues () const
 
Index rank () const
 
BDCSVD< MatrixType_, Options_ > & setThreshold (const RealScalar &threshold)
 
BDCSVD< MatrixType_, Options_ > & setThreshold (Default_t)
 
RealScalar threshold () const
 
bool computeU () const
 
bool computeV () const
 
Index rows () const
 
Index cols () const
 
Index diagSize () const
 
EIGEN_DEVICE_FUNC ComputationInfo info () const
 Reports whether previous computation was successful. More...
 
void _solve_impl (const RhsType &rhs, DstType &dst) const
 
void _solve_impl_transposed (const RhsType &rhs, DstType &dst) const
 
- Public Member Functions inherited from Eigen::SolverBase< Derived >
 SolverBase ()
 
 ~SolverBase ()
 
template<typename Rhs >
const Solve< Derived, Rhs > solve (const MatrixBase< Rhs > &b) const
 
const ConstTransposeReturnType transpose () const
 
const AdjointReturnType adjoint () const
 
constexpr EIGEN_DEVICE_FUNC Derived & derived ()
 
constexpr EIGEN_DEVICE_FUNC const Derived & derived () const
 
- Public Member Functions inherited from Eigen::EigenBase< Derived >
constexpr EIGEN_DEVICE_FUNC Derived & derived ()
 
constexpr EIGEN_DEVICE_FUNC const Derived & derived () const
 
EIGEN_DEVICE_FUNC Derived & const_cast_derived () const
 
EIGEN_DEVICE_FUNC const Derived & const_derived () const
 
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows () const EIGEN_NOEXCEPT
 
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols () const EIGEN_NOEXCEPT
 
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index size () const EIGEN_NOEXCEPT
 
template<typename Dest >
EIGEN_DEVICE_FUNC void evalTo (Dest &dst) const
 
template<typename Dest >
EIGEN_DEVICE_FUNC void addTo (Dest &dst) const
 
template<typename Dest >
EIGEN_DEVICE_FUNC void subTo (Dest &dst) const
 
template<typename Dest >
EIGEN_DEVICE_FUNC void applyThisOnTheRight (Dest &dst) const
 
template<typename Dest >
EIGEN_DEVICE_FUNC void applyThisOnTheLeft (Dest &dst) const
 
template<typename Device >
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DeviceWrapper< Derived, Device > device (Device &device)
 
template<typename Device >
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DeviceWrapper< const Derived, Device > device (Device &device) const
 

Public Attributes

int m_numIters
 

Protected Member Functions

void allocate (Index rows, Index cols, unsigned int computationOptions)
 
- Protected Member Functions inherited from Eigen::SVDBase< BDCSVD< MatrixType_, Options_ > >
void _check_compute_assertions () const
 
void _check_solve_assertion (const Rhs &b) const
 
bool allocate (Index rows, Index cols, unsigned int computationOptions)
 
 SVDBase ()
 Default Constructor. More...
 
- Protected Member Functions inherited from Eigen::SolverBase< Derived >
template<bool Transpose_, typename Rhs >
void _check_solve_assertion (const Rhs &b) const
 

Protected Attributes

MatrixXr m_naiveU
 
MatrixXr m_naiveV
 
MatrixXr m_computed
 
Index m_nRec
 
ArrayXr m_workspace
 
ArrayXi m_workspaceI
 
int m_algoswap
 
bool m_isTranspose
 
bool m_compU
 
bool m_compV
 
bool m_useQrDecomp
 
JacobiSVD< MatrixType, ComputationOptionssmallSvd
 
HouseholderQR< MatrixXqrDecomp
 
internal::UpperBidiagonalization< MatrixXbid
 
MatrixX copyWorkspace
 
MatrixX reducedTriangle
 
- Protected Attributes inherited from Eigen::SVDBase< BDCSVD< MatrixType_, Options_ > >
MatrixUType m_matrixU
 
MatrixVType m_matrixV
 
SingularValuesType m_singularValues
 
ComputationInfo m_info
 
bool m_isInitialized
 
bool m_isAllocated
 
bool m_usePrescribedThreshold
 
bool m_computeFullU
 
bool m_computeThinU
 
bool m_computeFullV
 
bool m_computeThinV
 
unsigned int m_computationOptions
 
Index m_nonzeroSingularValues
 
internal::variable_if_dynamic< Index, RowsAtCompileTimem_rows
 
internal::variable_if_dynamic< Index, ColsAtCompileTimem_cols
 
internal::variable_if_dynamic< Index, DiagSizeAtCompileTimem_diagSize
 
RealScalar m_prescribedThreshold
 

Private Types

typedef SVDBase< BDCSVDBase
 

Private Member Functions

BDCSVDcompute_impl (const MatrixType &matrix, unsigned int computationOptions)
 
void divide (Index firstCol, Index lastCol, Index firstRowW, Index firstColW, Index shift)
 
void computeSVDofM (Index firstCol, Index n, MatrixXr &U, VectorType &singVals, MatrixXr &V)
 
void computeSingVals (const ArrayRef &col0, const ArrayRef &diag, const IndicesRef &perm, VectorType &singVals, ArrayRef shifts, ArrayRef mus)
 
void perturbCol0 (const ArrayRef &col0, const ArrayRef &diag, const IndicesRef &perm, const VectorType &singVals, const ArrayRef &shifts, const ArrayRef &mus, ArrayRef zhat)
 
void computeSingVecs (const ArrayRef &zhat, const ArrayRef &diag, const IndicesRef &perm, const VectorType &singVals, const ArrayRef &shifts, const ArrayRef &mus, MatrixXr &U, MatrixXr &V)
 
void deflation43 (Index firstCol, Index shift, Index i, Index size)
 
void deflation44 (Index firstColu, Index firstColm, Index firstRowW, Index firstColW, Index i, Index j, Index size)
 
void deflation (Index firstCol, Index lastCol, Index k, Index firstRowW, Index firstColW, Index shift)
 
template<typename HouseholderU , typename HouseholderV , typename NaiveU , typename NaiveV >
void copyUV (const HouseholderU &householderU, const HouseholderV &householderV, const NaiveU &naiveU, const NaiveV &naivev)
 
void structured_update (Block< MatrixXr, Dynamic, Dynamic > A, const MatrixXr &B, Index n1)
 
template<typename SVDType >
void computeBaseCase (SVDType &svd, Index n, Index firstCol, Index firstRowW, Index firstColW, Index shift)
 

Static Private Member Functions

static RealScalar secularEq (RealScalar x, const ArrayRef &col0, const ArrayRef &diag, const IndicesRef &perm, const ArrayRef &diagShifted, RealScalar shift)
 

Additional Inherited Members

- Static Public Attributes inherited from Eigen::SVDBase< BDCSVD< MatrixType_, Options_ > >
static constexpr bool ShouldComputeFullU
 
static constexpr bool ShouldComputeThinU
 
static constexpr bool ShouldComputeFullV
 
static constexpr bool ShouldComputeThinV
 

Detailed Description

template<typename MatrixType_, int Options_>
class Eigen::BDCSVD< MatrixType_, Options_ >

class Bidiagonal Divide and Conquer SVD

Template Parameters
MatrixType_the type of the matrix of which we are computing the SVD decomposition
Options_this optional parameter allows one to specify options for computing unitaries U and V. Possible values are ComputeThinU, ComputeThinV, ComputeFullU, ComputeFullV, and DisableQRDecomposition. It is not possible to request both the thin and full version of U or V. By default, unitaries are not computed. BDCSVD uses R-Bidiagonalization to improve performance on tall and wide matrices. For backwards compatility, the option DisableQRDecomposition can be used to disable this optimization.

This class first reduces the input matrix to bi-diagonal form using class UpperBidiagonalization, and then performs a divide-and-conquer diagonalization. Small blocks are diagonalized using class JacobiSVD. You can control the switching size with the setSwitchSize() method, default is 16. For small matrice (<16), it is thus preferable to directly use JacobiSVD. For larger ones, BDCSVD is highly recommended and can several order of magnitude faster.

Warning
this algorithm is unlikely to provide accurate result when compiled with unsafe math optimizations. For instance, this concerns Intel's compiler (ICC), which performs such optimization by default unless you compile with the -fp-model precise option. Likewise, the -ffast-math option of GCC or clang will significantly degrade the accuracy.
See also
class JacobiSVD

Member Typedef Documentation

◆ ArrayRef

template<typename MatrixType_ , int Options_>
typedef Ref<ArrayXr> Eigen::BDCSVD< MatrixType_, Options_ >::ArrayRef

◆ ArrayXi

template<typename MatrixType_ , int Options_>
typedef Array<Index, 1, Dynamic> Eigen::BDCSVD< MatrixType_, Options_ >::ArrayXi

◆ ArrayXr

template<typename MatrixType_ , int Options_>
typedef Array<RealScalar, Dynamic, 1> Eigen::BDCSVD< MatrixType_, Options_ >::ArrayXr

◆ Base

template<typename MatrixType_ , int Options_>
typedef SVDBase<BDCSVD> Eigen::BDCSVD< MatrixType_, Options_ >::Base
private

◆ Index

template<typename MatrixType_ , int Options_>
typedef Base::Index Eigen::BDCSVD< MatrixType_, Options_ >::Index

◆ IndicesRef

template<typename MatrixType_ , int Options_>
typedef Ref<ArrayXi> Eigen::BDCSVD< MatrixType_, Options_ >::IndicesRef

◆ Literal

template<typename MatrixType_ , int Options_>
typedef NumTraits<RealScalar>::Literal Eigen::BDCSVD< MatrixType_, Options_ >::Literal

◆ MatrixType

template<typename MatrixType_ , int Options_>
typedef MatrixType_ Eigen::BDCSVD< MatrixType_, Options_ >::MatrixType

◆ MatrixUType

template<typename MatrixType_ , int Options_>
typedef Base::MatrixUType Eigen::BDCSVD< MatrixType_, Options_ >::MatrixUType

◆ MatrixVType

template<typename MatrixType_ , int Options_>
typedef Base::MatrixVType Eigen::BDCSVD< MatrixType_, Options_ >::MatrixVType

◆ MatrixX

template<typename MatrixType_ , int Options_>
typedef Matrix<Scalar, Dynamic, Dynamic, ColMajor> Eigen::BDCSVD< MatrixType_, Options_ >::MatrixX

◆ MatrixXr

template<typename MatrixType_ , int Options_>
typedef Matrix<RealScalar, Dynamic, Dynamic, ColMajor> Eigen::BDCSVD< MatrixType_, Options_ >::MatrixXr

◆ RealScalar

template<typename MatrixType_ , int Options_>
typedef Base::RealScalar Eigen::BDCSVD< MatrixType_, Options_ >::RealScalar

◆ Scalar

template<typename MatrixType_ , int Options_>
typedef Base::Scalar Eigen::BDCSVD< MatrixType_, Options_ >::Scalar

◆ SingularValuesType

template<typename MatrixType_ , int Options_>
typedef Base::SingularValuesType Eigen::BDCSVD< MatrixType_, Options_ >::SingularValuesType

◆ VectorType

template<typename MatrixType_ , int Options_>
typedef Matrix<RealScalar, Dynamic, 1> Eigen::BDCSVD< MatrixType_, Options_ >::VectorType

Member Enumeration Documentation

◆ anonymous enum

template<typename MatrixType_ , int Options_>
anonymous enum
Enumerator
Options 
QRDecomposition 
ComputationOptions 
RowsAtCompileTime 
ColsAtCompileTime 
DiagSizeAtCompileTime 
MaxRowsAtCompileTime 
MaxColsAtCompileTime 
MaxDiagSizeAtCompileTime 
MatrixOptions 
100  {
101  Options = Options_,
111  };
@ QRDecomposition
Definition: BDCSVD.h:102
@ DiagSizeAtCompileTime
Definition: BDCSVD.h:106
@ ComputationOptions
Definition: BDCSVD.h:103
@ MaxColsAtCompileTime
Definition: BDCSVD.h:108
@ RowsAtCompileTime
Definition: BDCSVD.h:104
@ ColsAtCompileTime
Definition: BDCSVD.h:105
@ MaxDiagSizeAtCompileTime
Definition: BDCSVD.h:109
@ MatrixOptions
Definition: BDCSVD.h:110
@ MaxRowsAtCompileTime
Definition: BDCSVD.h:107
@ Options
Definition: BDCSVD.h:101
@ MatrixOptions
Definition: SVDBase.h:141
@ ColsAtCompileTime
Definition: SVDBase.h:136
@ DiagSizeAtCompileTime
Definition: SVDBase.h:137
@ MaxRowsAtCompileTime
Definition: SVDBase.h:138
@ MaxDiagSizeAtCompileTime
Definition: SVDBase.h:140
@ MaxColsAtCompileTime
Definition: SVDBase.h:139
@ RowsAtCompileTime
Definition: SVDBase.h:135
@ QRPreconditionerBits
Definition: SVDBase.h:27
@ ComputationOptionsBits
Definition: SVDBase.h:29

Constructor & Destructor Documentation

◆ BDCSVD() [1/5]

template<typename MatrixType_ , int Options_>
Eigen::BDCSVD< MatrixType_, Options_ >::BDCSVD ( )
inline

Default Constructor.

The default constructor is useful in cases in which the user intends to perform decompositions via BDCSVD::compute(const MatrixType&).

130 : m_algoswap(16), m_isTranspose(false), m_compU(false), m_compV(false), m_numIters(0) {}
bool m_isTranspose
Definition: BDCSVD.h:245
int m_numIters
Definition: BDCSVD.h:263
bool m_compU
Definition: BDCSVD.h:245
int m_algoswap
Definition: BDCSVD.h:244
bool m_compV
Definition: BDCSVD.h:245

◆ BDCSVD() [2/5]

template<typename MatrixType_ , int Options_>
Eigen::BDCSVD< MatrixType_, Options_ >::BDCSVD ( Index  rows,
Index  cols 
)
inline

Default Constructor with memory preallocation.

Like the default constructor but with preallocation of the internal data according to the specified problem size and Options template parameter.

See also
BDCSVD()
138  : m_algoswap(16), m_numIters(0) {
140  }
void allocate(Index rows, Index cols, unsigned int computationOptions)
Definition: BDCSVD.h:268
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT
Definition: EigenBase.h:61
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT
Definition: EigenBase.h:59
constexpr int get_computation_options(int options)
Definition: SVDBase.h:34

References Eigen::BDCSVD< MatrixType_, Options_ >::allocate(), Eigen::BDCSVD< MatrixType_, Options_ >::cols(), Eigen::internal::get_computation_options(), Eigen::BDCSVD< MatrixType_, Options_ >::Options, and Eigen::BDCSVD< MatrixType_, Options_ >::rows().

◆ BDCSVD() [3/5]

template<typename MatrixType_ , int Options_>
EIGEN_DEPRECATED Eigen::BDCSVD< MatrixType_, Options_ >::BDCSVD ( Index  rows,
Index  cols,
unsigned int  computationOptions 
)
inline

Default Constructor with memory preallocation.

Like the default constructor but with preallocation of the internal data according to the specified problem size and the computationOptions.

One cannot request unitaries using both the Options template parameter and the constructor. If possible, prefer using the Options template parameter.

Parameters
computationOptionsspecification for computing Thin/Full unitaries U/V
See also
BDCSVD()
Deprecated:
Will be removed in the next major Eigen version. Options should be specified in the Options template parameter.
156  : m_algoswap(16), m_numIters(0) {
157  internal::check_svd_options_assertions<MatrixType, Options>(computationOptions, rows, cols);
158  allocate(rows, cols, computationOptions);
159  }

References Eigen::BDCSVD< MatrixType_, Options_ >::allocate(), Eigen::BDCSVD< MatrixType_, Options_ >::cols(), and Eigen::BDCSVD< MatrixType_, Options_ >::rows().

◆ BDCSVD() [4/5]

template<typename MatrixType_ , int Options_>
Eigen::BDCSVD< MatrixType_, Options_ >::BDCSVD ( const MatrixType matrix)
inline

Constructor performing the decomposition of given matrix, using the custom options specified with the Options template parameter.

Parameters
matrixthe matrix to decompose
166  : m_algoswap(16), m_numIters(0) {
168  }
BDCSVD & compute_impl(const MatrixType &matrix, unsigned int computationOptions)
Definition: BDCSVD.h:308
Eigen::Map< Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor >, 0, Eigen::OuterStride<> > matrix(T *data, int rows, int cols, int stride)
Definition: common.h:85

References Eigen::BDCSVD< MatrixType_, Options_ >::compute_impl(), Eigen::internal::get_computation_options(), matrix(), and Eigen::BDCSVD< MatrixType_, Options_ >::Options.

◆ BDCSVD() [5/5]

template<typename MatrixType_ , int Options_>
EIGEN_DEPRECATED Eigen::BDCSVD< MatrixType_, Options_ >::BDCSVD ( const MatrixType matrix,
unsigned int  computationOptions 
)
inline

Constructor performing the decomposition of given matrix using specified options for computing unitaries.

One cannot request unitaries using both the Options template parameter and the constructor. If possible, prefer using the Options template parameter.

Parameters
matrixthe matrix to decompose
computationOptionsspecification for computing Thin/Full unitaries U/V
Deprecated:
Will be removed in the next major Eigen version. Options should be specified in the Options template parameter.
182  : m_algoswap(16), m_numIters(0) {
183  internal::check_svd_options_assertions<MatrixType, Options>(computationOptions, matrix.rows(), matrix.cols());
184  compute_impl(matrix, computationOptions);
185  }

References Eigen::BDCSVD< MatrixType_, Options_ >::compute_impl(), and matrix().

◆ ~BDCSVD()

template<typename MatrixType_ , int Options_>
Eigen::BDCSVD< MatrixType_, Options_ >::~BDCSVD ( )
inline
187 {}

Member Function Documentation

◆ allocate()

template<typename MatrixType , int Options>
void Eigen::BDCSVD< MatrixType, Options >::allocate ( Index  rows,
Index  cols,
unsigned int  computationOptions 
)
protected
268  {
269  if (Base::allocate(rows, cols, computationOptions)) return;
270 
271  if (cols < m_algoswap)
273 
275  m_compU = computeV();
276  m_compV = computeU();
277  m_isTranspose = (cols > rows);
279 
280  // kMinAspectRatio is the crossover point that determines if we perform R-Bidiagonalization
281  // or bidiagonalize the input matrix directly.
282  // It is based off of LAPACK's dgesdd routine, which uses 11.0/6.0
283  // we use a larger scalar to prevent a regression for relatively square matrices.
284  constexpr Index kMinAspectRatio = 4;
285  constexpr bool disableQrDecomp = static_cast<int>(QRDecomposition) == static_cast<int>(DisableQRDecomposition);
286  m_useQrDecomp = !disableQrDecomp && ((rows / kMinAspectRatio > cols) || (cols / kMinAspectRatio > rows));
287  if (m_useQrDecomp) {
288  qrDecomp = HouseholderQR<MatrixX>((std::max)(rows, cols), (std::min)(rows, cols));
290  }
291 
293  bid = internal::UpperBidiagonalization<MatrixX>(m_useQrDecomp ? diagSize() : copyWorkspace.rows(),
295 
296  if (m_compU)
297  m_naiveU = MatrixXr::Zero(diagSize() + 1, diagSize() + 1);
298  else
299  m_naiveU = MatrixXr::Zero(2, diagSize() + 1);
300 
302 
303  m_workspace.resize((diagSize() + 1) * (diagSize() + 1) * 3);
305 } // end allocate
ArrayXi m_workspaceI
Definition: BDCSVD.h:243
bool m_useQrDecomp
Definition: BDCSVD.h:245
Base::Index Index
Definition: BDCSVD.h:99
MatrixX copyWorkspace
Definition: BDCSVD.h:249
JacobiSVD< MatrixType, ComputationOptions > smallSvd
Definition: BDCSVD.h:246
MatrixXr m_computed
Definition: BDCSVD.h:240
MatrixXr m_naiveV
Definition: BDCSVD.h:239
Matrix< Scalar, Dynamic, Dynamic, ColMajor > MatrixX
Definition: BDCSVD.h:117
MatrixXr m_naiveU
Definition: BDCSVD.h:239
HouseholderQR< MatrixX > qrDecomp
Definition: BDCSVD.h:247
ArrayXr m_workspace
Definition: BDCSVD.h:242
MatrixX reducedTriangle
Definition: BDCSVD.h:250
internal::UpperBidiagonalization< MatrixX > bid
Definition: BDCSVD.h:248
void allocate(Index rows_, Index cols_, unsigned int computationOptions)
Definition: JacobiSVD.h:614
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT
Definition: PlainObjectBase.h:192
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
Definition: PlainObjectBase.h:294
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT
Definition: PlainObjectBase.h:191
bool computeV() const
Definition: SVDBase.h:275
bool computeU() const
Definition: SVDBase.h:273
bool allocate(Index rows, Index cols, unsigned int computationOptions)
Definition: SVDBase.h:403
Index diagSize() const
Definition: SVDBase.h:279
#define min(a, b)
Definition: datatypes.h:22
#define max(a, b)
Definition: datatypes.h:23
@ DisableQRDecomposition
Definition: Constants.h:429
EIGEN_BLAS_FUNC() swap(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy)
Definition: level1_impl.h:117
double Zero
Definition: pseudosolid_node_update_elements.cc:35

References cols, Eigen::DisableQRDecomposition, Eigen::internal::get_computation_options(), max, min, rows, swap(), and oomph::PseudoSolidHelper::Zero.

Referenced by Eigen::BDCSVD< MatrixType_, Options_ >::BDCSVD().

◆ cols()

◆ compute() [1/2]

template<typename MatrixType_ , int Options_>
BDCSVD& Eigen::BDCSVD< MatrixType_, Options_ >::compute ( const MatrixType matrix)
inline

Method performing the decomposition of given matrix. Computes Thin/Full unitaries U/V if specified using the Options template parameter or the class constructor.

Parameters
matrixthe matrix to decompose
unsigned int m_computationOptions
Definition: SVDBase.h:338

References Eigen::BDCSVD< MatrixType_, Options_ >::compute_impl(), Eigen::SVDBase< BDCSVD< MatrixType_, Options_ > >::m_computationOptions, and matrix().

Referenced by bench(), and compare_bdc_jacobi().

◆ compute() [2/2]

template<typename MatrixType_ , int Options_>
EIGEN_DEPRECATED BDCSVD& Eigen::BDCSVD< MatrixType_, Options_ >::compute ( const MatrixType matrix,
unsigned int  computationOptions 
)
inline

Method performing the decomposition of given matrix, as specified by the computationOptions parameter.

Parameters
matrixthe matrix to decompose
computationOptionsspecify whether to compute Thin/Full unitaries U/V
Deprecated:
Will be removed in the next major Eigen version. Options should be specified in the Options template parameter.
205  {
206  internal::check_svd_options_assertions<MatrixType, Options>(computationOptions, matrix.rows(), matrix.cols());
207  return compute_impl(matrix, computationOptions);
208  }

References Eigen::BDCSVD< MatrixType_, Options_ >::compute_impl(), and matrix().

◆ compute_impl()

template<typename MatrixType , int Options>
BDCSVD< MatrixType, Options > & Eigen::BDCSVD< MatrixType, Options >::compute_impl ( const MatrixType matrix,
unsigned int  computationOptions 
)
private
309  {
310 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
311  std::cout << "\n\n\n================================================================================================="
312  "=====================\n\n\n";
313 #endif
314  using std::abs;
315 
316  allocate(matrix.rows(), matrix.cols(), computationOptions);
317 
318  const RealScalar considerZero = (std::numeric_limits<RealScalar>::min)();
319 
320  //**** step -1 - If the problem is too small, directly falls back to JacobiSVD and return
321  if (matrix.cols() < m_algoswap) {
323  m_isInitialized = true;
324  m_info = smallSvd.info();
325  if (m_info == Success || m_info == NoConvergence) {
326  if (computeU()) m_matrixU = smallSvd.matrixU();
327  if (computeV()) m_matrixV = smallSvd.matrixV();
330  }
331  return *this;
332  }
333 
334  //**** step 0 - Copy the input matrix and apply scaling to reduce over/under-flows
335  RealScalar scale = matrix.cwiseAbs().template maxCoeff<PropagateNaN>();
336  if (!(numext::isfinite)(scale)) {
337  m_isInitialized = true;
339  return *this;
340  }
341 
342  if (numext::is_exactly_zero(scale)) scale = Literal(1);
343 
344  if (m_isTranspose)
345  copyWorkspace = matrix.adjoint() / scale;
346  else
347  copyWorkspace = matrix / scale;
348 
349  //**** step 1 - Bidiagonalization.
350  // If the problem is sufficiently rectangular, we perform R-Bidiagonalization: compute A = Q(R/0)
351  // and then bidiagonalize R. Otherwise, if the problem is relatively square, we
352  // bidiagonalize the input matrix directly.
353  if (m_useQrDecomp) {
354  qrDecomp.compute(copyWorkspace);
355  reducedTriangle = qrDecomp.matrixQR().topRows(diagSize());
356  reducedTriangle.template triangularView<StrictlyLower>().setZero();
357  bid.compute(reducedTriangle);
358  } else {
359  bid.compute(copyWorkspace);
360  }
361 
362  //**** step 2 - Divide & Conquer
363  m_naiveU.setZero();
364  m_naiveV.setZero();
365  // FIXME this line involves a temporary matrix
366  m_computed.topRows(diagSize()) = bid.bidiagonal().toDenseMatrix().transpose();
367  m_computed.template bottomRows<1>().setZero();
368  divide(0, diagSize() - 1, 0, 0, 0);
369  if (m_info != Success && m_info != NoConvergence) {
370  m_isInitialized = true;
371  return *this;
372  }
373 
374  //**** step 3 - Copy singular values and vectors
375  for (int i = 0; i < diagSize(); i++) {
377  m_singularValues.coeffRef(i) = a * scale;
378  if (a < considerZero) {
380  m_singularValues.tail(diagSize() - i - 1).setZero();
381  break;
382  } else if (i == diagSize() - 1) {
384  break;
385  }
386  }
387 
388  //**** step 4 - Finalize unitaries U and V
389  if (m_isTranspose)
390  copyUV(bid.householderV(), bid.householderU(), m_naiveV, m_naiveU);
391  else
392  copyUV(bid.householderU(), bid.householderV(), m_naiveU, m_naiveV);
393 
394  if (m_useQrDecomp) {
395  if (m_isTranspose && computeV())
396  m_matrixV.applyOnTheLeft(qrDecomp.householderQ());
397  else if (!m_isTranspose && computeU())
398  m_matrixU.applyOnTheLeft(qrDecomp.householderQ());
399  }
400 
401  m_isInitialized = true;
402  return *this;
403 } // end compute
AnnoyingScalar abs(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:135
int i
Definition: BiCGSTAB_step_by_step.cpp:9
NumTraits< Scalar >::Real RealScalar
Definition: bench_gemm.cpp:46
void copyUV(const HouseholderU &householderU, const HouseholderV &householderV, const NaiveU &naiveU, const NaiveV &naivev)
Definition: BDCSVD.h:407
NumTraits< RealScalar >::Literal Literal
Definition: BDCSVD.h:98
void divide(Index firstCol, Index lastCol, Index firstRowW, Index firstColW, Index shift)
Definition: BDCSVD.h:508
JacobiSVD & compute(const MatrixType &matrix)
Method performing the decomposition of given matrix. Computes Thin/Full unitaries U/V if specified us...
Definition: JacobiSVD.h:591
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE const Scalar & coeff(Index rowId, Index colId) const
Definition: PlainObjectBase.h:198
EIGEN_DEVICE_FUNC Derived & setZero(Index size)
Definition: CwiseNullaryOp.h:569
const MatrixVType & matrixV() const
Definition: SVDBase.h:189
ComputationInfo m_info
Definition: SVDBase.h:334
const SingularValuesType & singularValues() const
Definition: SVDBase.h:200
EIGEN_DEVICE_FUNC ComputationInfo info() const
Reports whether previous computation was successful.
Definition: SVDBase.h:300
bool m_isInitialized
Definition: SVDBase.h:335
MatrixVType m_matrixV
Definition: SVDBase.h:332
Index m_nonzeroSingularValues
Definition: SVDBase.h:339
SingularValuesType m_singularValues
Definition: SVDBase.h:333
MatrixUType m_matrixU
Definition: SVDBase.h:331
const MatrixUType & matrixU() const
Definition: SVDBase.h:173
Index nonzeroSingularValues() const
Definition: SVDBase.h:206
@ InvalidInput
Definition: Constants.h:447
@ Success
Definition: Constants.h:440
@ NoConvergence
Definition: Constants.h:444
const Scalar * a
Definition: level2_cplx_impl.h:32
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool() isfinite(const Eigen::bfloat16 &h)
Definition: BFloat16.h:752
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool is_exactly_zero(const X &x)
Definition: Meta.h:592

References a, abs(), i, Eigen::InvalidInput, Eigen::numext::is_exactly_zero(), Eigen::numext::isfinite(), matrix(), min, Eigen::NoConvergence, and Eigen::Success.

Referenced by Eigen::BDCSVD< MatrixType_, Options_ >::BDCSVD(), and Eigen::BDCSVD< MatrixType_, Options_ >::compute().

◆ computeBaseCase()

template<typename MatrixType , int Options>
template<typename SVDType >
void Eigen::BDCSVD< MatrixType, Options >::computeBaseCase ( SVDType &  svd,
Index  n,
Index  firstCol,
Index  firstRowW,
Index  firstColW,
Index  shift 
)
private
479  {
480  svd.compute(m_computed.block(firstCol, firstCol, n + 1, n));
481  m_info = svd.info();
482  if (m_info != Success && m_info != NoConvergence) return;
483  if (m_compU)
484  m_naiveU.block(firstCol, firstCol, n + 1, n + 1).real() = svd.matrixU();
485  else {
486  m_naiveU.row(0).segment(firstCol, n + 1).real() = svd.matrixU().row(0);
487  m_naiveU.row(1).segment(firstCol, n + 1).real() = svd.matrixU().row(n);
488  }
489  if (m_compV) m_naiveV.block(firstRowW, firstColW, n, n).real() = svd.matrixV();
490  m_computed.block(firstCol + shift, firstCol + shift, n + 1, n).setZero();
491  m_computed.diagonal().segment(firstCol + shift, n) = svd.singularValues().head(n);
492 }
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
cout<< "Here is the matrix m:"<< endl<< m<< endl;JacobiSVD< MatrixXf, ComputeThinU|ComputeThinV > svd(m)

References n, Eigen::NoConvergence, Eigen::Success, and svd().

◆ computeSingVals()

template<typename MatrixType , int Options>
void Eigen::BDCSVD< MatrixType, Options >::computeSingVals ( const ArrayRef col0,
const ArrayRef diag,
const IndicesRef perm,
VectorType singVals,
ArrayRef  shifts,
ArrayRef  mus 
)
private
821  {
822  using std::abs;
823  using std::sqrt;
824  using std::swap;
825 
826  Index n = col0.size();
827  Index actual_n = n;
828  // Note that here actual_n is computed based on col0(i)==0 instead of diag(i)==0 as above
829  // because 1) we have diag(i)==0 => col0(i)==0 and 2) if col0(i)==0, then diag(i) is already a singular value.
830  while (actual_n > 1 && numext::is_exactly_zero(col0(actual_n - 1))) --actual_n;
831 
832  for (Index k = 0; k < n; ++k) {
833  if (numext::is_exactly_zero(col0(k)) || actual_n == 1) {
834  // if col0(k) == 0, then entry is deflated, so singular value is on diagonal
835  // if actual_n==1, then the deflated problem is already diagonalized
836  singVals(k) = k == 0 ? col0(0) : diag(k);
837  mus(k) = Literal(0);
838  shifts(k) = k == 0 ? col0(0) : diag(k);
839  continue;
840  }
841 
842  // otherwise, use secular equation to find singular value
843  RealScalar left = diag(k);
844  RealScalar right; // was: = (k != actual_n-1) ? diag(k+1) : (diag(actual_n-1) + col0.matrix().norm());
845  if (k == actual_n - 1)
846  right = (diag(actual_n - 1) + col0.matrix().norm());
847  else {
848  // Skip deflated singular values,
849  // recall that at this stage we assume that z[j]!=0 and all entries for which z[j]==0 have been put aside.
850  // This should be equivalent to using perm[]
851  Index l = k + 1;
852  while (numext::is_exactly_zero(col0(l))) {
853  ++l;
855  }
856  right = diag(l);
857  }
858 
859  // first decide whether it's closer to the left end or the right end
860  RealScalar mid = left + (right - left) / Literal(2);
861  RealScalar fMid = secularEq(mid, col0, diag, perm, diag, Literal(0));
862 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
863  std::cout << "right-left = " << right - left << "\n";
864  // std::cout << "fMid = " << fMid << " " << secularEq(mid-left, col0, diag, perm, ArrayXr(diag-left), left)
865  // << " " << secularEq(mid-right, col0, diag, perm, ArrayXr(diag-right), right) <<
866  // "\n";
867  std::cout << " = " << secularEq(left + RealScalar(0.000001) * (right - left), col0, diag, perm, diag, 0) << " "
868  << secularEq(left + RealScalar(0.1) * (right - left), col0, diag, perm, diag, 0) << " "
869  << secularEq(left + RealScalar(0.2) * (right - left), col0, diag, perm, diag, 0) << " "
870  << secularEq(left + RealScalar(0.3) * (right - left), col0, diag, perm, diag, 0) << " "
871  << secularEq(left + RealScalar(0.4) * (right - left), col0, diag, perm, diag, 0) << " "
872  << secularEq(left + RealScalar(0.49) * (right - left), col0, diag, perm, diag, 0) << " "
873  << secularEq(left + RealScalar(0.5) * (right - left), col0, diag, perm, diag, 0) << " "
874  << secularEq(left + RealScalar(0.51) * (right - left), col0, diag, perm, diag, 0) << " "
875  << secularEq(left + RealScalar(0.6) * (right - left), col0, diag, perm, diag, 0) << " "
876  << secularEq(left + RealScalar(0.7) * (right - left), col0, diag, perm, diag, 0) << " "
877  << secularEq(left + RealScalar(0.8) * (right - left), col0, diag, perm, diag, 0) << " "
878  << secularEq(left + RealScalar(0.9) * (right - left), col0, diag, perm, diag, 0) << " "
879  << secularEq(left + RealScalar(0.999999) * (right - left), col0, diag, perm, diag, 0) << "\n";
880 #endif
881  RealScalar shift = (k == actual_n - 1 || fMid > Literal(0)) ? left : right;
882 
883  // measure everything relative to shift
884  Map<ArrayXr> diagShifted(m_workspace.data() + 4 * n, n);
885  diagShifted = diag - shift;
886 
887  if (k != actual_n - 1) {
888  // check that after the shift, f(mid) is still negative:
889  RealScalar midShifted = (right - left) / RealScalar(2);
890  // we can test exact equality here, because shift comes from `... ? left : right`
891  if (numext::equal_strict(shift, right)) midShifted = -midShifted;
892  RealScalar fMidShifted = secularEq(midShifted, col0, diag, perm, diagShifted, shift);
893  if (fMidShifted > 0) {
894  // fMid was erroneous, fix it:
895  shift = fMidShifted > Literal(0) ? left : right;
896  diagShifted = diag - shift;
897  }
898  }
899 
900  // initial guess
901  RealScalar muPrev, muCur;
902  // we can test exact equality here, because shift comes from `... ? left : right`
903  if (numext::equal_strict(shift, left)) {
904  muPrev = (right - left) * RealScalar(0.1);
905  if (k == actual_n - 1)
906  muCur = right - left;
907  else
908  muCur = (right - left) * RealScalar(0.5);
909  } else {
910  muPrev = -(right - left) * RealScalar(0.1);
911  muCur = -(right - left) * RealScalar(0.5);
912  }
913 
914  RealScalar fPrev = secularEq(muPrev, col0, diag, perm, diagShifted, shift);
915  RealScalar fCur = secularEq(muCur, col0, diag, perm, diagShifted, shift);
916  if (abs(fPrev) < abs(fCur)) {
917  swap(fPrev, fCur);
918  swap(muPrev, muCur);
919  }
920 
921  // rational interpolation: fit a function of the form a / mu + b through the two previous
922  // iterates and use its zero to compute the next iterate
923  bool useBisection = fPrev * fCur > Literal(0);
924  while (!numext::is_exactly_zero(fCur) &&
925  abs(muCur - muPrev) >
926  Literal(8) * NumTraits<RealScalar>::epsilon() * numext::maxi<RealScalar>(abs(muCur), abs(muPrev)) &&
927  abs(fCur - fPrev) > NumTraits<RealScalar>::epsilon() && !useBisection) {
928  ++m_numIters;
929 
930  // Find a and b such that the function f(mu) = a / mu + b matches the current and previous samples.
931  RealScalar a = (fCur - fPrev) / (Literal(1) / muCur - Literal(1) / muPrev);
932  RealScalar b = fCur - a / muCur;
933  // And find mu such that f(mu)==0:
934  RealScalar muZero = -a / b;
935  RealScalar fZero = secularEq(muZero, col0, diag, perm, diagShifted, shift);
936 
937 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
939 #endif
940 
941  muPrev = muCur;
942  fPrev = fCur;
943  muCur = muZero;
944  fCur = fZero;
945 
946  // we can test exact equality here, because shift comes from `... ? left : right`
947  if (numext::equal_strict(shift, left) && (muCur < Literal(0) || muCur > right - left)) useBisection = true;
948  if (numext::equal_strict(shift, right) && (muCur < -(right - left) || muCur > Literal(0))) useBisection = true;
949  if (abs(fCur) > abs(fPrev)) useBisection = true;
950  }
951 
952  // fall back on bisection method if rational interpolation did not work
953  if (useBisection) {
954 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
955  std::cout << "useBisection for k = " << k << ", actual_n = " << actual_n << "\n";
956 #endif
957  RealScalar leftShifted, rightShifted;
958  // we can test exact equality here, because shift comes from `... ? left : right`
959  if (numext::equal_strict(shift, left)) {
960  // to avoid overflow, we must have mu > max(real_min, |z(k)|/sqrt(real_max)),
961  // the factor 2 is to be more conservative
962  leftShifted =
963  numext::maxi<RealScalar>((std::numeric_limits<RealScalar>::min)(),
965 
966  // check that we did it right:
968  (numext::isfinite)((col0(k) / leftShifted) * (col0(k) / (diag(k) + shift + leftShifted))));
969  // I don't understand why the case k==0 would be special there:
970  // if (k == 0) rightShifted = right - left; else
971  rightShifted = (k == actual_n - 1)
972  ? right
973  : ((right - left) * RealScalar(0.51)); // theoretically we can take 0.5, but let's be safe
974  } else {
975  leftShifted = -(right - left) * RealScalar(0.51);
976  if (k + 1 < n)
977  rightShifted = -numext::maxi<RealScalar>((std::numeric_limits<RealScalar>::min)(),
978  abs(col0(k + 1)) / sqrt((std::numeric_limits<RealScalar>::max)()));
979  else
980  rightShifted = -(std::numeric_limits<RealScalar>::min)();
981  }
982 
983  RealScalar fLeft = secularEq(leftShifted, col0, diag, perm, diagShifted, shift);
984  eigen_internal_assert(fLeft < Literal(0));
985 
986 #if defined EIGEN_BDCSVD_DEBUG_VERBOSE || defined EIGEN_BDCSVD_SANITY_CHECKS || defined EIGEN_INTERNAL_DEBUGGING
987  RealScalar fRight = secularEq(rightShifted, col0, diag, perm, diagShifted, shift);
988 #endif
989 
990 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
991  if (!(numext::isfinite)(fLeft))
992  std::cout << "f(" << leftShifted << ") =" << fLeft << " ; " << left << " " << shift << " " << right << "\n";
994 
995  if (!(numext::isfinite)(fRight))
996  std::cout << "f(" << rightShifted << ") =" << fRight << " ; " << left << " " << shift << " " << right << "\n";
997  // eigen_internal_assert((numext::isfinite)(fRight));
998 #endif
999 
1000 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
1001  if (!(fLeft * fRight < 0)) {
1002  std::cout << "f(leftShifted) using leftShifted=" << leftShifted
1003  << " ; diagShifted(1:10):" << diagShifted.head(10).transpose() << "\n ; "
1004  << "left==shift=" << bool(left == shift) << " ; left-shift = " << (left - shift) << "\n";
1005  std::cout << "k=" << k << ", " << fLeft << " * " << fRight << " == " << fLeft * fRight << " ; "
1006  << "[" << left << " .. " << right << "] -> [" << leftShifted << " " << rightShifted
1007  << "], shift=" << shift << " , f(right)=" << secularEq(0, col0, diag, perm, diagShifted, shift)
1008  << " == " << secularEq(right, col0, diag, perm, diag, 0) << " == " << fRight << "\n";
1009  }
1010 #endif
1011  eigen_internal_assert(fLeft * fRight < Literal(0));
1012 
1013  if (fLeft < Literal(0)) {
1014  while (rightShifted - leftShifted > Literal(2) * NumTraits<RealScalar>::epsilon() *
1015  numext::maxi<RealScalar>(abs(leftShifted), abs(rightShifted))) {
1016  RealScalar midShifted = (leftShifted + rightShifted) / Literal(2);
1017  fMid = secularEq(midShifted, col0, diag, perm, diagShifted, shift);
1019 
1020  if (fLeft * fMid < Literal(0)) {
1021  rightShifted = midShifted;
1022  } else {
1023  leftShifted = midShifted;
1024  fLeft = fMid;
1025  }
1026  }
1027  muCur = (leftShifted + rightShifted) / Literal(2);
1028  } else {
1029  // We have a problem as shifting on the left or right give either a positive or negative value
1030  // at the middle of [left,right]...
1031  // Instead of abbording or entering an infinite loop,
1032  // let's just use the middle as the estimated zero-crossing:
1033  muCur = (right - left) * RealScalar(0.5);
1034  // we can test exact equality here, because shift comes from `... ? left : right`
1035  if (numext::equal_strict(shift, right)) muCur = -muCur;
1036  }
1037  }
1038 
1039  singVals[k] = shift + muCur;
1040  shifts[k] = shift;
1041  mus[k] = muCur;
1042 
1043 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
1044  if (k + 1 < n)
1045  std::cout << "found " << singVals[k] << " == " << shift << " + " << muCur << " from " << diag(k) << " .. "
1046  << diag(k + 1) << "\n";
1047 #endif
1048 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
1049  eigen_internal_assert(k == 0 || singVals[k] >= singVals[k - 1]);
1050  eigen_internal_assert(singVals[k] >= diag(k));
1051 #endif
1052 
1053  // perturb singular value slightly if it equals diagonal entry to avoid division by zero later
1054  // (deflation is supposed to avoid this from happening)
1055  // - this does no seem to be necessary anymore -
1056  // if (singVals[k] == left) singVals[k] *= 1 + NumTraits<RealScalar>::epsilon();
1057  // if (singVals[k] == right) singVals[k] *= 1 - NumTraits<RealScalar>::epsilon();
1058  }
1059 }
AnnoyingScalar sqrt(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:134
#define eigen_internal_assert(x)
Definition: Macros.h:916
Scalar * b
Definition: benchVecAdd.cpp:17
Base::RealScalar RealScalar
Definition: BDCSVD.h:97
static RealScalar secularEq(RealScalar x, const ArrayRef &col0, const ArrayRef &diag, const IndicesRef &perm, const ArrayRef &diagShifted, RealScalar shift)
Definition: BDCSVD.h:805
constexpr EIGEN_DEVICE_FUNC const Scalar * data() const
Definition: PlainObjectBase.h:273
actual_n
Definition: level2_impl.h:445
const char const char const char * diag
Definition: level2_impl.h:86
char char char int int * k
Definition: level2_impl.h:374
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool equal_strict(const X &x, const Y &y)
Definition: Meta.h:571
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::enable_if_t< std::is_base_of< DenseBase< std::decay_t< DerivedA > >, std::decay_t< DerivedA > >::value &&std::is_base_of< DenseBase< std::decay_t< DerivedB > >, std::decay_t< DerivedB > >::value, void > swap(DerivedA &&a, DerivedB &&b)
Definition: DenseBase.h:655
double epsilon
Definition: osc_ring_sarah_asymptotics.h:43
list mus
Definition: plotDoE.py:17

References a, abs(), actual_n, b, diag, eigen_internal_assert, Eigen::numext::equal_strict(), Eigen::numext::is_exactly_zero(), Eigen::numext::isfinite(), k, max, min, plotDoE::mus, n, sqrt(), Eigen::swap(), and swap().

◆ computeSingVecs()

template<typename MatrixType , int Options>
void Eigen::BDCSVD< MatrixType, Options >::computeSingVecs ( const ArrayRef zhat,
const ArrayRef diag,
const IndicesRef perm,
const VectorType singVals,
const ArrayRef shifts,
const ArrayRef mus,
MatrixXr U,
MatrixXr V 
)
private
1148  {
1149  Index n = zhat.size();
1150  Index m = perm.size();
1151 
1152  for (Index k = 0; k < n; ++k) {
1153  if (numext::is_exactly_zero(zhat(k))) {
1154  U.col(k) = VectorType::Unit(n + 1, k);
1155  if (m_compV) V.col(k) = VectorType::Unit(n, k);
1156  } else {
1157  U.col(k).setZero();
1158  for (Index l = 0; l < m; ++l) {
1159  Index i = perm(l);
1160  U(i, k) = zhat(i) / (((diag(i) - shifts(k)) - mus(k))) / ((diag(i) + singVals[k]));
1161  }
1162  U(n, k) = Literal(0);
1163  U.col(k).normalize();
1164 
1165  if (m_compV) {
1166  V.col(k).setZero();
1167  for (Index l = 1; l < m; ++l) {
1168  Index i = perm(l);
1169  V(i, k) = diag(i) * zhat(i) / (((diag(i) - shifts(k)) - mus(k))) / ((diag(i) + singVals[k]));
1170  }
1171  V(0, k) = Literal(-1);
1172  V.col(k).normalize();
1173  }
1174  }
1175  }
1176  U.col(n) = VectorType::Unit(n + 1, n);
1177 }
MatrixXcd V
Definition: EigenSolver_EigenSolver_MatrixType.cpp:15
int * m
Definition: level2_cplx_impl.h:294
double U
Swimming speed.
Definition: two_d_variable_diff_adapt.cc:53

References diag, i, Eigen::numext::is_exactly_zero(), k, m, plotDoE::mus, n, RachelsAdvectionDiffusion::U, and V.

◆ computeSVDofM()

template<typename MatrixType , int Options>
void Eigen::BDCSVD< MatrixType, Options >::computeSVDofM ( Index  firstCol,
Index  n,
MatrixXr U,
VectorType singVals,
MatrixXr V 
)
private
673  {
674  const RealScalar considerZero = (std::numeric_limits<RealScalar>::min)();
675  using std::abs;
676  ArrayRef col0 = m_computed.col(firstCol).segment(firstCol, n);
677  m_workspace.head(n) = m_computed.block(firstCol, firstCol, n, n).diagonal();
678  ArrayRef diag = m_workspace.head(n);
679  diag(0) = Literal(0);
680 
681  // Allocate space for singular values and vectors
682  singVals.resize(n);
683  U.resize(n + 1, n + 1);
684  if (m_compV) V.resize(n, n);
685 
686 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
687  if (col0.hasNaN() || diag.hasNaN()) std::cout << "\n\nHAS NAN\n\n";
688 #endif
689 
690  // Many singular values might have been deflated, the zero ones have been moved to the end,
691  // but others are interleaved and we must ignore them at this stage.
692  // To this end, let's compute a permutation skipping them:
693  Index actual_n = n;
694  while (actual_n > 1 && numext::is_exactly_zero(diag(actual_n - 1))) {
695  --actual_n;
697  }
698  Index m = 0; // size of the deflated problem
699  for (Index k = 0; k < actual_n; ++k)
700  if (abs(col0(k)) > considerZero) m_workspaceI(m++) = k;
701  Map<ArrayXi> perm(m_workspaceI.data(), m);
702 
703  Map<ArrayXr> shifts(m_workspace.data() + 1 * n, n);
704  Map<ArrayXr> mus(m_workspace.data() + 2 * n, n);
705  Map<ArrayXr> zhat(m_workspace.data() + 3 * n, n);
706 
707 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
708  std::cout << "computeSVDofM using:\n";
709  std::cout << " z: " << col0.transpose() << "\n";
710  std::cout << " d: " << diag.transpose() << "\n";
711 #endif
712 
713  // Compute singVals, shifts, and mus
714  computeSingVals(col0, diag, perm, singVals, shifts, mus);
715 
716 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
717  std::cout << " j: "
718  << (m_computed.block(firstCol, firstCol, n, n)).jacobiSvd().singularValues().transpose().reverse()
719  << "\n\n";
720  std::cout << " sing-val: " << singVals.transpose() << "\n";
721  std::cout << " mu: " << mus.transpose() << "\n";
722  std::cout << " shift: " << shifts.transpose() << "\n";
723 
724  {
725  std::cout << "\n\n mus: " << mus.head(actual_n).transpose() << "\n\n";
726  std::cout << " check1 (expect0) : "
727  << ((singVals.array() - (shifts + mus)) / singVals.array()).head(actual_n).transpose() << "\n\n";
728  eigen_internal_assert((((singVals.array() - (shifts + mus)) / singVals.array()).head(actual_n) >= 0).all());
729  std::cout << " check2 (>0) : " << ((singVals.array() - diag) / singVals.array()).head(actual_n).transpose()
730  << "\n\n";
731  eigen_internal_assert((((singVals.array() - diag) / singVals.array()).head(actual_n) >= 0).all());
732  }
733 #endif
734 
735 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
736  eigen_internal_assert(singVals.allFinite());
737  eigen_internal_assert(mus.allFinite());
738  eigen_internal_assert(shifts.allFinite());
739 #endif
740 
741  // Compute zhat
742  perturbCol0(col0, diag, perm, singVals, shifts, mus, zhat);
743 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
744  std::cout << " zhat: " << zhat.transpose() << "\n";
745 #endif
746 
747 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
748  eigen_internal_assert(zhat.allFinite());
749 #endif
750 
751  computeSingVecs(zhat, diag, perm, singVals, shifts, mus, U, V);
752 
753 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
754  std::cout << "U^T U: " << (U.transpose() * U - MatrixXr(MatrixXr::Identity(U.cols(), U.cols()))).norm() << "\n";
755  std::cout << "V^T V: " << (V.transpose() * V - MatrixXr(MatrixXr::Identity(V.cols(), V.cols()))).norm() << "\n";
756 #endif
757 
758 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
759  eigen_internal_assert(m_naiveU.allFinite());
760  eigen_internal_assert(m_naiveV.allFinite());
761  eigen_internal_assert(m_computed.allFinite());
762  eigen_internal_assert(U.allFinite());
763  eigen_internal_assert(V.allFinite());
764 // eigen_internal_assert((U.transpose() * U - MatrixXr(MatrixXr::Identity(U.cols(),U.cols()))).norm() <
765 // 100*NumTraits<RealScalar>::epsilon() * n); eigen_internal_assert((V.transpose() * V -
766 // MatrixXr(MatrixXr::Identity(V.cols(),V.cols()))).norm() < 100*NumTraits<RealScalar>::epsilon() * n);
767 #endif
768 
769  // Because of deflation, the singular values might not be completely sorted.
770  // Fortunately, reordering them is a O(n) problem
771  for (Index i = 0; i < actual_n - 1; ++i) {
772  if (singVals(i) > singVals(i + 1)) {
773  using std::swap;
774  swap(singVals(i), singVals(i + 1));
775  U.col(i).swap(U.col(i + 1));
776  if (m_compV) V.col(i).swap(V.col(i + 1));
777  }
778  }
779 
780 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
781  {
782  bool singular_values_sorted =
783  (((singVals.segment(1, actual_n - 1) - singVals.head(actual_n - 1))).array() >= 0).all();
784  if (!singular_values_sorted)
785  std::cout << "Singular values are not sorted: " << singVals.segment(1, actual_n).transpose() << "\n";
786  eigen_internal_assert(singular_values_sorted);
787  }
788 #endif
789 
790  // Reverse order so that singular values in increased order
791  // Because of deflation, the zeros singular-values are already at the end
792  singVals.head(actual_n).reverseInPlace();
793  U.leftCols(actual_n).rowwise().reverseInPlace();
794  if (m_compV) V.leftCols(actual_n).rowwise().reverseInPlace();
795 
796 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
797  JacobiSVD<MatrixXr> jsvd(m_computed.block(firstCol, firstCol, n, n));
798  std::cout << " * j: " << jsvd.singularValues().transpose() << "\n\n";
799  std::cout << " * sing-val: " << singVals.transpose() << "\n";
800 // std::cout << " * err: " << ((jsvd.singularValues()-singVals)>1e-13*singVals.norm()).transpose() << "\n";
801 #endif
802 }
void computeSingVecs(const ArrayRef &zhat, const ArrayRef &diag, const IndicesRef &perm, const VectorType &singVals, const ArrayRef &shifts, const ArrayRef &mus, MatrixXr &U, MatrixXr &V)
Definition: BDCSVD.h:1146
Matrix< RealScalar, Dynamic, Dynamic, ColMajor > MatrixXr
Definition: BDCSVD.h:118
void perturbCol0(const ArrayRef &col0, const ArrayRef &diag, const IndicesRef &perm, const VectorType &singVals, const ArrayRef &shifts, const ArrayRef &mus, ArrayRef zhat)
Definition: BDCSVD.h:1063
void computeSingVals(const ArrayRef &col0, const ArrayRef &diag, const IndicesRef &perm, VectorType &singVals, ArrayRef shifts, ArrayRef mus)
Definition: BDCSVD.h:820
Ref< ArrayXr > ArrayRef
Definition: BDCSVD.h:122
static constexpr Eigen::internal::all_t all
Definition: IndexedViewHelper.h:86

References abs(), actual_n, Eigen::placeholders::all, diag, eigen_internal_assert, i, Eigen::numext::is_exactly_zero(), k, m, min, plotDoE::mus, n, Eigen::PlainObjectBase< Derived >::resize(), Eigen::SVDBase< Derived >::singularValues(), Eigen::swap(), swap(), RachelsAdvectionDiffusion::U, and V.

◆ copyUV()

template<typename MatrixType , int Options>
template<typename HouseholderU , typename HouseholderV , typename NaiveU , typename NaiveV >
void Eigen::BDCSVD< MatrixType, Options >::copyUV ( const HouseholderU &  householderU,
const HouseholderV &  householderV,
const NaiveU &  naiveU,
const NaiveV &  naivev 
)
private
408  {
409  // Note exchange of U and V: m_matrixU is set from m_naiveV and vice versa
410  if (computeU()) {
411  Index Ucols = m_computeThinU ? diagSize() : rows();
412  m_matrixU = MatrixX::Identity(rows(), Ucols);
413  m_matrixU.topLeftCorner(diagSize(), diagSize()) =
414  naiveV.template cast<Scalar>().topLeftCorner(diagSize(), diagSize());
415  // FIXME the following conditionals involve temporary buffers
416  if (m_useQrDecomp)
417  m_matrixU.topLeftCorner(householderU.cols(), diagSize()).applyOnTheLeft(householderU);
418  else
419  m_matrixU.applyOnTheLeft(householderU);
420  }
421  if (computeV()) {
422  Index Vcols = m_computeThinV ? diagSize() : cols();
423  m_matrixV = MatrixX::Identity(cols(), Vcols);
424  m_matrixV.topLeftCorner(diagSize(), diagSize()) =
425  naiveU.template cast<Scalar>().topLeftCorner(diagSize(), diagSize());
426  // FIXME the following conditionals involve temporary buffers
427  if (m_useQrDecomp)
428  m_matrixV.topLeftCorner(householderV.cols(), diagSize()).applyOnTheLeft(householderV);
429  else
430  m_matrixV.applyOnTheLeft(householderV);
431  }
432 }
bool m_computeThinU
Definition: SVDBase.h:336
bool m_computeThinV
Definition: SVDBase.h:337

References cols, and rows.

◆ deflation()

template<typename MatrixType , int Options>
void Eigen::BDCSVD< MatrixType, Options >::deflation ( Index  firstCol,
Index  lastCol,
Index  k,
Index  firstRowW,
Index  firstColW,
Index  shift 
)
private
1249  {
1250  using std::abs;
1251  using std::sqrt;
1252  const Index length = lastCol + 1 - firstCol;
1253 
1254  Block<MatrixXr, Dynamic, 1> col0(m_computed, firstCol + shift, firstCol + shift, length, 1);
1255  Diagonal<MatrixXr> fulldiag(m_computed);
1256  VectorBlock<Diagonal<MatrixXr>, Dynamic> diag(fulldiag, firstCol + shift, length);
1257 
1258  const RealScalar considerZero = (std::numeric_limits<RealScalar>::min)();
1259  RealScalar maxDiag = diag.tail((std::max)(Index(1), length - 1)).cwiseAbs().maxCoeff();
1260  RealScalar epsilon_strict = numext::maxi<RealScalar>(considerZero, NumTraits<RealScalar>::epsilon() * maxDiag);
1261  RealScalar epsilon_coarse =
1262  Literal(8) * NumTraits<RealScalar>::epsilon() * numext::maxi<RealScalar>(col0.cwiseAbs().maxCoeff(), maxDiag);
1263 
1264 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
1265  eigen_internal_assert(m_naiveU.allFinite());
1266  eigen_internal_assert(m_naiveV.allFinite());
1267  eigen_internal_assert(m_computed.allFinite());
1268 #endif
1269 
1270 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
1271  std::cout << "\ndeflate:" << diag.head(k + 1).transpose() << " | "
1272  << diag.segment(k + 1, length - k - 1).transpose() << "\n";
1273 #endif
1274 
1275  // condition 4.1
1276  if (diag(0) < epsilon_coarse) {
1277 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
1278  std::cout << "deflation 4.1, because " << diag(0) << " < " << epsilon_coarse << "\n";
1279 #endif
1280  diag(0) = epsilon_coarse;
1281  }
1282 
1283  // condition 4.2
1284  for (Index i = 1; i < length; ++i)
1285  if (abs(col0(i)) < epsilon_strict) {
1286 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
1287  std::cout << "deflation 4.2, set z(" << i << ") to zero because " << abs(col0(i)) << " < " << epsilon_strict
1288  << " (diag(" << i << ")=" << diag(i) << ")\n";
1289 #endif
1290  col0(i) = Literal(0);
1291  }
1292 
1293  // condition 4.3
1294  for (Index i = 1; i < length; i++)
1295  if (diag(i) < epsilon_coarse) {
1296 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
1297  std::cout << "deflation 4.3, cancel z(" << i << ")=" << col0(i) << " because diag(" << i << ")=" << diag(i)
1298  << " < " << epsilon_coarse << "\n";
1299 #endif
1300  deflation43(firstCol, shift, i, length);
1301  }
1302 
1303 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
1304  eigen_internal_assert(m_naiveU.allFinite());
1305  eigen_internal_assert(m_naiveV.allFinite());
1306  eigen_internal_assert(m_computed.allFinite());
1307 #endif
1308 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
1309  std::cout << "to be sorted: " << diag.transpose() << "\n\n";
1310  std::cout << " : " << col0.transpose() << "\n\n";
1311 #endif
1312  {
1313  // Check for total deflation:
1314  // If we have a total deflation, then we have to consider col0(0)==diag(0) as a singular value during sorting.
1315  const bool total_deflation = (col0.tail(length - 1).array().abs() < considerZero).all();
1316 
1317  // Sort the diagonal entries, since diag(1:k-1) and diag(k:length) are already sorted, let's do a sorted merge.
1318  // First, compute the respective permutation.
1319  Index* permutation = m_workspaceI.data();
1320  {
1321  permutation[0] = 0;
1322  Index p = 1;
1323 
1324  // Move deflated diagonal entries at the end.
1325  for (Index i = 1; i < length; ++i)
1326  if (diag(i) < considerZero) permutation[p++] = i;
1327 
1328  Index i = 1, j = k + 1;
1329  for (; p < length; ++p) {
1330  if (i > k)
1331  permutation[p] = j++;
1332  else if (j >= length)
1333  permutation[p] = i++;
1334  else if (diag(i) < diag(j))
1335  permutation[p] = j++;
1336  else
1337  permutation[p] = i++;
1338  }
1339  }
1340 
1341  // If we have a total deflation, then we have to insert diag(0) at the right place
1342  if (total_deflation) {
1343  for (Index i = 1; i < length; ++i) {
1344  Index pi = permutation[i];
1345  if (diag(pi) < considerZero || diag(0) < diag(pi))
1346  permutation[i - 1] = permutation[i];
1347  else {
1348  permutation[i - 1] = 0;
1349  break;
1350  }
1351  }
1352  }
1353 
1354  // Current index of each col, and current column of each index
1355  Index* realInd = m_workspaceI.data() + length;
1356  Index* realCol = m_workspaceI.data() + 2 * length;
1357 
1358  for (int pos = 0; pos < length; pos++) {
1359  realCol[pos] = pos;
1360  realInd[pos] = pos;
1361  }
1362 
1363  for (Index i = total_deflation ? 0 : 1; i < length; i++) {
1364  const Index pi = permutation[length - (total_deflation ? i + 1 : i)];
1365  const Index J = realCol[pi];
1366 
1367  using std::swap;
1368  // swap diagonal and first column entries:
1369  swap(diag(i), diag(J));
1370  if (i != 0 && J != 0) swap(col0(i), col0(J));
1371 
1372  // change columns
1373  if (m_compU)
1374  m_naiveU.col(firstCol + i)
1375  .segment(firstCol, length + 1)
1376  .swap(m_naiveU.col(firstCol + J).segment(firstCol, length + 1));
1377  else
1378  m_naiveU.col(firstCol + i).segment(0, 2).swap(m_naiveU.col(firstCol + J).segment(0, 2));
1379  if (m_compV)
1380  m_naiveV.col(firstColW + i)
1381  .segment(firstRowW, length)
1382  .swap(m_naiveV.col(firstColW + J).segment(firstRowW, length));
1383 
1384  // update real pos
1385  const Index realI = realInd[i];
1386  realCol[realI] = J;
1387  realCol[pi] = i;
1388  realInd[J] = realI;
1389  realInd[i] = pi;
1390  }
1391  }
1392 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
1393  std::cout << "sorted: " << diag.transpose().format(bdcsvdfmt) << "\n";
1394  std::cout << " : " << col0.transpose() << "\n\n";
1395 #endif
1396 
1397  // condition 4.4
1398  {
1399  Index i = length - 1;
1400  // Find last non-deflated entry.
1401  while (i > 0 && (diag(i) < considerZero || abs(col0(i)) < considerZero)) --i;
1402 
1403  for (; i > 1; --i)
1404  if ((diag(i) - diag(i - 1)) < epsilon_strict) {
1405 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
1406  std::cout << "deflation 4.4 with i = " << i << " because " << diag(i) << " - " << diag(i - 1)
1407  << " == " << (diag(i) - diag(i - 1)) << " < " << epsilon_strict << "\n";
1408 #endif
1409  eigen_internal_assert(abs(diag(i) - diag(i - 1)) < epsilon_coarse &&
1410  " diagonal entries are not properly sorted");
1411  deflation44(firstCol, firstCol + shift, firstRowW, firstColW, i, i - 1, length);
1412  }
1413  }
1414 
1415 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
1416  for (Index j = 2; j < length; ++j) eigen_internal_assert(diag(j - 1) <= diag(j) || abs(diag(j)) < considerZero);
1417 #endif
1418 
1419 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
1420  eigen_internal_assert(m_naiveU.allFinite());
1421  eigen_internal_assert(m_naiveV.allFinite());
1422  eigen_internal_assert(m_computed.allFinite());
1423 #endif
1424 } // end deflation
JacobiRotation< float > J
Definition: Jacobi_makeJacobi.cpp:3
float * p
Definition: Tutorial_Map_using.cpp:9
void deflation43(Index firstCol, Index shift, Index i, Index size)
Definition: BDCSVD.h:1183
void deflation44(Index firstColu, Index firstColm, Index firstRowW, Index firstColW, Index i, Index j, Index size)
Definition: BDCSVD.h:1210
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void swap(DenseBase< OtherDerived > &other)
Override DenseBase::swap() since for dynamic-sized matrices of same type it is enough to swap the dat...
Definition: PlainObjectBase.h:898
const int Dynamic
Definition: Constants.h:25
const Mdouble pi
Definition: ExtendedMath.h:23
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References abs(), Eigen::placeholders::all, diag, Eigen::Dynamic, eigen_internal_assert, oomph::SarahBL::epsilon, i, J, j, k, max, min, p, constants::pi, sqrt(), Eigen::swap(), and swap().

◆ deflation43()

template<typename MatrixType , int Options>
void Eigen::BDCSVD< MatrixType, Options >::deflation43 ( Index  firstCol,
Index  shift,
Index  i,
Index  size 
)
private
1183  {
1184  using std::abs;
1185  using std::pow;
1186  using std::sqrt;
1187  Index start = firstCol + shift;
1190  RealScalar r = numext::hypot(c, s);
1191  if (numext::is_exactly_zero(r)) {
1192  m_computed(start + i, start + i) = Literal(0);
1193  return;
1194  }
1195  m_computed(start, start) = r;
1196  m_computed(start + i, start) = Literal(0);
1197  m_computed(start + i, start + i) = Literal(0);
1198 
1199  JacobiRotation<RealScalar> J(c / r, -s / r);
1200  if (m_compU)
1201  m_naiveU.middleRows(firstCol, size + 1).applyOnTheRight(firstCol, firstCol + i, J);
1202  else
1203  m_naiveU.applyOnTheRight(firstCol, firstCol + i, J);
1204 } // end deflation 43
RealScalar s
Definition: level1_cplx_impl.h:130
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 pow(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:625
r
Definition: UniformPSDSelfTest.py:20
int c
Definition: calibrate.py:100
void start(const unsigned &i)
(Re-)start i-th timer
Definition: oomph_utilities.cc:243
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index size() const EIGEN_NOEXCEPT
Definition: EigenBase.h:64

References abs(), calibrate::c, i, Eigen::numext::is_exactly_zero(), J, Eigen::bfloat16_impl::pow(), UniformPSDSelfTest::r, s, size, sqrt(), and oomph::CumulativeTimings::start().

◆ deflation44()

template<typename MatrixType , int Options>
void Eigen::BDCSVD< MatrixType, Options >::deflation44 ( Index  firstColu,
Index  firstColm,
Index  firstRowW,
Index  firstColW,
Index  i,
Index  j,
Index  size 
)
private
1211  {
1212  using std::abs;
1213  using std::conj;
1214  using std::pow;
1215  using std::sqrt;
1216 
1217  RealScalar s = m_computed(firstColm + i, firstColm);
1218  RealScalar c = m_computed(firstColm + j, firstColm);
1219  RealScalar r = numext::hypot(c, s);
1220 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
1221  std::cout << "deflation 4.4: " << i << "," << j << " -> " << c << " " << s << " " << r << " ; "
1222  << m_computed(firstColm + i - 1, firstColm) << " " << m_computed(firstColm + i, firstColm) << " "
1223  << m_computed(firstColm + i + 1, firstColm) << " " << m_computed(firstColm + i + 2, firstColm) << "\n";
1224  std::cout << m_computed(firstColm + i - 1, firstColm + i - 1) << " " << m_computed(firstColm + i, firstColm + i)
1225  << " " << m_computed(firstColm + i + 1, firstColm + i + 1) << " "
1226  << m_computed(firstColm + i + 2, firstColm + i + 2) << "\n";
1227 #endif
1228  if (numext::is_exactly_zero(r)) {
1229  m_computed(firstColm + j, firstColm + j) = m_computed(firstColm + i, firstColm + i);
1230  return;
1231  }
1232  c /= r;
1233  s /= r;
1234  m_computed(firstColm + j, firstColm) = r;
1235  m_computed(firstColm + j, firstColm + j) = m_computed(firstColm + i, firstColm + i);
1236  m_computed(firstColm + i, firstColm) = Literal(0);
1237 
1238  JacobiRotation<RealScalar> J(c, -s);
1239  if (m_compU)
1240  m_naiveU.middleRows(firstColu, size + 1).applyOnTheRight(firstColu + j, firstColu + i, J);
1241  else
1242  m_naiveU.applyOnTheRight(firstColu + j, firstColu + i, J);
1243  if (m_compV) m_naiveV.middleRows(firstRowW, size).applyOnTheRight(firstColW + j, firstColW + i, J);
1244 } // end deflation 44
AnnoyingScalar conj(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:133

References abs(), calibrate::c, conj(), i, Eigen::numext::is_exactly_zero(), J, j, Eigen::bfloat16_impl::pow(), UniformPSDSelfTest::r, s, size, and sqrt().

◆ divide()

template<typename MatrixType , int Options>
void Eigen::BDCSVD< MatrixType, Options >::divide ( Index  firstCol,
Index  lastCol,
Index  firstRowW,
Index  firstColW,
Index  shift 
)
private
508  {
509  // requires rows = cols + 1;
510  using std::abs;
511  using std::pow;
512  using std::sqrt;
513  const Index n = lastCol - firstCol + 1;
514  const Index k = n / 2;
515  const RealScalar considerZero = (std::numeric_limits<RealScalar>::min)();
516  RealScalar alphaK;
517  RealScalar betaK;
518  RealScalar r0;
519  RealScalar lambda, phi, c0, s0;
520  VectorType l, f;
521  // We use the other algorithm which is more efficient for small
522  // matrices.
523  if (n < m_algoswap) {
524  // FIXME this block involves temporaries
525  if (m_compV) {
526  JacobiSVD<MatrixXr, ComputeFullU | ComputeFullV> baseSvd;
527  computeBaseCase(baseSvd, n, firstCol, firstRowW, firstColW, shift);
528  } else {
529  JacobiSVD<MatrixXr, ComputeFullU> baseSvd;
530  computeBaseCase(baseSvd, n, firstCol, firstRowW, firstColW, shift);
531  }
532  return;
533  }
534  // We use the divide and conquer algorithm
535  alphaK = m_computed(firstCol + k, firstCol + k);
536  betaK = m_computed(firstCol + k + 1, firstCol + k);
537  // The divide must be done in that order in order to have good results. Divide change the data inside the submatrices
538  // and the divide of the right submatrice reads one column of the left submatrice. That's why we need to treat the
539  // right submatrix before the left one.
540  divide(k + 1 + firstCol, lastCol, k + 1 + firstRowW, k + 1 + firstColW, shift);
541  if (m_info != Success && m_info != NoConvergence) return;
542  divide(firstCol, k - 1 + firstCol, firstRowW, firstColW + 1, shift + 1);
543  if (m_info != Success && m_info != NoConvergence) return;
544 
545  if (m_compU) {
546  lambda = m_naiveU(firstCol + k, firstCol + k);
547  phi = m_naiveU(firstCol + k + 1, lastCol + 1);
548  } else {
549  lambda = m_naiveU(1, firstCol + k);
550  phi = m_naiveU(0, lastCol + 1);
551  }
552  r0 = sqrt((abs(alphaK * lambda) * abs(alphaK * lambda)) + abs(betaK * phi) * abs(betaK * phi));
553  if (m_compU) {
554  l = m_naiveU.row(firstCol + k).segment(firstCol, k);
555  f = m_naiveU.row(firstCol + k + 1).segment(firstCol + k + 1, n - k - 1);
556  } else {
557  l = m_naiveU.row(1).segment(firstCol, k);
558  f = m_naiveU.row(0).segment(firstCol + k + 1, n - k - 1);
559  }
560  if (m_compV) m_naiveV(firstRowW + k, firstColW) = Literal(1);
561  if (r0 < considerZero) {
562  c0 = Literal(1);
563  s0 = Literal(0);
564  } else {
565  c0 = alphaK * lambda / r0;
566  s0 = betaK * phi / r0;
567  }
568 
569 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
570  eigen_internal_assert(m_naiveU.allFinite());
571  eigen_internal_assert(m_naiveV.allFinite());
572  eigen_internal_assert(m_computed.allFinite());
573 #endif
574 
575  if (m_compU) {
576  MatrixXr q1(m_naiveU.col(firstCol + k).segment(firstCol, k + 1));
577  // we shiftW Q1 to the right
578  for (Index i = firstCol + k - 1; i >= firstCol; i--)
579  m_naiveU.col(i + 1).segment(firstCol, k + 1) = m_naiveU.col(i).segment(firstCol, k + 1);
580  // we shift q1 at the left with a factor c0
581  m_naiveU.col(firstCol).segment(firstCol, k + 1) = (q1 * c0);
582  // last column = q1 * - s0
583  m_naiveU.col(lastCol + 1).segment(firstCol, k + 1) = (q1 * (-s0));
584  // first column = q2 * s0
585  m_naiveU.col(firstCol).segment(firstCol + k + 1, n - k) =
586  m_naiveU.col(lastCol + 1).segment(firstCol + k + 1, n - k) * s0;
587  // q2 *= c0
588  m_naiveU.col(lastCol + 1).segment(firstCol + k + 1, n - k) *= c0;
589  } else {
590  RealScalar q1 = m_naiveU(0, firstCol + k);
591  // we shift Q1 to the right
592  for (Index i = firstCol + k - 1; i >= firstCol; i--) m_naiveU(0, i + 1) = m_naiveU(0, i);
593  // we shift q1 at the left with a factor c0
594  m_naiveU(0, firstCol) = (q1 * c0);
595  // last column = q1 * - s0
596  m_naiveU(0, lastCol + 1) = (q1 * (-s0));
597  // first column = q2 * s0
598  m_naiveU(1, firstCol) = m_naiveU(1, lastCol + 1) * s0;
599  // q2 *= c0
600  m_naiveU(1, lastCol + 1) *= c0;
601  m_naiveU.row(1).segment(firstCol + 1, k).setZero();
602  m_naiveU.row(0).segment(firstCol + k + 1, n - k - 1).setZero();
603  }
604 
605 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
606  eigen_internal_assert(m_naiveU.allFinite());
607  eigen_internal_assert(m_naiveV.allFinite());
608  eigen_internal_assert(m_computed.allFinite());
609 #endif
610 
611  m_computed(firstCol + shift, firstCol + shift) = r0;
612  m_computed.col(firstCol + shift).segment(firstCol + shift + 1, k) = alphaK * l.transpose().real();
613  m_computed.col(firstCol + shift).segment(firstCol + shift + k + 1, n - k - 1) = betaK * f.transpose().real();
614 
615 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
616  ArrayXr tmp1 = (m_computed.block(firstCol + shift, firstCol + shift, n, n)).jacobiSvd().singularValues();
617 #endif
618  // Second part: try to deflate singular values in combined matrix
619  deflation(firstCol, lastCol, k, firstRowW, firstColW, shift);
620 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
621  ArrayXr tmp2 = (m_computed.block(firstCol + shift, firstCol + shift, n, n)).jacobiSvd().singularValues();
622  std::cout << "\n\nj1 = " << tmp1.transpose().format(bdcsvdfmt) << "\n";
623  std::cout << "j2 = " << tmp2.transpose().format(bdcsvdfmt) << "\n\n";
624  std::cout << "err: " << ((tmp1 - tmp2).abs() > 1e-12 * tmp2.abs()).transpose() << "\n";
625  static int count = 0;
626  std::cout << "# " << ++count << "\n\n";
627  eigen_internal_assert((tmp1 - tmp2).matrix().norm() < 1e-14 * tmp2.matrix().norm());
628 // eigen_internal_assert(count<681);
629 // eigen_internal_assert(((tmp1-tmp2).abs()<1e-13*tmp2.abs()).all());
630 #endif
631 
632  // Third part: compute SVD of combined matrix
633  MatrixXr UofSVD, VofSVD;
634  VectorType singVals;
635  computeSVDofM(firstCol + shift, n, UofSVD, singVals, VofSVD);
636 
637 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
638  eigen_internal_assert(UofSVD.allFinite());
639  eigen_internal_assert(VofSVD.allFinite());
640 #endif
641 
642  if (m_compU)
643  structured_update(m_naiveU.block(firstCol, firstCol, n + 1, n + 1), UofSVD, (n + 2) / 2);
644  else {
645  Map<Matrix<RealScalar, 2, Dynamic>, Aligned> tmp(m_workspace.data(), 2, n + 1);
646  tmp.noalias() = m_naiveU.middleCols(firstCol, n + 1) * UofSVD;
647  m_naiveU.middleCols(firstCol, n + 1) = tmp;
648  }
649 
650  if (m_compV) structured_update(m_naiveV.block(firstRowW, firstColW, n, n), VofSVD, (n + 1) / 2);
651 
652 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
653  eigen_internal_assert(m_naiveU.allFinite());
654  eigen_internal_assert(m_naiveV.allFinite());
655  eigen_internal_assert(m_computed.allFinite());
656 #endif
657 
658  m_computed.block(firstCol + shift, firstCol + shift, n, n).setZero();
659  m_computed.block(firstCol + shift, firstCol + shift, n, n).diagonal() = singVals;
660 } // end divide
cout<< "The eigenvalues of A are:"<< endl<< ces.eigenvalues()<< endl;cout<< "The matrix of eigenvectors, V, is:"<< endl<< ces.eigenvectors()<< endl<< endl;complex< float > lambda
Definition: ComplexEigenSolver_compute.cpp:9
Array< double, 1, 3 > e(1./3., 0.5, 2.)
void structured_update(Block< MatrixXr, Dynamic, Dynamic > A, const MatrixXr &B, Index n1)
Definition: BDCSVD.h:443
void computeBaseCase(SVDType &svd, Index n, Index firstCol, Index firstRowW, Index firstColW, Index shift)
Definition: BDCSVD.h:478
void computeSVDofM(Index firstCol, Index n, MatrixXr &U, VectorType &singVals, MatrixXr &V)
Definition: BDCSVD.h:672
Array< RealScalar, Dynamic, 1 > ArrayXr
Definition: BDCSVD.h:120
void deflation(Index firstCol, Index lastCol, Index k, Index firstRowW, Index firstColW, Index shift)
Definition: BDCSVD.h:1248
const ConstTransposeReturnType transpose() const
Definition: SolverBase.h:120
static int f(const TensorMap< Tensor< int, 3 > > &tensor)
Definition: cxx11_tensor_map.cpp:237
@ Aligned
Definition: Constants.h:242
Eigen::Matrix< Scalar, Dynamic, Dynamic, ColMajor > tmp
Definition: level3_impl.h:365
Definition: fft_test_shared.h:66

References abs(), Eigen::Aligned, e(), eigen_internal_assert, f(), i, k, lambda, matrix(), min, n, Eigen::NoConvergence, Eigen::bfloat16_impl::pow(), sqrt(), Eigen::Success, tmp, and anonymous_namespace{skew_symmetric_matrix3.cpp}::transpose().

◆ perturbCol0()

template<typename MatrixType , int Options>
void Eigen::BDCSVD< MatrixType, Options >::perturbCol0 ( const ArrayRef col0,
const ArrayRef diag,
const IndicesRef perm,
const VectorType singVals,
const ArrayRef shifts,
const ArrayRef mus,
ArrayRef  zhat 
)
private
1065  {
1066  using std::sqrt;
1067  Index n = col0.size();
1068  Index m = perm.size();
1069  if (m == 0) {
1070  zhat.setZero();
1071  return;
1072  }
1073  Index lastIdx = perm(m - 1);
1074  // The offset permits to skip deflated entries while computing zhat
1075  for (Index k = 0; k < n; ++k) {
1076  if (numext::is_exactly_zero(col0(k))) // deflated
1077  zhat(k) = Literal(0);
1078  else {
1079  // see equation (3.6)
1080  RealScalar dk = diag(k);
1081  RealScalar prod = (singVals(lastIdx) + dk) * (mus(lastIdx) + (shifts(lastIdx) - dk));
1082 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
1083  if (prod < 0) {
1084  std::cout << "k = " << k << " ; z(k)=" << col0(k) << ", diag(k)=" << dk << "\n";
1085  std::cout << "prod = "
1086  << "(" << singVals(lastIdx) << " + " << dk << ") * (" << mus(lastIdx) << " + (" << shifts(lastIdx)
1087  << " - " << dk << "))"
1088  << "\n";
1089  std::cout << " = " << singVals(lastIdx) + dk << " * " << mus(lastIdx) + (shifts(lastIdx) - dk) << "\n";
1090  }
1092 #endif
1093 
1094  for (Index l = 0; l < m; ++l) {
1095  Index i = perm(l);
1096  if (i != k) {
1097 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
1098  if (i >= k && (l == 0 || l - 1 >= m)) {
1099  std::cout << "Error in perturbCol0\n";
1100  std::cout << " " << k << "/" << n << " " << l << "/" << m << " " << i << "/" << n << " ; " << col0(k)
1101  << " " << diag(k) << " "
1102  << "\n";
1103  std::cout << " " << diag(i) << "\n";
1104  Index j = (i < k /*|| l==0*/) ? i : perm(l - 1);
1105  std::cout << " "
1106  << "j=" << j << "\n";
1107  }
1108 #endif
1109  Index j = i < k ? i : l > 0 ? perm(l - 1) : i;
1110 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
1111  if (!(dk != Literal(0) || diag(i) != Literal(0))) {
1112  std::cout << "k=" << k << ", i=" << i << ", l=" << l << ", perm.size()=" << perm.size() << "\n";
1113  }
1114  eigen_internal_assert(dk != Literal(0) || diag(i) != Literal(0));
1115 #endif
1116  prod *= ((singVals(j) + dk) / ((diag(i) + dk))) * ((mus(j) + (shifts(j) - dk)) / ((diag(i) - dk)));
1117 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
1119 #endif
1120 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
1121  if (i != k &&
1122  numext::abs(((singVals(j) + dk) * (mus(j) + (shifts(j) - dk))) / ((diag(i) + dk) * (diag(i) - dk)) - 1) >
1123  0.9)
1124  std::cout << " "
1125  << ((singVals(j) + dk) * (mus(j) + (shifts(j) - dk))) / ((diag(i) + dk) * (diag(i) - dk))
1126  << " == (" << (singVals(j) + dk) << " * " << (mus(j) + (shifts(j) - dk)) << ") / ("
1127  << (diag(i) + dk) << " * " << (diag(i) - dk) << ")\n";
1128 #endif
1129  }
1130  }
1131 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
1132  std::cout << "zhat(" << k << ") = sqrt( " << prod << ") ; " << (singVals(lastIdx) + dk) << " * "
1133  << mus(lastIdx) + shifts(lastIdx) << " - " << dk << "\n";
1134 #endif
1135  RealScalar tmp = sqrt(prod);
1136 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
1138 #endif
1139  zhat(k) = col0(k) > Literal(0) ? RealScalar(tmp) : RealScalar(-tmp);
1140  }
1141  }
1142 }
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE std::enable_if_t< NumTraits< T >::IsSigned||NumTraits< T >::IsComplex, typename NumTraits< T >::Real > abs(const T &x)
Definition: MathFunctions.h:1355
const Product< Lhs, Rhs > prod(const Lhs &lhs, const Rhs &rhs)
Definition: evaluators.cpp:7

References Eigen::numext::abs(), diag, eigen_internal_assert, i, Eigen::numext::is_exactly_zero(), Eigen::numext::isfinite(), j, k, m, plotDoE::mus, n, Eigen::prod(), sqrt(), and tmp.

◆ rows()

◆ secularEq()

template<typename MatrixType , int Options>
BDCSVD< MatrixType, Options >::RealScalar Eigen::BDCSVD< MatrixType, Options >::secularEq ( RealScalar  x,
const ArrayRef col0,
const ArrayRef diag,
const IndicesRef perm,
const ArrayRef diagShifted,
RealScalar  shift 
)
staticprivate
807  {
808  Index m = perm.size();
809  RealScalar res = Literal(1);
810  for (Index i = 0; i < m; ++i) {
811  Index j = perm(i);
812  // The following expression could be rewritten to involve only a single division,
813  // but this would make the expression more sensitive to overflow.
814  res += (col0(j) / (diagShifted(j) - mu)) * (col0(j) / (diag(j) + shift + mu));
815  }
816  return res;
817 }
cout<< "Here is the matrix m:"<< endl<< m<< endl;Matrix< ptrdiff_t, 3, 1 > res
Definition: PartialRedux_count.cpp:3
std::complex< double > mu
Definition: time_harmonic_fourier_decomposed_linear_elasticity/cylinder/cylinder.cc:52

References diag, i, j, m, Global_Parameters::mu, and res.

◆ setSwitchSize()

template<typename MatrixType_ , int Options_>
void Eigen::BDCSVD< MatrixType_, Options_ >::setSwitchSize ( int  s)
inline
210  {
211  eigen_assert(s >= 3 && "BDCSVD the size of the algo switch has to be at least 3.");
212  m_algoswap = s;
213  }
#define eigen_assert(x)
Definition: Macros.h:910

References eigen_assert, Eigen::BDCSVD< MatrixType_, Options_ >::m_algoswap, and s.

Referenced by compare_bdc_jacobi().

◆ structured_update()

template<typename MatrixType , int Options>
void Eigen::BDCSVD< MatrixType, Options >::structured_update ( Block< MatrixXr, Dynamic, Dynamic A,
const MatrixXr B,
Index  n1 
)
private

Performs A = A * B exploiting the special structure of the matrix A. Splitting A as: A = [A1] [A2] such that A1.rows()==n1, then we assume that at least half of the columns of A1 and A2 are zeros. We can thus pack them prior to the the matrix product. However, this is only worth the effort if the matrix is large enough.

443  {
444  Index n = A.rows();
445  if (n > 100) {
446  // If the matrices are large enough, let's exploit the sparse structure of A by
447  // splitting it in half (wrt n1), and packing the non-zero columns.
448  Index n2 = n - n1;
449  Map<MatrixXr> A1(m_workspace.data(), n1, n);
450  Map<MatrixXr> A2(m_workspace.data() + n1 * n, n2, n);
451  Map<MatrixXr> B1(m_workspace.data() + n * n, n, n);
452  Map<MatrixXr> B2(m_workspace.data() + 2 * n * n, n, n);
453  Index k1 = 0, k2 = 0;
454  for (Index j = 0; j < n; ++j) {
455  if ((A.col(j).head(n1).array() != Literal(0)).any()) {
456  A1.col(k1) = A.col(j).head(n1);
457  B1.row(k1) = B.row(j);
458  ++k1;
459  }
460  if ((A.col(j).tail(n2).array() != Literal(0)).any()) {
461  A2.col(k2) = A.col(j).tail(n2);
462  B2.row(k2) = B.row(j);
463  ++k2;
464  }
465  }
466 
467  A.topRows(n1).noalias() = A1.leftCols(k1) * B1.topRows(k1);
468  A.bottomRows(n2).noalias() = A2.leftCols(k2) * B2.topRows(k2);
469  } else {
470  Map<MatrixXr, Aligned> tmp(m_workspace.data(), n, n);
471  tmp.noalias() = A * B;
472  A = tmp;
473  }
474 }
Matrix< SCALARA, Dynamic, Dynamic, opt_A > A
Definition: bench_gemm.cpp:47
Matrix< SCALARB, Dynamic, Dynamic, opt_B > B
Definition: bench_gemm.cpp:48
Definition: matrices.h:74

References j, n, Eigen::PlainObjectBase< Derived >::rows(), and tmp.

Member Data Documentation

◆ bid

template<typename MatrixType_ , int Options_>
internal::UpperBidiagonalization<MatrixX> Eigen::BDCSVD< MatrixType_, Options_ >::bid
protected

◆ copyWorkspace

template<typename MatrixType_ , int Options_>
MatrixX Eigen::BDCSVD< MatrixType_, Options_ >::copyWorkspace
protected

◆ m_algoswap

template<typename MatrixType_ , int Options_>
int Eigen::BDCSVD< MatrixType_, Options_ >::m_algoswap
protected

◆ m_compU

template<typename MatrixType_ , int Options_>
bool Eigen::BDCSVD< MatrixType_, Options_ >::m_compU
protected

◆ m_computed

template<typename MatrixType_ , int Options_>
MatrixXr Eigen::BDCSVD< MatrixType_, Options_ >::m_computed
protected

◆ m_compV

template<typename MatrixType_ , int Options_>
bool Eigen::BDCSVD< MatrixType_, Options_ >::m_compV
protected

◆ m_isTranspose

template<typename MatrixType_ , int Options_>
bool Eigen::BDCSVD< MatrixType_, Options_ >::m_isTranspose
protected

◆ m_naiveU

template<typename MatrixType_ , int Options_>
MatrixXr Eigen::BDCSVD< MatrixType_, Options_ >::m_naiveU
protected

◆ m_naiveV

template<typename MatrixType_ , int Options_>
MatrixXr Eigen::BDCSVD< MatrixType_, Options_ >::m_naiveV
protected

◆ m_nRec

template<typename MatrixType_ , int Options_>
Index Eigen::BDCSVD< MatrixType_, Options_ >::m_nRec
protected

◆ m_numIters

template<typename MatrixType_ , int Options_>
int Eigen::BDCSVD< MatrixType_, Options_ >::m_numIters

◆ m_useQrDecomp

template<typename MatrixType_ , int Options_>
bool Eigen::BDCSVD< MatrixType_, Options_ >::m_useQrDecomp
protected

◆ m_workspace

template<typename MatrixType_ , int Options_>
ArrayXr Eigen::BDCSVD< MatrixType_, Options_ >::m_workspace
protected

◆ m_workspaceI

template<typename MatrixType_ , int Options_>
ArrayXi Eigen::BDCSVD< MatrixType_, Options_ >::m_workspaceI
protected

◆ qrDecomp

template<typename MatrixType_ , int Options_>
HouseholderQR<MatrixX> Eigen::BDCSVD< MatrixType_, Options_ >::qrDecomp
protected

◆ reducedTriangle

template<typename MatrixType_ , int Options_>
MatrixX Eigen::BDCSVD< MatrixType_, Options_ >::reducedTriangle
protected

◆ smallSvd

template<typename MatrixType_ , int Options_>
JacobiSVD<MatrixType, ComputationOptions> Eigen::BDCSVD< MatrixType_, Options_ >::smallSvd
protected

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