aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen/src/SVD/JacobiSVD.h
diff options
context:
space:
mode:
Diffstat (limited to 'Eigen/src/SVD/JacobiSVD.h')
-rw-r--r--Eigen/src/SVD/JacobiSVD.h51
1 files changed, 38 insertions, 13 deletions
diff --git a/Eigen/src/SVD/JacobiSVD.h b/Eigen/src/SVD/JacobiSVD.h
index b7cab023b..9323c0180 100644
--- a/Eigen/src/SVD/JacobiSVD.h
+++ b/Eigen/src/SVD/JacobiSVD.h
@@ -93,10 +93,35 @@ template<typename MatrixType, unsigned int Options> class JacobiSVD
public:
+ /** \brief Default Constructor.
+ *
+ * The default constructor is useful in cases in which the user intends to
+ * perform decompositions via JacobiSVD::compute(const MatrixType&).
+ */
JacobiSVD() : m_isInitialized(false) {}
- JacobiSVD(const MatrixType& matrix) : m_isInitialized(false)
+
+ /** \brief Default Constructor with memory preallocation
+ *
+ * Like the default constructor but with preallocation of the internal data
+ * according to the specified problem \a size.
+ * \sa JacobiSVD()
+ */
+ JacobiSVD(int rows, int cols) : m_matrixU(rows, rows),
+ m_matrixV(cols, cols),
+ m_singularValues(std::min(rows, cols)),
+ m_workMatrix(rows, cols),
+ m_isInitialized(false) {}
+
+ JacobiSVD(const MatrixType& matrix) : m_matrixU(matrix.rows(), matrix.rows()),
+ m_matrixV(matrix.cols(), matrix.cols()),
+ m_singularValues(),
+ m_workMatrix(),
+ m_isInitialized(false)
{
+ const int minSize = std::min(matrix.rows(), matrix.cols());
+ m_singularValues.resize(minSize);
+ m_workMatrix.resize(minSize, minSize);
compute(matrix);
}
@@ -124,6 +149,7 @@ template<typename MatrixType, unsigned int Options> class JacobiSVD
MatrixUType m_matrixU;
MatrixVType m_matrixV;
SingularValuesType m_singularValues;
+ WorkMatrixType m_workMatrix;
bool m_isInitialized;
template<typename _MatrixType, unsigned int _Options, bool _IsComplex>
@@ -289,17 +315,16 @@ struct ei_svd_precondition_if_more_cols_than_rows<MatrixType, Options, true>
template<typename MatrixType, unsigned int Options>
JacobiSVD<MatrixType, Options>& JacobiSVD<MatrixType, Options>::compute(const MatrixType& matrix)
{
- WorkMatrixType work_matrix;
int rows = matrix.rows();
int cols = matrix.cols();
int diagSize = std::min(rows, cols);
m_singularValues.resize(diagSize);
const RealScalar precision = 2 * NumTraits<Scalar>::epsilon();
- if(!ei_svd_precondition_if_more_rows_than_cols<MatrixType, Options>::run(matrix, work_matrix, *this)
- && !ei_svd_precondition_if_more_cols_than_rows<MatrixType, Options>::run(matrix, work_matrix, *this))
+ if(!ei_svd_precondition_if_more_rows_than_cols<MatrixType, Options>::run(matrix, m_workMatrix, *this)
+ && !ei_svd_precondition_if_more_cols_than_rows<MatrixType, Options>::run(matrix, m_workMatrix, *this))
{
- work_matrix = matrix.block(0,0,diagSize,diagSize);
+ m_workMatrix = matrix.block(0,0,diagSize,diagSize);
if(ComputeU) m_matrixU.setIdentity(rows,rows);
if(ComputeV) m_matrixV.setIdentity(cols,cols);
}
@@ -312,19 +337,19 @@ JacobiSVD<MatrixType, Options>& JacobiSVD<MatrixType, Options>::compute(const Ma
{
for(int q = 0; q < p; ++q)
{
- if(std::max(ei_abs(work_matrix.coeff(p,q)),ei_abs(work_matrix.coeff(q,p)))
- > std::max(ei_abs(work_matrix.coeff(p,p)),ei_abs(work_matrix.coeff(q,q)))*precision)
+ if(std::max(ei_abs(m_workMatrix.coeff(p,q)),ei_abs(m_workMatrix.coeff(q,p)))
+ > std::max(ei_abs(m_workMatrix.coeff(p,p)),ei_abs(m_workMatrix.coeff(q,q)))*precision)
{
finished = false;
- ei_svd_precondition_2x2_block_to_be_real<MatrixType, Options>::run(work_matrix, *this, p, q);
+ ei_svd_precondition_2x2_block_to_be_real<MatrixType, Options>::run(m_workMatrix, *this, p, q);
PlanarRotation<RealScalar> j_left, j_right;
- ei_real_2x2_jacobi_svd(work_matrix, p, q, &j_left, &j_right);
+ ei_real_2x2_jacobi_svd(m_workMatrix, p, q, &j_left, &j_right);
- work_matrix.applyOnTheLeft(p,q,j_left);
+ m_workMatrix.applyOnTheLeft(p,q,j_left);
if(ComputeU) m_matrixU.applyOnTheRight(p,q,j_left.transpose());
- work_matrix.applyOnTheRight(p,q,j_right);
+ m_workMatrix.applyOnTheRight(p,q,j_right);
if(ComputeV) m_matrixV.applyOnTheRight(p,q,j_right);
}
}
@@ -333,9 +358,9 @@ JacobiSVD<MatrixType, Options>& JacobiSVD<MatrixType, Options>::compute(const Ma
for(int i = 0; i < diagSize; ++i)
{
- RealScalar a = ei_abs(work_matrix.coeff(i,i));
+ RealScalar a = ei_abs(m_workMatrix.coeff(i,i));
m_singularValues.coeffRef(i) = a;
- if(ComputeU && (a!=RealScalar(0))) m_matrixU.col(i) *= work_matrix.coeff(i,i)/a;
+ if(ComputeU && (a!=RealScalar(0))) m_matrixU.col(i) *= m_workMatrix.coeff(i,i)/a;
}
for(int i = 0; i < diagSize; i++)