![]() |
Eigen
3.2.8
|
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2008-2011 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 #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 typedef typename internal::packet_traits<Scalar>::type PacketScalar; 00039 typedef typename internal::traits<Derived>::StorageKind StorageKind; 00040 typedef typename internal::traits<Derived>::Index Index; 00041 typedef typename internal::add_const_on_value_type_if_arithmetic< 00042 typename internal::packet_traits<Scalar>::type 00043 >::type PacketReturnType; 00044 00045 typedef SparseMatrixBase StorageBaseType; 00046 00047 template<typename OtherDerived> 00048 Derived& operator=(const EigenBase<OtherDerived> &other) 00049 { 00050 other.derived().evalTo(derived()); 00051 return derived(); 00052 } 00053 00054 enum { 00055 00056 RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime, 00062 ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime, 00069 SizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::RowsAtCompileTime, 00070 internal::traits<Derived>::ColsAtCompileTime>::ret), 00075 MaxRowsAtCompileTime = RowsAtCompileTime, 00076 MaxColsAtCompileTime = ColsAtCompileTime, 00077 00078 MaxSizeAtCompileTime = (internal::size_at_compile_time<MaxRowsAtCompileTime, 00079 MaxColsAtCompileTime>::ret), 00080 00081 IsVectorAtCompileTime = RowsAtCompileTime == 1 || ColsAtCompileTime == 1, 00087 Flags = internal::traits<Derived>::Flags, 00092 CoeffReadCost = internal::traits<Derived>::CoeffReadCost, 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 00113 00114 typedef SparseMatrix<Scalar, Flags&RowMajorBit ? RowMajor : ColMajor, Index> PlainObject; 00115 00116 00117 #ifndef EIGEN_PARSED_BY_DOXYGEN 00118 00124 typedef typename NumTraits<Scalar>::Real RealScalar; 00125 00128 typedef typename internal::conditional<_HasDirectAccess, const Scalar&, Scalar>::type CoeffReturnType; 00129 00131 typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,Matrix<Scalar,Dynamic,Dynamic> > ConstantReturnType; 00132 00134 typedef Matrix<Scalar,EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime), 00135 EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime)> SquareMatrixType; 00136 00137 inline const Derived& derived() const { return *static_cast<const Derived*>(this); } 00138 inline Derived& derived() { return *static_cast<Derived*>(this); } 00139 inline Derived& const_cast_derived() const 00140 { return *static_cast<Derived*>(const_cast<SparseMatrixBase*>(this)); } 00141 00142 typedef internal::special_scalar_op_base<Derived, Scalar, RealScalar, EigenBase<Derived> > Base; 00143 using Base::operator*; 00144 #endif // not EIGEN_PARSED_BY_DOXYGEN 00145 00146 #define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::SparseMatrixBase 00147 # include "../plugins/CommonCwiseUnaryOps.h" 00148 # include "../plugins/CommonCwiseBinaryOps.h" 00149 # include "../plugins/MatrixCwiseUnaryOps.h" 00150 # include "../plugins/MatrixCwiseBinaryOps.h" 00151 # include "../plugins/BlockMethods.h" 00152 # ifdef EIGEN_SPARSEMATRIXBASE_PLUGIN 00153 # include EIGEN_SPARSEMATRIXBASE_PLUGIN 00154 # endif 00155 # undef EIGEN_CURRENT_STORAGE_BASE_CLASS 00156 #undef EIGEN_CURRENT_STORAGE_BASE_CLASS 00157 00159 inline Index rows() const { return derived().rows(); } 00161 inline Index cols() const { return derived().cols(); } 00164 inline Index size() const { return rows() * cols(); } 00167 inline Index nonZeros() const { return derived().nonZeros(); } 00172 inline bool isVector() const { return rows()==1 || cols()==1; } 00175 Index outerSize() const { return (int(Flags)&RowMajorBit) ? this->rows() : this->cols(); } 00178 Index innerSize() const { return (int(Flags)&RowMajorBit) ? this->cols() : this->rows(); } 00179 00180 bool isRValue() const { return m_isRValue; } 00181 Derived& markAsRValue() { m_isRValue = true; return derived(); } 00182 00183 SparseMatrixBase() : m_isRValue(false) { /* TODO check flags */ } 00184 00185 00186 template<typename OtherDerived> 00187 Derived& operator=(const ReturnByValue<OtherDerived>& other) 00188 { 00189 other.evalTo(derived()); 00190 return derived(); 00191 } 00192 00193 00194 template<typename OtherDerived> 00195 inline Derived& operator=(const SparseMatrixBase<OtherDerived>& other) 00196 { 00197 return assign(other.derived()); 00198 } 00199 00200 inline Derived& operator=(const Derived& other) 00201 { 00202 // if (other.isRValue()) 00203 // derived().swap(other.const_cast_derived()); 00204 // else 00205 return assign(other.derived()); 00206 } 00207 00208 protected: 00209 00210 template<typename OtherDerived> 00211 inline Derived& assign(const OtherDerived& other) 00212 { 00213 const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); 00214 const Index outerSize = (int(OtherDerived::Flags) & RowMajorBit) ? other.rows() : other.cols(); 00215 if ((!transpose) && other.isRValue()) 00216 { 00217 // eval without temporary 00218 derived().resize(other.rows(), other.cols()); 00219 derived().setZero(); 00220 derived().reserve((std::max)(this->rows(),this->cols())*2); 00221 for (Index j=0; j<outerSize; ++j) 00222 { 00223 derived().startVec(j); 00224 for (typename OtherDerived::InnerIterator it(other, j); it; ++it) 00225 { 00226 Scalar v = it.value(); 00227 derived().insertBackByOuterInner(j,it.index()) = v; 00228 } 00229 } 00230 derived().finalize(); 00231 } 00232 else 00233 { 00234 assignGeneric(other); 00235 } 00236 return derived(); 00237 } 00238 00239 template<typename OtherDerived> 00240 inline void assignGeneric(const OtherDerived& other) 00241 { 00242 //const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); 00243 eigen_assert(( ((internal::traits<Derived>::SupportedAccessPatterns&OuterRandomAccessPattern)==OuterRandomAccessPattern) || 00244 (!((Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit)))) && 00245 "the transpose operation is supposed to be handled in SparseMatrix::operator="); 00246 00247 enum { Flip = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit) }; 00248 00249 const Index outerSize = other.outerSize(); 00250 //typedef typename internal::conditional<transpose, LinkedVectorMatrix<Scalar,Flags&RowMajorBit>, Derived>::type TempType; 00251 // thanks to shallow copies, we always eval to a tempary 00252 Derived temp(other.rows(), other.cols()); 00253 00254 temp.reserve((std::max)(this->rows(),this->cols())*2); 00255 for (Index j=0; j<outerSize; ++j) 00256 { 00257 temp.startVec(j); 00258 for (typename OtherDerived::InnerIterator it(other.derived(), j); it; ++it) 00259 { 00260 Scalar v = it.value(); 00261 temp.insertBackByOuterInner(Flip?it.index():j,Flip?j:it.index()) = v; 00262 } 00263 } 00264 temp.finalize(); 00265 00266 derived() = temp.markAsRValue(); 00267 } 00268 00269 public: 00270 00271 template<typename Lhs, typename Rhs> 00272 inline Derived& operator=(const SparseSparseProduct<Lhs,Rhs>& product); 00273 00274 friend std::ostream & operator << (std::ostream & s, const SparseMatrixBase& m) 00275 { 00276 typedef typename Derived::Nested Nested; 00277 typedef typename internal::remove_all<Nested>::type NestedCleaned; 00278 00279 if (Flags&RowMajorBit) 00280 { 00281 const Nested nm(m.derived()); 00282 for (Index row=0; row<nm.outerSize(); ++row) 00283 { 00284 Index col = 0; 00285 for (typename NestedCleaned::InnerIterator it(nm.derived(), row); it; ++it) 00286 { 00287 for ( ; col<it.index(); ++col) 00288 s << "0 "; 00289 s << it.value() << " "; 00290 ++col; 00291 } 00292 for ( ; col<m.cols(); ++col) 00293 s << "0 "; 00294 s << std::endl; 00295 } 00296 } 00297 else 00298 { 00299 const Nested nm(m.derived()); 00300 if (m.cols() == 1) { 00301 Index row = 0; 00302 for (typename NestedCleaned::InnerIterator it(nm.derived(), 0); it; ++it) 00303 { 00304 for ( ; row<it.index(); ++row) 00305 s << "0" << std::endl; 00306 s << it.value() << std::endl; 00307 ++row; 00308 } 00309 for ( ; row<m.rows(); ++row) 00310 s << "0" << std::endl; 00311 } 00312 else 00313 { 00314 SparseMatrix<Scalar, RowMajorBit, Index> trans = m; 00315 s << static_cast<const SparseMatrixBase<SparseMatrix<Scalar, RowMajorBit, Index> >&>(trans); 00316 } 00317 } 00318 return s; 00319 } 00320 00321 template<typename OtherDerived> 00322 Derived& operator+=(const SparseMatrixBase<OtherDerived>& other); 00323 template<typename OtherDerived> 00324 Derived& operator-=(const SparseMatrixBase<OtherDerived>& other); 00325 00326 Derived& operator*=(const Scalar& other); 00327 Derived& operator/=(const Scalar& other); 00328 00329 template<typename OtherDerived> struct CwiseProductDenseReturnType { 00330 typedef CwiseBinaryOp<internal::scalar_product_op<typename internal::scalar_product_traits< 00331 typename internal::traits<Derived>::Scalar, 00332 typename internal::traits<OtherDerived>::Scalar 00333 >::ReturnType>, 00334 const Derived, 00335 const OtherDerived 00336 > Type; 00337 }; 00338 00339 template<typename OtherDerived> 00340 EIGEN_STRONG_INLINE const typename CwiseProductDenseReturnType<OtherDerived>::Type 00341 cwiseProduct(const MatrixBase<OtherDerived> &other) const; 00342 00343 // sparse * sparse 00344 template<typename OtherDerived> 00345 const typename SparseSparseProductReturnType<Derived,OtherDerived>::Type 00346 operator*(const SparseMatrixBase<OtherDerived> &other) const; 00347 00348 // sparse * diagonal 00349 template<typename OtherDerived> 00350 const SparseDiagonalProduct<Derived,OtherDerived> 00351 operator*(const DiagonalBase<OtherDerived> &other) const; 00352 00353 // diagonal * sparse 00354 template<typename OtherDerived> friend 00355 const SparseDiagonalProduct<OtherDerived,Derived> 00356 operator*(const DiagonalBase<OtherDerived> &lhs, const SparseMatrixBase& rhs) 00357 { return SparseDiagonalProduct<OtherDerived,Derived>(lhs.derived(), rhs.derived()); } 00358 00360 template<typename OtherDerived> friend 00361 const typename DenseSparseProductReturnType<OtherDerived,Derived>::Type 00362 operator*(const MatrixBase<OtherDerived>& lhs, const Derived& rhs) 00363 { return typename DenseSparseProductReturnType<OtherDerived,Derived>::Type(lhs.derived(),rhs); } 00364 00366 template<typename OtherDerived> 00367 const typename SparseDenseProductReturnType<Derived,OtherDerived>::Type 00368 operator*(const MatrixBase<OtherDerived> &other) const 00369 { return typename SparseDenseProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived()); } 00370 00372 SparseSymmetricPermutationProduct<Derived,Upper|Lower> twistedBy(const PermutationMatrix<Dynamic,Dynamic,Index>& perm) const 00373 { 00374 return SparseSymmetricPermutationProduct<Derived,Upper|Lower>(derived(), perm); 00375 } 00376 00377 template<typename OtherDerived> 00378 Derived& operator*=(const SparseMatrixBase<OtherDerived>& other); 00379 00380 #ifdef EIGEN2_SUPPORT 00381 // deprecated 00382 template<typename OtherDerived> 00383 typename internal::plain_matrix_type_column_major<OtherDerived>::type 00384 solveTriangular(const MatrixBase<OtherDerived>& other) const; 00385 00386 // deprecated 00387 template<typename OtherDerived> 00388 void solveTriangularInPlace(MatrixBase<OtherDerived>& other) const; 00389 #endif // EIGEN2_SUPPORT 00390 00391 template<int Mode> 00392 inline const SparseTriangularView<Derived, Mode> triangularView() const; 00393 00394 template<unsigned int UpLo> inline const SparseSelfAdjointView<Derived, UpLo> selfadjointView() const; 00395 template<unsigned int UpLo> inline SparseSelfAdjointView<Derived, UpLo> selfadjointView(); 00396 00397 template<typename OtherDerived> Scalar dot(const MatrixBase<OtherDerived>& other) const; 00398 template<typename OtherDerived> Scalar dot(const SparseMatrixBase<OtherDerived>& other) const; 00399 RealScalar squaredNorm() const; 00400 RealScalar norm() const; 00401 RealScalar blueNorm() const; 00402 00403 Transpose<Derived> transpose() { return derived(); } 00404 const Transpose<const Derived> transpose() const { return derived(); } 00405 const AdjointReturnType adjoint() const { return transpose(); } 00406 00407 // inner-vector 00408 typedef Block<Derived,IsRowMajor?1:Dynamic,IsRowMajor?Dynamic:1,true> InnerVectorReturnType; 00409 typedef Block<const Derived,IsRowMajor?1:Dynamic,IsRowMajor?Dynamic:1,true> ConstInnerVectorReturnType; 00410 InnerVectorReturnType innerVector(Index outer); 00411 const ConstInnerVectorReturnType innerVector(Index outer) const; 00412 00413 // set of inner-vectors 00414 typedef Block<Derived,Dynamic,Dynamic,true> InnerVectorsReturnType; 00415 typedef Block<const Derived,Dynamic,Dynamic,true> ConstInnerVectorsReturnType; 00416 InnerVectorsReturnType innerVectors(Index outerStart, Index outerSize); 00417 const ConstInnerVectorsReturnType innerVectors(Index outerStart, Index outerSize) const; 00418 00420 template<typename DenseDerived> 00421 void evalTo(MatrixBase<DenseDerived>& dst) const 00422 { 00423 dst.setZero(); 00424 for (Index j=0; j<outerSize(); ++j) 00425 for (typename Derived::InnerIterator i(derived(),j); i; ++i) 00426 dst.coeffRef(i.row(),i.col()) = i.value(); 00427 } 00428 00429 Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> toDense() const 00430 { 00431 return derived(); 00432 } 00433 00434 template<typename OtherDerived> 00435 bool isApprox(const SparseMatrixBase<OtherDerived>& other, 00436 const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const 00437 { return toDense().isApprox(other.toDense(),prec); } 00438 00439 template<typename OtherDerived> 00440 bool isApprox(const MatrixBase<OtherDerived>& other, 00441 const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const 00442 { return toDense().isApprox(other,prec); } 00443 00449 inline const typename internal::eval<Derived>::type eval() const 00450 { return typename internal::eval<Derived>::type(derived()); } 00451 00452 Scalar sum() const; 00453 00454 protected: 00455 00456 bool m_isRValue; 00457 }; 00458 00459 } // end namespace Eigen 00460 00461 #endif // EIGEN_SPARSEMATRIXBASE_H