MOAB
4.9.3pre
|
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2008-2014 Gael Guennebaud <[email protected]> 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 #ifndef EIGEN_PARSED_BY_DOXYGEN 00028 : public internal::special_scalar_op_base<Derived,typename internal::traits<Derived>::Scalar, 00029 typename NumTraits<typename internal::traits<Derived>::Scalar>::Real, 00030 EigenBase<Derived> > 00031 #else 00032 : public EigenBase<Derived> 00033 #endif // not EIGEN_PARSED_BY_DOXYGEN 00034 { 00035 public: 00036 00037 typedef typename internal::traits<Derived>::Scalar Scalar; 00038 00042 typedef Scalar value_type; 00043 00044 typedef typename internal::packet_traits<Scalar>::type PacketScalar; 00045 typedef typename internal::traits<Derived>::StorageKind StorageKind; 00046 typedef typename internal::traits<Derived>::StorageIndex StorageIndex; 00047 typedef typename internal::add_const_on_value_type_if_arithmetic< 00048 typename internal::packet_traits<Scalar>::type 00049 >::type PacketReturnType; 00050 00051 typedef SparseMatrixBase StorageBaseType; 00052 00053 typedef Matrix<StorageIndex,Dynamic,1> IndexVector; 00054 typedef Matrix<Scalar,Dynamic,1> ScalarVector; 00055 00056 template<typename OtherDerived> 00057 Derived& operator=(const EigenBase<OtherDerived> &other); 00058 00059 enum { 00060 00061 RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime, 00067 ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime, 00074 SizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::RowsAtCompileTime, 00075 internal::traits<Derived>::ColsAtCompileTime>::ret), 00080 MaxRowsAtCompileTime = RowsAtCompileTime, 00081 MaxColsAtCompileTime = ColsAtCompileTime, 00082 00083 MaxSizeAtCompileTime = (internal::size_at_compile_time<MaxRowsAtCompileTime, 00084 MaxColsAtCompileTime>::ret), 00085 00086 IsVectorAtCompileTime = RowsAtCompileTime == 1 || ColsAtCompileTime == 1, 00092 Flags = internal::traits<Derived>::Flags, 00097 IsRowMajor = Flags&RowMajorBit ? 1 : 0, 00098 00099 InnerSizeAtCompileTime = int(IsVectorAtCompileTime) ? int(SizeAtCompileTime) 00100 : int(IsRowMajor) ? int(ColsAtCompileTime) : int(RowsAtCompileTime), 00101 00102 #ifndef EIGEN_PARSED_BY_DOXYGEN 00103 _HasDirectAccess = (int(Flags)&DirectAccessBit) ? 1 : 0 // workaround sunCC 00104 #endif 00105 }; 00106 00108 typedef typename internal::conditional<NumTraits<Scalar>::IsComplex, 00109 CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, Eigen::Transpose<const Derived> >, 00110 Transpose<const Derived> 00111 >::type AdjointReturnType; 00112 typedef Transpose<Derived> TransposeReturnType; 00113 typedef typename internal::add_const<Transpose<const Derived> >::type ConstTransposeReturnType; 00114 00115 // FIXME storage order do not match evaluator storage order 00116 typedef SparseMatrix<Scalar, Flags&RowMajorBit ? RowMajor : ColMajor, StorageIndex> PlainObject; 00117 00118 #ifndef EIGEN_PARSED_BY_DOXYGEN 00119 00125 typedef typename NumTraits<Scalar>::Real RealScalar; 00126 00129 typedef typename internal::conditional<_HasDirectAccess, const Scalar&, Scalar>::type CoeffReturnType; 00130 00132 typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,Matrix<Scalar,Dynamic,Dynamic> > ConstantReturnType; 00133 00135 typedef Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> DenseMatrixType; 00137 typedef Matrix<Scalar,EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime), 00138 EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime)> SquareMatrixType; 00139 00140 inline const Derived& derived() const { return *static_cast<const Derived*>(this); } 00141 inline Derived& derived() { return *static_cast<Derived*>(this); } 00142 inline Derived& const_cast_derived() const 00143 { return *static_cast<Derived*>(const_cast<SparseMatrixBase*>(this)); } 00144 00145 typedef internal::special_scalar_op_base<Derived, Scalar, RealScalar, EigenBase<Derived> > Base; 00146 using Base::operator*; 00147 using Base::operator/; 00148 #endif // not EIGEN_PARSED_BY_DOXYGEN 00149 00150 #define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::SparseMatrixBase 00151 # include "../plugins/CommonCwiseUnaryOps.h" 00152 # include "../plugins/CommonCwiseBinaryOps.h" 00153 # include "../plugins/MatrixCwiseUnaryOps.h" 00154 # include "../plugins/MatrixCwiseBinaryOps.h" 00155 # include "../plugins/BlockMethods.h" 00156 # ifdef EIGEN_SPARSEMATRIXBASE_PLUGIN 00157 # include EIGEN_SPARSEMATRIXBASE_PLUGIN 00158 # endif 00159 # undef EIGEN_CURRENT_STORAGE_BASE_CLASS 00160 #undef EIGEN_CURRENT_STORAGE_BASE_CLASS 00161 00163 inline Index rows() const { return derived().rows(); } 00165 inline Index cols() const { return derived().cols(); } 00168 inline Index size() const { return rows() * cols(); } 00173 inline bool isVector() const { return rows()==1 || cols()==1; } 00176 Index outerSize() const { return (int(Flags)&RowMajorBit) ? this->rows() : this->cols(); } 00179 Index innerSize() const { return (int(Flags)&RowMajorBit) ? this->cols() : this->rows(); } 00180 00181 bool isRValue() const { return m_isRValue; } 00182 Derived& markAsRValue() { m_isRValue = true; return derived(); } 00183 00184 SparseMatrixBase() : m_isRValue(false) { /* TODO check flags */ } 00185 00186 00187 template<typename OtherDerived> 00188 Derived& operator=(const ReturnByValue<OtherDerived>& other); 00189 00190 template<typename OtherDerived> 00191 inline Derived& operator=(const SparseMatrixBase<OtherDerived>& other); 00192 00193 inline Derived& operator=(const Derived& other); 00194 00195 protected: 00196 00197 template<typename OtherDerived> 00198 inline Derived& assign(const OtherDerived& other); 00199 00200 template<typename OtherDerived> 00201 inline void assignGeneric(const OtherDerived& other); 00202 00203 public: 00204 00205 friend std::ostream & operator << (std::ostream & s, const SparseMatrixBase& m) 00206 { 00207 typedef typename Derived::Nested Nested; 00208 typedef typename internal::remove_all<Nested>::type NestedCleaned; 00209 00210 if (Flags&RowMajorBit) 00211 { 00212 const Nested nm(m.derived()); 00213 for (Index row=0; row<nm.outerSize(); ++row) 00214 { 00215 Index col = 0; 00216 for (typename NestedCleaned::InnerIterator it(nm.derived(), row); it; ++it) 00217 { 00218 for ( ; col<it.index(); ++col) 00219 s << "0 "; 00220 s << it.value() << " "; 00221 ++col; 00222 } 00223 for ( ; col<m.cols(); ++col) 00224 s << "0 "; 00225 s << std::endl; 00226 } 00227 } 00228 else 00229 { 00230 const Nested nm(m.derived()); 00231 if (m.cols() == 1) { 00232 Index row = 0; 00233 for (typename NestedCleaned::InnerIterator it(nm.derived(), 0); it; ++it) 00234 { 00235 for ( ; row<it.index(); ++row) 00236 s << "0" << std::endl; 00237 s << it.value() << std::endl; 00238 ++row; 00239 } 00240 for ( ; row<m.rows(); ++row) 00241 s << "0" << std::endl; 00242 } 00243 else 00244 { 00245 SparseMatrix<Scalar, RowMajorBit, StorageIndex> trans = m; 00246 s << static_cast<const SparseMatrixBase<SparseMatrix<Scalar, RowMajorBit, StorageIndex> >&>(trans); 00247 } 00248 } 00249 return s; 00250 } 00251 00252 template<typename OtherDerived> 00253 Derived& operator+=(const SparseMatrixBase<OtherDerived>& other); 00254 template<typename OtherDerived> 00255 Derived& operator-=(const SparseMatrixBase<OtherDerived>& other); 00256 00257 template<typename OtherDerived> 00258 Derived& operator+=(const DiagonalBase<OtherDerived>& other); 00259 template<typename OtherDerived> 00260 Derived& operator-=(const DiagonalBase<OtherDerived>& other); 00261 00262 Derived& operator*=(const Scalar& other); 00263 Derived& operator/=(const Scalar& other); 00264 00265 template<typename OtherDerived> struct CwiseProductDenseReturnType { 00266 typedef CwiseBinaryOp<internal::scalar_product_op<typename internal::scalar_product_traits< 00267 typename internal::traits<Derived>::Scalar, 00268 typename internal::traits<OtherDerived>::Scalar 00269 >::ReturnType>, 00270 const Derived, 00271 const OtherDerived 00272 > Type; 00273 }; 00274 00275 template<typename OtherDerived> 00276 EIGEN_STRONG_INLINE const typename CwiseProductDenseReturnType<OtherDerived>::Type 00277 cwiseProduct(const MatrixBase<OtherDerived> &other) const; 00278 00279 // sparse * diagonal 00280 template<typename OtherDerived> 00281 const Product<Derived,OtherDerived> 00282 operator*(const DiagonalBase<OtherDerived> &other) const 00283 { return Product<Derived,OtherDerived>(derived(), other.derived()); } 00284 00285 // diagonal * sparse 00286 template<typename OtherDerived> friend 00287 const Product<OtherDerived,Derived> 00288 operator*(const DiagonalBase<OtherDerived> &lhs, const SparseMatrixBase& rhs) 00289 { return Product<OtherDerived,Derived>(lhs.derived(), rhs.derived()); } 00290 00291 // sparse * sparse 00292 template<typename OtherDerived> 00293 const Product<Derived,OtherDerived,AliasFreeProduct> 00294 operator*(const SparseMatrixBase<OtherDerived> &other) const; 00295 00296 // sparse * dense 00297 template<typename OtherDerived> 00298 const Product<Derived,OtherDerived> 00299 operator*(const MatrixBase<OtherDerived> &other) const 00300 { return Product<Derived,OtherDerived>(derived(), other.derived()); } 00301 00302 // dense * sparse 00303 template<typename OtherDerived> friend 00304 const Product<OtherDerived,Derived> 00305 operator*(const MatrixBase<OtherDerived> &lhs, const SparseMatrixBase& rhs) 00306 { return Product<OtherDerived,Derived>(lhs.derived(), rhs.derived()); } 00307 00309 SparseSymmetricPermutationProduct<Derived,Upper|Lower> twistedBy(const PermutationMatrix<Dynamic,Dynamic,StorageIndex>& perm) const 00310 { 00311 return SparseSymmetricPermutationProduct<Derived,Upper|Lower>(derived(), perm); 00312 } 00313 00314 template<typename OtherDerived> 00315 Derived& operator*=(const SparseMatrixBase<OtherDerived>& other); 00316 00317 template<int Mode> 00318 inline const TriangularView<const Derived, Mode> triangularView() const; 00319 00320 template<unsigned int UpLo> struct SelfAdjointViewReturnType { typedef SparseSelfAdjointView<Derived, UpLo> Type; }; 00321 template<unsigned int UpLo> struct ConstSelfAdjointViewReturnType { typedef const SparseSelfAdjointView<const Derived, UpLo> Type; }; 00322 00323 template<unsigned int UpLo> inline 00324 typename ConstSelfAdjointViewReturnType<UpLo>::Type selfadjointView() const; 00325 template<unsigned int UpLo> inline 00326 typename SelfAdjointViewReturnType<UpLo>::Type selfadjointView(); 00327 00328 template<typename OtherDerived> Scalar dot(const MatrixBase<OtherDerived>& other) const; 00329 template<typename OtherDerived> Scalar dot(const SparseMatrixBase<OtherDerived>& other) const; 00330 RealScalar squaredNorm() const; 00331 RealScalar norm() const; 00332 RealScalar blueNorm() const; 00333 00334 TransposeReturnType transpose() { return TransposeReturnType(derived()); } 00335 const ConstTransposeReturnType transpose() const { return ConstTransposeReturnType(derived()); } 00336 const AdjointReturnType adjoint() const { return AdjointReturnType(transpose()); } 00337 00338 // inner-vector 00339 typedef Block<Derived,IsRowMajor?1:Dynamic,IsRowMajor?Dynamic:1,true> InnerVectorReturnType; 00340 typedef Block<const Derived,IsRowMajor?1:Dynamic,IsRowMajor?Dynamic:1,true> ConstInnerVectorReturnType; 00341 InnerVectorReturnType innerVector(Index outer); 00342 const ConstInnerVectorReturnType innerVector(Index outer) const; 00343 00344 // set of inner-vectors 00345 typedef Block<Derived,Dynamic,Dynamic,true> InnerVectorsReturnType; 00346 typedef Block<const Derived,Dynamic,Dynamic,true> ConstInnerVectorsReturnType; 00347 InnerVectorsReturnType innerVectors(Index outerStart, Index outerSize); 00348 const ConstInnerVectorsReturnType innerVectors(Index outerStart, Index outerSize) const; 00349 00350 DenseMatrixType toDense() const 00351 { 00352 return DenseMatrixType(derived()); 00353 } 00354 00355 template<typename OtherDerived> 00356 bool isApprox(const SparseMatrixBase<OtherDerived>& other, 00357 const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const; 00358 00359 template<typename OtherDerived> 00360 bool isApprox(const MatrixBase<OtherDerived>& other, 00361 const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const 00362 { return toDense().isApprox(other,prec); } 00363 00369 inline const typename internal::eval<Derived>::type eval() const 00370 { return typename internal::eval<Derived>::type(derived()); } 00371 00372 Scalar sum() const; 00373 00374 inline const SparseView<Derived> 00375 pruned(const Scalar& reference = Scalar(0), const RealScalar& epsilon = NumTraits<Scalar>::dummy_precision()) const; 00376 00377 protected: 00378 00379 bool m_isRValue; 00380 00381 static inline StorageIndex convert_index(const Index idx) { 00382 return internal::convert_index<StorageIndex>(idx); 00383 } 00384 private: 00385 template<typename Dest> void evalTo(Dest &) const; 00386 }; 00387 00388 } // end namespace Eigen 00389 00390 #endif // EIGEN_SPARSEMATRIXBASE_H