1 // This file is part of Eigen, a lightweight C++ template library 2 // for linear algebra. 3 // 4 // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud (at) inria.fr> 5 // 6 // This Source Code Form is subject to the terms of the Mozilla 7 // Public License v. 2.0. If a copy of the MPL was not distributed 8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9 10 #ifndef EIGEN_SPARSE_BLOCKFORDYNAMICMATRIX_H 11 #define EIGEN_SPARSE_BLOCKFORDYNAMICMATRIX_H 12 13 namespace Eigen { 14 15 /*************************************************************************** 16 * specialisation for DynamicSparseMatrix 17 ***************************************************************************/ 18 19 template<typename _Scalar, int _Options, typename _Index, int Size> 20 class SparseInnerVectorSet<DynamicSparseMatrix<_Scalar, _Options, _Index>, Size> 21 : public SparseMatrixBase<SparseInnerVectorSet<DynamicSparseMatrix<_Scalar, _Options, _Index>, Size> > 22 { 23 typedef DynamicSparseMatrix<_Scalar, _Options, _Index> MatrixType; 24 public: 25 26 enum { IsRowMajor = internal::traits<SparseInnerVectorSet>::IsRowMajor }; 27 28 EIGEN_SPARSE_PUBLIC_INTERFACE(SparseInnerVectorSet) 29 class InnerIterator: public MatrixType::InnerIterator 30 { 31 public: 32 inline InnerIterator(const SparseInnerVectorSet& xpr, Index outer) 33 : MatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer) 34 {} 35 inline Index row() const { return IsRowMajor ? m_outer : this->index(); } 36 inline Index col() const { return IsRowMajor ? this->index() : m_outer; } 37 protected: 38 Index m_outer; 39 }; 40 41 inline SparseInnerVectorSet(const MatrixType& matrix, Index outerStart, Index outerSize) 42 : m_matrix(matrix), m_outerStart(outerStart), m_outerSize(outerSize) 43 { 44 eigen_assert( (outerStart>=0) && ((outerStart+outerSize)<=matrix.outerSize()) ); 45 } 46 47 inline SparseInnerVectorSet(const MatrixType& matrix, Index outer) 48 : m_matrix(matrix), m_outerStart(outer), m_outerSize(Size) 49 { 50 eigen_assert(Size!=Dynamic); 51 eigen_assert( (outer>=0) && (outer<matrix.outerSize()) ); 52 } 53 54 template<typename OtherDerived> 55 inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other) 56 { 57 if (IsRowMajor != ((OtherDerived::Flags&RowMajorBit)==RowMajorBit)) 58 { 59 // need to transpose => perform a block evaluation followed by a big swap 60 DynamicSparseMatrix<Scalar,IsRowMajor?RowMajorBit:0> aux(other); 61 *this = aux.markAsRValue(); 62 } 63 else 64 { 65 // evaluate/copy vector per vector 66 for (Index j=0; j<m_outerSize.value(); ++j) 67 { 68 SparseVector<Scalar,IsRowMajor ? RowMajorBit : 0> aux(other.innerVector(j)); 69 m_matrix.const_cast_derived()._data()[m_outerStart+j].swap(aux._data()); 70 } 71 } 72 return *this; 73 } 74 75 inline SparseInnerVectorSet& operator=(const SparseInnerVectorSet& other) 76 { 77 return operator=<SparseInnerVectorSet>(other); 78 } 79 80 Index nonZeros() const 81 { 82 Index count = 0; 83 for (Index j=0; j<m_outerSize.value(); ++j) 84 count += m_matrix._data()[m_outerStart+j].size(); 85 return count; 86 } 87 88 const Scalar& lastCoeff() const 89 { 90 EIGEN_STATIC_ASSERT_VECTOR_ONLY(SparseInnerVectorSet); 91 eigen_assert(m_matrix.data()[m_outerStart].size()>0); 92 return m_matrix.data()[m_outerStart].vale(m_matrix.data()[m_outerStart].size()-1); 93 } 94 95 // template<typename Sparse> 96 // inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other) 97 // { 98 // return *this; 99 // } 100 101 EIGEN_STRONG_INLINE Index rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); } 102 EIGEN_STRONG_INLINE Index cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); } 103 104 protected: 105 106 const typename MatrixType::Nested m_matrix; 107 Index m_outerStart; 108 const internal::variable_if_dynamic<Index, Size> m_outerSize; 109 110 }; 111 112 } // end namespace Eigen 113 114 #endif // EIGEN_SPARSE_BLOCKFORDYNAMICMATRIX_H 115