aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen/src/SparseCore/SparseTriangularView.h
diff options
context:
space:
mode:
Diffstat (limited to 'Eigen/src/SparseCore/SparseTriangularView.h')
-rw-r--r--Eigen/src/SparseCore/SparseTriangularView.h183
1 files changed, 144 insertions, 39 deletions
diff --git a/Eigen/src/SparseCore/SparseTriangularView.h b/Eigen/src/SparseCore/SparseTriangularView.h
index 333127b78..b044d6778 100644
--- a/Eigen/src/SparseCore/SparseTriangularView.h
+++ b/Eigen/src/SparseCore/SparseTriangularView.h
@@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
-// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
+// Copyright (C) 2009-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
@@ -13,17 +13,8 @@
namespace Eigen {
-namespace internal {
-
-template<typename MatrixType, int Mode>
-struct traits<SparseTriangularView<MatrixType,Mode> >
-: public traits<MatrixType>
-{};
-
-} // namespace internal
-
-template<typename MatrixType, int Mode> class SparseTriangularView
- : public SparseMatrixBase<SparseTriangularView<MatrixType,Mode> >
+template<typename MatrixType, unsigned int Mode> class TriangularViewImpl<MatrixType,Mode,Sparse>
+ : public SparseMatrixBase<TriangularView<MatrixType,Mode> >
{
enum { SkipFirst = ((Mode&Lower) && !(MatrixType::Flags&RowMajorBit))
|| ((Mode&Upper) && (MatrixType::Flags&RowMajorBit)),
@@ -31,46 +22,53 @@ template<typename MatrixType, int Mode> class SparseTriangularView
SkipDiag = (Mode&ZeroDiag) ? 1 : 0,
HasUnitDiag = (Mode&UnitDiag) ? 1 : 0
};
+
+ typedef TriangularView<MatrixType,Mode> TriangularViewType;
+
+protected:
+ // dummy solve function to make TriangularView happy.
+ void solve() const;
public:
- EIGEN_SPARSE_PUBLIC_INTERFACE(SparseTriangularView)
-
+ EIGEN_SPARSE_PUBLIC_INTERFACE(TriangularViewType)
+
class InnerIterator;
class ReverseInnerIterator;
- inline Index rows() const { return m_matrix.rows(); }
- inline Index cols() const { return m_matrix.cols(); }
-
typedef typename MatrixType::Nested MatrixTypeNested;
typedef typename internal::remove_reference<MatrixTypeNested>::type MatrixTypeNestedNonRef;
typedef typename internal::remove_all<MatrixTypeNested>::type MatrixTypeNestedCleaned;
- inline SparseTriangularView(const MatrixType& matrix) : m_matrix(matrix) {}
-
- /** \internal */
- inline const MatrixTypeNestedCleaned& nestedExpression() const { return m_matrix; }
-
- template<typename OtherDerived>
- typename internal::plain_matrix_type_column_major<OtherDerived>::type
- solve(const MatrixBase<OtherDerived>& other) const;
+ template<typename RhsType, typename DstType>
+ EIGEN_DEVICE_FUNC
+ EIGEN_STRONG_INLINE void _solve_impl(const RhsType &rhs, DstType &dst) const {
+ if(!(internal::is_same<RhsType,DstType>::value && internal::extract_data(dst) == internal::extract_data(rhs)))
+ dst = rhs;
+ this->solveInPlace(dst);
+ }
template<typename OtherDerived> void solveInPlace(MatrixBase<OtherDerived>& other) const;
template<typename OtherDerived> void solveInPlace(SparseMatrixBase<OtherDerived>& other) const;
- protected:
- MatrixTypeNested m_matrix;
+ inline Index nonZeros() const {
+ // FIXME HACK number of nonZeros is required for product logic
+ // this returns only an upper bound (but should be OK for most purposes)
+ return derived().nestedExpression().nonZeros();
+ }
+
+
};
-template<typename MatrixType, int Mode>
-class SparseTriangularView<MatrixType,Mode>::InnerIterator : public MatrixTypeNestedCleaned::InnerIterator
+template<typename MatrixType, unsigned int Mode>
+class TriangularViewImpl<MatrixType,Mode,Sparse>::InnerIterator : public MatrixTypeNestedCleaned::InnerIterator
{
typedef typename MatrixTypeNestedCleaned::InnerIterator Base;
- typedef typename SparseTriangularView::Index Index;
+ typedef typename TriangularViewType::Index Index;
public:
- EIGEN_STRONG_INLINE InnerIterator(const SparseTriangularView& view, Index outer)
- : Base(view.nestedExpression(), outer), m_returnOne(false)
+ EIGEN_STRONG_INLINE InnerIterator(const TriangularViewImpl& view, Index outer)
+ : Base(view.derived().nestedExpression(), outer), m_returnOne(false)
{
if(SkipFirst)
{
@@ -132,15 +130,15 @@ class SparseTriangularView<MatrixType,Mode>::InnerIterator : public MatrixTypeNe
bool m_returnOne;
};
-template<typename MatrixType, int Mode>
-class SparseTriangularView<MatrixType,Mode>::ReverseInnerIterator : public MatrixTypeNestedCleaned::ReverseInnerIterator
+template<typename MatrixType, unsigned int Mode>
+class TriangularViewImpl<MatrixType,Mode,Sparse>::ReverseInnerIterator : public MatrixTypeNestedCleaned::ReverseInnerIterator
{
typedef typename MatrixTypeNestedCleaned::ReverseInnerIterator Base;
- typedef typename SparseTriangularView::Index Index;
+ typedef typename TriangularViewImpl::Index Index;
public:
- EIGEN_STRONG_INLINE ReverseInnerIterator(const SparseTriangularView& view, Index outer)
- : Base(view.nestedExpression(), outer)
+ EIGEN_STRONG_INLINE ReverseInnerIterator(const TriangularViewType& view, Index outer)
+ : Base(view.derived().nestedExpression(), outer)
{
eigen_assert((!HasUnitDiag) && "ReverseInnerIterator does not support yet triangular views with a unit diagonal");
if(SkipLast) {
@@ -166,12 +164,119 @@ class SparseTriangularView<MatrixType,Mode>::ReverseInnerIterator : public Matri
}
};
+namespace internal {
+
+template<typename ArgType, unsigned int Mode>
+struct unary_evaluator<TriangularView<ArgType,Mode>, IteratorBased>
+ : evaluator_base<TriangularView<ArgType,Mode> >
+{
+ typedef TriangularView<ArgType,Mode> XprType;
+
+protected:
+
+ typedef typename XprType::Scalar Scalar;
+ typedef typename XprType::Index Index;
+ typedef typename evaluator<ArgType>::InnerIterator EvalIterator;
+
+ enum { SkipFirst = ((Mode&Lower) && !(ArgType::Flags&RowMajorBit))
+ || ((Mode&Upper) && (ArgType::Flags&RowMajorBit)),
+ SkipLast = !SkipFirst,
+ SkipDiag = (Mode&ZeroDiag) ? 1 : 0,
+ HasUnitDiag = (Mode&UnitDiag) ? 1 : 0
+ };
+
+public:
+
+ enum {
+ CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
+ Flags = XprType::Flags
+ };
+
+ explicit unary_evaluator(const XprType &xpr) : m_argImpl(xpr.nestedExpression()) {}
+
+ class InnerIterator : public EvalIterator
+ {
+ typedef EvalIterator Base;
+ public:
+
+ EIGEN_STRONG_INLINE InnerIterator(const unary_evaluator& xprEval, Index outer)
+ : Base(xprEval.m_argImpl,outer), m_returnOne(false)
+ {
+ if(SkipFirst)
+ {
+ while((*this) && ((HasUnitDiag||SkipDiag) ? this->index()<=outer : this->index()<outer))
+ Base::operator++();
+ if(HasUnitDiag)
+ m_returnOne = true;
+ }
+ else if(HasUnitDiag && ((!Base::operator bool()) || Base::index()>=Base::outer()))
+ {
+ if((!SkipFirst) && Base::operator bool())
+ Base::operator++();
+ m_returnOne = true; // FIXME check innerSize()>outer();
+ }
+ }
+
+ EIGEN_STRONG_INLINE InnerIterator& operator++()
+ {
+ if(HasUnitDiag && m_returnOne)
+ m_returnOne = false;
+ else
+ {
+ Base::operator++();
+ if(HasUnitDiag && (!SkipFirst) && ((!Base::operator bool()) || Base::index()>=Base::outer()))
+ {
+ if((!SkipFirst) && Base::operator bool())
+ Base::operator++();
+ m_returnOne = true; // FIXME check innerSize()>outer();
+ }
+ }
+ return *this;
+ }
+
+ EIGEN_STRONG_INLINE operator bool() const
+ {
+ if(HasUnitDiag && m_returnOne)
+ return true;
+ if(SkipFirst) return Base::operator bool();
+ else
+ {
+ if (SkipDiag) return (Base::operator bool() && this->index() < this->outer());
+ else return (Base::operator bool() && this->index() <= this->outer());
+ }
+ }
+
+// inline Index row() const { return (ArgType::Flags&RowMajorBit ? Base::outer() : this->index()); }
+// inline Index col() const { return (ArgType::Flags&RowMajorBit ? this->index() : Base::outer()); }
+ inline Index index() const
+ {
+ if(HasUnitDiag && m_returnOne) return Base::outer();
+ else return Base::index();
+ }
+ inline Scalar value() const
+ {
+ if(HasUnitDiag && m_returnOne) return Scalar(1);
+ else return Base::value();
+ }
+
+ protected:
+ bool m_returnOne;
+ private:
+ Scalar& valueRef();
+ };
+
+protected:
+ typename evaluator<ArgType>::type m_argImpl;
+};
+
+} // end namespace internal
+
template<typename Derived>
template<int Mode>
-inline const SparseTriangularView<Derived, Mode>
+inline const TriangularView<const Derived, Mode>
SparseMatrixBase<Derived>::triangularView() const
{
- return derived();
+ return TriangularView<const Derived, Mode>(derived());
}
} // end namespace Eigen