mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-08-12 11:49:02 +08:00
Make the array of directly compute column norms a member to avoid allocation in computeInPlace.
This commit is contained in:
parent
00f9ef6c76
commit
d9a6f86cc0
@ -86,7 +86,8 @@ template<typename _MatrixType> class ColPivHouseholderQR
|
|||||||
m_colsPermutation(),
|
m_colsPermutation(),
|
||||||
m_colsTranspositions(),
|
m_colsTranspositions(),
|
||||||
m_temp(),
|
m_temp(),
|
||||||
m_colNorms(),
|
m_colNormsUpdated(),
|
||||||
|
m_colNormsDirect(),
|
||||||
m_isInitialized(false),
|
m_isInitialized(false),
|
||||||
m_usePrescribedThreshold(false) {}
|
m_usePrescribedThreshold(false) {}
|
||||||
|
|
||||||
@ -102,7 +103,8 @@ template<typename _MatrixType> class ColPivHouseholderQR
|
|||||||
m_colsPermutation(PermIndexType(cols)),
|
m_colsPermutation(PermIndexType(cols)),
|
||||||
m_colsTranspositions(cols),
|
m_colsTranspositions(cols),
|
||||||
m_temp(cols),
|
m_temp(cols),
|
||||||
m_colNorms(cols),
|
m_colNormsUpdated(cols),
|
||||||
|
m_colNormsDirect(cols),
|
||||||
m_isInitialized(false),
|
m_isInitialized(false),
|
||||||
m_usePrescribedThreshold(false) {}
|
m_usePrescribedThreshold(false) {}
|
||||||
|
|
||||||
@ -125,7 +127,8 @@ template<typename _MatrixType> class ColPivHouseholderQR
|
|||||||
m_colsPermutation(PermIndexType(matrix.cols())),
|
m_colsPermutation(PermIndexType(matrix.cols())),
|
||||||
m_colsTranspositions(matrix.cols()),
|
m_colsTranspositions(matrix.cols()),
|
||||||
m_temp(matrix.cols()),
|
m_temp(matrix.cols()),
|
||||||
m_colNorms(matrix.cols()),
|
m_colNormsUpdated(matrix.cols()),
|
||||||
|
m_colNormsDirect(matrix.cols()),
|
||||||
m_isInitialized(false),
|
m_isInitialized(false),
|
||||||
m_usePrescribedThreshold(false)
|
m_usePrescribedThreshold(false)
|
||||||
{
|
{
|
||||||
@ -413,7 +416,8 @@ template<typename _MatrixType> class ColPivHouseholderQR
|
|||||||
PermutationType m_colsPermutation;
|
PermutationType m_colsPermutation;
|
||||||
IntRowVectorType m_colsTranspositions;
|
IntRowVectorType m_colsTranspositions;
|
||||||
RowVectorType m_temp;
|
RowVectorType m_temp;
|
||||||
RealRowVectorType m_colNorms;
|
RealRowVectorType m_colNormsUpdated;
|
||||||
|
RealRowVectorType m_colNormsDirect;
|
||||||
bool m_isInitialized, m_usePrescribedThreshold;
|
bool m_isInitialized, m_usePrescribedThreshold;
|
||||||
RealScalar m_prescribedThreshold, m_maxpivot;
|
RealScalar m_prescribedThreshold, m_maxpivot;
|
||||||
Index m_nonzero_pivots;
|
Index m_nonzero_pivots;
|
||||||
@ -475,12 +479,16 @@ void ColPivHouseholderQR<MatrixType>::computeInPlace()
|
|||||||
m_colsTranspositions.resize(m_qr.cols());
|
m_colsTranspositions.resize(m_qr.cols());
|
||||||
Index number_of_transpositions = 0;
|
Index number_of_transpositions = 0;
|
||||||
|
|
||||||
m_colNorms.resize(cols);
|
m_colNormsUpdated.resize(cols);
|
||||||
for (Index k = 0; k < cols; ++k)
|
m_colNormsDirect.resize(cols);
|
||||||
m_colNorms.coeffRef(k) = m_qr.col(k).norm();
|
for (Index k = 0; k < cols; ++k) {
|
||||||
RealRowVectorType colNormsMostRecentDirect(m_colNorms);
|
// colNormsDirect(k) caches the most recent directly computed norm of
|
||||||
|
// column k.
|
||||||
|
m_colNormsDirect.coeffRef(k) = m_qr.col(k).norm();
|
||||||
|
m_colNormsUpdated.coeffRef(k) = m_colNormsDirect.coeffRef(k);
|
||||||
|
}
|
||||||
|
|
||||||
RealScalar threshold_helper = numext::abs2(m_colNorms.maxCoeff() * NumTraits<Scalar>::epsilon()) / RealScalar(rows);
|
RealScalar threshold_helper = numext::abs2(m_colNormsUpdated.maxCoeff() * NumTraits<Scalar>::epsilon()) / RealScalar(rows);
|
||||||
RealScalar norm_downdate_threshold = numext::sqrt(NumTraits<Scalar>::epsilon());
|
RealScalar norm_downdate_threshold = numext::sqrt(NumTraits<Scalar>::epsilon());
|
||||||
|
|
||||||
m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case)
|
m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case)
|
||||||
@ -488,9 +496,9 @@ void ColPivHouseholderQR<MatrixType>::computeInPlace()
|
|||||||
|
|
||||||
for(Index k = 0; k < size; ++k)
|
for(Index k = 0; k < size; ++k)
|
||||||
{
|
{
|
||||||
// first, we look up in our table m_colNorms which column has the biggest norm
|
// first, we look up in our table m_colNormsUpdated which column has the biggest norm
|
||||||
Index biggest_col_index;
|
Index biggest_col_index;
|
||||||
RealScalar biggest_col_sq_norm = numext::abs2(m_colNorms.tail(cols-k).maxCoeff(&biggest_col_index));
|
RealScalar biggest_col_sq_norm = numext::abs2(m_colNormsUpdated.tail(cols-k).maxCoeff(&biggest_col_index));
|
||||||
biggest_col_index += k;
|
biggest_col_index += k;
|
||||||
|
|
||||||
// Track the number of meaningful pivots but do not stop the decomposition to make
|
// Track the number of meaningful pivots but do not stop the decomposition to make
|
||||||
@ -502,9 +510,9 @@ void ColPivHouseholderQR<MatrixType>::computeInPlace()
|
|||||||
m_colsTranspositions.coeffRef(k) = biggest_col_index;
|
m_colsTranspositions.coeffRef(k) = biggest_col_index;
|
||||||
if(k != biggest_col_index) {
|
if(k != biggest_col_index) {
|
||||||
m_qr.col(k).swap(m_qr.col(biggest_col_index));
|
m_qr.col(k).swap(m_qr.col(biggest_col_index));
|
||||||
std::swap(m_colNorms.coeffRef(k), m_colNorms.coeffRef(biggest_col_index));
|
std::swap(m_colNormsUpdated.coeffRef(k), m_colNormsUpdated.coeffRef(biggest_col_index));
|
||||||
std::swap(colNormsMostRecentDirect.coeffRef(k),
|
std::swap(m_colNormsDirect.coeffRef(k),
|
||||||
colNormsMostRecentDirect.coeffRef(biggest_col_index));
|
m_colNormsDirect.coeffRef(biggest_col_index));
|
||||||
++number_of_transpositions;
|
++number_of_transpositions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -528,20 +536,19 @@ void ColPivHouseholderQR<MatrixType>::computeInPlace()
|
|||||||
// http://www.netlib.org/lapack/lawnspdf/lawn176.pdf
|
// http://www.netlib.org/lapack/lawnspdf/lawn176.pdf
|
||||||
// and used in LAPACK routines xGEQPF and xGEQP3.
|
// and used in LAPACK routines xGEQPF and xGEQP3.
|
||||||
// See lines 278-297 in http://www.netlib.org/lapack/explore-html/dc/df4/sgeqpf_8f_source.html
|
// See lines 278-297 in http://www.netlib.org/lapack/explore-html/dc/df4/sgeqpf_8f_source.html
|
||||||
if (m_colNorms.coeffRef(j) != 0) {
|
if (m_colNormsUpdated.coeffRef(j) != 0) {
|
||||||
RealScalar temp = abs(m_qr.coeffRef(k, j)) / m_colNorms.coeffRef(j);
|
RealScalar temp = abs(m_qr.coeffRef(k, j)) / m_colNormsUpdated.coeffRef(j);
|
||||||
temp = (RealScalar(1) + temp) * (RealScalar(1) - temp);
|
temp = (RealScalar(1) + temp) * (RealScalar(1) - temp);
|
||||||
temp = temp < 0 ? 0 : temp;
|
temp = temp < 0 ? 0 : temp;
|
||||||
RealScalar temp2 =
|
RealScalar temp2 = temp * numext::abs2(m_colNormsUpdated.coeffRef(j) /
|
||||||
temp * numext::abs2(m_colNorms.coeffRef(j) /
|
m_colNormsDirect.coeffRef(j));
|
||||||
colNormsMostRecentDirect.coeffRef(j));
|
|
||||||
if (temp2 <= norm_downdate_threshold) {
|
if (temp2 <= norm_downdate_threshold) {
|
||||||
// The updated norm has become to inaccurate so re-compute the column
|
// The updated norm has become too inaccurate so re-compute the column
|
||||||
// norm directly.
|
// norm directly.
|
||||||
m_colNorms.coeffRef(j) = m_qr.col(j).tail(rows - k - 1).norm();
|
m_colNormsDirect.coeffRef(j) = m_qr.col(j).tail(rows - k - 1).norm();
|
||||||
colNormsMostRecentDirect.coeffRef(j) = m_colNorms.coeffRef(j);
|
m_colNormsUpdated.coeffRef(j) = m_colNormsDirect.coeffRef(j);
|
||||||
} else {
|
} else {
|
||||||
m_colNorms.coeffRef(j) *= numext::sqrt(temp);
|
m_colNormsUpdated.coeffRef(j) *= numext::sqrt(temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user