$treeview $search $mathjax
Eigen
3.2.5
$projectbrief
|
$projectbrief
|
$searchbox |
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 : public EigenBase<Derived> 00027 { 00028 public: 00029 00030 typedef typename internal::traits<Derived>::Scalar Scalar; 00031 typedef typename internal::packet_traits<Scalar>::type PacketScalar; 00032 typedef typename internal::traits<Derived>::StorageKind StorageKind; 00033 typedef typename internal::traits<Derived>::Index Index; 00034 typedef typename internal::add_const_on_value_type_if_arithmetic< 00035 typename internal::packet_traits<Scalar>::type 00036 >::type PacketReturnType; 00037 00038 typedef SparseMatrixBase StorageBaseType; 00039 typedef EigenBase<Derived> Base; 00040 00041 template<typename OtherDerived> 00042 Derived& operator=(const EigenBase<OtherDerived> &other) 00043 { 00044 other.derived().evalTo(derived()); 00045 return derived(); 00046 } 00047 00048 enum { 00049 00050 RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime, 00056 ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime, 00063 SizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::RowsAtCompileTime, 00064 internal::traits<Derived>::ColsAtCompileTime>::ret), 00069 MaxRowsAtCompileTime = RowsAtCompileTime, 00070 MaxColsAtCompileTime = ColsAtCompileTime, 00071 00072 MaxSizeAtCompileTime = (internal::size_at_compile_time<MaxRowsAtCompileTime, 00073 MaxColsAtCompileTime>::ret), 00074 00075 IsVectorAtCompileTime = RowsAtCompileTime == 1 || ColsAtCompileTime == 1, 00081 Flags = internal::traits<Derived>::Flags, 00086 CoeffReadCost = internal::traits<Derived>::CoeffReadCost, 00091 IsRowMajor = Flags&RowMajorBit ? 1 : 0, 00092 00093 InnerSizeAtCompileTime = int(IsVectorAtCompileTime) ? int(SizeAtCompileTime) 00094 : int(IsRowMajor) ? int(ColsAtCompileTime) : int(RowsAtCompileTime), 00095 00096 #ifndef EIGEN_PARSED_BY_DOXYGEN 00097 _HasDirectAccess = (int(Flags)&DirectAccessBit) ? 1 : 0 // workaround sunCC 00098 #endif 00099 }; 00100 00102 typedef typename internal::conditional<NumTraits<Scalar>::IsComplex, 00103 CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, Eigen::Transpose<const Derived> >, 00104 Transpose<const Derived> 00105 >::type AdjointReturnType; 00106 00107 00108 typedef SparseMatrix<Scalar, Flags&RowMajorBit ? RowMajor : ColMajor, Index> PlainObject; 00109 00110 00111 #ifndef EIGEN_PARSED_BY_DOXYGEN 00112 00118 typedef typename NumTraits<Scalar>::Real RealScalar; 00119 00122 typedef typename internal::conditional<_HasDirectAccess, const Scalar&, Scalar>::type CoeffReturnType; 00123 00125 typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,Matrix<Scalar,Dynamic,Dynamic> > ConstantReturnType; 00126 00128 typedef Matrix<Scalar,EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime), 00129 EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime)> SquareMatrixType; 00130 00131 inline const Derived& derived() const { return *static_cast<const Derived*>(this); } 00132 inline Derived& derived() { return *static_cast<Derived*>(this); } 00133 inline Derived& const_cast_derived() const 00134 { return *static_cast<Derived*>(const_cast<SparseMatrixBase*>(this)); } 00135 #endif // not EIGEN_PARSED_BY_DOXYGEN 00136 00137 #define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::SparseMatrixBase 00138 # include "../plugins/CommonCwiseUnaryOps.h" 00139 # include "../plugins/CommonCwiseBinaryOps.h" 00140 # include "../plugins/MatrixCwiseUnaryOps.h" 00141 # include "../plugins/MatrixCwiseBinaryOps.h" 00142 # include "../plugins/BlockMethods.h" 00143 # ifdef EIGEN_SPARSEMATRIXBASE_PLUGIN 00144 # include EIGEN_SPARSEMATRIXBASE_PLUGIN 00145 # endif 00146 # undef EIGEN_CURRENT_STORAGE_BASE_CLASS 00147 #undef EIGEN_CURRENT_STORAGE_BASE_CLASS 00148 00150 inline Index rows() const { return derived().rows(); } 00152 inline Index cols() const { return derived().cols(); } 00155 inline Index size() const { return rows() * cols(); } 00158 inline Index nonZeros() const { return derived().nonZeros(); } 00163 inline bool isVector() const { return rows()==1 || cols()==1; } 00166 Index outerSize() const { return (int(Flags)&RowMajorBit) ? this->rows() : this->cols(); } 00169 Index innerSize() const { return (int(Flags)&RowMajorBit) ? this->cols() : this->rows(); } 00170 00171 bool isRValue() const { return m_isRValue; } 00172 Derived& markAsRValue() { m_isRValue = true; return derived(); } 00173 00174 SparseMatrixBase() : m_isRValue(false) { /* TODO check flags */ } 00175 00176 00177 template<typename OtherDerived> 00178 Derived& operator=(const ReturnByValue<OtherDerived>& other) 00179 { 00180 other.evalTo(derived()); 00181 return derived(); 00182 } 00183 00184 00185 template<typename OtherDerived> 00186 inline Derived& operator=(const SparseMatrixBase<OtherDerived>& other) 00187 { 00188 return assign(other.derived()); 00189 } 00190 00191 inline Derived& operator=(const Derived& other) 00192 { 00193 // if (other.isRValue()) 00194 // derived().swap(other.const_cast_derived()); 00195 // else 00196 return assign(other.derived()); 00197 } 00198 00199 protected: 00200 00201 template<typename OtherDerived> 00202 inline Derived& assign(const OtherDerived& other) 00203 { 00204 const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); 00205 const Index outerSize = (int(OtherDerived::Flags) & RowMajorBit) ? other.rows() : other.cols(); 00206 if ((!transpose) && other.isRValue()) 00207 { 00208 // eval without temporary 00209 derived().resize(other.rows(), other.cols()); 00210 derived().setZero(); 00211 derived().reserve((std::max)(this->rows(),this->cols())*2); 00212 for (Index j=0; j<outerSize; ++j) 00213 { 00214 derived().startVec(j); 00215 for (typename OtherDerived::InnerIterator it(other, j); it; ++it) 00216 { 00217 Scalar v = it.value(); 00218 derived().insertBackByOuterInner(j,it.index()) = v; 00219 } 00220 } 00221 derived().finalize(); 00222 } 00223 else 00224 { 00225 assignGeneric(other); 00226 } 00227 return derived(); 00228 } 00229 00230 template<typename OtherDerived> 00231 inline void assignGeneric(const OtherDerived& other) 00232 { 00233 //const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); 00234 eigen_assert(( ((internal::traits<Derived>::SupportedAccessPatterns&OuterRandomAccessPattern)==OuterRandomAccessPattern) || 00235 (!((Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit)))) && 00236 "the transpose operation is supposed to be handled in SparseMatrix::operator="); 00237 00238 enum { Flip = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit) }; 00239 00240 const Index outerSize = other.outerSize(); 00241 //typedef typename internal::conditional<transpose, LinkedVectorMatrix<Scalar,Flags&RowMajorBit>, Derived>::type TempType; 00242 // thanks to shallow copies, we always eval to a tempary 00243 Derived temp(other.rows(), other.cols()); 00244 00245 temp.reserve((std::max)(this->rows(),this->cols())*2); 00246 for (Index j=0; j<outerSize; ++j) 00247 { 00248 temp.startVec(j); 00249 for (typename OtherDerived::InnerIterator it(other.derived(), j); it; ++it) 00250 { 00251 Scalar v = it.value(); 00252 temp.insertBackByOuterInner(Flip?it.index():j,Flip?j:it.index()) = v; 00253 } 00254 } 00255 temp.finalize(); 00256 00257 derived() = temp.markAsRValue(); 00258 } 00259 00260 public: 00261 00262 template<typename Lhs, typename Rhs> 00263 inline Derived& operator=(const SparseSparseProduct<Lhs,Rhs>& product); 00264 00265 friend std::ostream & operator << (std::ostream & s, const SparseMatrixBase& m) 00266 { 00267 typedef typename Derived::Nested Nested; 00268 typedef typename internal::remove_all<Nested>::type NestedCleaned; 00269 00270 if (Flags&RowMajorBit) 00271 { 00272 const Nested nm(m.derived()); 00273 for (Index row=0; row<nm.outerSize(); ++row) 00274 { 00275 Index col = 0; 00276 for (typename NestedCleaned::InnerIterator it(nm.derived(), row); it; ++it) 00277 { 00278 for ( ; col<it.index(); ++col) 00279 s << "0 "; 00280 s << it.value() << " "; 00281 ++col; 00282 } 00283 for ( ; col<m.cols(); ++col) 00284 s << "0 "; 00285 s << std::endl; 00286 } 00287 } 00288 else 00289 { 00290 const Nested nm(m.derived()); 00291 if (m.cols() == 1) { 00292 Index row = 0; 00293 for (typename NestedCleaned::InnerIterator it(nm.derived(), 0); it; ++it) 00294 { 00295 for ( ; row<it.index(); ++row) 00296 s << "0" << std::endl; 00297 s << it.value() << std::endl; 00298 ++row; 00299 } 00300 for ( ; row<m.rows(); ++row) 00301 s << "0" << std::endl; 00302 } 00303 else 00304 { 00305 SparseMatrix<Scalar, RowMajorBit, Index> trans = m; 00306 s << static_cast<const SparseMatrixBase<SparseMatrix<Scalar, RowMajorBit, Index> >&>(trans); 00307 } 00308 } 00309 return s; 00310 } 00311 00312 template<typename OtherDerived> 00313 Derived& operator+=(const SparseMatrixBase<OtherDerived>& other); 00314 template<typename OtherDerived> 00315 Derived& operator-=(const SparseMatrixBase<OtherDerived>& other); 00316 00317 Derived& operator*=(const Scalar& other); 00318 Derived& operator/=(const Scalar& other); 00319 00320 #define EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE \ 00321 CwiseBinaryOp< \ 00322 internal::scalar_product_op< \ 00323 typename internal::scalar_product_traits< \ 00324 typename internal::traits<Derived>::Scalar, \ 00325 typename internal::traits<OtherDerived>::Scalar \ 00326 >::ReturnType \ 00327 >, \ 00328 const Derived, \ 00329 const OtherDerived \ 00330 > 00331 00332 template<typename OtherDerived> 00333 EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE 00334 cwiseProduct(const MatrixBase<OtherDerived> &other) const; 00335 00336 // sparse * sparse 00337 template<typename OtherDerived> 00338 const typename SparseSparseProductReturnType<Derived,OtherDerived>::Type 00339 operator*(const SparseMatrixBase<OtherDerived> &other) const; 00340 00341 // sparse * diagonal 00342 template<typename OtherDerived> 00343 const SparseDiagonalProduct<Derived,OtherDerived> 00344 operator*(const DiagonalBase<OtherDerived> &other) const; 00345 00346 // diagonal * sparse 00347 template<typename OtherDerived> friend 00348 const SparseDiagonalProduct<OtherDerived,Derived> 00349 operator*(const DiagonalBase<OtherDerived> &lhs, const SparseMatrixBase& rhs) 00350 { return SparseDiagonalProduct<OtherDerived,Derived>(lhs.derived(), rhs.derived()); } 00351 00353 template<typename OtherDerived> friend 00354 const typename DenseSparseProductReturnType<OtherDerived,Derived>::Type 00355 operator*(const MatrixBase<OtherDerived>& lhs, const Derived& rhs) 00356 { return typename DenseSparseProductReturnType<OtherDerived,Derived>::Type(lhs.derived(),rhs); } 00357 00359 template<typename OtherDerived> 00360 const typename SparseDenseProductReturnType<Derived,OtherDerived>::Type 00361 operator*(const MatrixBase<OtherDerived> &other) const 00362 { return typename SparseDenseProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived()); } 00363 00365 SparseSymmetricPermutationProduct<Derived,Upper|Lower> twistedBy(const PermutationMatrix<Dynamic,Dynamic,Index>& perm) const 00366 { 00367 return SparseSymmetricPermutationProduct<Derived,Upper|Lower>(derived(), perm); 00368 } 00369 00370 template<typename OtherDerived> 00371 Derived& operator*=(const SparseMatrixBase<OtherDerived>& other); 00372 00373 #ifdef EIGEN2_SUPPORT 00374 // deprecated 00375 template<typename OtherDerived> 00376 typename internal::plain_matrix_type_column_major<OtherDerived>::type 00377 solveTriangular(const MatrixBase<OtherDerived>& other) const; 00378 00379 // deprecated 00380 template<typename OtherDerived> 00381 void solveTriangularInPlace(MatrixBase<OtherDerived>& other) const; 00382 #endif // EIGEN2_SUPPORT 00383 00384 template<int Mode> 00385 inline const SparseTriangularView<Derived, Mode> triangularView() const; 00386 00387 template<unsigned int UpLo> inline const SparseSelfAdjointView<Derived, UpLo> selfadjointView() const; 00388 template<unsigned int UpLo> inline SparseSelfAdjointView<Derived, UpLo> selfadjointView(); 00389 00390 template<typename OtherDerived> Scalar dot(const MatrixBase<OtherDerived>& other) const; 00391 template<typename OtherDerived> Scalar dot(const SparseMatrixBase<OtherDerived>& other) const; 00392 RealScalar squaredNorm() const; 00393 RealScalar norm() const; 00394 RealScalar blueNorm() const; 00395 00396 Transpose<Derived> transpose() { return derived(); } 00397 const Transpose<const Derived> transpose() const { return derived(); } 00398 const AdjointReturnType adjoint() const { return transpose(); } 00399 00400 // inner-vector 00401 typedef Block<Derived,IsRowMajor?1:Dynamic,IsRowMajor?Dynamic:1,true> InnerVectorReturnType; 00402 typedef Block<const Derived,IsRowMajor?1:Dynamic,IsRowMajor?Dynamic:1,true> ConstInnerVectorReturnType; 00403 InnerVectorReturnType innerVector(Index outer); 00404 const ConstInnerVectorReturnType innerVector(Index outer) const; 00405 00406 // set of inner-vectors 00407 typedef Block<Derived,Dynamic,Dynamic,true> InnerVectorsReturnType; 00408 typedef Block<const Derived,Dynamic,Dynamic,true> ConstInnerVectorsReturnType; 00409 InnerVectorsReturnType innerVectors(Index outerStart, Index outerSize); 00410 const ConstInnerVectorsReturnType innerVectors(Index outerStart, Index outerSize) const; 00411 00413 template<typename DenseDerived> 00414 void evalTo(MatrixBase<DenseDerived>& dst) const 00415 { 00416 dst.setZero(); 00417 for (Index j=0; j<outerSize(); ++j) 00418 for (typename Derived::InnerIterator i(derived(),j); i; ++i) 00419 dst.coeffRef(i.row(),i.col()) = i.value(); 00420 } 00421 00422 Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> toDense() const 00423 { 00424 return derived(); 00425 } 00426 00427 template<typename OtherDerived> 00428 bool isApprox(const SparseMatrixBase<OtherDerived>& other, 00429 const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const 00430 { return toDense().isApprox(other.toDense(),prec); } 00431 00432 template<typename OtherDerived> 00433 bool isApprox(const MatrixBase<OtherDerived>& other, 00434 const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const 00435 { return toDense().isApprox(other,prec); } 00436 00442 inline const typename internal::eval<Derived>::type eval() const 00443 { return typename internal::eval<Derived>::type(derived()); } 00444 00445 Scalar sum() const; 00446 00447 protected: 00448 00449 bool m_isRValue; 00450 }; 00451 00452 } // end namespace Eigen 00453 00454 #endif // EIGEN_SPARSEMATRIXBASE_H