aboutsummaryrefslogtreecommitdiffhomepage
path: root/third_party/eigen3/Eigen/src/SVD/UpperBidiagonalization.h
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/eigen3/Eigen/src/SVD/UpperBidiagonalization.h')
-rw-r--r--third_party/eigen3/Eigen/src/SVD/UpperBidiagonalization.h396
1 files changed, 0 insertions, 396 deletions
diff --git a/third_party/eigen3/Eigen/src/SVD/UpperBidiagonalization.h b/third_party/eigen3/Eigen/src/SVD/UpperBidiagonalization.h
deleted file mode 100644
index 40067682c9..0000000000
--- a/third_party/eigen3/Eigen/src/SVD/UpperBidiagonalization.h
+++ /dev/null
@@ -1,396 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_BIDIAGONALIZATION_H
-#define EIGEN_BIDIAGONALIZATION_H
-
-namespace Eigen {
-
-namespace internal {
-// UpperBidiagonalization will probably be replaced by a Bidiagonalization class, don't want to make it stable API.
-// At the same time, it's useful to keep for now as it's about the only thing that is testing the BandMatrix class.
-
-template<typename _MatrixType> class UpperBidiagonalization
-{
- public:
-
- typedef _MatrixType MatrixType;
- enum {
- RowsAtCompileTime = MatrixType::RowsAtCompileTime,
- ColsAtCompileTime = MatrixType::ColsAtCompileTime,
- ColsAtCompileTimeMinusOne = internal::decrement_size<ColsAtCompileTime>::ret
- };
- typedef typename MatrixType::Scalar Scalar;
- typedef typename MatrixType::RealScalar RealScalar;
- typedef typename MatrixType::Index Index;
- typedef Matrix<Scalar, 1, ColsAtCompileTime> RowVectorType;
- typedef Matrix<Scalar, RowsAtCompileTime, 1> ColVectorType;
- typedef BandMatrix<RealScalar, ColsAtCompileTime, ColsAtCompileTime, 1, 0, RowMajor> BidiagonalType;
- typedef Matrix<Scalar, ColsAtCompileTime, 1> DiagVectorType;
- typedef Matrix<Scalar, ColsAtCompileTimeMinusOne, 1> SuperDiagVectorType;
- typedef HouseholderSequence<
- const MatrixType,
- CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, const Diagonal<const MatrixType,0> >
- > HouseholderUSequenceType;
- typedef HouseholderSequence<
- const typename internal::remove_all<typename MatrixType::ConjugateReturnType>::type,
- Diagonal<const MatrixType,1>,
- OnTheRight
- > HouseholderVSequenceType;
-
- /**
- * \brief Default Constructor.
- *
- * The default constructor is useful in cases in which the user intends to
- * perform decompositions via Bidiagonalization::compute(const MatrixType&).
- */
- UpperBidiagonalization() : m_householder(), m_bidiagonal(), m_isInitialized(false) {}
-
- UpperBidiagonalization(const MatrixType& matrix)
- : m_householder(matrix.rows(), matrix.cols()),
- m_bidiagonal(matrix.cols(), matrix.cols()),
- m_isInitialized(false)
- {
- compute(matrix);
- }
-
- UpperBidiagonalization& compute(const MatrixType& matrix);
- UpperBidiagonalization& computeUnblocked(const MatrixType& matrix);
-
- const MatrixType& householder() const { return m_householder; }
- const BidiagonalType& bidiagonal() const { return m_bidiagonal; }
-
- const HouseholderUSequenceType householderU() const
- {
- eigen_assert(m_isInitialized && "UpperBidiagonalization is not initialized.");
- return HouseholderUSequenceType(m_householder, m_householder.diagonal().conjugate());
- }
-
- const HouseholderVSequenceType householderV() // const here gives nasty errors and i'm lazy
- {
- eigen_assert(m_isInitialized && "UpperBidiagonalization is not initialized.");
- return HouseholderVSequenceType(m_householder.conjugate(), m_householder.const_derived().template diagonal<1>())
- .setLength(m_householder.cols()-1)
- .setShift(1);
- }
-
- protected:
- MatrixType m_householder;
- BidiagonalType m_bidiagonal;
- bool m_isInitialized;
-};
-
-// Standard upper bidiagonalization without fancy optimizations
-// This version should be faster for small matrix size
-template<typename MatrixType>
-void upperbidiagonalization_inplace_unblocked(MatrixType& mat,
- typename MatrixType::RealScalar *diagonal,
- typename MatrixType::RealScalar *upper_diagonal,
- typename MatrixType::Scalar* tempData = 0)
-{
- typedef typename MatrixType::Index Index;
- typedef typename MatrixType::Scalar Scalar;
-
- Index rows = mat.rows();
- Index cols = mat.cols();
-
- typedef Matrix<Scalar,Dynamic,1,ColMajor,MatrixType::MaxRowsAtCompileTime,1> TempType;
- TempType tempVector;
- if(tempData==0)
- {
- tempVector.resize(rows);
- tempData = tempVector.data();
- }
-
- for (Index k = 0; /* breaks at k==cols-1 below */ ; ++k)
- {
- Index remainingRows = rows - k;
- Index remainingCols = cols - k - 1;
-
- // construct left householder transform in-place in A
- mat.col(k).tail(remainingRows)
- .makeHouseholderInPlace(mat.coeffRef(k,k), diagonal[k]);
- // apply householder transform to remaining part of A on the left
- mat.bottomRightCorner(remainingRows, remainingCols)
- .applyHouseholderOnTheLeft(mat.col(k).tail(remainingRows-1), mat.coeff(k,k), tempData);
-
- if(k == cols-1) break;
-
- // construct right householder transform in-place in mat
- mat.row(k).tail(remainingCols)
- .makeHouseholderInPlace(mat.coeffRef(k,k+1), upper_diagonal[k]);
- // apply householder transform to remaining part of mat on the left
- mat.bottomRightCorner(remainingRows-1, remainingCols)
- .applyHouseholderOnTheRight(mat.row(k).tail(remainingCols-1).transpose(), mat.coeff(k,k+1), tempData);
- }
-}
-
-/** \internal
- * Helper routine for the block reduction to upper bidiagonal form.
- *
- * Let's partition the matrix A:
- *
- * | A00 A01 |
- * A = | |
- * | A10 A11 |
- *
- * This function reduces to bidiagonal form the left \c rows x \a blockSize vertical panel [A00/A10]
- * and the \a blockSize x \c cols horizontal panel [A00 A01] of the matrix \a A. The bottom-right block A11
- * is updated using matrix-matrix products:
- * A22 -= V * Y^T - X * U^T
- * where V and U contains the left and right Householder vectors. U and V are stored in A10, and A01
- * respectively, and the update matrices X and Y are computed during the reduction.
- *
- */
-template<typename MatrixType>
-void upperbidiagonalization_blocked_helper(MatrixType& A,
- typename MatrixType::RealScalar *diagonal,
- typename MatrixType::RealScalar *upper_diagonal,
- typename MatrixType::Index bs,
- Ref<Matrix<typename MatrixType::Scalar, Dynamic, Dynamic> > X,
- Ref<Matrix<typename MatrixType::Scalar, Dynamic, Dynamic> > Y)
-{
- typedef typename MatrixType::Index Index;
- typedef typename MatrixType::Scalar Scalar;
- typedef Ref<Matrix<Scalar, Dynamic, 1> > SubColumnType;
- typedef Ref<Matrix<Scalar, 1, Dynamic>, 0, InnerStride<> > SubRowType;
- typedef Ref<Matrix<Scalar, Dynamic, Dynamic> > SubMatType;
-
- Index brows = A.rows();
- Index bcols = A.cols();
-
- Scalar tau_u, tau_u_prev(0), tau_v;
-
- for(Index k = 0; k < bs; ++k)
- {
- Index remainingRows = brows - k;
- Index remainingCols = bcols - k - 1;
-
- SubMatType X_k1( X.block(k,0, remainingRows,k) );
- SubMatType V_k1( A.block(k,0, remainingRows,k) );
-
- // 1 - update the k-th column of A
- SubColumnType v_k = A.col(k).tail(remainingRows);
- v_k -= V_k1 * Y.row(k).head(k).adjoint();
- if(k) v_k -= X_k1 * A.col(k).head(k);
-
- // 2 - construct left Householder transform in-place
- v_k.makeHouseholderInPlace(tau_v, diagonal[k]);
-
- if(k+1<bcols)
- {
- SubMatType Y_k ( Y.block(k+1,0, remainingCols, k+1) );
- SubMatType U_k1 ( A.block(0,k+1, k,remainingCols) );
-
- // this eases the application of Householder transforAions
- // A(k,k) will store tau_v later
- A(k,k) = Scalar(1);
-
- // 3 - Compute y_k^T = tau_v * ( A^T*v_k - Y_k-1*V_k-1^T*v_k - U_k-1*X_k-1^T*v_k )
- {
- SubColumnType y_k( Y.col(k).tail(remainingCols) );
-
- // let's use the begining of column k of Y as a temporary vector
- SubColumnType tmp( Y.col(k).head(k) );
- y_k.noalias() = A.block(k,k+1, remainingRows,remainingCols).adjoint() * v_k; // bottleneck
- tmp.noalias() = V_k1.adjoint() * v_k;
- y_k.noalias() -= Y_k.leftCols(k) * tmp;
- tmp.noalias() = X_k1.adjoint() * v_k;
- y_k.noalias() -= U_k1.adjoint() * tmp;
- y_k *= numext::conj(tau_v);
- }
-
- // 4 - update k-th row of A (it will become u_k)
- SubRowType u_k( A.row(k).tail(remainingCols) );
- u_k = u_k.conjugate();
- {
- u_k -= Y_k * A.row(k).head(k+1).adjoint();
- if(k) u_k -= U_k1.adjoint() * X.row(k).head(k).adjoint();
- }
-
- // 5 - construct right Householder transform in-placecols
- u_k.makeHouseholderInPlace(tau_u, upper_diagonal[k]);
-
- // this eases the application of Householder transforAions
- // A(k,k+1) will store tau_u later
- A(k,k+1) = Scalar(1);
-
- // 6 - Compute x_k = tau_u * ( A*u_k - X_k-1*U_k-1^T*u_k - V_k*Y_k^T*u_k )
- {
- SubColumnType x_k ( X.col(k).tail(remainingRows-1) );
-
- // let's use the begining of column k of X as a temporary vectors
- // note that tmp0 and tmp1 overlaps
- SubColumnType tmp0 ( X.col(k).head(k) ),
- tmp1 ( X.col(k).head(k+1) );
-
- x_k.noalias() = A.block(k+1,k+1, remainingRows-1,remainingCols) * u_k.transpose(); // bottleneck
- tmp0.noalias() = U_k1 * u_k.transpose();
- x_k.noalias() -= X_k1.bottomRows(remainingRows-1) * tmp0;
- tmp1.noalias() = Y_k.adjoint() * u_k.transpose();
- x_k.noalias() -= A.block(k+1,0, remainingRows-1,k+1) * tmp1;
- x_k *= numext::conj(tau_u);
- tau_u = numext::conj(tau_u);
- u_k = u_k.conjugate();
- }
-
- if(k>0) A.coeffRef(k-1,k) = tau_u_prev;
- tau_u_prev = tau_u;
- }
- else
- A.coeffRef(k-1,k) = tau_u_prev;
-
- A.coeffRef(k,k) = tau_v;
- }
-
- if(bs<bcols)
- A.coeffRef(bs-1,bs) = tau_u_prev;
-
- // update A22
- if(bcols>bs && brows>bs)
- {
- SubMatType A11( A.bottomRightCorner(brows-bs,bcols-bs) );
- SubMatType A10( A.block(bs,0, brows-bs,bs) );
- SubMatType A01( A.block(0,bs, bs,bcols-bs) );
- Scalar tmp = A01(bs-1,0);
- A01(bs-1,0) = 1;
- A11.noalias() -= A10 * Y.topLeftCorner(bcols,bs).bottomRows(bcols-bs).adjoint();
- A11.noalias() -= X.topLeftCorner(brows,bs).bottomRows(brows-bs) * A01;
- A01(bs-1,0) = tmp;
- }
-}
-
-/** \internal
- *
- * Implementation of a block-bidiagonal reduction.
- * It is based on the following paper:
- * The Design of a Parallel Dense Linear Algebra Software Library: Reduction to Hessenberg, Tridiagonal, and Bidiagonal Form.
- * by Jaeyoung Choi, Jack J. Dongarra, David W. Walker. (1995)
- * section 3.3
- */
-template<typename MatrixType, typename BidiagType>
-void upperbidiagonalization_inplace_blocked(MatrixType& A, BidiagType& bidiagonal,
- typename MatrixType::Index maxBlockSize=32,
- typename MatrixType::Scalar* /*tempData*/ = 0)
-{
- typedef typename MatrixType::Index Index;
- typedef typename MatrixType::Scalar Scalar;
- typedef Block<MatrixType,Dynamic,Dynamic> BlockType;
-
- Index rows = A.rows();
- Index cols = A.cols();
- Index size = (std::min)(rows, cols);
-
- Matrix<Scalar,MatrixType::RowsAtCompileTime,Dynamic,ColMajor,MatrixType::MaxRowsAtCompileTime> X(rows,maxBlockSize);
- Matrix<Scalar,MatrixType::ColsAtCompileTime,Dynamic,ColMajor,MatrixType::MaxColsAtCompileTime> Y(cols,maxBlockSize);
- Index blockSize = (std::min)(maxBlockSize,size);
-
- Index k = 0;
- for(k = 0; k < size; k += blockSize)
- {
- Index bs = (std::min)(size-k,blockSize); // actual size of the block
- Index brows = rows - k; // rows of the block
- Index bcols = cols - k; // columns of the block
-
- // partition the matrix A:
- //
- // | A00 A01 A02 |
- // | |
- // A = | A10 A11 A12 |
- // | |
- // | A20 A21 A22 |
- //
- // where A11 is a bs x bs diagonal block,
- // and let:
- // | A11 A12 |
- // B = | |
- // | A21 A22 |
-
- BlockType B = A.block(k,k,brows,bcols);
-
- // This stage performs the bidiagonalization of A11, A21, A12, and updating of A22.
- // Finally, the algorithm continue on the updated A22.
- //
- // However, if B is too small, or A22 empty, then let's use an unblocked strategy
- if(k+bs==cols || bcols<48) // somewhat arbitrary threshold
- {
- upperbidiagonalization_inplace_unblocked(B,
- &(bidiagonal.template diagonal<0>().coeffRef(k)),
- &(bidiagonal.template diagonal<1>().coeffRef(k)),
- X.data()
- );
- break; // We're done
- }
- else
- {
- upperbidiagonalization_blocked_helper<BlockType>( B,
- &(bidiagonal.template diagonal<0>().coeffRef(k)),
- &(bidiagonal.template diagonal<1>().coeffRef(k)),
- bs,
- X.topLeftCorner(brows,bs),
- Y.topLeftCorner(bcols,bs)
- );
- }
- }
-}
-
-template<typename _MatrixType>
-UpperBidiagonalization<_MatrixType>& UpperBidiagonalization<_MatrixType>::computeUnblocked(const _MatrixType& matrix)
-{
- Index rows = matrix.rows();
- Index cols = matrix.cols();
-
- eigen_assert(rows >= cols && "UpperBidiagonalization is only for Arices satisfying rows>=cols.");
-
- m_householder = matrix;
-
- ColVectorType temp(rows);
-
- upperbidiagonalization_inplace_unblocked(m_householder,
- &(m_bidiagonal.template diagonal<0>().coeffRef(0)),
- &(m_bidiagonal.template diagonal<1>().coeffRef(0)),
- temp.data());
-
- m_isInitialized = true;
- return *this;
-}
-
-template<typename _MatrixType>
-UpperBidiagonalization<_MatrixType>& UpperBidiagonalization<_MatrixType>::compute(const _MatrixType& matrix)
-{
- Index rows = matrix.rows();
- Index cols = matrix.cols();
-
- eigen_assert(rows >= cols && "UpperBidiagonalization is only for Arices satisfying rows>=cols.");
-
- m_householder = matrix;
- upperbidiagonalization_inplace_blocked(m_householder, m_bidiagonal);
-
- m_isInitialized = true;
- return *this;
-}
-
-#if 0
-/** \return the Householder QR decomposition of \c *this.
- *
- * \sa class Bidiagonalization
- */
-template<typename Derived>
-const UpperBidiagonalization<typename MatrixBase<Derived>::PlainObject>
-MatrixBase<Derived>::bidiagonalization() const
-{
- return UpperBidiagonalization<PlainObject>(eval());
-}
-#endif
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_BIDIAGONALIZATION_H