11 #ifndef EIGEN_BIDIAGONALIZATION_H
12 #define EIGEN_BIDIAGONALIZATION_H
22 template<
typename MatrixType_>
class UpperBidiagonalization
28 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
29 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
30 ColsAtCompileTimeMinusOne = internal::decrement_size<ColsAtCompileTime>::ret
35 typedef Matrix<Scalar, 1, ColsAtCompileTime> RowVectorType;
36 typedef Matrix<Scalar, RowsAtCompileTime, 1> ColVectorType;
37 typedef BandMatrix<RealScalar, ColsAtCompileTime, ColsAtCompileTime, 1, 0, RowMajor> BidiagonalType;
38 typedef Matrix<Scalar, ColsAtCompileTime, 1> DiagVectorType;
39 typedef Matrix<Scalar, ColsAtCompileTimeMinusOne, 1> SuperDiagVectorType;
40 typedef HouseholderSequence<
42 const internal::remove_all_t<typename Diagonal<const MatrixType,0>::ConjugateReturnType>
43 > HouseholderUSequenceType;
44 typedef HouseholderSequence<
45 const internal::remove_all_t<typename MatrixType::ConjugateReturnType>,
46 Diagonal<const MatrixType,1>,
48 > HouseholderVSequenceType;
56 UpperBidiagonalization() : m_householder(), m_bidiagonal(0, 0), m_isInitialized(false) {}
58 explicit UpperBidiagonalization(
const MatrixType& matrix)
59 : m_householder(matrix.
rows(), matrix.
cols()),
60 m_bidiagonal(matrix.
cols(), matrix.
cols()),
61 m_isInitialized(false)
69 m_isInitialized(false)
73 UpperBidiagonalization& computeUnblocked(
const MatrixType& matrix);
75 const MatrixType& householder()
const {
return m_householder; }
76 const BidiagonalType& bidiagonal()
const {
return m_bidiagonal; }
78 const HouseholderUSequenceType householderU()
const
80 eigen_assert(m_isInitialized &&
"UpperBidiagonalization is not initialized.");
81 return HouseholderUSequenceType(m_householder, m_householder.diagonal().conjugate());
84 const HouseholderVSequenceType householderV()
86 eigen_assert(m_isInitialized &&
"UpperBidiagonalization is not initialized.");
87 return HouseholderVSequenceType(m_householder.conjugate(), m_householder.const_derived().template diagonal<1>())
88 .setLength(m_householder.cols()-1)
94 BidiagonalType m_bidiagonal;
100 template<
typename MatrixType>
104 typename MatrixType::Scalar* tempData = 0)
106 typedef typename MatrixType::Scalar Scalar;
116 tempData = tempVector.data();
119 for (
Index k = 0; ; ++k)
125 mat.col(k).tail(remainingRows)
126 .makeHouseholderInPlace(
mat.coeffRef(k,k), diagonal[k]);
128 mat.bottomRightCorner(remainingRows, remainingCols)
129 .applyHouseholderOnTheLeft(
mat.col(k).tail(remainingRows-1),
mat.coeff(k,k), tempData);
131 if(k ==
cols-1)
break;
134 mat.row(k).tail(remainingCols)
135 .makeHouseholderInPlace(
mat.coeffRef(k,k+1), upper_diagonal[k]);
137 mat.bottomRightCorner(remainingRows-1, remainingCols)
138 .applyHouseholderOnTheRight(
mat.row(k).tail(remainingCols-1).adjoint(),
mat.coeff(k,k+1), tempData);
159 template<
typename MatrixType>
169 typedef typename MatrixType::Scalar Scalar;
182 Scalar tau_u, tau_u_prev(0), tau_v;
184 for(
Index k = 0; k < bs; ++k)
186 Index remainingRows = brows - k;
187 Index remainingCols = bcols - k - 1;
189 SubMatType X_k1(
X.block(k,0, remainingRows,k) );
190 SubMatType V_k1(
A.block(k,0, remainingRows,k) );
193 SubColumnType v_k =
A.col(k).tail(remainingRows);
194 v_k -= V_k1 * Y.row(k).head(k).adjoint();
195 if(k) v_k -= X_k1 *
A.col(k).head(k);
198 v_k.makeHouseholderInPlace(tau_v, diagonal[k]);
202 SubMatType Y_k ( Y.block(k+1,0, remainingCols, k+1) );
203 SubMatType U_k1 (
A.block(0,k+1, k,remainingCols) );
211 SubColumnType y_k( Y.col(k).tail(remainingCols) );
214 SubColumnType tmp( Y.col(k).head(k) );
215 y_k.noalias() =
A.block(k,k+1, remainingRows,remainingCols).adjoint() * v_k;
216 tmp.noalias() = V_k1.adjoint() * v_k;
217 y_k.noalias() -= Y_k.leftCols(k) * tmp;
218 tmp.noalias() = X_k1.adjoint() * v_k;
219 y_k.noalias() -= U_k1.adjoint() * tmp;
224 SubRowType u_k(
A.row(k).tail(remainingCols) );
225 u_k = u_k.conjugate();
227 u_k -= Y_k *
A.row(k).head(k+1).adjoint();
228 if(k) u_k -= U_k1.adjoint() *
X.row(k).head(k).adjoint();
232 u_k.makeHouseholderInPlace(tau_u, upper_diagonal[k]);
236 A(k,k+1) = Scalar(1);
240 SubColumnType x_k (
X.col(k).tail(remainingRows-1) );
244 SubColumnType tmp0 (
X.col(k).head(k) ),
245 tmp1 (
X.col(k).head(k+1) );
247 x_k.noalias() =
A.block(k+1,k+1, remainingRows-1,remainingCols) * u_k.transpose();
248 tmp0.noalias() = U_k1 * u_k.transpose();
249 x_k.noalias() -= X_k1.bottomRows(remainingRows-1) * tmp0;
250 tmp1.noalias() = Y_k.adjoint() * u_k.transpose();
251 x_k.noalias() -=
A.block(k+1,0, remainingRows-1,k+1) * tmp1;
254 u_k = u_k.conjugate();
257 if(k>0)
A.coeffRef(k-1,k) = tau_u_prev;
261 A.coeffRef(k-1,k) = tau_u_prev;
263 A.coeffRef(k,k) = tau_v;
267 A.coeffRef(bs-1,bs) = tau_u_prev;
270 if(bcols>bs && brows>bs)
272 SubMatType A11(
A.bottomRightCorner(brows-bs,bcols-bs) );
273 SubMatType A10(
A.block(bs,0, brows-bs,bs) );
274 SubMatType A01(
A.block(0,bs, bs,bcols-bs) );
275 Scalar tmp = A01(bs-1,0);
276 A01(bs-1,0) = Literal(1);
277 A11.noalias() -= A10 * Y.topLeftCorner(bcols,bs).bottomRows(bcols-bs).adjoint();
278 A11.noalias() -=
X.topLeftCorner(brows,bs).bottomRows(brows-bs) * A01;
291 template<
typename MatrixType,
typename B
idiagType>
293 Index maxBlockSize=32,
294 typename MatrixType::Scalar* = 0)
296 typedef typename MatrixType::Scalar Scalar;
306 MatrixType::RowsAtCompileTime,
309 MatrixType::MaxRowsAtCompileTime>
X(
rows,maxBlockSize);
311 MatrixType::ColsAtCompileTime,
314 MatrixType::MaxColsAtCompileTime> Y(
cols,maxBlockSize);
318 for(k = 0; k <
size; k += blockSize)
338 BlockType
B =
A.block(k,k,brows,bcols);
344 if(k+bs==
cols || bcols<48)
347 &(bidiagonal.template diagonal<0>().coeffRef(k)),
348 &(bidiagonal.template diagonal<1>().coeffRef(k)),
355 upperbidiagonalization_blocked_helper<BlockType>(
B,
356 &(bidiagonal.template diagonal<0>().coeffRef(k)),
357 &(bidiagonal.template diagonal<1>().coeffRef(k)),
359 X.topLeftCorner(brows,bs),
360 Y.topLeftCorner(bcols,bs)
366 template<
typename MatrixType_>
367 UpperBidiagonalization<MatrixType_>& UpperBidiagonalization<MatrixType_>::computeUnblocked(
const MatrixType_& matrix)
373 eigen_assert(
rows >=
cols &&
"UpperBidiagonalization is only for Arices satisfying rows>=cols.");
375 m_householder = matrix;
377 ColVectorType temp(
rows);
380 &(m_bidiagonal.template diagonal<0>().coeffRef(0)),
381 &(m_bidiagonal.template diagonal<1>().coeffRef(0)),
384 m_isInitialized =
true;
388 template<
typename MatrixType_>
396 eigen_assert(
rows >=
cols &&
"UpperBidiagonalization is only for Arices satisfying rows>=cols.");
398 m_householder = matrix;
401 m_isInitialized =
true;
410 template<
typename Derived>
411 const UpperBidiagonalization<typename MatrixBase<Derived>::PlainObject>
412 MatrixBase<Derived>::bidiagonalization()
const
414 return UpperBidiagonalization<PlainObject>(eval());
#define EIGEN_ONLY_USED_FOR_DEBUG(x)
Matrix< float, 1, Dynamic > MatrixType
Expression of a fixed-size or dynamic-size block.
NumTraits< Scalar >::Real RealScalar
internal::traits< Derived >::Scalar Scalar
Convenience specialization of Stride to specify only an inner stride See class Map for some examples.
The matrix class, also used for vectors and row-vectors.
constexpr void resize(Index rows, Index cols)
A matrix or vector expression mapping an existing expression.
const unsigned int RowMajorBit
bfloat16() min(const bfloat16 &a, const bfloat16 &b)
void upperbidiagonalization_inplace_unblocked(MatrixType &mat, typename MatrixType::RealScalar *diagonal, typename MatrixType::RealScalar *upper_diagonal, typename MatrixType::Scalar *tempData=0)
void upperbidiagonalization_inplace_blocked(MatrixType &A, BidiagType &bidiagonal, Index maxBlockSize=32, typename MatrixType::Scalar *=0)
void upperbidiagonalization_blocked_helper(MatrixType &A, typename MatrixType::RealScalar *diagonal, typename MatrixType::RealScalar *upper_diagonal, Index bs, Ref< Matrix< typename MatrixType::Scalar, Dynamic, Dynamic, traits< MatrixType >::Flags &RowMajorBit > > X, Ref< Matrix< typename MatrixType::Scalar, Dynamic, Dynamic, traits< MatrixType >::Flags &RowMajorBit > > Y)
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_conjugate_op< typename Derived::Scalar >, const Derived > conj(const Eigen::ArrayBase< Derived > &x)
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.