diff --git a/Eigen/src/SparseCore/SparseTriangularView.h b/Eigen/src/SparseCore/SparseTriangularView.h index 68c4c3397..88a345b22 100644 --- a/Eigen/src/SparseCore/SparseTriangularView.h +++ b/Eigen/src/SparseCore/SparseTriangularView.h @@ -2,6 +2,7 @@ // for linear algebra. // // Copyright (C) 2009 Gael Guennebaud +// Copyright (C) 2012 Désiré Nuentsa-Wakam // // 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 @@ -27,6 +28,7 @@ template class SparseTriangularView enum { SkipFirst = ((Mode&Lower) && !(MatrixType::Flags&RowMajorBit)) || ((Mode&Upper) && (MatrixType::Flags&RowMajorBit)), SkipLast = !SkipFirst, + SkipDiag = (Mode&ZeroDiag) ? 1 : 0, HasUnitDiag = (Mode&UnitDiag) ? 1 : 0 }; @@ -71,7 +73,7 @@ class SparseTriangularView::InnerIterator : public MatrixTypeNe { if(SkipFirst) { - while((*this) && (HasUnitDiag ? this->index()<=outer : this->index()index()<=outer : this->index()::InnerIterator : public MatrixTypeNe return *this; } - inline Index row() const { return Base::row(); } - inline Index col() const { return Base::col(); } + inline Index row() const { return (MatrixType::Flags&RowMajorBit ? Base::outer() : this->index()); } + inline Index col() const { return (MatrixType::Flags&RowMajorBit ? this->index() : Base::outer()); } inline Index index() const { if(HasUnitDiag && m_returnOne) return Base::outer(); @@ -118,7 +120,12 @@ class SparseTriangularView::InnerIterator : public MatrixTypeNe { if(HasUnitDiag && m_returnOne) return true; - return (SkipFirst ? Base::operator bool() : (Base::operator bool() && this->index() <= this->outer())); + 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()); + } } protected: bool m_returnOne; @@ -134,9 +141,10 @@ class SparseTriangularView::ReverseInnerIterator : public Matri : Base(view.nestedExpression(), outer) { eigen_assert((!HasUnitDiag) && "ReverseInnerIterator does not support yet triangular views with a unit diagonal"); - if(SkipLast) - while((*this) && this->index()>outer) + if(SkipLast) { + while((*this) && (SkipDiag ? this->index()>=outer : this->index()>outer)) --(*this); + } } EIGEN_STRONG_INLINE ReverseInnerIterator& operator--() @@ -147,7 +155,12 @@ class SparseTriangularView::ReverseInnerIterator : public Matri EIGEN_STRONG_INLINE operator bool() const { - return SkipLast ? Base::operator bool() : (Base::operator bool() && this->index() >= this->outer()); + if (SkipLast) return Base::operator bool() ; + else + { + if(SkipDiag) return (Base::operator bool() && this->index() > this->outer()); + else return (Base::operator bool() && this->index() >= this->outer()); + } } }; diff --git a/test/sparse_basic.cpp b/test/sparse_basic.cpp index 121cc05b1..2f92f1627 100644 --- a/test/sparse_basic.cpp +++ b/test/sparse_basic.cpp @@ -3,6 +3,7 @@ // // Copyright (C) 2008-2011 Gael Guennebaud // Copyright (C) 2008 Daniel Gomez Ferro +// Copyright (C) 2013 Désiré Nuentsa-Wakam // // 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 @@ -391,6 +392,14 @@ template void sparse_basic(const SparseMatrixType& re refMat3 = refMat2.template triangularView(); m3 = m2.template triangularView(); VERIFY_IS_APPROX(m3, refMat3); + + refMat3 = refMat2.template triangularView(); + m3 = m2.template triangularView(); + VERIFY_IS_APPROX(m3, refMat3); + + refMat3 = refMat2.template triangularView(); + m3 = m2.template triangularView(); + VERIFY_IS_APPROX(m3, refMat3); } // test selfadjointView @@ -454,6 +463,14 @@ template void sparse_basic(const SparseMatrixType& re } } + + // test Identity matrix + { + DenseMatrix refMat1 = DenseMatrix::Identity(rows, rows); + SparseMatrixType m1(rows, rows); + m1.setIdentity(); + VERIFY_IS_APPROX(m1, refMat1); + } } void test_sparse_basic()