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 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
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) { }
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
00194
00195
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
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
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
00242
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
00337 template<typename OtherDerived>
00338 const typename SparseSparseProductReturnType<Derived,OtherDerived>::Type
00339 operator*(const SparseMatrixBase<OtherDerived> &other) const;
00340
00341
00342 template<typename OtherDerived>
00343 const SparseDiagonalProduct<Derived,OtherDerived>
00344 operator*(const DiagonalBase<OtherDerived> &other) const;
00345
00346
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
00375 template<typename OtherDerived>
00376 typename internal::plain_matrix_type_column_major<OtherDerived>::type
00377 solveTriangular(const MatrixBase<OtherDerived>& other) const;
00378
00379
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
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
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 }
00453
00454 #endif // EIGEN_SPARSEMATRIXBASE_H