BlockOfDynamicSparseMatrix.h
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
00005 //
00006 // Eigen is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 3 of the License, or (at your option) any later version.
00010 //
00011 // Alternatively, you can redistribute it and/or
00012 // modify it under the terms of the GNU General Public License as
00013 // published by the Free Software Foundation; either version 2 of
00014 // the License, or (at your option) any later version.
00015 //
00016 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
00017 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00018 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
00019 // GNU General Public License for more details.
00020 //
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License and a copy of the GNU General Public License along with
00023 // Eigen. If not, see <http://www.gnu.org/licenses/>.
00024 
00025 #ifndef EIGEN_SPARSE_BLOCKFORDYNAMICMATRIX_H
00026 #define EIGEN_SPARSE_BLOCKFORDYNAMICMATRIX_H
00027 
00028 namespace Eigen { 
00029 
00030 /***************************************************************************
00031 * specialisation for DynamicSparseMatrix
00032 ***************************************************************************/
00033 
00034 template<typename _Scalar, int _Options, typename _Index, int Size>
00035 class SparseInnerVectorSet<DynamicSparseMatrix<_Scalar, _Options, _Index>, Size>
00036   : public SparseMatrixBase<SparseInnerVectorSet<DynamicSparseMatrix<_Scalar, _Options, _Index>, Size> >
00037 {
00038     typedef DynamicSparseMatrix<_Scalar, _Options, _Index> MatrixType;
00039   public:
00040 
00041     enum { IsRowMajor = internal::traits<SparseInnerVectorSet>::IsRowMajor };
00042 
00043     EIGEN_SPARSE_PUBLIC_INTERFACE(SparseInnerVectorSet)
00044     class InnerIterator: public MatrixType::InnerIterator
00045     {
00046       public:
00047         inline InnerIterator(const SparseInnerVectorSet& xpr, Index outer)
00048           : MatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
00049         {}
00050         inline Index row() const { return IsRowMajor ? m_outer : this->index(); }
00051         inline Index col() const { return IsRowMajor ? this->index() : m_outer; }
00052       protected:
00053         Index m_outer;
00054     };
00055 
00056     inline SparseInnerVectorSet(const MatrixType& matrix, Index outerStart, Index outerSize)
00057       : m_matrix(matrix), m_outerStart(outerStart), m_outerSize(outerSize)
00058     {
00059       eigen_assert( (outerStart>=0) && ((outerStart+outerSize)<=matrix.outerSize()) );
00060     }
00061 
00062     inline SparseInnerVectorSet(const MatrixType& matrix, Index outer)
00063       : m_matrix(matrix), m_outerStart(outer), m_outerSize(Size)
00064     {
00065       eigen_assert(Size!=Dynamic);
00066       eigen_assert( (outer>=0) && (outer<matrix.outerSize()) );
00067     }
00068 
00069     template<typename OtherDerived>
00070     inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other)
00071     {
00072       if (IsRowMajor != ((OtherDerived::Flags&RowMajorBit)==RowMajorBit))
00073       {
00074         // need to transpose => perform a block evaluation followed by a big swap
00075         DynamicSparseMatrix<Scalar,IsRowMajor?RowMajorBit:0> aux(other);
00076         *this = aux.markAsRValue();
00077       }
00078       else
00079       {
00080         // evaluate/copy vector per vector
00081         for (Index j=0; j<m_outerSize.value(); ++j)
00082         {
00083           SparseVector<Scalar,IsRowMajor ? RowMajorBit : 0> aux(other.innerVector(j));
00084           m_matrix.const_cast_derived()._data()[m_outerStart+j].swap(aux._data());
00085         }
00086       }
00087       return *this;
00088     }
00089 
00090     inline SparseInnerVectorSet& operator=(const SparseInnerVectorSet& other)
00091     {
00092       return operator=<SparseInnerVectorSet>(other);
00093     }
00094 
00095     Index nonZeros() const
00096     {
00097       Index count = 0;
00098       for (Index j=0; j<m_outerSize.value(); ++j)
00099         count += m_matrix._data()[m_outerStart+j].size();
00100       return count;
00101     }
00102 
00103     const Scalar& lastCoeff() const
00104     {
00105       EIGEN_STATIC_ASSERT_VECTOR_ONLY(SparseInnerVectorSet);
00106       eigen_assert(m_matrix.data()[m_outerStart].size()>0);
00107       return m_matrix.data()[m_outerStart].vale(m_matrix.data()[m_outerStart].size()-1);
00108     }
00109 
00110 //     template<typename Sparse>
00111 //     inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other)
00112 //     {
00113 //       return *this;
00114 //     }
00115 
00116     EIGEN_STRONG_INLINE Index rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
00117     EIGEN_STRONG_INLINE Index cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }
00118 
00119   protected:
00120 
00121     const typename MatrixType::Nested m_matrix;
00122     Index m_outerStart;
00123     const internal::variable_if_dynamic<Index, Size> m_outerSize;
00124 
00125 };
00126 
00127 } // end namespace Eigen
00128 
00129 #endif // EIGEN_SPARSE_BLOCKFORDYNAMICMATRIX_H