11#ifndef EIGEN_BIDIAGONALIZATION_H
12#define EIGEN_BIDIAGONALIZATION_H
24 typedef _MatrixType MatrixType;
26 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
27 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
30 typedef typename MatrixType::Scalar Scalar;
31 typedef typename MatrixType::RealScalar RealScalar;
43 const typename internal::remove_all<typename MatrixType::ConjugateReturnType>::type,
57 : m_householder(matrix.rows(), matrix.cols()),
58 m_bidiagonal(matrix.cols(), matrix.cols()),
59 m_isInitialized(
false)
67 const MatrixType& householder()
const {
return m_householder; }
68 const BidiagonalType& bidiagonal()
const {
return m_bidiagonal; }
70 const HouseholderUSequenceType householderU()
const
72 eigen_assert(m_isInitialized &&
"UpperBidiagonalization is not initialized.");
73 return HouseholderUSequenceType(m_householder, m_householder.diagonal().conjugate());
76 const HouseholderVSequenceType householderV()
78 eigen_assert(m_isInitialized &&
"UpperBidiagonalization is not initialized.");
79 return HouseholderVSequenceType(m_householder.conjugate(), m_householder.const_derived().template diagonal<1>())
80 .setLength(m_householder.cols()-1)
85 MatrixType m_householder;
86 BidiagonalType m_bidiagonal;
92template<
typename MatrixType>
93void upperbidiagonalization_inplace_unblocked(MatrixType& mat,
94 typename MatrixType::RealScalar *diagonal,
95 typename MatrixType::RealScalar *upper_diagonal,
96 typename MatrixType::Scalar* tempData = 0)
98 typedef typename MatrixType::Scalar Scalar;
100 Index rows = mat.rows();
101 Index cols = mat.cols();
107 tempVector.resize(rows);
108 tempData = tempVector.data();
111 for (
Index k = 0; ; ++k)
113 Index remainingRows = rows - k;
114 Index remainingCols = cols - k - 1;
117 mat.col(k).tail(remainingRows)
118 .makeHouseholderInPlace(mat.coeffRef(k,k), diagonal[k]);
120 mat.bottomRightCorner(remainingRows, remainingCols)
121 .applyHouseholderOnTheLeft(mat.col(k).tail(remainingRows-1), mat.coeff(k,k), tempData);
123 if(k == cols-1)
break;
126 mat.row(k).tail(remainingCols)
127 .makeHouseholderInPlace(mat.coeffRef(k,k+1), upper_diagonal[k]);
129 mat.bottomRightCorner(remainingRows-1, remainingCols)
130 .applyHouseholderOnTheRight(mat.row(k).tail(remainingCols-1).adjoint(), mat.coeff(k,k+1), tempData);
151template<
typename MatrixType>
152void upperbidiagonalization_blocked_helper(MatrixType& A,
153 typename MatrixType::RealScalar *diagonal,
154 typename MatrixType::RealScalar *upper_diagonal,
161 typedef typename MatrixType::Scalar Scalar;
162 typedef typename MatrixType::RealScalar RealScalar;
163 typedef typename NumTraits<RealScalar>::Literal Literal;
164 static const int StorageOrder =
166 typedef InnerStride<StorageOrder == ColMajor ? 1 : Dynamic> ColInnerStride;
167 typedef InnerStride<StorageOrder == ColMajor ? Dynamic : 1> RowInnerStride;
168 typedef Ref<Matrix<Scalar, Dynamic, 1>, 0, ColInnerStride> SubColumnType;
169 typedef Ref<Matrix<Scalar, 1, Dynamic>, 0, RowInnerStride> SubRowType;
170 typedef Ref<Matrix<Scalar, Dynamic, Dynamic, StorageOrder > > SubMatType;
172 Index brows = A.rows();
173 Index bcols = A.cols();
175 Scalar tau_u, tau_u_prev(0), tau_v;
177 for(
Index k = 0; k < bs; ++k)
179 Index remainingRows = brows - k;
180 Index remainingCols = bcols - k - 1;
182 SubMatType X_k1( X.block(k,0, remainingRows,k) );
183 SubMatType V_k1( A.block(k,0, remainingRows,k) );
186 SubColumnType v_k = A.col(k).tail(remainingRows);
187 v_k -= V_k1 * Y.row(k).head(k).adjoint();
188 if(k) v_k -= X_k1 * A.col(k).head(k);
191 v_k.makeHouseholderInPlace(tau_v, diagonal[k]);
195 SubMatType Y_k ( Y.block(k+1,0, remainingCols, k+1) );
196 SubMatType U_k1 ( A.block(0,k+1, k,remainingCols) );
204 SubColumnType y_k( Y.col(k).tail(remainingCols) );
207 SubColumnType tmp( Y.col(k).head(k) );
208 y_k.noalias() = A.block(k,k+1, remainingRows,remainingCols).adjoint() * v_k;
209 tmp.noalias() = V_k1.adjoint() * v_k;
210 y_k.noalias() -= Y_k.leftCols(k) * tmp;
211 tmp.noalias() = X_k1.adjoint() * v_k;
212 y_k.noalias() -= U_k1.adjoint() * tmp;
213 y_k *= numext::conj(tau_v);
217 SubRowType u_k( A.row(k).tail(remainingCols) );
218 u_k = u_k.conjugate();
220 u_k -= Y_k * A.row(k).head(k+1).adjoint();
221 if(k) u_k -= U_k1.adjoint() * X.row(k).head(k).adjoint();
225 u_k.makeHouseholderInPlace(tau_u, upper_diagonal[k]);
229 A(k,k+1) = Scalar(1);
233 SubColumnType x_k ( X.col(k).tail(remainingRows-1) );
237 SubColumnType tmp0 ( X.col(k).head(k) ),
238 tmp1 ( X.col(k).head(k+1) );
240 x_k.noalias() = A.block(k+1,k+1, remainingRows-1,remainingCols) * u_k.transpose();
241 tmp0.noalias() = U_k1 * u_k.transpose();
242 x_k.noalias() -= X_k1.bottomRows(remainingRows-1) * tmp0;
243 tmp1.noalias() = Y_k.adjoint() * u_k.transpose();
244 x_k.noalias() -= A.block(k+1,0, remainingRows-1,k+1) * tmp1;
245 x_k *= numext::conj(tau_u);
246 tau_u = numext::conj(tau_u);
247 u_k = u_k.conjugate();
250 if(k>0) A.coeffRef(k-1,k) = tau_u_prev;
254 A.coeffRef(k-1,k) = tau_u_prev;
256 A.coeffRef(k,k) = tau_v;
260 A.coeffRef(bs-1,bs) = tau_u_prev;
263 if(bcols>bs && brows>bs)
265 SubMatType A11( A.bottomRightCorner(brows-bs,bcols-bs) );
266 SubMatType A10( A.block(bs,0, brows-bs,bs) );
267 SubMatType A01( A.block(0,bs, bs,bcols-bs) );
268 Scalar tmp = A01(bs-1,0);
269 A01(bs-1,0) = Literal(1);
270 A11.noalias() -= A10 * Y.topLeftCorner(bcols,bs).bottomRows(bcols-bs).adjoint();
271 A11.noalias() -= X.topLeftCorner(brows,bs).bottomRows(brows-bs) * A01;
284template<
typename MatrixType,
typename B
idiagType>
285void upperbidiagonalization_inplace_blocked(MatrixType& A, BidiagType& bidiagonal,
286 Index maxBlockSize=32,
287 typename MatrixType::Scalar* = 0)
289 typedef typename MatrixType::Scalar Scalar;
290 typedef Block<MatrixType,Dynamic,Dynamic> BlockType;
292 Index rows = A.rows();
293 Index cols = A.cols();
294 Index size = (std::min)(rows, cols);
299 MatrixType::RowsAtCompileTime,
302 MatrixType::MaxRowsAtCompileTime> X(rows,maxBlockSize);
304 MatrixType::ColsAtCompileTime,
307 MatrixType::MaxColsAtCompileTime> Y(cols,maxBlockSize);
308 Index blockSize = (std::min)(maxBlockSize,size);
311 for(k = 0; k < size; k += blockSize)
313 Index bs = (std::min)(size-k,blockSize);
314 Index brows = rows - k;
315 Index bcols = cols - k;
331 BlockType B = A.block(k,k,brows,bcols);
337 if(k+bs==cols || bcols<48)
339 upperbidiagonalization_inplace_unblocked(B,
340 &(bidiagonal.template diagonal<0>().coeffRef(k)),
341 &(bidiagonal.template diagonal<1>().coeffRef(k)),
348 upperbidiagonalization_blocked_helper<BlockType>( B,
349 &(bidiagonal.template diagonal<0>().coeffRef(k)),
350 &(bidiagonal.template diagonal<1>().coeffRef(k)),
352 X.topLeftCorner(brows,bs),
353 Y.topLeftCorner(bcols,bs)
359template<
typename _MatrixType>
360UpperBidiagonalization<_MatrixType>& UpperBidiagonalization<_MatrixType>::computeUnblocked(
const _MatrixType& matrix)
362 Index rows = matrix.rows();
363 Index cols = matrix.cols();
364 EIGEN_ONLY_USED_FOR_DEBUG(cols);
366 eigen_assert(rows >= cols &&
"UpperBidiagonalization is only for Arices satisfying rows>=cols.");
368 m_householder = matrix;
370 ColVectorType temp(rows);
372 upperbidiagonalization_inplace_unblocked(m_householder,
373 &(m_bidiagonal.template diagonal<0>().coeffRef(0)),
374 &(m_bidiagonal.template diagonal<1>().coeffRef(0)),
377 m_isInitialized =
true;
381template<
typename _MatrixType>
382UpperBidiagonalization<_MatrixType>& UpperBidiagonalization<_MatrixType>::compute(
const _MatrixType& matrix)
384 Index rows = matrix.rows();
385 Index cols = matrix.cols();
386 EIGEN_ONLY_USED_FOR_DEBUG(rows);
387 EIGEN_ONLY_USED_FOR_DEBUG(cols);
389 eigen_assert(rows >= cols &&
"UpperBidiagonalization is only for Arices satisfying rows>=cols.");
391 m_householder = matrix;
392 upperbidiagonalization_inplace_blocked(m_householder, m_bidiagonal);
394 m_isInitialized =
true;
403template<
typename Derived>
404const UpperBidiagonalization<typename MatrixBase<Derived>::PlainObject>
405MatrixBase<Derived>::bidiagonalization()
const
407 return UpperBidiagonalization<PlainObject>(eval());
\householder_module
Definition HouseholderSequence.h:123
Base class for all dense matrices, vectors, and expressions.
Definition MatrixBase.h:50
Definition UpperBidiagonalization.h:21
UpperBidiagonalization()
Default Constructor.
Definition UpperBidiagonalization.h:54
Eigen::Index Index
Definition UpperBidiagonalization.h:32
@ ColMajor
Storage order is column major (see TopicStorageOrders).
Definition Constants.h:319
@ RowMajor
Storage order is row major (see TopicStorageOrders).
Definition Constants.h:321
@ OnTheRight
Apply transformation on the right.
Definition Constants.h:334
const unsigned int RowMajorBit
for a matrix, this means that the storage order is row-major.
Definition Constants.h:66
Namespace containing all symbols from the Eigen library.
Definition LDLT.h:16
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:74
const int Dynamic
This value means that a positive quantity (e.g., a size) is not known at compile-time,...
Definition Constants.h:22
Definition Householder.h:18
Definition inference.c:32