00001
00002
00003
00004
00005
00006
00007
00008
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 #ifndef EIGEN_PARSED_BY_DOXYGEN
00094 _HasDirectAccess = (int(Flags)&DirectAccessBit) ? 1 : 0
00095 #endif
00096 };
00097
00099 typedef typename internal::conditional<NumTraits<Scalar>::IsComplex,
00100 CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, Eigen::Transpose<const Derived> >,
00101 Transpose<const Derived>
00102 >::type AdjointReturnType;
00103
00104
00105 typedef SparseMatrix<Scalar, Flags&RowMajorBit ? RowMajor : ColMajor> PlainObject;
00106
00107
00108 #ifndef EIGEN_PARSED_BY_DOXYGEN
00109
00115 typedef typename NumTraits<Scalar>::Real RealScalar;
00116
00119 typedef typename internal::conditional<_HasDirectAccess, const Scalar&, Scalar>::type CoeffReturnType;
00120
00122 typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,Matrix<Scalar,Dynamic,Dynamic> > ConstantReturnType;
00123
00125 typedef Matrix<Scalar,EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime),
00126 EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime)> SquareMatrixType;
00127
00128 inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
00129 inline Derived& derived() { return *static_cast<Derived*>(this); }
00130 inline Derived& const_cast_derived() const
00131 { return *static_cast<Derived*>(const_cast<SparseMatrixBase*>(this)); }
00132 #endif // not EIGEN_PARSED_BY_DOXYGEN
00133
00134 #define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::SparseMatrixBase
00135 # include "../plugins/CommonCwiseUnaryOps.h"
00136 # include "../plugins/CommonCwiseBinaryOps.h"
00137 # include "../plugins/MatrixCwiseUnaryOps.h"
00138 # include "../plugins/MatrixCwiseBinaryOps.h"
00139 # ifdef EIGEN_SPARSEMATRIXBASE_PLUGIN
00140 # include EIGEN_SPARSEMATRIXBASE_PLUGIN
00141 # endif
00142 # undef EIGEN_CURRENT_STORAGE_BASE_CLASS
00143 #undef EIGEN_CURRENT_STORAGE_BASE_CLASS
00144
00145
00147 inline Index rows() const { return derived().rows(); }
00149 inline Index cols() const { return derived().cols(); }
00152 inline Index size() const { return rows() * cols(); }
00155 inline Index nonZeros() const { return derived().nonZeros(); }
00160 inline bool isVector() const { return rows()==1 || cols()==1; }
00163 Index outerSize() const { return (int(Flags)&RowMajorBit) ? this->rows() : this->cols(); }
00166 Index innerSize() const { return (int(Flags)&RowMajorBit) ? this->cols() : this->rows(); }
00167
00168 bool isRValue() const { return m_isRValue; }
00169 Derived& markAsRValue() { m_isRValue = true; return derived(); }
00170
00171 SparseMatrixBase() : m_isRValue(false) { }
00172
00173
00174 template<typename OtherDerived>
00175 Derived& operator=(const ReturnByValue<OtherDerived>& other)
00176 {
00177 other.evalTo(derived());
00178 return derived();
00179 }
00180
00181
00182 template<typename OtherDerived>
00183 inline Derived& operator=(const SparseMatrixBase<OtherDerived>& other)
00184 {
00185 return assign(other.derived());
00186 }
00187
00188 inline Derived& operator=(const Derived& other)
00189 {
00190
00191
00192
00193 return assign(other.derived());
00194 }
00195
00196 protected:
00197
00198 template<typename OtherDerived>
00199 inline Derived& assign(const OtherDerived& other)
00200 {
00201 const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
00202 const Index outerSize = (int(OtherDerived::Flags) & RowMajorBit) ? other.rows() : other.cols();
00203 if ((!transpose) && other.isRValue())
00204 {
00205
00206 derived().resize(other.rows(), other.cols());
00207 derived().setZero();
00208 derived().reserve((std::max)(this->rows(),this->cols())*2);
00209 for (Index j=0; j<outerSize; ++j)
00210 {
00211 derived().startVec(j);
00212 for (typename OtherDerived::InnerIterator it(other, j); it; ++it)
00213 {
00214 Scalar v = it.value();
00215 derived().insertBackByOuterInner(j,it.index()) = v;
00216 }
00217 }
00218 derived().finalize();
00219 }
00220 else
00221 {
00222 assignGeneric(other);
00223 }
00224 return derived();
00225 }
00226
00227 template<typename OtherDerived>
00228 inline void assignGeneric(const OtherDerived& other)
00229 {
00230
00231 eigen_assert(( ((internal::traits<Derived>::SupportedAccessPatterns&OuterRandomAccessPattern)==OuterRandomAccessPattern) ||
00232 (!((Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit)))) &&
00233 "the transpose operation is supposed to be handled in SparseMatrix::operator=");
00234
00235 enum { Flip = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit) };
00236
00237 const Index outerSize = other.outerSize();
00238
00239
00240 Derived temp(other.rows(), other.cols());
00241
00242 temp.reserve((std::max)(this->rows(),this->cols())*2);
00243 for (Index j=0; j<outerSize; ++j)
00244 {
00245 temp.startVec(j);
00246 for (typename OtherDerived::InnerIterator it(other.derived(), j); it; ++it)
00247 {
00248 Scalar v = it.value();
00249 temp.insertBackByOuterInner(Flip?it.index():j,Flip?j:it.index()) = v;
00250 }
00251 }
00252 temp.finalize();
00253
00254 derived() = temp.markAsRValue();
00255 }
00256
00257 public:
00258
00259 template<typename Lhs, typename Rhs>
00260 inline Derived& operator=(const SparseSparseProduct<Lhs,Rhs>& product);
00261
00262 friend std::ostream & operator << (std::ostream & s, const SparseMatrixBase& m)
00263 {
00264 typedef typename Derived::Nested Nested;
00265 typedef typename internal::remove_all<Nested>::type NestedCleaned;
00266
00267 if (Flags&RowMajorBit)
00268 {
00269 const Nested nm(m.derived());
00270 for (Index row=0; row<nm.outerSize(); ++row)
00271 {
00272 Index col = 0;
00273 for (typename NestedCleaned::InnerIterator it(nm.derived(), row); it; ++it)
00274 {
00275 for ( ; col<it.index(); ++col)
00276 s << "0 ";
00277 s << it.value() << " ";
00278 ++col;
00279 }
00280 for ( ; col<m.cols(); ++col)
00281 s << "0 ";
00282 s << std::endl;
00283 }
00284 }
00285 else
00286 {
00287 const Nested nm(m.derived());
00288 if (m.cols() == 1) {
00289 Index row = 0;
00290 for (typename NestedCleaned::InnerIterator it(nm.derived(), 0); it; ++it)
00291 {
00292 for ( ; row<it.index(); ++row)
00293 s << "0" << std::endl;
00294 s << it.value() << std::endl;
00295 ++row;
00296 }
00297 for ( ; row<m.rows(); ++row)
00298 s << "0" << std::endl;
00299 }
00300 else
00301 {
00302 SparseMatrix<Scalar, RowMajorBit> trans = m;
00303 s << static_cast<const SparseMatrixBase<SparseMatrix<Scalar, RowMajorBit> >&>(trans);
00304 }
00305 }
00306 return s;
00307 }
00308
00309 template<typename OtherDerived>
00310 Derived& operator+=(const SparseMatrixBase<OtherDerived>& other);
00311 template<typename OtherDerived>
00312 Derived& operator-=(const SparseMatrixBase<OtherDerived>& other);
00313
00314 Derived& operator*=(const Scalar& other);
00315 Derived& operator/=(const Scalar& other);
00316
00317 #define EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE \
00318 CwiseBinaryOp< \
00319 internal::scalar_product_op< \
00320 typename internal::scalar_product_traits< \
00321 typename internal::traits<Derived>::Scalar, \
00322 typename internal::traits<OtherDerived>::Scalar \
00323 >::ReturnType \
00324 >, \
00325 Derived, \
00326 OtherDerived \
00327 >
00328
00329 template<typename OtherDerived>
00330 EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE
00331 cwiseProduct(const MatrixBase<OtherDerived> &other) const;
00332
00333
00334 template<typename OtherDerived>
00335 const typename SparseSparseProductReturnType<Derived,OtherDerived>::Type
00336 operator*(const SparseMatrixBase<OtherDerived> &other) const;
00337
00338
00339 template<typename OtherDerived>
00340 const SparseDiagonalProduct<Derived,OtherDerived>
00341 operator*(const DiagonalBase<OtherDerived> &other) const;
00342
00343
00344 template<typename OtherDerived> friend
00345 const SparseDiagonalProduct<OtherDerived,Derived>
00346 operator*(const DiagonalBase<OtherDerived> &lhs, const SparseMatrixBase& rhs)
00347 { return SparseDiagonalProduct<OtherDerived,Derived>(lhs.derived(), rhs.derived()); }
00348
00350 template<typename OtherDerived> friend
00351 const typename DenseSparseProductReturnType<OtherDerived,Derived>::Type
00352 operator*(const MatrixBase<OtherDerived>& lhs, const Derived& rhs)
00353 { return typename DenseSparseProductReturnType<OtherDerived,Derived>::Type(lhs.derived(),rhs); }
00354
00356 template<typename OtherDerived>
00357 const typename SparseDenseProductReturnType<Derived,OtherDerived>::Type
00358 operator*(const MatrixBase<OtherDerived> &other) const;
00359
00361 SparseSymmetricPermutationProduct<Derived,Upper|Lower> twistedBy(const PermutationMatrix<Dynamic,Dynamic,Index>& perm) const
00362 {
00363 return SparseSymmetricPermutationProduct<Derived,Upper|Lower>(derived(), perm);
00364 }
00365
00366 template<typename OtherDerived>
00367 Derived& operator*=(const SparseMatrixBase<OtherDerived>& other);
00368
00369 #ifdef EIGEN2_SUPPORT
00370
00371 template<typename OtherDerived>
00372 typename internal::plain_matrix_type_column_major<OtherDerived>::type
00373 solveTriangular(const MatrixBase<OtherDerived>& other) const;
00374
00375
00376 template<typename OtherDerived>
00377 void solveTriangularInPlace(MatrixBase<OtherDerived>& other) const;
00378 #endif // EIGEN2_SUPPORT
00379
00380 template<int Mode>
00381 inline const SparseTriangularView<Derived, Mode> triangularView() const;
00382
00383 template<unsigned int UpLo> inline const SparseSelfAdjointView<Derived, UpLo> selfadjointView() const;
00384 template<unsigned int UpLo> inline SparseSelfAdjointView<Derived, UpLo> selfadjointView();
00385
00386 template<typename OtherDerived> Scalar dot(const MatrixBase<OtherDerived>& other) const;
00387 template<typename OtherDerived> Scalar dot(const SparseMatrixBase<OtherDerived>& other) const;
00388 RealScalar squaredNorm() const;
00389 RealScalar norm() const;
00390
00391 Transpose<Derived> transpose() { return derived(); }
00392 const Transpose<const Derived> transpose() const { return derived(); }
00393 const AdjointReturnType adjoint() const { return transpose(); }
00394
00395
00396 SparseInnerVectorSet<Derived,1> row(Index i);
00397 const SparseInnerVectorSet<Derived,1> row(Index i) const;
00398 SparseInnerVectorSet<Derived,1> col(Index j);
00399 const SparseInnerVectorSet<Derived,1> col(Index j) const;
00400 SparseInnerVectorSet<Derived,1> innerVector(Index outer);
00401 const SparseInnerVectorSet<Derived,1> innerVector(Index outer) const;
00402
00403
00404 SparseInnerVectorSet<Derived,Dynamic> subrows(Index start, Index size);
00405 const SparseInnerVectorSet<Derived,Dynamic> subrows(Index start, Index size) const;
00406 SparseInnerVectorSet<Derived,Dynamic> subcols(Index start, Index size);
00407 const SparseInnerVectorSet<Derived,Dynamic> subcols(Index start, Index size) const;
00408
00409 SparseInnerVectorSet<Derived,Dynamic> middleRows(Index start, Index size);
00410 const SparseInnerVectorSet<Derived,Dynamic> middleRows(Index start, Index size) const;
00411 SparseInnerVectorSet<Derived,Dynamic> middleCols(Index start, Index size);
00412 const SparseInnerVectorSet<Derived,Dynamic> middleCols(Index start, Index size) const;
00413 SparseInnerVectorSet<Derived,Dynamic> innerVectors(Index outerStart, Index outerSize);
00414 const SparseInnerVectorSet<Derived,Dynamic> innerVectors(Index outerStart, Index outerSize) const;
00415
00417 template<typename DenseDerived>
00418 void evalTo(MatrixBase<DenseDerived>& dst) const
00419 {
00420 dst.setZero();
00421 for (Index j=0; j<outerSize(); ++j)
00422 for (typename Derived::InnerIterator i(derived(),j); i; ++i)
00423 dst.coeffRef(i.row(),i.col()) = i.value();
00424 }
00425
00426 Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> toDense() const
00427 {
00428 return derived();
00429 }
00430
00431 template<typename OtherDerived>
00432 bool isApprox(const SparseMatrixBase<OtherDerived>& other,
00433 RealScalar prec = NumTraits<Scalar>::dummy_precision()) const
00434 { return toDense().isApprox(other.toDense(),prec); }
00435
00436 template<typename OtherDerived>
00437 bool isApprox(const MatrixBase<OtherDerived>& other,
00438 RealScalar prec = NumTraits<Scalar>::dummy_precision()) const
00439 { return toDense().isApprox(other,prec); }
00440
00446 inline const typename internal::eval<Derived>::type eval() const
00447 { return typename internal::eval<Derived>::type(derived()); }
00448
00449 Scalar sum() const;
00450
00451 protected:
00452
00453 bool m_isRValue;
00454 };
00455
00456 }
00457
00458 #endif // EIGEN_SPARSEMATRIXBASE_H