![]() |
Eigen
3.3.3
|
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2008-2014 Gael Guennebaud <gael.guennebaud@inria.fr> 00005 // 00006 // This Source Code Form is subject to the terms of the Mozilla 00007 // Public License v. 2.0. If a copy of the MPL was not distributed 00008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 00009 00010 #ifndef EIGEN_SPARSEMATRIXBASE_H 00011 #define EIGEN_SPARSEMATRIXBASE_H 00012 00013 namespace Eigen { 00014 00026 template<typename Derived> class SparseMatrixBase 00027 : public EigenBase<Derived> 00028 { 00029 public: 00030 00031 typedef typename internal::traits<Derived>::Scalar Scalar; 00032 00036 typedef Scalar value_type; 00037 00038 typedef typename internal::packet_traits<Scalar>::type PacketScalar; 00039 typedef typename internal::traits<Derived>::StorageKind StorageKind; 00040 00043 typedef typename internal::traits<Derived>::StorageIndex StorageIndex; 00044 00045 typedef typename internal::add_const_on_value_type_if_arithmetic< 00046 typename internal::packet_traits<Scalar>::type 00047 >::type PacketReturnType; 00048 00049 typedef SparseMatrixBase StorageBaseType; 00050 00051 typedef Matrix<StorageIndex,Dynamic,1> IndexVector; 00052 typedef Matrix<Scalar,Dynamic,1> ScalarVector; 00053 00054 template<typename OtherDerived> 00055 Derived& operator=(const EigenBase<OtherDerived> &other); 00056 00057 enum { 00058 00059 RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime, 00065 ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime, 00072 SizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::RowsAtCompileTime, 00073 internal::traits<Derived>::ColsAtCompileTime>::ret), 00078 MaxRowsAtCompileTime = RowsAtCompileTime, 00079 MaxColsAtCompileTime = ColsAtCompileTime, 00080 00081 MaxSizeAtCompileTime = (internal::size_at_compile_time<MaxRowsAtCompileTime, 00082 MaxColsAtCompileTime>::ret), 00083 00084 IsVectorAtCompileTime = RowsAtCompileTime == 1 || ColsAtCompileTime == 1, 00090 Flags = internal::traits<Derived>::Flags, 00095 IsRowMajor = Flags&RowMajorBit ? 1 : 0, 00096 00097 InnerSizeAtCompileTime = int(IsVectorAtCompileTime) ? int(SizeAtCompileTime) 00098 : int(IsRowMajor) ? int(ColsAtCompileTime) : int(RowsAtCompileTime), 00099 00100 #ifndef EIGEN_PARSED_BY_DOXYGEN 00101 _HasDirectAccess = (int(Flags)&DirectAccessBit) ? 1 : 0 // workaround sunCC 00102 #endif 00103 }; 00104 00106 typedef typename internal::conditional<NumTraits<Scalar>::IsComplex, 00107 CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, Eigen::Transpose<const Derived> >, 00108 Transpose<const Derived> 00109 >::type AdjointReturnType; 00110 typedef Transpose<Derived> TransposeReturnType; 00111 typedef typename internal::add_const<Transpose<const Derived> >::type ConstTransposeReturnType; 00112 00113 // FIXME storage order do not match evaluator storage order 00114 typedef SparseMatrix<Scalar, Flags&RowMajorBit ? RowMajor : ColMajor, StorageIndex> PlainObject; 00115 00116 #ifndef EIGEN_PARSED_BY_DOXYGEN 00117 00123 typedef typename NumTraits<Scalar>::Real RealScalar; 00124 00127 typedef typename internal::conditional<_HasDirectAccess, const Scalar&, Scalar>::type CoeffReturnType; 00128 00130 typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,Matrix<Scalar,Dynamic,Dynamic> > ConstantReturnType; 00131 00133 typedef Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> DenseMatrixType; 00135 typedef Matrix<Scalar,EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime), 00136 EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime)> SquareMatrixType; 00137 00138 inline const Derived& derived() const { return *static_cast<const Derived*>(this); } 00139 inline Derived& derived() { return *static_cast<Derived*>(this); } 00140 inline Derived& const_cast_derived() const 00141 { return *static_cast<Derived*>(const_cast<SparseMatrixBase*>(this)); } 00142 00143 typedef EigenBase<Derived> Base; 00144 00145 #endif // not EIGEN_PARSED_BY_DOXYGEN 00146 00147 #define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::SparseMatrixBase 00148 #ifdef EIGEN_PARSED_BY_DOXYGEN 00149 #define EIGEN_DOC_UNARY_ADDONS(METHOD,OP) 00150 #define EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL 00151 #define EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(COND) 00152 #else 00153 #define EIGEN_DOC_UNARY_ADDONS(X,Y) 00154 #define EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL 00155 #define EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(COND) 00156 #endif 00157 # include "../plugins/CommonCwiseUnaryOps.h" 00158 # include "../plugins/CommonCwiseBinaryOps.h" 00159 # include "../plugins/MatrixCwiseUnaryOps.h" 00160 # include "../plugins/MatrixCwiseBinaryOps.h" 00161 # include "../plugins/BlockMethods.h" 00162 # ifdef EIGEN_SPARSEMATRIXBASE_PLUGIN 00163 # include EIGEN_SPARSEMATRIXBASE_PLUGIN 00164 # endif 00165 #undef EIGEN_CURRENT_STORAGE_BASE_CLASS 00166 #undef EIGEN_DOC_UNARY_ADDONS 00167 #undef EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL 00168 #undef EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF 00169 00171 inline Index rows() const { return derived().rows(); } 00173 inline Index cols() const { return derived().cols(); } 00176 inline Index size() const { return rows() * cols(); } 00181 inline bool isVector() const { return rows()==1 || cols()==1; } 00184 Index outerSize() const { return (int(Flags)&RowMajorBit) ? this->rows() : this->cols(); } 00187 Index innerSize() const { return (int(Flags)&RowMajorBit) ? this->cols() : this->rows(); } 00188 00189 bool isRValue() const { return m_isRValue; } 00190 Derived& markAsRValue() { m_isRValue = true; return derived(); } 00191 00192 SparseMatrixBase() : m_isRValue(false) { /* TODO check flags */ } 00193 00194 00195 template<typename OtherDerived> 00196 Derived& operator=(const ReturnByValue<OtherDerived>& other); 00197 00198 template<typename OtherDerived> 00199 inline Derived& operator=(const SparseMatrixBase<OtherDerived>& other); 00200 00201 inline Derived& operator=(const Derived& other); 00202 00203 protected: 00204 00205 template<typename OtherDerived> 00206 inline Derived& assign(const OtherDerived& other); 00207 00208 template<typename OtherDerived> 00209 inline void assignGeneric(const OtherDerived& other); 00210 00211 public: 00212 00213 friend std::ostream & operator << (std::ostream & s, const SparseMatrixBase& m) 00214 { 00215 typedef typename Derived::Nested Nested; 00216 typedef typename internal::remove_all<Nested>::type NestedCleaned; 00217 00218 if (Flags&RowMajorBit) 00219 { 00220 Nested nm(m.derived()); 00221 internal::evaluator<NestedCleaned> thisEval(nm); 00222 for (Index row=0; row<nm.outerSize(); ++row) 00223 { 00224 Index col = 0; 00225 for (typename internal::evaluator<NestedCleaned>::InnerIterator it(thisEval, row); it; ++it) 00226 { 00227 for ( ; col<it.index(); ++col) 00228 s << "0 "; 00229 s << it.value() << " "; 00230 ++col; 00231 } 00232 for ( ; col<m.cols(); ++col) 00233 s << "0 "; 00234 s << std::endl; 00235 } 00236 } 00237 else 00238 { 00239 Nested nm(m.derived()); 00240 internal::evaluator<NestedCleaned> thisEval(nm); 00241 if (m.cols() == 1) { 00242 Index row = 0; 00243 for (typename internal::evaluator<NestedCleaned>::InnerIterator it(thisEval, 0); it; ++it) 00244 { 00245 for ( ; row<it.index(); ++row) 00246 s << "0" << std::endl; 00247 s << it.value() << std::endl; 00248 ++row; 00249 } 00250 for ( ; row<m.rows(); ++row) 00251 s << "0" << std::endl; 00252 } 00253 else 00254 { 00255 SparseMatrix<Scalar, RowMajorBit, StorageIndex> trans = m; 00256 s << static_cast<const SparseMatrixBase<SparseMatrix<Scalar, RowMajorBit, StorageIndex> >&>(trans); 00257 } 00258 } 00259 return s; 00260 } 00261 00262 template<typename OtherDerived> 00263 Derived& operator+=(const SparseMatrixBase<OtherDerived>& other); 00264 template<typename OtherDerived> 00265 Derived& operator-=(const SparseMatrixBase<OtherDerived>& other); 00266 00267 template<typename OtherDerived> 00268 Derived& operator+=(const DiagonalBase<OtherDerived>& other); 00269 template<typename OtherDerived> 00270 Derived& operator-=(const DiagonalBase<OtherDerived>& other); 00271 00272 template<typename OtherDerived> 00273 Derived& operator+=(const EigenBase<OtherDerived> &other); 00274 template<typename OtherDerived> 00275 Derived& operator-=(const EigenBase<OtherDerived> &other); 00276 00277 Derived& operator*=(const Scalar& other); 00278 Derived& operator/=(const Scalar& other); 00279 00280 template<typename OtherDerived> struct CwiseProductDenseReturnType { 00281 typedef CwiseBinaryOp<internal::scalar_product_op<typename ScalarBinaryOpTraits< 00282 typename internal::traits<Derived>::Scalar, 00283 typename internal::traits<OtherDerived>::Scalar 00284 >::ReturnType>, 00285 const Derived, 00286 const OtherDerived 00287 > Type; 00288 }; 00289 00290 template<typename OtherDerived> 00291 EIGEN_STRONG_INLINE const typename CwiseProductDenseReturnType<OtherDerived>::Type 00292 cwiseProduct(const MatrixBase<OtherDerived> &other) const; 00293 00294 // sparse * diagonal 00295 template<typename OtherDerived> 00296 const Product<Derived,OtherDerived> 00297 operator*(const DiagonalBase<OtherDerived> &other) const 00298 { return Product<Derived,OtherDerived>(derived(), other.derived()); } 00299 00300 // diagonal * sparse 00301 template<typename OtherDerived> friend 00302 const Product<OtherDerived,Derived> 00303 operator*(const DiagonalBase<OtherDerived> &lhs, const SparseMatrixBase& rhs) 00304 { return Product<OtherDerived,Derived>(lhs.derived(), rhs.derived()); } 00305 00306 // sparse * sparse 00307 template<typename OtherDerived> 00308 const Product<Derived,OtherDerived,AliasFreeProduct> 00309 operator*(const SparseMatrixBase<OtherDerived> &other) const; 00310 00311 // sparse * dense 00312 template<typename OtherDerived> 00313 const Product<Derived,OtherDerived> 00314 operator*(const MatrixBase<OtherDerived> &other) const 00315 { return Product<Derived,OtherDerived>(derived(), other.derived()); } 00316 00317 // dense * sparse 00318 template<typename OtherDerived> friend 00319 const Product<OtherDerived,Derived> 00320 operator*(const MatrixBase<OtherDerived> &lhs, const SparseMatrixBase& rhs) 00321 { return Product<OtherDerived,Derived>(lhs.derived(), rhs.derived()); } 00322 00324 SparseSymmetricPermutationProduct<Derived,Upper|Lower> twistedBy(const PermutationMatrix<Dynamic,Dynamic,StorageIndex>& perm) const 00325 { 00326 return SparseSymmetricPermutationProduct<Derived,Upper|Lower>(derived(), perm); 00327 } 00328 00329 template<typename OtherDerived> 00330 Derived& operator*=(const SparseMatrixBase<OtherDerived>& other); 00331 00332 template<int Mode> 00333 inline const TriangularView<const Derived, Mode> triangularView() const; 00334 00335 template<unsigned int UpLo> struct SelfAdjointViewReturnType { typedef SparseSelfAdjointView<Derived, UpLo> Type; }; 00336 template<unsigned int UpLo> struct ConstSelfAdjointViewReturnType { typedef const SparseSelfAdjointView<const Derived, UpLo> Type; }; 00337 00338 template<unsigned int UpLo> inline 00339 typename ConstSelfAdjointViewReturnType<UpLo>::Type selfadjointView() const; 00340 template<unsigned int UpLo> inline 00341 typename SelfAdjointViewReturnType<UpLo>::Type selfadjointView(); 00342 00343 template<typename OtherDerived> Scalar dot(const MatrixBase<OtherDerived>& other) const; 00344 template<typename OtherDerived> Scalar dot(const SparseMatrixBase<OtherDerived>& other) const; 00345 RealScalar squaredNorm() const; 00346 RealScalar norm() const; 00347 RealScalar blueNorm() const; 00348 00349 TransposeReturnType transpose() { return TransposeReturnType(derived()); } 00350 const ConstTransposeReturnType transpose() const { return ConstTransposeReturnType(derived()); } 00351 const AdjointReturnType adjoint() const { return AdjointReturnType(transpose()); } 00352 00353 // inner-vector 00354 typedef Block<Derived,IsRowMajor?1:Dynamic,IsRowMajor?Dynamic:1,true> InnerVectorReturnType; 00355 typedef Block<const Derived,IsRowMajor?1:Dynamic,IsRowMajor?Dynamic:1,true> ConstInnerVectorReturnType; 00356 InnerVectorReturnType innerVector(Index outer); 00357 const ConstInnerVectorReturnType innerVector(Index outer) const; 00358 00359 // set of inner-vectors 00360 typedef Block<Derived,Dynamic,Dynamic,true> InnerVectorsReturnType; 00361 typedef Block<const Derived,Dynamic,Dynamic,true> ConstInnerVectorsReturnType; 00362 InnerVectorsReturnType innerVectors(Index outerStart, Index outerSize); 00363 const ConstInnerVectorsReturnType innerVectors(Index outerStart, Index outerSize) const; 00364 00365 DenseMatrixType toDense() const 00366 { 00367 return DenseMatrixType(derived()); 00368 } 00369 00370 template<typename OtherDerived> 00371 bool isApprox(const SparseMatrixBase<OtherDerived>& other, 00372 const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const; 00373 00374 template<typename OtherDerived> 00375 bool isApprox(const MatrixBase<OtherDerived>& other, 00376 const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const 00377 { return toDense().isApprox(other,prec); } 00378 00384 inline const typename internal::eval<Derived>::type eval() const 00385 { return typename internal::eval<Derived>::type(derived()); } 00386 00387 Scalar sum() const; 00388 00389 inline const SparseView<Derived> 00390 pruned(const Scalar& reference = Scalar(0), const RealScalar& epsilon = NumTraits<Scalar>::dummy_precision()) const; 00391 00392 protected: 00393 00394 bool m_isRValue; 00395 00396 static inline StorageIndex convert_index(const Index idx) { 00397 return internal::convert_index<StorageIndex>(idx); 00398 } 00399 private: 00400 template<typename Dest> void evalTo(Dest &) const; 00401 }; 00402 00403 } // end namespace Eigen 00404 00405 #endif // EIGEN_SPARSEMATRIXBASE_H