Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef EIGEN_SPARSE_TRIANGULARVIEW_H
00012 #define EIGEN_SPARSE_TRIANGULARVIEW_H
00013
00014 namespace Eigen {
00015
00016 namespace internal {
00017
00018 template<typename MatrixType, int Mode>
00019 struct traits<SparseTriangularView<MatrixType,Mode> >
00020 : public traits<MatrixType>
00021 {};
00022
00023 }
00024
00025 template<typename MatrixType, int Mode> class SparseTriangularView
00026 : public SparseMatrixBase<SparseTriangularView<MatrixType,Mode> >
00027 {
00028 enum { SkipFirst = ((Mode&Lower) && !(MatrixType::Flags&RowMajorBit))
00029 || ((Mode&Upper) && (MatrixType::Flags&RowMajorBit)),
00030 SkipLast = !SkipFirst,
00031 SkipDiag = (Mode&ZeroDiag) ? 1 : 0,
00032 HasUnitDiag = (Mode&UnitDiag) ? 1 : 0
00033 };
00034
00035 public:
00036
00037 EIGEN_SPARSE_PUBLIC_INTERFACE(SparseTriangularView)
00038
00039 class InnerIterator;
00040 class ReverseInnerIterator;
00041
00042 inline Index rows() const { return m_matrix.rows(); }
00043 inline Index cols() const { return m_matrix.cols(); }
00044
00045 typedef typename MatrixType::Nested MatrixTypeNested;
00046 typedef typename internal::remove_reference<MatrixTypeNested>::type MatrixTypeNestedNonRef;
00047 typedef typename internal::remove_all<MatrixTypeNested>::type MatrixTypeNestedCleaned;
00048
00049 inline SparseTriangularView(const MatrixType& matrix) : m_matrix(matrix) {}
00050
00052 inline const MatrixTypeNestedCleaned& nestedExpression() const { return m_matrix; }
00053
00054 template<typename OtherDerived>
00055 typename internal::plain_matrix_type_column_major<OtherDerived>::type
00056 solve(const MatrixBase<OtherDerived>& other) const;
00057
00058 template<typename OtherDerived> void solveInPlace(MatrixBase<OtherDerived>& other) const;
00059 template<typename OtherDerived> void solveInPlace(SparseMatrixBase<OtherDerived>& other) const;
00060
00061 protected:
00062 MatrixTypeNested m_matrix;
00063 };
00064
00065 template<typename MatrixType, int Mode>
00066 class SparseTriangularView<MatrixType,Mode>::InnerIterator : public MatrixTypeNestedCleaned::InnerIterator
00067 {
00068 typedef typename MatrixTypeNestedCleaned::InnerIterator Base;
00069 typedef typename SparseTriangularView::Index Index;
00070 public:
00071
00072 EIGEN_STRONG_INLINE InnerIterator(const SparseTriangularView& view, Index outer)
00073 : Base(view.nestedExpression(), outer), m_returnOne(false)
00074 {
00075 if(SkipFirst)
00076 {
00077 while((*this) && ((HasUnitDiag||SkipDiag) ? this->index()<=outer : this->index()<outer))
00078 Base::operator++();
00079 if(HasUnitDiag)
00080 m_returnOne = true;
00081 }
00082 else if(HasUnitDiag && ((!Base::operator bool()) || Base::index()>=Base::outer()))
00083 {
00084 if((!SkipFirst) && Base::operator bool())
00085 Base::operator++();
00086 m_returnOne = true;
00087 }
00088 }
00089
00090 EIGEN_STRONG_INLINE InnerIterator& operator++()
00091 {
00092 if(HasUnitDiag && m_returnOne)
00093 m_returnOne = false;
00094 else
00095 {
00096 Base::operator++();
00097 if(HasUnitDiag && (!SkipFirst) && ((!Base::operator bool()) || Base::index()>=Base::outer()))
00098 {
00099 if((!SkipFirst) && Base::operator bool())
00100 Base::operator++();
00101 m_returnOne = true;
00102 }
00103 }
00104 return *this;
00105 }
00106
00107 inline Index row() const { return (MatrixType::Flags&RowMajorBit ? Base::outer() : this->index()); }
00108 inline Index col() const { return (MatrixType::Flags&RowMajorBit ? this->index() : Base::outer()); }
00109 inline Index index() const
00110 {
00111 if(HasUnitDiag && m_returnOne) return Base::outer();
00112 else return Base::index();
00113 }
00114 inline Scalar value() const
00115 {
00116 if(HasUnitDiag && m_returnOne) return Scalar(1);
00117 else return Base::value();
00118 }
00119
00120 EIGEN_STRONG_INLINE operator bool() const
00121 {
00122 if(HasUnitDiag && m_returnOne)
00123 return true;
00124 if(SkipFirst) return Base::operator bool();
00125 else
00126 {
00127 if (SkipDiag) return (Base::operator bool() && this->index() < this->outer());
00128 else return (Base::operator bool() && this->index() <= this->outer());
00129 }
00130 }
00131 protected:
00132 bool m_returnOne;
00133 };
00134
00135 template<typename MatrixType, int Mode>
00136 class SparseTriangularView<MatrixType,Mode>::ReverseInnerIterator : public MatrixTypeNestedCleaned::ReverseInnerIterator
00137 {
00138 typedef typename MatrixTypeNestedCleaned::ReverseInnerIterator Base;
00139 typedef typename SparseTriangularView::Index Index;
00140 public:
00141
00142 EIGEN_STRONG_INLINE ReverseInnerIterator(const SparseTriangularView& view, Index outer)
00143 : Base(view.nestedExpression(), outer)
00144 {
00145 eigen_assert((!HasUnitDiag) && "ReverseInnerIterator does not support yet triangular views with a unit diagonal");
00146 if(SkipLast) {
00147 while((*this) && (SkipDiag ? this->index()>=outer : this->index()>outer))
00148 --(*this);
00149 }
00150 }
00151
00152 EIGEN_STRONG_INLINE ReverseInnerIterator& operator--()
00153 { Base::operator--(); return *this; }
00154
00155 inline Index row() const { return Base::row(); }
00156 inline Index col() const { return Base::col(); }
00157
00158 EIGEN_STRONG_INLINE operator bool() const
00159 {
00160 if (SkipLast) return Base::operator bool() ;
00161 else
00162 {
00163 if(SkipDiag) return (Base::operator bool() && this->index() > this->outer());
00164 else return (Base::operator bool() && this->index() >= this->outer());
00165 }
00166 }
00167 };
00168
00169 template<typename Derived>
00170 template<int Mode>
00171 inline const SparseTriangularView<Derived, Mode>
00172 SparseMatrixBase<Derived>::triangularView() const
00173 {
00174 return derived();
00175 }
00176
00177 }
00178
00179 #endif // EIGEN_SPARSE_TRIANGULARVIEW_H