aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Eigen/src/Array/VectorwiseOp.h4
-rw-r--r--Eigen/src/Eigenvalues/ComplexSchur.h57
-rw-r--r--test/schur_complex.cpp5
3 files changed, 35 insertions, 31 deletions
diff --git a/Eigen/src/Array/VectorwiseOp.h b/Eigen/src/Array/VectorwiseOp.h
index 2aa382df2..b809283a7 100644
--- a/Eigen/src/Array/VectorwiseOp.h
+++ b/Eigen/src/Array/VectorwiseOp.h
@@ -380,8 +380,8 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
/** \returns a matrix expression
* where each column (or row) are reversed.
*
- * Example: \include VectorWise_reverse.cpp
- * Output: \verbinclude VectorWise_reverse.out
+ * Example: \include Vectorwise_reverse.cpp
+ * Output: \verbinclude Vectorwise_reverse.out
*
* \sa DenseBase::reverse() */
const Reverse<ExpressionType, Direction> reverse() const
diff --git a/Eigen/src/Eigenvalues/ComplexSchur.h b/Eigen/src/Eigenvalues/ComplexSchur.h
index 673cb46f9..84da40f22 100644
--- a/Eigen/src/Eigenvalues/ComplexSchur.h
+++ b/Eigen/src/Eigenvalues/ComplexSchur.h
@@ -110,21 +110,21 @@ template<typename _MatrixType> class ComplexSchur
/** \brief Constructor; computes Schur decomposition of given matrix.
*
- * \param[in] matrix Square matrix whose Schur decomposition is to be computed.
- * \param[in] skipU If true, then the unitary matrix U in the decomposition is not computed.
+ * \param[in] matrix Square matrix whose Schur decomposition is to be computed.
+ * \param[in] computeU If true, both T and U are computed; if false, only T is computed.
*
* This constructor calls compute() to compute the Schur decomposition.
*
* \sa matrixT() and matrixU() for examples.
*/
- ComplexSchur(const MatrixType& matrix, bool skipU = false)
+ ComplexSchur(const MatrixType& matrix, bool computeU = true)
: m_matT(matrix.rows(),matrix.cols()),
m_matU(matrix.rows(),matrix.cols()),
m_hess(matrix.rows()),
m_isInitialized(false),
m_matUisUptodate(false)
{
- compute(matrix, skipU);
+ compute(matrix, computeU);
}
/** \brief Returns the unitary matrix in the Schur decomposition.
@@ -132,10 +132,10 @@ template<typename _MatrixType> class ComplexSchur
* \returns A const reference to the matrix U.
*
* It is assumed that either the constructor
- * ComplexSchur(const MatrixType& matrix, bool skipU) or the
- * member function compute(const MatrixType& matrix, bool skipU)
+ * ComplexSchur(const MatrixType& matrix, bool computeU) or the
+ * member function compute(const MatrixType& matrix, bool computeU)
* has been called before to compute the Schur decomposition of a
- * matrix, and that \p skipU was set to false (the default
+ * matrix, and that \p computeU was set to true (the default
* value).
*
* Example: \include ComplexSchur_matrixU.cpp
@@ -153,8 +153,8 @@ template<typename _MatrixType> class ComplexSchur
* \returns A const reference to the matrix T.
*
* It is assumed that either the constructor
- * ComplexSchur(const MatrixType& matrix, bool skipU) or the
- * member function compute(const MatrixType& matrix, bool skipU)
+ * ComplexSchur(const MatrixType& matrix, bool computeU) or the
+ * member function compute(const MatrixType& matrix, bool computeU)
* has been called before to compute the Schur decomposition of a
* matrix.
*
@@ -174,7 +174,7 @@ template<typename _MatrixType> class ComplexSchur
/** \brief Computes Schur decomposition of given matrix.
*
* \param[in] matrix Square matrix whose Schur decomposition is to be computed.
- * \param[in] skipU If true, then the unitary matrix U in the decomposition is not computed.
+ * \param[in] computeU If true, both T and U are computed; if false, only T is computed.
*
* The Schur decomposition is computed by first reducing the
* matrix to Hessenberg form using the class
@@ -182,13 +182,14 @@ template<typename _MatrixType> class ComplexSchur
* to triangular form by performing QR iterations with a single
* shift. The cost of computing the Schur decomposition depends
* on the number of iterations; as a rough guide, it may be taken
+ * on the number of iterations; as a rough guide, it may be taken
* to be \f$25n^3\f$ complex flops, or \f$10n^3\f$ complex flops
- * if \a skipU is true.
+ * if \a computeU is false.
*
* Example: \include ComplexSchur_compute.cpp
* Output: \verbinclude ComplexSchur_compute.out
*/
- void compute(const MatrixType& matrix, bool skipU = false);
+ void compute(const MatrixType& matrix, bool computeU = true);
protected:
ComplexMatrixType m_matT, m_matU;
@@ -199,7 +200,7 @@ template<typename _MatrixType> class ComplexSchur
private:
bool subdiagonalEntryIsNeglegible(Index i);
ComplexScalar computeShift(Index iu, Index iter);
- void reduceToTriangularForm(bool skipU);
+ void reduceToTriangularForm(bool computeU);
friend struct ei_complex_schur_reduce_to_hessenberg<MatrixType, NumTraits<Scalar>::IsComplex>;
};
@@ -295,22 +296,22 @@ typename ComplexSchur<MatrixType>::ComplexScalar ComplexSchur<MatrixType>::compu
template<typename MatrixType>
-void ComplexSchur<MatrixType>::compute(const MatrixType& matrix, bool skipU)
+void ComplexSchur<MatrixType>::compute(const MatrixType& matrix, bool computeU)
{
m_matUisUptodate = false;
ei_assert(matrix.cols() == matrix.rows());
if(matrix.cols() == 1)
{
- m_matU = ComplexMatrixType::Identity(1,1);
- if(!skipU) m_matT = matrix.template cast<ComplexScalar>();
+ m_matT = matrix.template cast<ComplexScalar>();
+ if(computeU) m_matU = ComplexMatrixType::Identity(1,1);
m_isInitialized = true;
- m_matUisUptodate = !skipU;
+ m_matUisUptodate = computeU;
return;
}
- ei_complex_schur_reduce_to_hessenberg<MatrixType, NumTraits<Scalar>::IsComplex>::run(*this, matrix, skipU);
- reduceToTriangularForm(skipU);
+ ei_complex_schur_reduce_to_hessenberg<MatrixType, NumTraits<Scalar>::IsComplex>::run(*this, matrix, computeU);
+ reduceToTriangularForm(computeU);
}
/* Reduce given matrix to Hessenberg form */
@@ -318,28 +319,26 @@ template<typename MatrixType, bool IsComplex>
struct ei_complex_schur_reduce_to_hessenberg
{
// this is the implementation for the case IsComplex = true
- static void run(ComplexSchur<MatrixType>& _this, const MatrixType& matrix, bool skipU)
+ static void run(ComplexSchur<MatrixType>& _this, const MatrixType& matrix, bool computeU)
{
- // TODO skip Q if skipU = true
_this.m_hess.compute(matrix);
_this.m_matT = _this.m_hess.matrixH();
- if(!skipU) _this.m_matU = _this.m_hess.matrixQ();
+ if(computeU) _this.m_matU = _this.m_hess.matrixQ();
}
};
template<typename MatrixType>
struct ei_complex_schur_reduce_to_hessenberg<MatrixType, false>
{
- static void run(ComplexSchur<MatrixType>& _this, const MatrixType& matrix, bool skipU)
+ static void run(ComplexSchur<MatrixType>& _this, const MatrixType& matrix, bool computeU)
{
typedef typename ComplexSchur<MatrixType>::ComplexScalar ComplexScalar;
typedef typename ComplexSchur<MatrixType>::ComplexMatrixType ComplexMatrixType;
// Note: m_hess is over RealScalar; m_matT and m_matU is over ComplexScalar
- // TODO skip Q if skipU = true
_this.m_hess.compute(matrix);
_this.m_matT = _this.m_hess.matrixH().template cast<ComplexScalar>();
- if(!skipU)
+ if(computeU)
{
// This may cause an allocation which seems to be avoidable
MatrixType Q = _this.m_hess.matrixQ();
@@ -350,7 +349,7 @@ struct ei_complex_schur_reduce_to_hessenberg<MatrixType, false>
// Reduce the Hessenberg matrix m_matT to triangular form by QR iteration.
template<typename MatrixType>
-void ComplexSchur<MatrixType>::reduceToTriangularForm(bool skipU)
+void ComplexSchur<MatrixType>::reduceToTriangularForm(bool computeU)
{
// The matrix m_matT is divided in three parts.
// Rows 0,...,il-1 are decoupled from the rest because m_matT(il,il-1) is zero.
@@ -393,7 +392,7 @@ void ComplexSchur<MatrixType>::reduceToTriangularForm(bool skipU)
rot.makeGivens(m_matT.coeff(il,il) - shift, m_matT.coeff(il+1,il));
m_matT.rightCols(m_matT.cols()-il).applyOnTheLeft(il, il+1, rot.adjoint());
m_matT.topRows(std::min(il+2,iu)+1).applyOnTheRight(il, il+1, rot);
- if(!skipU) m_matU.applyOnTheRight(il, il+1, rot);
+ if(computeU) m_matU.applyOnTheRight(il, il+1, rot);
for(Index i=il+1 ; i<iu ; i++)
{
@@ -401,7 +400,7 @@ void ComplexSchur<MatrixType>::reduceToTriangularForm(bool skipU)
m_matT.coeffRef(i+1,i-1) = ComplexScalar(0);
m_matT.rightCols(m_matT.cols()-i).applyOnTheLeft(i, i+1, rot.adjoint());
m_matT.topRows(std::min(i+2,iu)+1).applyOnTheRight(i, i+1, rot);
- if(!skipU) m_matU.applyOnTheRight(i, i+1, rot);
+ if(computeU) m_matU.applyOnTheRight(i, i+1, rot);
}
}
@@ -413,7 +412,7 @@ void ComplexSchur<MatrixType>::reduceToTriangularForm(bool skipU)
}
m_isInitialized = true;
- m_matUisUptodate = !skipU;
+ m_matUisUptodate = computeU;
}
#endif // EIGEN_COMPLEX_SCHUR_H
diff --git a/test/schur_complex.cpp b/test/schur_complex.cpp
index b33411cf2..cc8174d00 100644
--- a/test/schur_complex.cpp
+++ b/test/schur_complex.cpp
@@ -56,6 +56,11 @@ template<typename MatrixType> void schur(int size = MatrixType::ColsAtCompileTim
ComplexSchur<MatrixType> cs2(A);
VERIFY_IS_EQUAL(cs1.matrixT(), cs2.matrixT());
VERIFY_IS_EQUAL(cs1.matrixU(), cs2.matrixU());
+
+ // Test computation of only T, not U
+ ComplexSchur<MatrixType> csOnlyT(A, false);
+ VERIFY_IS_EQUAL(cs1.matrixT(), csOnlyT.matrixT());
+ VERIFY_RAISES_ASSERT(csOnlyT.matrixU());
}
void test_schur_complex()