00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef EIGEN_SPARSEMATRIXBASE_H
00026 #define EIGEN_SPARSEMATRIXBASE_H
00027
00039 template<typename Derived> class SparseMatrixBase : public EigenBase<Derived>
00040 {
00041 public:
00042
00043 typedef typename internal::traits<Derived>::Scalar Scalar;
00044 typedef typename internal::packet_traits<Scalar>::type PacketScalar;
00045 typedef typename internal::traits<Derived>::StorageKind StorageKind;
00046 typedef typename internal::traits<Derived>::Index Index;
00047
00048 typedef SparseMatrixBase StorageBaseType;
00049 typedef EigenBase<Derived> Base;
00050
00051 template<typename OtherDerived>
00052 Derived& operator=(const EigenBase<OtherDerived> &other)
00053 {
00054 other.derived().evalTo(derived());
00055 return derived();
00056 }
00057
00058
00059
00060 enum {
00061
00062 RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
00068 ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
00075 SizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::RowsAtCompileTime,
00076 internal::traits<Derived>::ColsAtCompileTime>::ret),
00081 MaxRowsAtCompileTime = RowsAtCompileTime,
00082 MaxColsAtCompileTime = ColsAtCompileTime,
00083
00084 MaxSizeAtCompileTime = (internal::size_at_compile_time<MaxRowsAtCompileTime,
00085 MaxColsAtCompileTime>::ret),
00086
00087 IsVectorAtCompileTime = RowsAtCompileTime == 1 || ColsAtCompileTime == 1,
00093 Flags = internal::traits<Derived>::Flags,
00098 CoeffReadCost = internal::traits<Derived>::CoeffReadCost,
00103 IsRowMajor = Flags&RowMajorBit ? 1 : 0,
00104
00105 #ifndef EIGEN_PARSED_BY_DOXYGEN
00106 _HasDirectAccess = (int(Flags)&DirectAccessBit) ? 1 : 0
00107 #endif
00108 };
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00120 typedef typename internal::conditional<NumTraits<Scalar>::IsComplex,
00121 CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, Eigen::Transpose<const Derived> >,
00122 Transpose<const Derived>
00123 >::type AdjointReturnType;
00124
00125
00126 typedef SparseMatrix<Scalar, Flags&RowMajorBit ? RowMajor : ColMajor> PlainObject;
00127
00128 #define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::SparseMatrixBase
00129 # include "../plugins/CommonCwiseUnaryOps.h"
00130 # include "../plugins/CommonCwiseBinaryOps.h"
00131 # include "../plugins/MatrixCwiseUnaryOps.h"
00132 # include "../plugins/MatrixCwiseBinaryOps.h"
00133 # ifdef EIGEN_SPARSEMATRIXBASE_PLUGIN
00134 # include EIGEN_SPARSEMATRIXBASE_PLUGIN
00135 # endif
00136 # undef EIGEN_CURRENT_STORAGE_BASE_CLASS
00137 #undef EIGEN_CURRENT_STORAGE_BASE_CLASS
00138
00139 #ifndef EIGEN_PARSED_BY_DOXYGEN
00140
00146 typedef typename NumTraits<Scalar>::Real RealScalar;
00147
00150 typedef typename internal::conditional<_HasDirectAccess, const Scalar&, Scalar>::type CoeffReturnType;
00151
00153 typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,Matrix<Scalar,Dynamic,Dynamic> > ConstantReturnType;
00154
00156 typedef Matrix<Scalar,EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime),
00157 EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime)> SquareMatrixType;
00158
00159 inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
00160 inline Derived& derived() { return *static_cast<Derived*>(this); }
00161 inline Derived& const_cast_derived() const
00162 { return *static_cast<Derived*>(const_cast<SparseMatrixBase*>(this)); }
00163 #endif // not EIGEN_PARSED_BY_DOXYGEN
00164
00166 inline Index rows() const { return derived().rows(); }
00168 inline Index cols() const { return derived().cols(); }
00171 inline Index size() const { return rows() * cols(); }
00174 inline Index nonZeros() const { return derived().nonZeros(); }
00179 inline bool isVector() const { return rows()==1 || cols()==1; }
00182 Index outerSize() const { return (int(Flags)&RowMajorBit) ? this->rows() : this->cols(); }
00185 Index innerSize() const { return (int(Flags)&RowMajorBit) ? this->cols() : this->rows(); }
00186
00187 bool isRValue() const { return m_isRValue; }
00188 Derived& markAsRValue() { m_isRValue = true; return derived(); }
00189
00190 SparseMatrixBase() : m_isRValue(false) { }
00191
00192 inline Derived& operator=(const Derived& other)
00193 {
00194
00195
00196
00197
00198 this->operator=<Derived>(other);
00199 return derived();
00200 }
00201
00202 template<typename OtherDerived>
00203 Derived& operator=(const ReturnByValue<OtherDerived>& other)
00204 {
00205 other.evalTo(derived());
00206 return derived();
00207 }
00208
00209
00210 template<typename OtherDerived>
00211 inline void assignGeneric(const OtherDerived& other)
00212 {
00213
00214
00215 eigen_assert(( ((internal::traits<Derived>::SupportedAccessPatterns&OuterRandomAccessPattern)==OuterRandomAccessPattern) ||
00216 (!((Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit)))) &&
00217 "the transpose operation is supposed to be handled in SparseMatrix::operator=");
00218
00219 enum { Flip = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit) };
00220
00221 const Index outerSize = other.outerSize();
00222
00223
00224 Derived temp(other.rows(), other.cols());
00225
00226 temp.reserve(std::max(this->rows(),this->cols())*2);
00227 for (Index j=0; j<outerSize; ++j)
00228 {
00229 temp.startVec(j);
00230 for (typename OtherDerived::InnerIterator it(other.derived(), j); it; ++it)
00231 {
00232 Scalar v = it.value();
00233 if (v!=Scalar(0))
00234 temp.insertBackByOuterInner(Flip?it.index():j,Flip?j:it.index()) = v;
00235 }
00236 }
00237 temp.finalize();
00238
00239 derived() = temp.markAsRValue();
00240 }
00241
00242
00243 template<typename OtherDerived>
00244 inline Derived& operator=(const SparseMatrixBase<OtherDerived>& other)
00245 {
00246
00247
00248 const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
00249
00250 const Index outerSize = (int(OtherDerived::Flags) & RowMajorBit) ? other.rows() : other.cols();
00251 if ((!transpose) && other.isRValue())
00252 {
00253
00254 derived().resize(other.rows(), other.cols());
00255 derived().setZero();
00256 derived().reserve(std::max(this->rows(),this->cols())*2);
00257 for (Index j=0; j<outerSize; ++j)
00258 {
00259 derived().startVec(j);
00260 for (typename OtherDerived::InnerIterator it(other.derived(), j); it; ++it)
00261 {
00262 Scalar v = it.value();
00263 if (v!=Scalar(0))
00264 derived().insertBackByOuterInner(j,it.index()) = v;
00265 }
00266 }
00267 derived().finalize();
00268 }
00269 else
00270 {
00271 assignGeneric(other.derived());
00272 }
00273 return derived();
00274 }
00275
00276 template<typename Lhs, typename Rhs>
00277 inline Derived& operator=(const SparseSparseProduct<Lhs,Rhs>& product);
00278
00279 template<typename Lhs, typename Rhs>
00280 inline void _experimentalNewProduct(const Lhs& lhs, const Rhs& rhs);
00281
00282 friend std::ostream & operator << (std::ostream & s, const SparseMatrixBase& m)
00283 {
00284 if (Flags&RowMajorBit)
00285 {
00286 for (Index row=0; row<m.outerSize(); ++row)
00287 {
00288 Index col = 0;
00289 for (typename Derived::InnerIterator it(m.derived(), row); it; ++it)
00290 {
00291 for ( ; col<it.index(); ++col)
00292 s << "0 ";
00293 s << it.value() << " ";
00294 ++col;
00295 }
00296 for ( ; col<m.cols(); ++col)
00297 s << "0 ";
00298 s << std::endl;
00299 }
00300 }
00301 else
00302 {
00303 if (m.cols() == 1) {
00304 Index row = 0;
00305 for (typename Derived::InnerIterator it(m.derived(), 0); it; ++it)
00306 {
00307 for ( ; row<it.index(); ++row)
00308 s << "0" << std::endl;
00309 s << it.value() << std::endl;
00310 ++row;
00311 }
00312 for ( ; row<m.rows(); ++row)
00313 s << "0" << std::endl;
00314 }
00315 else
00316 {
00317 SparseMatrix<Scalar, RowMajorBit> trans = m.derived();
00318 s << trans;
00319 }
00320 }
00321 return s;
00322 }
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334 template<typename OtherDerived>
00335 Derived& operator+=(const SparseMatrixBase<OtherDerived>& other);
00336 template<typename OtherDerived>
00337 Derived& operator-=(const SparseMatrixBase<OtherDerived>& other);
00338
00339
00340
00341
00342 Derived& operator*=(const Scalar& other);
00343 Derived& operator/=(const Scalar& other);
00344
00345 #define EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE \
00346 CwiseBinaryOp< \
00347 internal::scalar_product_op< \
00348 typename internal::scalar_product_traits< \
00349 typename internal::traits<Derived>::Scalar, \
00350 typename internal::traits<OtherDerived>::Scalar \
00351 >::ReturnType \
00352 >, \
00353 Derived, \
00354 OtherDerived \
00355 >
00356
00357 template<typename OtherDerived>
00358 EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE
00359 cwiseProduct(const MatrixBase<OtherDerived> &other) const;
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 template<typename OtherDerived>
00373 const typename SparseSparseProductReturnType<Derived,OtherDerived>::Type
00374 operator*(const SparseMatrixBase<OtherDerived> &other) const;
00375
00376
00377 template<typename OtherDerived>
00378 const SparseDiagonalProduct<Derived,OtherDerived>
00379 operator*(const DiagonalBase<OtherDerived> &other) const;
00380
00381
00382 template<typename OtherDerived> friend
00383 const SparseDiagonalProduct<OtherDerived,Derived>
00384 operator*(const DiagonalBase<OtherDerived> &lhs, const SparseMatrixBase& rhs)
00385 { return SparseDiagonalProduct<OtherDerived,Derived>(lhs.derived(), rhs.derived()); }
00386
00388 template<typename OtherDerived> friend
00389 const typename DenseSparseProductReturnType<OtherDerived,Derived>::Type
00390 operator*(const MatrixBase<OtherDerived>& lhs, const Derived& rhs)
00391 { return typename DenseSparseProductReturnType<OtherDerived,Derived>::Type(lhs.derived(),rhs); }
00392
00394 template<typename OtherDerived>
00395 const typename SparseDenseProductReturnType<Derived,OtherDerived>::Type
00396 operator*(const MatrixBase<OtherDerived> &other) const;
00397
00398 template<typename OtherDerived>
00399 Derived& operator*=(const SparseMatrixBase<OtherDerived>& other);
00400
00401 #ifdef EIGEN2_SUPPORT
00402
00403 template<typename OtherDerived>
00404 typename internal::plain_matrix_type_column_major<OtherDerived>::type
00405 solveTriangular(const MatrixBase<OtherDerived>& other) const;
00406
00407
00408 template<typename OtherDerived>
00409 void solveTriangularInPlace(MatrixBase<OtherDerived>& other) const;
00410
00411
00412 #endif // EIGEN2_SUPPORT
00413
00414 template<int Mode>
00415 inline const SparseTriangularView<Derived, Mode> triangularView() const;
00416
00417 template<unsigned int UpLo> inline const SparseSelfAdjointView<Derived, UpLo> selfadjointView() const;
00418 template<unsigned int UpLo> inline SparseSelfAdjointView<Derived, UpLo> selfadjointView();
00419
00420 template<typename OtherDerived> Scalar dot(const MatrixBase<OtherDerived>& other) const;
00421 template<typename OtherDerived> Scalar dot(const SparseMatrixBase<OtherDerived>& other) const;
00422 RealScalar squaredNorm() const;
00423 RealScalar norm() const;
00424
00425
00426
00427 Transpose<Derived> transpose() { return derived(); }
00428 const Transpose<const Derived> transpose() const { return derived(); }
00429
00430 const AdjointReturnType adjoint() const { return transpose(); }
00431
00432
00433 SparseInnerVectorSet<Derived,1> row(Index i);
00434 const SparseInnerVectorSet<Derived,1> row(Index i) const;
00435 SparseInnerVectorSet<Derived,1> col(Index j);
00436 const SparseInnerVectorSet<Derived,1> col(Index j) const;
00437 SparseInnerVectorSet<Derived,1> innerVector(Index outer);
00438 const SparseInnerVectorSet<Derived,1> innerVector(Index outer) const;
00439
00440
00441 SparseInnerVectorSet<Derived,Dynamic> subrows(Index start, Index size);
00442 const SparseInnerVectorSet<Derived,Dynamic> subrows(Index start, Index size) const;
00443 SparseInnerVectorSet<Derived,Dynamic> subcols(Index start, Index size);
00444 const SparseInnerVectorSet<Derived,Dynamic> subcols(Index start, Index size) const;
00445 SparseInnerVectorSet<Derived,Dynamic> innerVectors(Index outerStart, Index outerSize);
00446 const SparseInnerVectorSet<Derived,Dynamic> innerVectors(Index outerStart, Index outerSize) const;
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00517 template<typename DenseDerived>
00518 void evalTo(MatrixBase<DenseDerived>& dst) const
00519 {
00520 dst.setZero();
00521 for (Index j=0; j<outerSize(); ++j)
00522 for (typename Derived::InnerIterator i(derived(),j); i; ++i)
00523 dst.coeffRef(i.row(),i.col()) = i.value();
00524 }
00525
00526 Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> toDense() const
00527 {
00528 return derived();
00529 }
00530
00531 template<typename OtherDerived>
00532 bool isApprox(const SparseMatrixBase<OtherDerived>& other,
00533 RealScalar prec = NumTraits<Scalar>::dummy_precision()) const
00534 { return toDense().isApprox(other.toDense(),prec); }
00535
00536 template<typename OtherDerived>
00537 bool isApprox(const MatrixBase<OtherDerived>& other,
00538 RealScalar prec = NumTraits<Scalar>::dummy_precision()) const
00539 { return toDense().isApprox(other,prec); }
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00577 inline const typename internal::eval<Derived>::type eval() const
00578 { return typename internal::eval<Derived>::type(derived()); }
00579
00580
00581
00582
00583
00584
00585
00586
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607 Scalar sum() const;
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701 protected:
00702
00703 bool m_isRValue;
00704 };
00705
00706 #endif // EIGEN_SPARSEMATRIXBASE_H