mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
bug #86 : use internal:: namespace instead of ei_ prefix
This commit is contained in:
@@ -25,12 +25,12 @@
|
||||
#ifndef EIGEN_JACOBISVD_H
|
||||
#define EIGEN_JACOBISVD_H
|
||||
|
||||
namespace internal {
|
||||
// forward declaration (needed by ICC)
|
||||
// the empty body is required by MSVC
|
||||
template<typename MatrixType, int QRPreconditioner,
|
||||
bool IsComplex = NumTraits<typename MatrixType::Scalar>::IsComplex>
|
||||
struct ei_svd_precondition_2x2_block_to_be_real {};
|
||||
|
||||
struct svd_precondition_2x2_block_to_be_real {};
|
||||
|
||||
/*** QR preconditioners (R-SVD)
|
||||
***
|
||||
@@ -42,7 +42,7 @@ struct ei_svd_precondition_2x2_block_to_be_real {};
|
||||
enum { PreconditionIfMoreColsThanRows, PreconditionIfMoreRowsThanCols };
|
||||
|
||||
template<typename MatrixType, int QRPreconditioner, int Case>
|
||||
struct ei_qr_preconditioner_should_do_anything
|
||||
struct qr_preconditioner_should_do_anything
|
||||
{
|
||||
enum { a = MatrixType::RowsAtCompileTime != Dynamic &&
|
||||
MatrixType::ColsAtCompileTime != Dynamic &&
|
||||
@@ -57,11 +57,11 @@ struct ei_qr_preconditioner_should_do_anything
|
||||
};
|
||||
|
||||
template<typename MatrixType, int QRPreconditioner, int Case,
|
||||
bool DoAnything = ei_qr_preconditioner_should_do_anything<MatrixType, QRPreconditioner, Case>::ret
|
||||
> struct ei_qr_preconditioner_impl {};
|
||||
bool DoAnything = qr_preconditioner_should_do_anything<MatrixType, QRPreconditioner, Case>::ret
|
||||
> struct qr_preconditioner_impl {};
|
||||
|
||||
template<typename MatrixType, int QRPreconditioner, int Case>
|
||||
struct ei_qr_preconditioner_impl<MatrixType, QRPreconditioner, Case, false>
|
||||
struct qr_preconditioner_impl<MatrixType, QRPreconditioner, Case, false>
|
||||
{
|
||||
static bool run(JacobiSVD<MatrixType, QRPreconditioner>&, const MatrixType&)
|
||||
{
|
||||
@@ -72,7 +72,7 @@ struct ei_qr_preconditioner_impl<MatrixType, QRPreconditioner, Case, false>
|
||||
/*** preconditioner using FullPivHouseholderQR ***/
|
||||
|
||||
template<typename MatrixType>
|
||||
struct ei_qr_preconditioner_impl<MatrixType, FullPivHouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true>
|
||||
struct qr_preconditioner_impl<MatrixType, FullPivHouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true>
|
||||
{
|
||||
static bool run(JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix)
|
||||
{
|
||||
@@ -89,7 +89,7 @@ struct ei_qr_preconditioner_impl<MatrixType, FullPivHouseholderQRPreconditioner,
|
||||
};
|
||||
|
||||
template<typename MatrixType>
|
||||
struct ei_qr_preconditioner_impl<MatrixType, FullPivHouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true>
|
||||
struct qr_preconditioner_impl<MatrixType, FullPivHouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true>
|
||||
{
|
||||
static bool run(JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix)
|
||||
{
|
||||
@@ -111,7 +111,7 @@ struct ei_qr_preconditioner_impl<MatrixType, FullPivHouseholderQRPreconditioner,
|
||||
/*** preconditioner using ColPivHouseholderQR ***/
|
||||
|
||||
template<typename MatrixType>
|
||||
struct ei_qr_preconditioner_impl<MatrixType, ColPivHouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true>
|
||||
struct qr_preconditioner_impl<MatrixType, ColPivHouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true>
|
||||
{
|
||||
static bool run(JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix)
|
||||
{
|
||||
@@ -132,7 +132,7 @@ struct ei_qr_preconditioner_impl<MatrixType, ColPivHouseholderQRPreconditioner,
|
||||
};
|
||||
|
||||
template<typename MatrixType>
|
||||
struct ei_qr_preconditioner_impl<MatrixType, ColPivHouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true>
|
||||
struct qr_preconditioner_impl<MatrixType, ColPivHouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true>
|
||||
{
|
||||
static bool run(JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix)
|
||||
{
|
||||
@@ -158,7 +158,7 @@ struct ei_qr_preconditioner_impl<MatrixType, ColPivHouseholderQRPreconditioner,
|
||||
/*** preconditioner using HouseholderQR ***/
|
||||
|
||||
template<typename MatrixType>
|
||||
struct ei_qr_preconditioner_impl<MatrixType, HouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true>
|
||||
struct qr_preconditioner_impl<MatrixType, HouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true>
|
||||
{
|
||||
static bool run(JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd, const MatrixType& matrix)
|
||||
{
|
||||
@@ -179,7 +179,7 @@ struct ei_qr_preconditioner_impl<MatrixType, HouseholderQRPreconditioner, Precon
|
||||
};
|
||||
|
||||
template<typename MatrixType>
|
||||
struct ei_qr_preconditioner_impl<MatrixType, HouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true>
|
||||
struct qr_preconditioner_impl<MatrixType, HouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true>
|
||||
{
|
||||
static bool run(JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd, const MatrixType& matrix)
|
||||
{
|
||||
@@ -202,7 +202,90 @@ struct ei_qr_preconditioner_impl<MatrixType, HouseholderQRPreconditioner, Precon
|
||||
}
|
||||
};
|
||||
|
||||
/*** 2x2 SVD implementation
|
||||
***
|
||||
*** JacobiSVD consists in performing a series of 2x2 SVD subproblems
|
||||
***/
|
||||
|
||||
template<typename MatrixType, int QRPreconditioner>
|
||||
struct svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner, false>
|
||||
{
|
||||
typedef JacobiSVD<MatrixType, QRPreconditioner> SVD;
|
||||
typedef typename SVD::Index Index;
|
||||
static void run(typename SVD::WorkMatrixType&, SVD&, Index, Index) {}
|
||||
};
|
||||
|
||||
template<typename MatrixType, int QRPreconditioner>
|
||||
struct svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner, true>
|
||||
{
|
||||
typedef JacobiSVD<MatrixType, QRPreconditioner> SVD;
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename MatrixType::RealScalar RealScalar;
|
||||
typedef typename SVD::Index Index;
|
||||
static void run(typename SVD::WorkMatrixType& work_matrix, SVD& svd, Index p, Index q)
|
||||
{
|
||||
Scalar z;
|
||||
JacobiRotation<Scalar> rot;
|
||||
RealScalar n = sqrt(abs2(work_matrix.coeff(p,p)) + abs2(work_matrix.coeff(q,p)));
|
||||
if(n==0)
|
||||
{
|
||||
z = abs(work_matrix.coeff(p,q)) / work_matrix.coeff(p,q);
|
||||
work_matrix.row(p) *= z;
|
||||
if(svd.computeU()) svd.m_matrixU.col(p) *= conj(z);
|
||||
z = abs(work_matrix.coeff(q,q)) / work_matrix.coeff(q,q);
|
||||
work_matrix.row(q) *= z;
|
||||
if(svd.computeU()) svd.m_matrixU.col(q) *= conj(z);
|
||||
}
|
||||
else
|
||||
{
|
||||
rot.c() = conj(work_matrix.coeff(p,p)) / n;
|
||||
rot.s() = work_matrix.coeff(q,p) / n;
|
||||
work_matrix.applyOnTheLeft(p,q,rot);
|
||||
if(svd.computeU()) svd.m_matrixU.applyOnTheRight(p,q,rot.adjoint());
|
||||
if(work_matrix.coeff(p,q) != Scalar(0))
|
||||
{
|
||||
Scalar z = abs(work_matrix.coeff(p,q)) / work_matrix.coeff(p,q);
|
||||
work_matrix.col(q) *= z;
|
||||
if(svd.computeV()) svd.m_matrixV.col(q) *= z;
|
||||
}
|
||||
if(work_matrix.coeff(q,q) != Scalar(0))
|
||||
{
|
||||
z = abs(work_matrix.coeff(q,q)) / work_matrix.coeff(q,q);
|
||||
work_matrix.row(q) *= z;
|
||||
if(svd.computeU()) svd.m_matrixU.col(q) *= conj(z);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename MatrixType, typename RealScalar, typename Index>
|
||||
void real_2x2_jacobi_svd(const MatrixType& matrix, Index p, Index q,
|
||||
JacobiRotation<RealScalar> *j_left,
|
||||
JacobiRotation<RealScalar> *j_right)
|
||||
{
|
||||
Matrix<RealScalar,2,2> m;
|
||||
m << real(matrix.coeff(p,p)), real(matrix.coeff(p,q)),
|
||||
real(matrix.coeff(q,p)), real(matrix.coeff(q,q));
|
||||
JacobiRotation<RealScalar> rot1;
|
||||
RealScalar t = m.coeff(0,0) + m.coeff(1,1);
|
||||
RealScalar d = m.coeff(1,0) - m.coeff(0,1);
|
||||
if(t == RealScalar(0))
|
||||
{
|
||||
rot1.c() = 0;
|
||||
rot1.s() = d > 0 ? 1 : -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
RealScalar u = d / t;
|
||||
rot1.c() = RealScalar(1) / sqrt(1 + abs2(u));
|
||||
rot1.s() = rot1.c() * u;
|
||||
}
|
||||
m.applyOnTheLeft(0,1,rot1);
|
||||
j_right->makeJacobi(m,0,1);
|
||||
*j_left = rot1 * j_right->transpose();
|
||||
}
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
/** \ingroup SVD_Module
|
||||
*
|
||||
@@ -281,9 +364,9 @@ template<typename _MatrixType, int QRPreconditioner> class JacobiSVD
|
||||
typedef Matrix<Scalar, ColsAtCompileTime, ColsAtCompileTime,
|
||||
MatrixOptions, MaxColsAtCompileTime, MaxColsAtCompileTime>
|
||||
MatrixVType;
|
||||
typedef typename ei_plain_diag_type<MatrixType, RealScalar>::type SingularValuesType;
|
||||
typedef typename ei_plain_row_type<MatrixType>::type RowType;
|
||||
typedef typename ei_plain_col_type<MatrixType>::type ColType;
|
||||
typedef typename internal::plain_diag_type<MatrixType, RealScalar>::type SingularValuesType;
|
||||
typedef typename internal::plain_row_type<MatrixType>::type RowType;
|
||||
typedef typename internal::plain_col_type<MatrixType>::type ColType;
|
||||
typedef Matrix<Scalar, DiagSizeAtCompileTime, DiagSizeAtCompileTime,
|
||||
MatrixOptions, MaxDiagSizeAtCompileTime, MaxDiagSizeAtCompileTime>
|
||||
WorkMatrixType;
|
||||
@@ -345,8 +428,8 @@ template<typename _MatrixType, int QRPreconditioner> class JacobiSVD
|
||||
*/
|
||||
const MatrixUType& matrixU() const
|
||||
{
|
||||
ei_assert(m_isInitialized && "JacobiSVD is not initialized.");
|
||||
ei_assert(computeU() && "This JacobiSVD decomposition didn't compute U. Did you ask for it?");
|
||||
eigen_assert(m_isInitialized && "JacobiSVD is not initialized.");
|
||||
eigen_assert(computeU() && "This JacobiSVD decomposition didn't compute U. Did you ask for it?");
|
||||
return m_matrixU;
|
||||
}
|
||||
|
||||
@@ -361,8 +444,8 @@ template<typename _MatrixType, int QRPreconditioner> class JacobiSVD
|
||||
*/
|
||||
const MatrixVType& matrixV() const
|
||||
{
|
||||
ei_assert(m_isInitialized && "JacobiSVD is not initialized.");
|
||||
ei_assert(computeV() && "This JacobiSVD decomposition didn't compute V. Did you ask for it?");
|
||||
eigen_assert(m_isInitialized && "JacobiSVD is not initialized.");
|
||||
eigen_assert(computeV() && "This JacobiSVD decomposition didn't compute V. Did you ask for it?");
|
||||
return m_matrixV;
|
||||
}
|
||||
|
||||
@@ -373,7 +456,7 @@ template<typename _MatrixType, int QRPreconditioner> class JacobiSVD
|
||||
*/
|
||||
const SingularValuesType& singularValues() const
|
||||
{
|
||||
ei_assert(m_isInitialized && "JacobiSVD is not initialized.");
|
||||
eigen_assert(m_isInitialized && "JacobiSVD is not initialized.");
|
||||
return m_singularValues;
|
||||
}
|
||||
|
||||
@@ -392,18 +475,18 @@ template<typename _MatrixType, int QRPreconditioner> class JacobiSVD
|
||||
* In other words, the returned solution is guaranteed to minimize the Euclidean norm \f$ \Vert A x - b \Vert \f$.
|
||||
*/
|
||||
template<typename Rhs>
|
||||
inline const ei_solve_retval<JacobiSVD, Rhs>
|
||||
inline const internal::solve_retval<JacobiSVD, Rhs>
|
||||
solve(const MatrixBase<Rhs>& b) const
|
||||
{
|
||||
ei_assert(m_isInitialized && "JacobiSVD is not initialized.");
|
||||
ei_assert(computeU() && computeV() && "JacobiSVD::solve() requires both unitaries U and V to be computed (thin unitaries suffice).");
|
||||
return ei_solve_retval<JacobiSVD, Rhs>(*this, b.derived());
|
||||
eigen_assert(m_isInitialized && "JacobiSVD is not initialized.");
|
||||
eigen_assert(computeU() && computeV() && "JacobiSVD::solve() requires both unitaries U and V to be computed (thin unitaries suffice).");
|
||||
return internal::solve_retval<JacobiSVD, Rhs>(*this, b.derived());
|
||||
}
|
||||
|
||||
/** \returns the number of singular values that are not exactly 0 */
|
||||
Index nonzeroSingularValues() const
|
||||
{
|
||||
ei_assert(m_isInitialized && "JacobiSVD is not initialized.");
|
||||
eigen_assert(m_isInitialized && "JacobiSVD is not initialized.");
|
||||
return m_nonzeroSingularValues;
|
||||
}
|
||||
|
||||
@@ -424,9 +507,9 @@ template<typename _MatrixType, int QRPreconditioner> class JacobiSVD
|
||||
Index m_nonzeroSingularValues, m_rows, m_cols, m_diagSize;
|
||||
|
||||
template<typename __MatrixType, int _QRPreconditioner, bool _IsComplex>
|
||||
friend struct ei_svd_precondition_2x2_block_to_be_real;
|
||||
friend struct internal::svd_precondition_2x2_block_to_be_real;
|
||||
template<typename __MatrixType, int _QRPreconditioner, int _Case, bool _DoAnything>
|
||||
friend struct ei_qr_preconditioner_impl;
|
||||
friend struct internal::qr_preconditioner_impl;
|
||||
};
|
||||
|
||||
template<typename MatrixType, int QRPreconditioner>
|
||||
@@ -439,13 +522,13 @@ void JacobiSVD<MatrixType, QRPreconditioner>::allocate(Index rows, Index cols, u
|
||||
m_computeThinU = (computationOptions & ComputeThinU) != 0;
|
||||
m_computeFullV = (computationOptions & ComputeFullV) != 0;
|
||||
m_computeThinV = (computationOptions & ComputeThinV) != 0;
|
||||
ei_assert(!(m_computeFullU && m_computeThinU) && "JacobiSVD: you can't ask for both full and thin U");
|
||||
ei_assert(!(m_computeFullV && m_computeThinV) && "JacobiSVD: you can't ask for both full and thin V");
|
||||
ei_assert(EIGEN_IMPLIES(m_computeThinU || m_computeThinV, MatrixType::ColsAtCompileTime==Dynamic) &&
|
||||
eigen_assert(!(m_computeFullU && m_computeThinU) && "JacobiSVD: you can't ask for both full and thin U");
|
||||
eigen_assert(!(m_computeFullV && m_computeThinV) && "JacobiSVD: you can't ask for both full and thin V");
|
||||
eigen_assert(EIGEN_IMPLIES(m_computeThinU || m_computeThinV, MatrixType::ColsAtCompileTime==Dynamic) &&
|
||||
"JacobiSVD: thin U and V are only available when your matrix has a dynamic number of columns.");
|
||||
if (QRPreconditioner == FullPivHouseholderQRPreconditioner)
|
||||
{
|
||||
ei_assert(!(m_computeThinU || m_computeThinV) &&
|
||||
eigen_assert(!(m_computeThinU || m_computeThinV) &&
|
||||
"JacobiSVD: can't compute thin U or thin V with the FullPivHouseholderQR preconditioner. "
|
||||
"Use the ColPivHouseholderQR preconditioner instead.");
|
||||
}
|
||||
@@ -460,85 +543,6 @@ void JacobiSVD<MatrixType, QRPreconditioner>::allocate(Index rows, Index cols, u
|
||||
m_workMatrix.resize(m_diagSize, m_diagSize);
|
||||
}
|
||||
|
||||
|
||||
template<typename MatrixType, int QRPreconditioner>
|
||||
struct ei_svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner, false>
|
||||
{
|
||||
typedef JacobiSVD<MatrixType, QRPreconditioner> SVD;
|
||||
typedef typename SVD::Index Index;
|
||||
static void run(typename SVD::WorkMatrixType&, SVD&, Index, Index) {}
|
||||
};
|
||||
|
||||
template<typename MatrixType, int QRPreconditioner>
|
||||
struct ei_svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner, true>
|
||||
{
|
||||
typedef JacobiSVD<MatrixType, QRPreconditioner> SVD;
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename MatrixType::RealScalar RealScalar;
|
||||
typedef typename SVD::Index Index;
|
||||
static void run(typename SVD::WorkMatrixType& work_matrix, SVD& svd, Index p, Index q)
|
||||
{
|
||||
Scalar z;
|
||||
JacobiRotation<Scalar> rot;
|
||||
RealScalar n = ei_sqrt(ei_abs2(work_matrix.coeff(p,p)) + ei_abs2(work_matrix.coeff(q,p)));
|
||||
if(n==0)
|
||||
{
|
||||
z = ei_abs(work_matrix.coeff(p,q)) / work_matrix.coeff(p,q);
|
||||
work_matrix.row(p) *= z;
|
||||
if(svd.computeU()) svd.m_matrixU.col(p) *= ei_conj(z);
|
||||
z = ei_abs(work_matrix.coeff(q,q)) / work_matrix.coeff(q,q);
|
||||
work_matrix.row(q) *= z;
|
||||
if(svd.computeU()) svd.m_matrixU.col(q) *= ei_conj(z);
|
||||
}
|
||||
else
|
||||
{
|
||||
rot.c() = ei_conj(work_matrix.coeff(p,p)) / n;
|
||||
rot.s() = work_matrix.coeff(q,p) / n;
|
||||
work_matrix.applyOnTheLeft(p,q,rot);
|
||||
if(svd.computeU()) svd.m_matrixU.applyOnTheRight(p,q,rot.adjoint());
|
||||
if(work_matrix.coeff(p,q) != Scalar(0))
|
||||
{
|
||||
Scalar z = ei_abs(work_matrix.coeff(p,q)) / work_matrix.coeff(p,q);
|
||||
work_matrix.col(q) *= z;
|
||||
if(svd.computeV()) svd.m_matrixV.col(q) *= z;
|
||||
}
|
||||
if(work_matrix.coeff(q,q) != Scalar(0))
|
||||
{
|
||||
z = ei_abs(work_matrix.coeff(q,q)) / work_matrix.coeff(q,q);
|
||||
work_matrix.row(q) *= z;
|
||||
if(svd.computeU()) svd.m_matrixU.col(q) *= ei_conj(z);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename MatrixType, typename RealScalar, typename Index>
|
||||
void ei_real_2x2_jacobi_svd(const MatrixType& matrix, Index p, Index q,
|
||||
JacobiRotation<RealScalar> *j_left,
|
||||
JacobiRotation<RealScalar> *j_right)
|
||||
{
|
||||
Matrix<RealScalar,2,2> m;
|
||||
m << ei_real(matrix.coeff(p,p)), ei_real(matrix.coeff(p,q)),
|
||||
ei_real(matrix.coeff(q,p)), ei_real(matrix.coeff(q,q));
|
||||
JacobiRotation<RealScalar> rot1;
|
||||
RealScalar t = m.coeff(0,0) + m.coeff(1,1);
|
||||
RealScalar d = m.coeff(1,0) - m.coeff(0,1);
|
||||
if(t == RealScalar(0))
|
||||
{
|
||||
rot1.c() = 0;
|
||||
rot1.s() = d > 0 ? 1 : -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
RealScalar u = d / t;
|
||||
rot1.c() = RealScalar(1) / ei_sqrt(1 + ei_abs2(u));
|
||||
rot1.s() = rot1.c() * u;
|
||||
}
|
||||
m.applyOnTheLeft(0,1,rot1);
|
||||
j_right->makeJacobi(m,0,1);
|
||||
*j_left = rot1 * j_right->transpose();
|
||||
}
|
||||
|
||||
template<typename MatrixType, int QRPreconditioner>
|
||||
JacobiSVD<MatrixType, QRPreconditioner>&
|
||||
JacobiSVD<MatrixType, QRPreconditioner>::compute(const MatrixType& matrix, unsigned int computationOptions)
|
||||
@@ -551,8 +555,8 @@ JacobiSVD<MatrixType, QRPreconditioner>::compute(const MatrixType& matrix, unsig
|
||||
|
||||
/*** step 1. The R-SVD step: we use a QR decomposition to reduce to the case of a square matrix */
|
||||
|
||||
if(!ei_qr_preconditioner_impl<MatrixType, QRPreconditioner, PreconditionIfMoreColsThanRows>::run(*this, matrix)
|
||||
&& !ei_qr_preconditioner_impl<MatrixType, QRPreconditioner, PreconditionIfMoreRowsThanCols>::run(*this, matrix))
|
||||
if(!internal::qr_preconditioner_impl<MatrixType, QRPreconditioner, internal::PreconditionIfMoreColsThanRows>::run(*this, matrix)
|
||||
&& !internal::qr_preconditioner_impl<MatrixType, QRPreconditioner, internal::PreconditionIfMoreRowsThanCols>::run(*this, matrix))
|
||||
{
|
||||
m_workMatrix = matrix.block(0,0,m_diagSize,m_diagSize);
|
||||
if(m_computeFullU) m_matrixU.setIdentity(m_rows,m_rows);
|
||||
@@ -577,15 +581,15 @@ JacobiSVD<MatrixType, QRPreconditioner>::compute(const MatrixType& matrix, unsig
|
||||
// if this 2x2 sub-matrix is not diagonal already...
|
||||
// notice that this comparison will evaluate to false if any NaN is involved, ensuring that NaN's don't
|
||||
// keep us iterating forever.
|
||||
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)
|
||||
if(std::max(internal::abs(m_workMatrix.coeff(p,q)),internal::abs(m_workMatrix.coeff(q,p)))
|
||||
> std::max(internal::abs(m_workMatrix.coeff(p,p)),internal::abs(m_workMatrix.coeff(q,q)))*precision)
|
||||
{
|
||||
finished = false;
|
||||
|
||||
// perform SVD decomposition of 2x2 sub-matrix corresponding to indices p,q to make it diagonal
|
||||
ei_svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner>::run(m_workMatrix, *this, p, q);
|
||||
internal::svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner>::run(m_workMatrix, *this, p, q);
|
||||
JacobiRotation<RealScalar> j_left, j_right;
|
||||
ei_real_2x2_jacobi_svd(m_workMatrix, p, q, &j_left, &j_right);
|
||||
internal::real_2x2_jacobi_svd(m_workMatrix, p, q, &j_left, &j_right);
|
||||
|
||||
// accumulate resulting Jacobi rotations
|
||||
m_workMatrix.applyOnTheLeft(p,q,j_left);
|
||||
@@ -602,7 +606,7 @@ JacobiSVD<MatrixType, QRPreconditioner>::compute(const MatrixType& matrix, unsig
|
||||
|
||||
for(Index i = 0; i < m_diagSize; ++i)
|
||||
{
|
||||
RealScalar a = ei_abs(m_workMatrix.coeff(i,i));
|
||||
RealScalar a = internal::abs(m_workMatrix.coeff(i,i));
|
||||
m_singularValues.coeffRef(i) = a;
|
||||
if(computeU() && (a!=RealScalar(0))) m_matrixU.col(i) *= m_workMatrix.coeff(i,i)/a;
|
||||
}
|
||||
@@ -632,16 +636,17 @@ JacobiSVD<MatrixType, QRPreconditioner>::compute(const MatrixType& matrix, unsig
|
||||
return *this;
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
template<typename _MatrixType, int QRPreconditioner, typename Rhs>
|
||||
struct ei_solve_retval<JacobiSVD<_MatrixType, QRPreconditioner>, Rhs>
|
||||
: ei_solve_retval_base<JacobiSVD<_MatrixType, QRPreconditioner>, Rhs>
|
||||
struct solve_retval<JacobiSVD<_MatrixType, QRPreconditioner>, Rhs>
|
||||
: solve_retval_base<JacobiSVD<_MatrixType, QRPreconditioner>, Rhs>
|
||||
{
|
||||
typedef JacobiSVD<_MatrixType, QRPreconditioner> JacobiSVDType;
|
||||
EIGEN_MAKE_SOLVE_HELPERS(JacobiSVDType,Rhs)
|
||||
|
||||
template<typename Dest> void evalTo(Dest& dst) const
|
||||
{
|
||||
ei_assert(rhs().rows() == dec().rows());
|
||||
eigen_assert(rhs().rows() == dec().rows());
|
||||
|
||||
// A = U S V^*
|
||||
// So A^{-1} = V S^{-1} U^*
|
||||
@@ -659,6 +664,7 @@ struct ei_solve_retval<JacobiSVD<_MatrixType, QRPreconditioner>, Rhs>
|
||||
* rhs();
|
||||
}
|
||||
};
|
||||
} // end namespace internal
|
||||
|
||||
template<typename Derived>
|
||||
JacobiSVD<typename MatrixBase<Derived>::PlainObject>
|
||||
|
||||
@@ -33,7 +33,7 @@ template<typename _MatrixType> class UpperBidiagonalization
|
||||
enum {
|
||||
RowsAtCompileTime = MatrixType::RowsAtCompileTime,
|
||||
ColsAtCompileTime = MatrixType::ColsAtCompileTime,
|
||||
ColsAtCompileTimeMinusOne = ei_decrement_size<ColsAtCompileTime>::ret
|
||||
ColsAtCompileTimeMinusOne = internal::decrement_size<ColsAtCompileTime>::ret
|
||||
};
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename MatrixType::RealScalar RealScalar;
|
||||
@@ -45,7 +45,7 @@ template<typename _MatrixType> class UpperBidiagonalization
|
||||
typedef Matrix<Scalar, ColsAtCompileTimeMinusOne, 1> SuperDiagVectorType;
|
||||
typedef HouseholderSequence<
|
||||
MatrixType,
|
||||
CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Diagonal<MatrixType,0> >
|
||||
CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, Diagonal<MatrixType,0> >
|
||||
> HouseholderUSequenceType;
|
||||
typedef HouseholderSequence<
|
||||
MatrixType,
|
||||
@@ -76,13 +76,13 @@ template<typename _MatrixType> class UpperBidiagonalization
|
||||
|
||||
HouseholderUSequenceType householderU() const
|
||||
{
|
||||
ei_assert(m_isInitialized && "UpperBidiagonalization is not initialized.");
|
||||
eigen_assert(m_isInitialized && "UpperBidiagonalization is not initialized.");
|
||||
return HouseholderUSequenceType(m_householder, m_householder.diagonal().conjugate());
|
||||
}
|
||||
|
||||
HouseholderVSequenceType householderV() // const here gives nasty errors and i'm lazy
|
||||
{
|
||||
ei_assert(m_isInitialized && "UpperBidiagonalization is not initialized.");
|
||||
eigen_assert(m_isInitialized && "UpperBidiagonalization is not initialized.");
|
||||
return HouseholderVSequenceType(m_householder, m_householder.template diagonal<1>(),
|
||||
false, m_householder.cols()-1, 1);
|
||||
}
|
||||
@@ -99,7 +99,7 @@ UpperBidiagonalization<_MatrixType>& UpperBidiagonalization<_MatrixType>::comput
|
||||
Index rows = matrix.rows();
|
||||
Index cols = matrix.cols();
|
||||
|
||||
ei_assert(rows >= cols && "UpperBidiagonalization is only for matrices satisfying rows>=cols.");
|
||||
eigen_assert(rows >= cols && "UpperBidiagonalization is only for matrices satisfying rows>=cols.");
|
||||
|
||||
m_householder = matrix;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user