From f41959ccb2d9d4c722fe8fc3351401d53bcf4900 Mon Sep 17 00:00:00 2001 From: Manjunath Kudlur Date: Fri, 6 Nov 2015 16:27:58 -0800 Subject: TensorFlow: Initial commit of TensorFlow library. TensorFlow is an open source software library for numerical computation using data flow graphs. Base CL: 107276108 --- .../eigen3/Eigen/src/Core/TriangularMatrix.h | 900 +++++++++++++++++++++ 1 file changed, 900 insertions(+) create mode 100644 third_party/eigen3/Eigen/src/Core/TriangularMatrix.h (limited to 'third_party/eigen3/Eigen/src/Core/TriangularMatrix.h') diff --git a/third_party/eigen3/Eigen/src/Core/TriangularMatrix.h b/third_party/eigen3/Eigen/src/Core/TriangularMatrix.h new file mode 100644 index 0000000000..1d6e346506 --- /dev/null +++ b/third_party/eigen3/Eigen/src/Core/TriangularMatrix.h @@ -0,0 +1,900 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Benoit Jacob +// Copyright (C) 2008-2009 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_TRIANGULARMATRIX_H +#define EIGEN_TRIANGULARMATRIX_H + +namespace Eigen { + +namespace internal { + +template struct triangular_solve_retval; + +} + +/** \internal + * + * \class TriangularBase + * \ingroup Core_Module + * + * \brief Base class for triangular part in a matrix + */ +template class TriangularBase : public EigenBase +{ + public: + + enum { + Mode = internal::traits::Mode, + CoeffReadCost = internal::traits::CoeffReadCost, + RowsAtCompileTime = internal::traits::RowsAtCompileTime, + ColsAtCompileTime = internal::traits::ColsAtCompileTime, + MaxRowsAtCompileTime = internal::traits::MaxRowsAtCompileTime, + MaxColsAtCompileTime = internal::traits::MaxColsAtCompileTime + }; + typedef typename internal::traits::Scalar Scalar; + typedef typename internal::traits::StorageKind StorageKind; + typedef typename internal::traits::Index Index; + typedef typename internal::traits::DenseMatrixType DenseMatrixType; + typedef DenseMatrixType DenseType; + + EIGEN_DEVICE_FUNC + inline TriangularBase() { eigen_assert(!((Mode&UnitDiag) && (Mode&ZeroDiag))); } + + EIGEN_DEVICE_FUNC + inline Index rows() const { return derived().rows(); } + EIGEN_DEVICE_FUNC + inline Index cols() const { return derived().cols(); } + EIGEN_DEVICE_FUNC + inline Index outerStride() const { return derived().outerStride(); } + EIGEN_DEVICE_FUNC + inline Index innerStride() const { return derived().innerStride(); } + + EIGEN_DEVICE_FUNC + inline Scalar coeff(Index row, Index col) const { return derived().coeff(row,col); } + EIGEN_DEVICE_FUNC + inline Scalar& coeffRef(Index row, Index col) { return derived().coeffRef(row,col); } + + /** \see MatrixBase::copyCoeff(row,col) + */ + template + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE void copyCoeff(Index row, Index col, Other& other) + { + derived().coeffRef(row, col) = other.coeff(row, col); + } + + EIGEN_DEVICE_FUNC + inline Scalar operator()(Index row, Index col) const + { + check_coordinates(row, col); + return coeff(row,col); + } + EIGEN_DEVICE_FUNC + inline Scalar& operator()(Index row, Index col) + { + check_coordinates(row, col); + return coeffRef(row,col); + } + + #ifndef EIGEN_PARSED_BY_DOXYGEN + EIGEN_DEVICE_FUNC + inline const Derived& derived() const { return *static_cast(this); } + EIGEN_DEVICE_FUNC + inline Derived& derived() { return *static_cast(this); } + #endif // not EIGEN_PARSED_BY_DOXYGEN + + template + EIGEN_DEVICE_FUNC + void evalTo(MatrixBase &other) const; + template + EIGEN_DEVICE_FUNC + void evalToLazy(MatrixBase &other) const; + + EIGEN_DEVICE_FUNC + DenseMatrixType toDenseMatrix() const + { + DenseMatrixType res(rows(), cols()); + evalToLazy(res); + return res; + } + + protected: + + void check_coordinates(Index row, Index col) const + { + EIGEN_ONLY_USED_FOR_DEBUG(row); + EIGEN_ONLY_USED_FOR_DEBUG(col); + eigen_assert(col>=0 && col=0 && row=row) + || (mode==Lower && col<=row) + || ((mode==StrictlyUpper || mode==UnitUpper) && col>row) + || ((mode==StrictlyLower || mode==UnitLower) && col +struct traits > : traits +{ + typedef typename nested::type MatrixTypeNested; + typedef typename remove_reference::type MatrixTypeNestedNonRef; + typedef typename remove_all::type MatrixTypeNestedCleaned; + typedef MatrixType ExpressionType; + typedef typename MatrixType::PlainObject DenseMatrixType; + enum { + Mode = _Mode, + Flags = (MatrixTypeNestedCleaned::Flags & (HereditaryBits) & (~(PacketAccessBit | DirectAccessBit | LinearAccessBit))) | Mode, + CoeffReadCost = MatrixTypeNestedCleaned::CoeffReadCost + }; +}; +} + +template +struct TriangularProduct; + +template class TriangularView + : public TriangularBase > +{ + public: + + typedef TriangularBase Base; + typedef typename internal::traits::Scalar Scalar; + + typedef _MatrixType MatrixType; + typedef typename internal::traits::DenseMatrixType DenseMatrixType; + typedef DenseMatrixType PlainObject; + + protected: + typedef typename internal::traits::MatrixTypeNested MatrixTypeNested; + typedef typename internal::traits::MatrixTypeNestedNonRef MatrixTypeNestedNonRef; + typedef typename internal::traits::MatrixTypeNestedCleaned MatrixTypeNestedCleaned; + + typedef typename internal::remove_all::type MatrixConjugateReturnType; + + public: + using Base::evalToLazy; + + + typedef typename internal::traits::StorageKind StorageKind; + typedef typename internal::traits::Index Index; + + enum { + Mode = _Mode, + TransposeMode = (Mode & Upper ? Lower : 0) + | (Mode & Lower ? Upper : 0) + | (Mode & (UnitDiag)) + | (Mode & (ZeroDiag)) + }; + + EIGEN_DEVICE_FUNC + inline TriangularView(const MatrixType& matrix) : m_matrix(matrix) + {} + + EIGEN_DEVICE_FUNC + inline Index rows() const { return m_matrix.rows(); } + EIGEN_DEVICE_FUNC + inline Index cols() const { return m_matrix.cols(); } + EIGEN_DEVICE_FUNC + inline Index outerStride() const { return m_matrix.outerStride(); } + EIGEN_DEVICE_FUNC + inline Index innerStride() const { return m_matrix.innerStride(); } + + /** \sa MatrixBase::operator+=() */ + template + EIGEN_DEVICE_FUNC + TriangularView& operator+=(const DenseBase& other) { return *this = m_matrix + other.derived(); } + /** \sa MatrixBase::operator-=() */ + template + EIGEN_DEVICE_FUNC + TriangularView& operator-=(const DenseBase& other) { return *this = m_matrix - other.derived(); } + /** \sa MatrixBase::operator*=() */ + EIGEN_DEVICE_FUNC + TriangularView& operator*=(const typename internal::traits::Scalar& other) { return *this = m_matrix * other; } + /** \sa MatrixBase::operator/=() */ + EIGEN_DEVICE_FUNC + TriangularView& operator/=(const typename internal::traits::Scalar& other) { return *this = m_matrix / other; } + + /** \sa MatrixBase::fill() */ + EIGEN_DEVICE_FUNC + void fill(const Scalar& value) { setConstant(value); } + /** \sa MatrixBase::setConstant() */ + EIGEN_DEVICE_FUNC + TriangularView& setConstant(const Scalar& value) + { return *this = MatrixType::Constant(rows(), cols(), value); } + /** \sa MatrixBase::setZero() */ + EIGEN_DEVICE_FUNC + TriangularView& setZero() { return setConstant(Scalar(0)); } + /** \sa MatrixBase::setOnes() */ + EIGEN_DEVICE_FUNC + TriangularView& setOnes() { return setConstant(Scalar(1)); } + + /** \sa MatrixBase::coeff() + * \warning the coordinates must fit into the referenced triangular part + */ + EIGEN_DEVICE_FUNC + inline Scalar coeff(Index row, Index col) const + { + Base::check_coordinates_internal(row, col); + return m_matrix.coeff(row, col); + } + + /** \sa MatrixBase::coeffRef() + * \warning the coordinates must fit into the referenced triangular part + */ + EIGEN_DEVICE_FUNC + inline Scalar& coeffRef(Index row, Index col) + { + Base::check_coordinates_internal(row, col); + return m_matrix.const_cast_derived().coeffRef(row, col); + } + + EIGEN_DEVICE_FUNC + const MatrixTypeNestedCleaned& nestedExpression() const { return m_matrix; } + EIGEN_DEVICE_FUNC + MatrixTypeNestedCleaned& nestedExpression() { return *const_cast(&m_matrix); } + + /** Assigns a triangular matrix to a triangular part of a dense matrix */ + template + EIGEN_DEVICE_FUNC + TriangularView& operator=(const TriangularBase& other); + + template + EIGEN_DEVICE_FUNC + TriangularView& operator=(const MatrixBase& other); + + EIGEN_DEVICE_FUNC + TriangularView& operator=(const TriangularView& other) + { return *this = other.nestedExpression(); } + + template + EIGEN_DEVICE_FUNC + void lazyAssign(const TriangularBase& other); + + template + EIGEN_DEVICE_FUNC + void lazyAssign(const MatrixBase& other); + + /** \sa MatrixBase::conjugate() */ + EIGEN_DEVICE_FUNC + inline TriangularView conjugate() + { return m_matrix.conjugate(); } + /** \sa MatrixBase::conjugate() const */ + EIGEN_DEVICE_FUNC + inline const TriangularView conjugate() const + { return m_matrix.conjugate(); } + + /** \sa MatrixBase::adjoint() const */ + EIGEN_DEVICE_FUNC + inline const TriangularView adjoint() const + { return m_matrix.adjoint(); } + + /** \sa MatrixBase::transpose() */ + EIGEN_DEVICE_FUNC + inline TriangularView,TransposeMode> transpose() + { + EIGEN_STATIC_ASSERT_LVALUE(MatrixType) + return m_matrix.const_cast_derived().transpose(); + } + /** \sa MatrixBase::transpose() const */ + EIGEN_DEVICE_FUNC + inline const TriangularView,TransposeMode> transpose() const + { + return m_matrix.transpose(); + } + + /** Efficient triangular matrix times vector/matrix product */ + template + EIGEN_DEVICE_FUNC + TriangularProduct + operator*(const MatrixBase& rhs) const + { + return TriangularProduct + + (m_matrix, rhs.derived()); + } + + /** Efficient vector/matrix times triangular matrix product */ + template friend + EIGEN_DEVICE_FUNC + TriangularProduct + operator*(const MatrixBase& lhs, const TriangularView& rhs) + { + return TriangularProduct + + (lhs.derived(),rhs.m_matrix); + } + + #ifdef EIGEN2_SUPPORT + template + struct eigen2_product_return_type + { + typedef typename TriangularView::DenseMatrixType DenseMatrixType; + typedef typename OtherDerived::PlainObject::DenseType OtherPlainObject; + typedef typename ProductReturnType::Type ProdRetType; + typedef typename ProdRetType::PlainObject type; + }; + template + const typename eigen2_product_return_type::type + operator*(const EigenBase& rhs) const + { + typename OtherDerived::PlainObject::DenseType rhsPlainObject; + rhs.evalTo(rhsPlainObject); + return this->toDenseMatrix() * rhsPlainObject; + } + template + bool isApprox(const TriangularView& other, typename NumTraits::Real precision = NumTraits::dummy_precision()) const + { + return this->toDenseMatrix().isApprox(other.toDenseMatrix(), precision); + } + template + bool isApprox(const MatrixBase& other, typename NumTraits::Real precision = NumTraits::dummy_precision()) const + { + return this->toDenseMatrix().isApprox(other, precision); + } + #endif // EIGEN2_SUPPORT + + template + EIGEN_DEVICE_FUNC + inline const internal::triangular_solve_retval + solve(const MatrixBase& other) const; + + template + EIGEN_DEVICE_FUNC + void solveInPlace(const MatrixBase& other) const; + + template + EIGEN_DEVICE_FUNC + inline const internal::triangular_solve_retval + solve(const MatrixBase& other) const + { return solve(other); } + + template + EIGEN_DEVICE_FUNC + void solveInPlace(const MatrixBase& other) const + { return solveInPlace(other); } + + EIGEN_DEVICE_FUNC + const SelfAdjointView selfadjointView() const + { + EIGEN_STATIC_ASSERT((Mode&UnitDiag)==0,PROGRAMMING_ERROR); + return SelfAdjointView(m_matrix); + } + EIGEN_DEVICE_FUNC + SelfAdjointView selfadjointView() + { + EIGEN_STATIC_ASSERT((Mode&UnitDiag)==0,PROGRAMMING_ERROR); + return SelfAdjointView(m_matrix); + } + + template + EIGEN_DEVICE_FUNC + void swap(TriangularBase const & other) + { + TriangularView,Mode>(const_cast(m_matrix)).lazyAssign(other.derived()); + } + + template + EIGEN_DEVICE_FUNC + void swap(MatrixBase const & other) + { + SwapWrapper swaper(const_cast(m_matrix)); + TriangularView,Mode>(swaper).lazyAssign(other.derived()); + } + + EIGEN_DEVICE_FUNC + Scalar determinant() const + { + if (Mode & UnitDiag) + return 1; + else if (Mode & ZeroDiag) + return 0; + else + return m_matrix.diagonal().prod(); + } + + // TODO simplify the following: + template + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE TriangularView& operator=(const ProductBase& other) + { + setZero(); + return assignProduct(other,1); + } + + template + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE TriangularView& operator+=(const ProductBase& other) + { + return assignProduct(other,1); + } + + template + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE TriangularView& operator-=(const ProductBase& other) + { + return assignProduct(other,-1); + } + + + template + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE TriangularView& operator=(const ScaledProduct& other) + { + setZero(); + return assignProduct(other,other.alpha()); + } + + template + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE TriangularView& operator+=(const ScaledProduct& other) + { + return assignProduct(other,other.alpha()); + } + + template + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE TriangularView& operator-=(const ScaledProduct& other) + { + return assignProduct(other,-other.alpha()); + } + + protected: + + template + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE TriangularView& assignProduct(const ProductBase& prod, const Scalar& alpha); + + MatrixTypeNested m_matrix; +}; + +/*************************************************************************** +* Implementation of triangular evaluation/assignment +***************************************************************************/ + +namespace internal { + +template +struct triangular_assignment_selector +{ + enum { + col = (UnrollCount-1) / Derived1::RowsAtCompileTime, + row = (UnrollCount-1) % Derived1::RowsAtCompileTime + }; + + typedef typename Derived1::Scalar Scalar; + + EIGEN_DEVICE_FUNC + static inline void run(Derived1 &dst, const Derived2 &src) + { + triangular_assignment_selector::run(dst, src); + + eigen_assert( Mode == Upper || Mode == Lower + || Mode == StrictlyUpper || Mode == StrictlyLower + || Mode == UnitUpper || Mode == UnitLower); + if((Mode == Upper && row <= col) + || (Mode == Lower && row >= col) + || (Mode == StrictlyUpper && row < col) + || (Mode == StrictlyLower && row > col) + || (Mode == UnitUpper && row < col) + || (Mode == UnitLower && row > col)) + dst.copyCoeff(row, col, src); + else if(ClearOpposite) + { + if (Mode&UnitDiag && row==col) + dst.coeffRef(row, col) = Scalar(1); + else + dst.coeffRef(row, col) = Scalar(0); + } + } +}; + +// prevent buggy user code from causing an infinite recursion +template +struct triangular_assignment_selector +{ + EIGEN_DEVICE_FUNC + static inline void run(Derived1 &, const Derived2 &) {} +}; + +template +struct triangular_assignment_selector +{ + typedef typename Derived1::Index Index; + typedef typename Derived1::Scalar Scalar; + EIGEN_DEVICE_FUNC + static inline void run(Derived1 &dst, const Derived2 &src) + { + for(Index j = 0; j < dst.cols(); ++j) + { + Index maxi = (std::min)(j, dst.rows()-1); + for(Index i = 0; i <= maxi; ++i) + dst.copyCoeff(i, j, src); + if (ClearOpposite) + for(Index i = maxi+1; i < dst.rows(); ++i) + dst.coeffRef(i, j) = Scalar(0); + } + } +}; + +template +struct triangular_assignment_selector +{ + typedef typename Derived1::Index Index; + EIGEN_DEVICE_FUNC + static inline void run(Derived1 &dst, const Derived2 &src) + { + for(Index j = 0; j < dst.cols(); ++j) + { + for(Index i = j; i < dst.rows(); ++i) + dst.copyCoeff(i, j, src); + Index maxi = (std::min)(j, dst.rows()); + if (ClearOpposite) + for(Index i = 0; i < maxi; ++i) + dst.coeffRef(i, j) = static_cast(0); + } + } +}; + +template +struct triangular_assignment_selector +{ + typedef typename Derived1::Index Index; + typedef typename Derived1::Scalar Scalar; + EIGEN_DEVICE_FUNC + static inline void run(Derived1 &dst, const Derived2 &src) + { + for(Index j = 0; j < dst.cols(); ++j) + { + Index maxi = (std::min)(j, dst.rows()); + for(Index i = 0; i < maxi; ++i) + dst.copyCoeff(i, j, src); + if (ClearOpposite) + for(Index i = maxi; i < dst.rows(); ++i) + dst.coeffRef(i, j) = Scalar(0); + } + } +}; + +template +struct triangular_assignment_selector +{ + typedef typename Derived1::Index Index; + EIGEN_DEVICE_FUNC + static inline void run(Derived1 &dst, const Derived2 &src) + { + for(Index j = 0; j < dst.cols(); ++j) + { + for(Index i = j+1; i < dst.rows(); ++i) + dst.copyCoeff(i, j, src); + Index maxi = (std::min)(j, dst.rows()-1); + if (ClearOpposite) + for(Index i = 0; i <= maxi; ++i) + dst.coeffRef(i, j) = static_cast(0); + } + } +}; + +template +struct triangular_assignment_selector +{ + typedef typename Derived1::Index Index; + EIGEN_DEVICE_FUNC + static inline void run(Derived1 &dst, const Derived2 &src) + { + for(Index j = 0; j < dst.cols(); ++j) + { + Index maxi = (std::min)(j, dst.rows()); + for(Index i = 0; i < maxi; ++i) + dst.copyCoeff(i, j, src); + if (ClearOpposite) + { + for(Index i = maxi+1; i < dst.rows(); ++i) + dst.coeffRef(i, j) = 0; + } + } + dst.diagonal().setOnes(); + } +}; +template +struct triangular_assignment_selector +{ + typedef typename Derived1::Index Index; + EIGEN_DEVICE_FUNC + static inline void run(Derived1 &dst, const Derived2 &src) + { + for(Index j = 0; j < dst.cols(); ++j) + { + Index maxi = (std::min)(j, dst.rows()); + for(Index i = maxi+1; i < dst.rows(); ++i) + dst.copyCoeff(i, j, src); + if (ClearOpposite) + { + for(Index i = 0; i < maxi; ++i) + dst.coeffRef(i, j) = 0; + } + } + dst.diagonal().setOnes(); + } +}; + +} // end namespace internal + +// FIXME should we keep that possibility +template +template +inline TriangularView& +TriangularView::operator=(const MatrixBase& other) +{ + if(OtherDerived::Flags & EvalBeforeAssigningBit) + { + typename internal::plain_matrix_type::type other_evaluated(other.rows(), other.cols()); + other_evaluated.template triangularView().lazyAssign(other.derived()); + lazyAssign(other_evaluated); + } + else + lazyAssign(other.derived()); + return *this; +} + +// FIXME should we keep that possibility +template +template +void TriangularView::lazyAssign(const MatrixBase& other) +{ + enum { + unroll = MatrixType::SizeAtCompileTime != Dynamic + && internal::traits::CoeffReadCost != Dynamic + && MatrixType::SizeAtCompileTime*internal::traits::CoeffReadCost/2 <= EIGEN_UNROLLING_LIMIT + }; + eigen_assert(m_matrix.rows() == other.rows() && m_matrix.cols() == other.cols()); + + internal::triangular_assignment_selector + ::run(m_matrix.const_cast_derived(), other.derived()); +} + + + +template +template +inline TriangularView& +TriangularView::operator=(const TriangularBase& other) +{ + eigen_assert(Mode == int(OtherDerived::Mode)); + if(internal::traits::Flags & EvalBeforeAssigningBit) + { + typename OtherDerived::DenseMatrixType other_evaluated(other.rows(), other.cols()); + other_evaluated.template triangularView().lazyAssign(other.derived().nestedExpression()); + lazyAssign(other_evaluated); + } + else + lazyAssign(other.derived().nestedExpression()); + return *this; +} + +template +template +void TriangularView::lazyAssign(const TriangularBase& other) +{ + enum { + unroll = MatrixType::SizeAtCompileTime != Dynamic + && internal::traits::CoeffReadCost != Dynamic + && MatrixType::SizeAtCompileTime * internal::traits::CoeffReadCost / 2 + <= EIGEN_UNROLLING_LIMIT + }; + eigen_assert(m_matrix.rows() == other.rows() && m_matrix.cols() == other.cols()); + + internal::triangular_assignment_selector + ::run(m_matrix.const_cast_derived(), other.derived().nestedExpression()); +} + +/*************************************************************************** +* Implementation of TriangularBase methods +***************************************************************************/ + +/** Assigns a triangular or selfadjoint matrix to a dense matrix. + * If the matrix is triangular, the opposite part is set to zero. */ +template +template +void TriangularBase::evalTo(MatrixBase &other) const +{ + if(internal::traits::Flags & EvalBeforeAssigningBit) + { + typename internal::plain_matrix_type::type other_evaluated(rows(), cols()); + evalToLazy(other_evaluated); + other.derived().swap(other_evaluated); + } + else + evalToLazy(other.derived()); +} + +/** Assigns a triangular or selfadjoint matrix to a dense matrix. + * If the matrix is triangular, the opposite part is set to zero. */ +template +template +void TriangularBase::evalToLazy(MatrixBase &other) const +{ + enum { + unroll = DenseDerived::SizeAtCompileTime != Dynamic + && internal::traits::CoeffReadCost != Dynamic + && DenseDerived::SizeAtCompileTime * internal::traits::CoeffReadCost / 2 + <= EIGEN_UNROLLING_LIMIT + }; + other.derived().resize(this->rows(), this->cols()); + + internal::triangular_assignment_selector + ::MatrixTypeNestedCleaned, Derived::Mode, + unroll ? int(DenseDerived::SizeAtCompileTime) : Dynamic, + true // clear the opposite triangular part + >::run(other.derived(), derived().nestedExpression()); +} + +/*************************************************************************** +* Implementation of TriangularView methods +***************************************************************************/ + +/*************************************************************************** +* Implementation of MatrixBase methods +***************************************************************************/ + +#ifdef EIGEN2_SUPPORT + +// implementation of part<>(), including the SelfAdjoint case. + +namespace internal { +template +struct eigen2_part_return_type +{ + typedef TriangularView type; +}; + +template +struct eigen2_part_return_type +{ + typedef SelfAdjointView type; +}; +} + +/** \deprecated use MatrixBase::triangularView() */ +template +template +const typename internal::eigen2_part_return_type::type MatrixBase::part() const +{ + return derived(); +} + +/** \deprecated use MatrixBase::triangularView() */ +template +template +typename internal::eigen2_part_return_type::type MatrixBase::part() +{ + return derived(); +} +#endif + +/** + * \returns an expression of a triangular view extracted from the current matrix + * + * The parameter \a Mode can have the following values: \c #Upper, \c #StrictlyUpper, \c #UnitUpper, + * \c #Lower, \c #StrictlyLower, \c #UnitLower. + * + * Example: \include MatrixBase_extract.cpp + * Output: \verbinclude MatrixBase_extract.out + * + * \sa class TriangularView + */ +template +template +typename MatrixBase::template TriangularViewReturnType::Type +MatrixBase::triangularView() +{ + return derived(); +} + +/** This is the const version of MatrixBase::triangularView() */ +template +template +typename MatrixBase::template ConstTriangularViewReturnType::Type +MatrixBase::triangularView() const +{ + return derived(); +} + +/** \returns true if *this is approximately equal to an upper triangular matrix, + * within the precision given by \a prec. + * + * \sa isLowerTriangular() + */ +template +bool MatrixBase::isUpperTriangular(const RealScalar& prec) const +{ + using std::abs; + RealScalar maxAbsOnUpperPart = static_cast(-1); + for(Index j = 0; j < cols(); ++j) + { + Index maxi = (std::min)(j, rows()-1); + for(Index i = 0; i <= maxi; ++i) + { + RealScalar absValue = abs(coeff(i,j)); + if(absValue > maxAbsOnUpperPart) maxAbsOnUpperPart = absValue; + } + } + RealScalar threshold = maxAbsOnUpperPart * prec; + for(Index j = 0; j < cols(); ++j) + for(Index i = j+1; i < rows(); ++i) + if(abs(coeff(i, j)) > threshold) return false; + return true; +} + +/** \returns true if *this is approximately equal to a lower triangular matrix, + * within the precision given by \a prec. + * + * \sa isUpperTriangular() + */ +template +bool MatrixBase::isLowerTriangular(const RealScalar& prec) const +{ + using std::abs; + RealScalar maxAbsOnLowerPart = static_cast(-1); + for(Index j = 0; j < cols(); ++j) + for(Index i = j; i < rows(); ++i) + { + RealScalar absValue = abs(coeff(i,j)); + if(absValue > maxAbsOnLowerPart) maxAbsOnLowerPart = absValue; + } + RealScalar threshold = maxAbsOnLowerPart * prec; + for(Index j = 1; j < cols(); ++j) + { + Index maxi = (std::min)(j, rows()-1); + for(Index i = 0; i < maxi; ++i) + if(abs(coeff(i, j)) > threshold) return false; + } + return true; +} + +} // end namespace Eigen + +#endif // EIGEN_TRIANGULARMATRIX_H -- cgit v1.2.3