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
00028 template<typename Derived> class SparseMatrixBase
00029 {
00030 public:
00031
00032 typedef typename ei_traits<Derived>::Scalar Scalar;
00033
00034
00035 enum {
00036
00037 RowsAtCompileTime = ei_traits<Derived>::RowsAtCompileTime,
00043 ColsAtCompileTime = ei_traits<Derived>::ColsAtCompileTime,
00050 SizeAtCompileTime = (ei_size_at_compile_time<ei_traits<Derived>::RowsAtCompileTime,
00051 ei_traits<Derived>::ColsAtCompileTime>::ret),
00056 MaxRowsAtCompileTime = RowsAtCompileTime,
00057 MaxColsAtCompileTime = ColsAtCompileTime,
00058
00059 MaxSizeAtCompileTime = (ei_size_at_compile_time<MaxRowsAtCompileTime,
00060 MaxColsAtCompileTime>::ret),
00061
00062 IsVectorAtCompileTime = RowsAtCompileTime == 1 || ColsAtCompileTime == 1,
00068 Flags = ei_traits<Derived>::Flags,
00073 CoeffReadCost = ei_traits<Derived>::CoeffReadCost,
00078 IsRowMajor = Flags&RowMajorBit ? 1 : 0
00079 };
00080
00082 typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex,
00083 const SparseCwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Derived>,
00084 const Derived&
00085 >::ret ConjugateReturnType;
00087 typedef CwiseUnaryOp<ei_scalar_real_op<Scalar>, Derived> RealReturnType;
00089 typedef CwiseUnaryOp<ei_scalar_imag_op<Scalar>, Derived> ImagReturnType;
00091 typedef SparseTranspose<typename ei_cleantype<ConjugateReturnType>::type>
00092 AdjointReturnType;
00093
00094 #ifndef EIGEN_PARSED_BY_DOXYGEN
00095
00101 typedef typename NumTraits<Scalar>::Real RealScalar;
00102
00104 typedef Matrix<Scalar,EIGEN_ENUM_MAX(RowsAtCompileTime,ColsAtCompileTime),
00105 EIGEN_ENUM_MAX(RowsAtCompileTime,ColsAtCompileTime)> SquareMatrixType;
00106
00107 inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
00108 inline Derived& derived() { return *static_cast<Derived*>(this); }
00109 inline Derived& const_cast_derived() const
00110 { return *static_cast<Derived*>(const_cast<SparseMatrixBase*>(this)); }
00111 #endif // not EIGEN_PARSED_BY_DOXYGEN
00112
00114 inline int rows() const { return derived().rows(); }
00116 inline int cols() const { return derived().cols(); }
00119 inline int size() const { return rows() * cols(); }
00122 inline int nonZeros() const { return derived().nonZeros(); }
00127 inline bool isVector() const { return rows()==1 || cols()==1; }
00130 int outerSize() const { return (int(Flags)&RowMajorBit) ? this->rows() : this->cols(); }
00133 int innerSize() const { return (int(Flags)&RowMajorBit) ? this->cols() : this->rows(); }
00134
00135 bool isRValue() const { return m_isRValue; }
00136 Derived& markAsRValue() { m_isRValue = true; return derived(); }
00137
00138 SparseMatrixBase() : m_isRValue(false) { }
00139
00140 inline Derived& operator=(const Derived& other)
00141 {
00142
00143
00144
00145
00146 this->operator=<Derived>(other);
00147 return derived();
00148 }
00149
00150
00151 template<typename OtherDerived>
00152 inline void assignGeneric(const OtherDerived& other)
00153 {
00154
00155
00156 ei_assert(( ((ei_traits<Derived>::SupportedAccessPatterns&OuterRandomAccessPattern)==OuterRandomAccessPattern) ||
00157 (!((Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit)))) &&
00158 "the transpose operation is supposed to be handled in SparseMatrix::operator=");
00159
00160 const int outerSize = other.outerSize();
00161
00162
00163 Derived temp(other.rows(), other.cols());
00164
00165 temp.startFill(std::max(this->rows(),this->cols())*2);
00166 for (int j=0; j<outerSize; ++j)
00167 {
00168 for (typename OtherDerived::InnerIterator it(other.derived(), j); it; ++it)
00169 {
00170 Scalar v = it.value();
00171 if (v!=Scalar(0))
00172 {
00173 if (OtherDerived::Flags & RowMajorBit) temp.fill(j,it.index()) = v;
00174 else temp.fill(it.index(),j) = v;
00175 }
00176 }
00177 }
00178 temp.endFill();
00179
00180 derived() = temp.markAsRValue();
00181 }
00182
00183
00184 template<typename OtherDerived>
00185 inline Derived& operator=(const SparseMatrixBase<OtherDerived>& other)
00186 {
00187
00188
00189 const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
00190
00191 const int outerSize = (int(OtherDerived::Flags) & RowMajorBit) ? other.rows() : other.cols();
00192 if ((!transpose) && other.isRValue())
00193 {
00194
00195 derived().resize(other.rows(), other.cols());
00196 derived().startFill(std::max(this->rows(),this->cols())*2);
00197 for (int j=0; j<outerSize; ++j)
00198 {
00199 for (typename OtherDerived::InnerIterator it(other.derived(), j); it; ++it)
00200 {
00201 Scalar v = it.value();
00202 if (v!=Scalar(0))
00203 {
00204 if (IsRowMajor) derived().fill(j,it.index()) = v;
00205 else derived().fill(it.index(),j) = v;
00206 }
00207 }
00208 }
00209 derived().endFill();
00210 }
00211 else
00212 {
00213 assignGeneric(other.derived());
00214 }
00215 return derived();
00216 }
00217
00218 template<typename Lhs, typename Rhs>
00219 inline Derived& operator=(const SparseProduct<Lhs,Rhs,SparseTimeSparseProduct>& product);
00220
00221 friend std::ostream & operator << (std::ostream & s, const SparseMatrixBase& m)
00222 {
00223 if (Flags&RowMajorBit)
00224 {
00225 for (int row=0; row<m.outerSize(); ++row)
00226 {
00227 int col = 0;
00228 for (typename Derived::InnerIterator it(m.derived(), row); it; ++it)
00229 {
00230 for ( ; col<it.index(); ++col)
00231 s << "0 ";
00232 s << it.value() << " ";
00233 ++col;
00234 }
00235 for ( ; col<m.cols(); ++col)
00236 s << "0 ";
00237 s << std::endl;
00238 }
00239 }
00240 else
00241 {
00242 if (m.cols() == 1) {
00243 int row = 0;
00244 for (typename Derived::InnerIterator it(m.derived(), 0); it; ++it)
00245 {
00246 for ( ; row<it.index(); ++row)
00247 s << "0" << std::endl;
00248 s << it.value() << std::endl;
00249 ++row;
00250 }
00251 for ( ; row<m.rows(); ++row)
00252 s << "0" << std::endl;
00253 }
00254 else
00255 {
00256 SparseMatrix<Scalar, RowMajorBit> trans = m.derived();
00257 s << trans;
00258 }
00259 }
00260 return s;
00261 }
00262
00263 const SparseCwiseUnaryOp<ei_scalar_opposite_op<typename ei_traits<Derived>::Scalar>,Derived> operator-() const;
00264
00265 template<typename OtherDerived>
00266 const SparseCwiseBinaryOp<ei_scalar_sum_op<typename ei_traits<Derived>::Scalar>, Derived, OtherDerived>
00267 operator+(const SparseMatrixBase<OtherDerived> &other) const;
00268
00269 template<typename OtherDerived>
00270 const SparseCwiseBinaryOp<ei_scalar_difference_op<typename ei_traits<Derived>::Scalar>, Derived, OtherDerived>
00271 operator-(const SparseMatrixBase<OtherDerived> &other) const;
00272
00273 template<typename OtherDerived>
00274 Derived& operator+=(const SparseMatrixBase<OtherDerived>& other);
00275 template<typename OtherDerived>
00276 Derived& operator-=(const SparseMatrixBase<OtherDerived>& other);
00277
00278
00279
00280
00281 Derived& operator*=(const Scalar& other);
00282 Derived& operator/=(const Scalar& other);
00283
00284 const SparseCwiseUnaryOp<ei_scalar_multiple_op<typename ei_traits<Derived>::Scalar>, Derived>
00285 operator*(const Scalar& scalar) const;
00286 const SparseCwiseUnaryOp<ei_scalar_quotient1_op<typename ei_traits<Derived>::Scalar>, Derived>
00287 operator/(const Scalar& scalar) const;
00288
00289 inline friend const SparseCwiseUnaryOp<ei_scalar_multiple_op<typename ei_traits<Derived>::Scalar>, Derived>
00290 operator*(const Scalar& scalar, const SparseMatrixBase& matrix)
00291 { return matrix*scalar; }
00292
00293
00294 template<typename OtherDerived>
00295 const typename SparseProductReturnType<Derived,OtherDerived>::Type
00296 operator*(const SparseMatrixBase<OtherDerived> &other) const;
00297
00298
00299 template<typename OtherDerived> friend
00300 const typename SparseProductReturnType<OtherDerived,Derived>::Type
00301 operator*(const MatrixBase<OtherDerived>& lhs, const Derived& rhs)
00302 { return typename SparseProductReturnType<OtherDerived,Derived>::Type(lhs.derived(),rhs); }
00303
00304 template<typename OtherDerived>
00305 const typename SparseProductReturnType<Derived,OtherDerived>::Type
00306 operator*(const MatrixBase<OtherDerived> &other) const;
00307
00308 template<typename OtherDerived>
00309 Derived& operator*=(const SparseMatrixBase<OtherDerived>& other);
00310
00311 template<typename OtherDerived>
00312 typename ei_plain_matrix_type_column_major<OtherDerived>::type
00313 solveTriangular(const MatrixBase<OtherDerived>& other) const;
00314
00315 template<typename OtherDerived>
00316 void solveTriangularInPlace(MatrixBase<OtherDerived>& other) const;
00317
00318 template<typename OtherDerived> Scalar dot(const MatrixBase<OtherDerived>& other) const;
00319 template<typename OtherDerived> Scalar dot(const SparseMatrixBase<OtherDerived>& other) const;
00320 RealScalar squaredNorm() const;
00321 RealScalar norm() const;
00322
00323
00324
00325 SparseTranspose<Derived> transpose() { return derived(); }
00326 const SparseTranspose<Derived> transpose() const { return derived(); }
00327
00328 const AdjointReturnType adjoint() const { return conjugate(); }
00329
00330
00331 SparseInnerVectorSet<Derived,1> row(int i);
00332 const SparseInnerVectorSet<Derived,1> row(int i) const;
00333 SparseInnerVectorSet<Derived,1> col(int j);
00334 const SparseInnerVectorSet<Derived,1> col(int j) const;
00335 SparseInnerVectorSet<Derived,1> innerVector(int outer);
00336 const SparseInnerVectorSet<Derived,1> innerVector(int outer) const;
00337
00338
00339 SparseInnerVectorSet<Derived,Dynamic> subrows(int start, int size);
00340 const SparseInnerVectorSet<Derived,Dynamic> subrows(int start, int size) const;
00341 SparseInnerVectorSet<Derived,Dynamic> subcols(int start, int size);
00342 const SparseInnerVectorSet<Derived,Dynamic> subcols(int start, int size) const;
00343 SparseInnerVectorSet<Derived,Dynamic> innerVectors(int outerStart, int outerSize);
00344 const SparseInnerVectorSet<Derived,Dynamic> innerVectors(int outerStart, int outerSize) const;
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422 Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> toDense() const
00423 {
00424 Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> res(rows(),cols());
00425 res.setZero();
00426 for (int j=0; j<outerSize(); ++j)
00427 {
00428 for (typename Derived::InnerIterator i(derived(),j); i; ++i)
00429 if(IsRowMajor)
00430 res.coeffRef(j,i.index()) = i.value();
00431 else
00432 res.coeffRef(i.index(),j) = i.value();
00433 }
00434 return res;
00435 }
00436
00437 template<typename OtherDerived>
00438 bool isApprox(const SparseMatrixBase<OtherDerived>& other,
00439 RealScalar prec = precision<Scalar>()) const
00440 { return toDense().isApprox(other.toDense(),prec); }
00441
00442 template<typename OtherDerived>
00443 bool isApprox(const MatrixBase<OtherDerived>& other,
00444 RealScalar prec = precision<Scalar>()) const
00445 { return toDense().isApprox(other,prec); }
00446
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 template<typename NewType>
00476 const SparseCwiseUnaryOp<ei_scalar_cast_op<typename ei_traits<Derived>::Scalar, NewType>, Derived> cast() const;
00477
00483 EIGEN_STRONG_INLINE const typename ei_eval<Derived>::type eval() const
00484 { return typename ei_eval<Derived>::type(derived()); }
00485
00486
00487
00488
00489 template<unsigned int Added>
00490 const SparseFlagged<Derived, Added, 0> marked() const;
00491
00492
00498
00499
00500
00501
00502
00503 ConjugateReturnType conjugate() const;
00504 const RealReturnType real() const;
00505 const ImagReturnType imag() const;
00506
00507 template<typename CustomUnaryOp>
00508 const SparseCwiseUnaryOp<CustomUnaryOp, Derived> unaryExpr(const CustomUnaryOp& func = CustomUnaryOp()) const;
00509
00510
00511
00512
00513
00514
00515 Scalar sum() const;
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532 const SparseCwise<Derived> cwise() const;
00533 SparseCwise<Derived> cwise();
00534
00535
00536
00538
00539
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
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609 #ifdef EIGEN_TAUCS_SUPPORT
00610 taucs_ccs_matrix asTaucsMatrix();
00611 #endif
00612
00613 #ifdef EIGEN_CHOLMOD_SUPPORT
00614 cholmod_sparse asCholmodMatrix();
00615 #endif
00616
00617 #ifdef EIGEN_SUPERLU_SUPPORT
00618 SluMatrix asSluMatrix();
00619 #endif
00620
00621 protected:
00622
00623 bool m_isRValue;
00624 };
00625
00626 #endif // EIGEN_SPARSEMATRIXBASE_H