Lines 21-37
struct traits<TridiagonalizationMatrixTR
Link Here
|
21 |
: public traits<typename MatrixType::PlainObject> |
21 |
: public traits<typename MatrixType::PlainObject> |
22 |
{ |
22 |
{ |
23 |
typedef typename MatrixType::PlainObject ReturnType; // FIXME shall it be a BandMatrix? |
23 |
typedef typename MatrixType::PlainObject ReturnType; // FIXME shall it be a BandMatrix? |
24 |
enum { Flags = 0 }; |
24 |
enum { Flags = 0 }; |
25 |
}; |
25 |
}; |
26 |
|
26 |
|
27 |
template<typename MatrixType, typename CoeffVectorType> |
27 |
template<typename MatrixType, typename CoeffVectorType> |
28 |
EIGEN_DEVICE_FUNC |
28 |
EIGEN_DEVICE_FUNC |
29 |
void tridiagonalization_inplace(MatrixType& matA, CoeffVectorType& hCoeffs); |
29 |
void tridiagonalization_inplace(MatrixType& matA, CoeffVectorType& hCoeffs, typename MatrixType::Scalar* workspace); |
|
|
30 |
|
31 |
EIGEN_DEVICE_FUNC |
32 |
Index tridiagonalization_inplace_blocked_workspace_size(Index N, Index r); |
33 |
|
30 |
} |
34 |
} |
31 |
|
35 |
|
32 |
/** \eigenvalues_module \ingroup Eigenvalues_Module |
36 |
/** \eigenvalues_module \ingroup Eigenvalues_Module |
33 |
* |
37 |
* |
34 |
* |
38 |
* |
35 |
* \class Tridiagonalization |
39 |
* \class Tridiagonalization |
36 |
* |
40 |
* |
37 |
* \brief Tridiagonal decomposition of a selfadjoint matrix |
41 |
* \brief Tridiagonal decomposition of a selfadjoint matrix |
Lines 72-95
template<typename _MatrixType> class Tri
Link Here
|
72 |
typedef typename NumTraits<Scalar>::Real RealScalar; |
76 |
typedef typename NumTraits<Scalar>::Real RealScalar; |
73 |
typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3 |
77 |
typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3 |
74 |
|
78 |
|
75 |
enum { |
79 |
enum { |
76 |
Size = MatrixType::RowsAtCompileTime, |
80 |
Size = MatrixType::RowsAtCompileTime, |
77 |
SizeMinusOne = Size == Dynamic ? Dynamic : (Size > 1 ? Size - 1 : 1), |
81 |
SizeMinusOne = Size == Dynamic ? Dynamic : (Size > 1 ? Size - 1 : 1), |
78 |
Options = MatrixType::Options, |
82 |
Options = MatrixType::Options, |
79 |
MaxSize = MatrixType::MaxRowsAtCompileTime, |
83 |
MaxSize = MatrixType::MaxRowsAtCompileTime, |
80 |
MaxSizeMinusOne = MaxSize == Dynamic ? Dynamic : (MaxSize > 1 ? MaxSize - 1 : 1) |
84 |
MaxSizeMinusOne = MaxSize == Dynamic ? Dynamic : (MaxSize > 1 ? MaxSize - 1 : 1), |
|
|
85 |
BlockThreshold = 300, |
86 |
BlockSize = 60 |
81 |
}; |
87 |
}; |
82 |
|
88 |
|
83 |
typedef Matrix<Scalar, SizeMinusOne, 1, Options & ~RowMajor, MaxSizeMinusOne, 1> CoeffVectorType; |
89 |
typedef Matrix<Scalar, SizeMinusOne, 1, Options & ~RowMajor, MaxSizeMinusOne, 1> CoeffVectorType; |
84 |
typedef typename internal::plain_col_type<MatrixType, RealScalar>::type DiagonalType; |
90 |
typedef typename internal::plain_col_type<MatrixType, RealScalar>::type DiagonalType; |
85 |
typedef Matrix<RealScalar, SizeMinusOne, 1, Options & ~RowMajor, MaxSizeMinusOne, 1> SubDiagonalType; |
91 |
typedef Matrix<RealScalar, SizeMinusOne, 1, Options & ~RowMajor, MaxSizeMinusOne, 1> SubDiagonalType; |
86 |
typedef typename internal::remove_all<typename MatrixType::RealReturnType>::type MatrixTypeRealView; |
92 |
typedef typename internal::remove_all<typename MatrixType::RealReturnType>::type MatrixTypeRealView; |
87 |
typedef internal::TridiagonalizationMatrixTReturnType<MatrixTypeRealView> MatrixTReturnType; |
93 |
typedef internal::TridiagonalizationMatrixTReturnType<MatrixTypeRealView> MatrixTReturnType; |
|
|
94 |
typedef Matrix<Scalar, Dynamic, 1, Options & ~RowMajor> WorkspaceType; |
88 |
|
95 |
|
89 |
typedef typename internal::conditional<NumTraits<Scalar>::IsComplex, |
96 |
typedef typename internal::conditional<NumTraits<Scalar>::IsComplex, |
90 |
typename internal::add_const_on_value_type<typename Diagonal<const MatrixType>::RealReturnType>::type, |
97 |
typename internal::add_const_on_value_type<typename Diagonal<const MatrixType>::RealReturnType>::type, |
91 |
const Diagonal<const MatrixType> |
98 |
const Diagonal<const MatrixType> |
92 |
>::type DiagonalReturnType; |
99 |
>::type DiagonalReturnType; |
93 |
|
100 |
|
94 |
typedef typename internal::conditional<NumTraits<Scalar>::IsComplex, |
101 |
typedef typename internal::conditional<NumTraits<Scalar>::IsComplex, |
95 |
typename internal::add_const_on_value_type<typename Diagonal<const MatrixType, -1>::RealReturnType>::type, |
102 |
typename internal::add_const_on_value_type<typename Diagonal<const MatrixType, -1>::RealReturnType>::type, |
Lines 126-144
template<typename _MatrixType> class Tri
Link Here
|
126 |
* |
133 |
* |
127 |
* Example: \include Tridiagonalization_Tridiagonalization_MatrixType.cpp |
134 |
* Example: \include Tridiagonalization_Tridiagonalization_MatrixType.cpp |
128 |
* Output: \verbinclude Tridiagonalization_Tridiagonalization_MatrixType.out |
135 |
* Output: \verbinclude Tridiagonalization_Tridiagonalization_MatrixType.out |
129 |
*/ |
136 |
*/ |
130 |
template<typename InputType> |
137 |
template<typename InputType> |
131 |
explicit Tridiagonalization(const EigenBase<InputType>& matrix) |
138 |
explicit Tridiagonalization(const EigenBase<InputType>& matrix) |
132 |
: m_matrix(matrix.derived()), |
139 |
: m_matrix(matrix.derived()), |
133 |
m_hCoeffs(matrix.cols() > 1 ? matrix.cols()-1 : 1), |
140 |
m_hCoeffs(matrix.cols() > 1 ? matrix.cols()-1 : 1), |
|
|
141 |
m_workspace(matrix.cols() > BlockThreshold ? internal::tridiagonalization_inplace_blocked_workspace_size(matrix.cols(), BlockSize) : 0), |
134 |
m_isInitialized(false) |
142 |
m_isInitialized(false) |
135 |
{ |
143 |
{ |
136 |
internal::tridiagonalization_inplace(m_matrix, m_hCoeffs); |
144 |
internal::tridiagonalization_inplace(m_matrix, m_hCoeffs, m_workspace.data()); |
137 |
m_isInitialized = true; |
145 |
m_isInitialized = true; |
138 |
} |
146 |
} |
139 |
|
147 |
|
140 |
/** \brief Computes tridiagonal decomposition of given matrix. |
148 |
/** \brief Computes tridiagonal decomposition of given matrix. |
141 |
* |
149 |
* |
142 |
* \param[in] matrix Selfadjoint matrix whose tridiagonal decomposition |
150 |
* \param[in] matrix Selfadjoint matrix whose tridiagonal decomposition |
143 |
* is to be computed. |
151 |
* is to be computed. |
144 |
* \returns Reference to \c *this |
152 |
* \returns Reference to \c *this |
Lines 154-170
template<typename _MatrixType> class Tri
Link Here
|
154 |
* Example: \include Tridiagonalization_compute.cpp |
162 |
* Example: \include Tridiagonalization_compute.cpp |
155 |
* Output: \verbinclude Tridiagonalization_compute.out |
163 |
* Output: \verbinclude Tridiagonalization_compute.out |
156 |
*/ |
164 |
*/ |
157 |
template<typename InputType> |
165 |
template<typename InputType> |
158 |
Tridiagonalization& compute(const EigenBase<InputType>& matrix) |
166 |
Tridiagonalization& compute(const EigenBase<InputType>& matrix) |
159 |
{ |
167 |
{ |
160 |
m_matrix = matrix.derived(); |
168 |
m_matrix = matrix.derived(); |
161 |
m_hCoeffs.resize(matrix.rows()-1, 1); |
169 |
m_hCoeffs.resize(matrix.rows()-1, 1); |
162 |
internal::tridiagonalization_inplace(m_matrix, m_hCoeffs); |
170 |
if(matrix.cols() > BlockThreshold){ |
|
|
171 |
m_workspace.resize(internal::tridiagonalization_inplace_blocked_workspace_size(matrix.cols(), BlockSize)); |
172 |
} |
173 |
internal::tridiagonalization_inplace(m_matrix, m_hCoeffs, m_workspace.data()); |
163 |
m_isInitialized = true; |
174 |
m_isInitialized = true; |
164 |
return *this; |
175 |
return *this; |
165 |
} |
176 |
} |
166 |
|
177 |
|
167 |
/** \brief Returns the Householder coefficients. |
178 |
/** \brief Returns the Householder coefficients. |
168 |
* |
179 |
* |
169 |
* \returns a const reference to the vector of Householder coefficients |
180 |
* \returns a const reference to the vector of Householder coefficients |
170 |
* |
181 |
* |
Lines 295-310
template<typename _MatrixType> class Tri
Link Here
|
295 |
* \sa diagonal() for an example, matrixT() |
306 |
* \sa diagonal() for an example, matrixT() |
296 |
*/ |
307 |
*/ |
297 |
SubDiagonalReturnType subDiagonal() const; |
308 |
SubDiagonalReturnType subDiagonal() const; |
298 |
|
309 |
|
299 |
protected: |
310 |
protected: |
300 |
|
311 |
|
301 |
MatrixType m_matrix; |
312 |
MatrixType m_matrix; |
302 |
CoeffVectorType m_hCoeffs; |
313 |
CoeffVectorType m_hCoeffs; |
|
|
314 |
WorkspaceType m_workspace; |
303 |
bool m_isInitialized; |
315 |
bool m_isInitialized; |
304 |
}; |
316 |
}; |
305 |
|
317 |
|
306 |
template<typename MatrixType> |
318 |
template<typename MatrixType> |
307 |
typename Tridiagonalization<MatrixType>::DiagonalReturnType |
319 |
typename Tridiagonalization<MatrixType>::DiagonalReturnType |
308 |
Tridiagonalization<MatrixType>::diagonal() const |
320 |
Tridiagonalization<MatrixType>::diagonal() const |
309 |
{ |
321 |
{ |
310 |
eigen_assert(m_isInitialized && "Tridiagonalization is not initialized."); |
322 |
eigen_assert(m_isInitialized && "Tridiagonalization is not initialized."); |
Lines 315-331
template<typename MatrixType>
Link Here
|
315 |
typename Tridiagonalization<MatrixType>::SubDiagonalReturnType |
327 |
typename Tridiagonalization<MatrixType>::SubDiagonalReturnType |
316 |
Tridiagonalization<MatrixType>::subDiagonal() const |
328 |
Tridiagonalization<MatrixType>::subDiagonal() const |
317 |
{ |
329 |
{ |
318 |
eigen_assert(m_isInitialized && "Tridiagonalization is not initialized."); |
330 |
eigen_assert(m_isInitialized && "Tridiagonalization is not initialized."); |
319 |
return m_matrix.template diagonal<-1>().real(); |
331 |
return m_matrix.template diagonal<-1>().real(); |
320 |
} |
332 |
} |
321 |
|
333 |
|
322 |
namespace internal { |
334 |
namespace internal { |
323 |
|
|
|
324 |
/** \internal |
335 |
/** \internal |
325 |
* Performs a tridiagonal decomposition of the selfadjoint matrix \a matA in-place. |
336 |
* Performs a tridiagonal decomposition of the selfadjoint matrix \a matA in-place. |
326 |
* |
337 |
* |
327 |
* \param[in,out] matA On input the selfadjoint matrix. Only the \b lower triangular part is referenced. |
338 |
* \param[in,out] matA On input the selfadjoint matrix. Only the \b lower triangular part is referenced. |
328 |
* On output, the strict upper part is left unchanged, and the lower triangular part |
339 |
* On output, the strict upper part is left unchanged, and the lower triangular part |
329 |
* represents the T and Q matrices in packed format has detailed below. |
340 |
* represents the T and Q matrices in packed format has detailed below. |
330 |
* \param[out] hCoeffs returned Householder coefficients (see below) |
341 |
* \param[out] hCoeffs returned Householder coefficients (see below) |
331 |
* |
342 |
* |
Lines 341-357
namespace internal {
Link Here
|
341 |
* \f$ v_i = [ 0, \ldots, 0, 1, matA(i+2,i), \ldots, matA(N-1,i) ]^T \f$. |
352 |
* \f$ v_i = [ 0, \ldots, 0, 1, matA(i+2,i), \ldots, matA(N-1,i) ]^T \f$. |
342 |
* |
353 |
* |
343 |
* Implemented from Golub's "Matrix Computations", algorithm 8.3.1. |
354 |
* Implemented from Golub's "Matrix Computations", algorithm 8.3.1. |
344 |
* |
355 |
* |
345 |
* \sa Tridiagonalization::packedMatrix() |
356 |
* \sa Tridiagonalization::packedMatrix() |
346 |
*/ |
357 |
*/ |
347 |
template<typename MatrixType, typename CoeffVectorType> |
358 |
template<typename MatrixType, typename CoeffVectorType> |
348 |
EIGEN_DEVICE_FUNC |
359 |
EIGEN_DEVICE_FUNC |
349 |
void tridiagonalization_inplace(MatrixType& matA, CoeffVectorType& hCoeffs) |
360 |
void tridiagonalization_inplace_unblocked(MatrixType& matA, CoeffVectorType& hCoeffs) |
350 |
{ |
361 |
{ |
351 |
using numext::conj; |
362 |
using numext::conj; |
352 |
typedef typename MatrixType::Scalar Scalar; |
363 |
typedef typename MatrixType::Scalar Scalar; |
353 |
typedef typename MatrixType::RealScalar RealScalar; |
364 |
typedef typename MatrixType::RealScalar RealScalar; |
354 |
Index n = matA.rows(); |
365 |
Index n = matA.rows(); |
355 |
eigen_assert(n==matA.cols()); |
366 |
eigen_assert(n==matA.cols()); |
356 |
eigen_assert(n==hCoeffs.size()+1 || n==1); |
367 |
eigen_assert(n==hCoeffs.size()+1 || n==1); |
357 |
|
368 |
|
Lines 374-389
void tridiagonalization_inplace(MatrixTy
Link Here
|
374 |
matA.bottomRightCorner(remainingSize, remainingSize).template selfadjointView<Lower>() |
385 |
matA.bottomRightCorner(remainingSize, remainingSize).template selfadjointView<Lower>() |
375 |
.rankUpdate(matA.col(i).tail(remainingSize), hCoeffs.tail(remainingSize), Scalar(-1)); |
386 |
.rankUpdate(matA.col(i).tail(remainingSize), hCoeffs.tail(remainingSize), Scalar(-1)); |
376 |
|
387 |
|
377 |
matA.col(i).coeffRef(i+1) = beta; |
388 |
matA.col(i).coeffRef(i+1) = beta; |
378 |
hCoeffs.coeffRef(i) = h; |
389 |
hCoeffs.coeffRef(i) = h; |
379 |
} |
390 |
} |
380 |
} |
391 |
} |
381 |
|
392 |
|
|
|
393 |
/** |
394 |
* Calculates required workspace size for block householder tridiagonalization |
395 |
* of a matrix of size n * n, by using block size of r. |
396 |
* @param N matrix dimenstion |
397 |
* @param r block size |
398 |
* @return minimum workspace size |
399 |
*/ |
400 |
EIGEN_DEVICE_FUNC |
401 |
Index tridiagonalization_inplace_blocked_workspace_size(Index N, Index r){ |
402 |
Index first_actual_r = std::min({r, static_cast<Index>(N - 1)}); |
403 |
Index V_size = (N - 1) * r; |
404 |
Index partial_update_size = (N - first_actual_r) * (N - first_actual_r); |
405 |
return V_size + partial_update_size; |
406 |
} |
407 |
|
408 |
/** |
409 |
* Tridiagonalize a selfadjoint matrix using block Housholder algorithm. |
410 |
* A = Q * T * Q^T, where T is tridiagonal and Q is unitary. |
411 |
* @param[in,out] packed On input the input matrix. On output packed form of the |
412 |
* tridiagonal matrix. Elements of the resulting selfadjoint tridiagonal matrix |
413 |
* T are in the diagonal and first subdiagonal, which contains subdiagonal |
414 |
* entries of T. Columns bellow diagonal contain householder vectors that can be |
415 |
* used to construct unitary matrix Q. |
416 |
* @param[out] hCoeffs householder coefficients |
417 |
* @param workspace Workspace. Minimal required size can be determined by |
418 |
* calling `tridiagonalization_inplace_blocked_workspace_size()` |
419 |
* @param r Block size. Affects only performance of the algorithm. Optimal value |
420 |
* depends on the size of A and cache of the processor. For larger matrices or |
421 |
* larger cache sizes a larger value is optimal. |
422 |
*/ |
423 |
template<typename MatrixType, typename CoeffVectorType> |
424 |
EIGEN_DEVICE_FUNC |
425 |
void tridiagonalization_inplace_blocked( |
426 |
MatrixType& packed, |
427 |
CoeffVectorType& hCoeffs, |
428 |
typename MatrixType::Scalar* workspace, const Index r) { |
429 |
using Scalar = typename MatrixType::Scalar; |
430 |
using Real = typename NumTraits<Scalar>::Real; |
431 |
using MapType = typename Matrix<Scalar, Dynamic, Dynamic>::MapType; |
432 |
using MapTypeVec = typename Matrix<Scalar, Dynamic, 1>::MapType; |
433 |
Index N = packed.rows(); |
434 |
for (Index k = 0; k < N - 1; k += r) { |
435 |
const Index actual_r = std::min({r, static_cast<Index>(N - k - 1)}); |
436 |
MapType V(workspace, N - k - 1, actual_r); |
437 |
for (Index j = 0; j < actual_r; j++) { |
438 |
if (j != 0) { |
439 |
Index householder_whole_size = N - k - j; |
440 |
Scalar temp = packed(k + j, k + j - 1); |
441 |
packed(k + j, k + j - 1) = Scalar(1); |
442 |
packed.col(k + j).tail(householder_whole_size) -= packed.block(k + j, k, householder_whole_size, j) * V.block(j - 1, 0, 1, j).adjoint(); |
443 |
packed.col(k + j).tail(householder_whole_size) -= V.block(j - 1, 0, householder_whole_size, j) * packed.block(k + j, k, 1, j).adjoint(); |
444 |
packed(k + j, k + j - 1) = temp; |
445 |
} |
446 |
typename Matrix<Scalar, Dynamic, Dynamic>::ColXpr::SegmentReturnType householder = packed.col(k + j).tail(N- k - j - 1); |
447 |
Scalar tau; |
448 |
Real beta; |
449 |
householder.makeHouseholderInPlace(tau, beta); |
450 |
householder[0] = Scalar(1); |
451 |
|
452 |
typename MapType::ColXpr::SegmentReturnType v = V.col(j).tail(householder.size()); |
453 |
v.noalias() = packed.bottomRightCorner(N - k - j - 1,N - k - j - 1) |
454 |
.template selfadjointView<Lower>() * householder * numext::conj(tau); |
455 |
MapTypeVec tmp(workspace + V.size(), j); |
456 |
|
457 |
//Reminder of packed is not transformed by current block yet - v needs some fixes |
458 |
tmp.noalias() = V.bottomLeftCorner(householder.size(), j).adjoint() * householder * numext::conj(tau); |
459 |
v.noalias() -= packed.block(k + j + 1, k, householder.size(), j) * tmp; |
460 |
tmp.noalias() = packed.block(k + j + 1, k, householder.size(), j).adjoint() * householder * numext::conj(tau); |
461 |
v.noalias() -= V.bottomLeftCorner(householder.size(), j) * tmp; |
462 |
|
463 |
const Scalar cnst = (v.adjoint() * householder)[0]; |
464 |
v -= Real(0.5) * numext::conj(tau) * cnst * householder; |
465 |
|
466 |
//store householder transformation scaling and subdiagonal of T |
467 |
hCoeffs(k + j) = tau; |
468 |
packed(k + j + 1, k + j) = beta; |
469 |
} |
470 |
//update reminder of packed with the last block |
471 |
MapType partial_update(workspace + V.size(), V.rows() - actual_r + 1,V.rows() - actual_r + 1); |
472 |
Scalar tmp = packed(k + actual_r, k+actual_r-1); |
473 |
packed(k + actual_r, k+actual_r-1) = Scalar(1); |
474 |
partial_update.noalias() = packed.block(k + actual_r, k, N - k - actual_r, actual_r) * V.bottomRows(V.rows() - actual_r + 1).adjoint(); |
475 |
packed(k + actual_r, k+actual_r-1) = tmp; |
476 |
packed.block(k + actual_r, k + actual_r, N - k - actual_r, N - k - actual_r).template triangularView<Lower>() |
477 |
-= partial_update + partial_update.adjoint(); |
478 |
} |
479 |
} |
480 |
|
481 |
template<typename MatrixType, typename CoeffVectorType> |
482 |
EIGEN_DEVICE_FUNC |
483 |
void tridiagonalization_inplace(MatrixType& matA, CoeffVectorType& hCoeffs, typename MatrixType::Scalar* workspace) |
484 |
{ |
485 |
if(matA.rows() > Tridiagonalization<MatrixType>::BlockThreshold) |
486 |
tridiagonalization_inplace_blocked(matA, hCoeffs, workspace, Tridiagonalization<MatrixType>::BlockSize); |
487 |
else { |
488 |
tridiagonalization_inplace_unblocked(matA, hCoeffs); |
489 |
} |
490 |
} |
491 |
|
382 |
// forward declaration, implementation at the end of this file |
492 |
// forward declaration, implementation at the end of this file |
383 |
template<typename MatrixType, |
493 |
template<typename MatrixType, |
384 |
int Size=MatrixType::ColsAtCompileTime, |
494 |
int Size=MatrixType::ColsAtCompileTime, |
385 |
bool IsComplex=NumTraits<typename MatrixType::Scalar>::IsComplex> |
495 |
bool IsComplex=NumTraits<typename MatrixType::Scalar>::IsComplex> |
386 |
struct tridiagonalization_inplace_selector; |
496 |
struct tridiagonalization_inplace_selector; |
387 |
|
497 |
|
388 |
/** \brief Performs a full tridiagonalization in place |
498 |
/** \brief Performs a full tridiagonalization in place |
389 |
* |
499 |
* |
Lines 436-457
void tridiagonalization_inplace(MatrixTy
Link Here
|
436 |
/** \internal |
546 |
/** \internal |
437 |
* General full tridiagonalization |
547 |
* General full tridiagonalization |
438 |
*/ |
548 |
*/ |
439 |
template<typename MatrixType, int Size, bool IsComplex> |
549 |
template<typename MatrixType, int Size, bool IsComplex> |
440 |
struct tridiagonalization_inplace_selector |
550 |
struct tridiagonalization_inplace_selector |
441 |
{ |
551 |
{ |
442 |
typedef typename Tridiagonalization<MatrixType>::CoeffVectorType CoeffVectorType; |
552 |
typedef typename Tridiagonalization<MatrixType>::CoeffVectorType CoeffVectorType; |
443 |
typedef typename Tridiagonalization<MatrixType>::HouseholderSequenceType HouseholderSequenceType; |
553 |
typedef typename Tridiagonalization<MatrixType>::HouseholderSequenceType HouseholderSequenceType; |
|
|
554 |
typedef typename Tridiagonalization<MatrixType>::WorkspaceType WorkspaceType; |
444 |
template<typename DiagonalType, typename SubDiagonalType> |
555 |
template<typename DiagonalType, typename SubDiagonalType> |
445 |
static EIGEN_DEVICE_FUNC |
556 |
static EIGEN_DEVICE_FUNC |
446 |
void run(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag, bool extractQ) |
557 |
void run(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag, bool extractQ) |
447 |
{ |
558 |
{ |
448 |
CoeffVectorType hCoeffs(mat.cols()-1); |
559 |
CoeffVectorType hCoeffs(mat.cols()-1); |
449 |
tridiagonalization_inplace(mat,hCoeffs); |
560 |
if(mat.cols()>Tridiagonalization<MatrixType>::BlockThreshold){ |
|
|
561 |
WorkspaceType workspace(tridiagonalization_inplace_blocked_workspace_size(mat.cols(), Tridiagonalization<MatrixType>::BlockSize)); |
562 |
tridiagonalization_inplace_blocked(mat, hCoeffs, workspace.data()); |
563 |
} |
564 |
else { |
565 |
tridiagonalization_inplace_unblocked(mat, hCoeffs); |
566 |
} |
450 |
diag = mat.diagonal().real(); |
567 |
diag = mat.diagonal().real(); |
451 |
subdiag = mat.template diagonal<-1>().real(); |
568 |
subdiag = mat.template diagonal<-1>().real(); |
452 |
if(extractQ) |
569 |
if(extractQ) |
453 |
mat = HouseholderSequenceType(mat, hCoeffs.conjugate()) |
570 |
mat = HouseholderSequenceType(mat, hCoeffs.conjugate()) |
454 |
.setLength(mat.rows() - 1) |
571 |
.setLength(mat.rows() - 1) |
455 |
.setShift(1); |
572 |
.setShift(1); |
456 |
} |
573 |
} |
457 |
}; |
574 |
}; |