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_SKYLINEMATRIX_H
00026 #define EIGEN_SKYLINEMATRIX_H
00027
00028 #include "SkylineStorage.h"
00029 #include "SkylineMatrixBase.h"
00030
00046 namespace internal {
00047 template<typename _Scalar, int _Options>
00048 struct traits<SkylineMatrix<_Scalar, _Options> > {
00049 typedef _Scalar Scalar;
00050 typedef Sparse StorageKind;
00051
00052 enum {
00053 RowsAtCompileTime = Dynamic,
00054 ColsAtCompileTime = Dynamic,
00055 MaxRowsAtCompileTime = Dynamic,
00056 MaxColsAtCompileTime = Dynamic,
00057 Flags = SkylineBit | _Options,
00058 CoeffReadCost = NumTraits<Scalar>::ReadCost,
00059 };
00060 };
00061 }
00062
00063 template<typename _Scalar, int _Options>
00064 class SkylineMatrix
00065 : public SkylineMatrixBase<SkylineMatrix<_Scalar, _Options> > {
00066 public:
00067 EIGEN_SKYLINE_GENERIC_PUBLIC_INTERFACE(SkylineMatrix)
00068 EIGEN_SKYLINE_INHERIT_ASSIGNMENT_OPERATOR(SkylineMatrix, +=)
00069 EIGEN_SKYLINE_INHERIT_ASSIGNMENT_OPERATOR(SkylineMatrix, -=)
00070
00071 using Base::IsRowMajor;
00072
00073 protected:
00074
00075 typedef SkylineMatrix<Scalar, (Flags&~RowMajorBit) | (IsRowMajor ? RowMajorBit : 0) > TransposedSkylineMatrix;
00076
00077 Index m_outerSize;
00078 Index m_innerSize;
00079
00080 public:
00081 Index* m_colStartIndex;
00082 Index* m_rowStartIndex;
00083 SkylineStorage<Scalar> m_data;
00084
00085 public:
00086
00087 inline Index rows() const {
00088 return IsRowMajor ? m_outerSize : m_innerSize;
00089 }
00090
00091 inline Index cols() const {
00092 return IsRowMajor ? m_innerSize : m_outerSize;
00093 }
00094
00095 inline Index innerSize() const {
00096 return m_innerSize;
00097 }
00098
00099 inline Index outerSize() const {
00100 return m_outerSize;
00101 }
00102
00103 inline Index upperNonZeros() const {
00104 return m_data.upperSize();
00105 }
00106
00107 inline Index lowerNonZeros() const {
00108 return m_data.lowerSize();
00109 }
00110
00111 inline Index upperNonZeros(Index j) const {
00112 return m_colStartIndex[j + 1] - m_colStartIndex[j];
00113 }
00114
00115 inline Index lowerNonZeros(Index j) const {
00116 return m_rowStartIndex[j + 1] - m_rowStartIndex[j];
00117 }
00118
00119 inline const Scalar* _diagPtr() const {
00120 return &m_data.diag(0);
00121 }
00122
00123 inline Scalar* _diagPtr() {
00124 return &m_data.diag(0);
00125 }
00126
00127 inline const Scalar* _upperPtr() const {
00128 return &m_data.upper(0);
00129 }
00130
00131 inline Scalar* _upperPtr() {
00132 return &m_data.upper(0);
00133 }
00134
00135 inline const Scalar* _lowerPtr() const {
00136 return &m_data.lower(0);
00137 }
00138
00139 inline Scalar* _lowerPtr() {
00140 return &m_data.lower(0);
00141 }
00142
00143 inline const Index* _upperProfilePtr() const {
00144 return &m_data.upperProfile(0);
00145 }
00146
00147 inline Index* _upperProfilePtr() {
00148 return &m_data.upperProfile(0);
00149 }
00150
00151 inline const Index* _lowerProfilePtr() const {
00152 return &m_data.lowerProfile(0);
00153 }
00154
00155 inline Index* _lowerProfilePtr() {
00156 return &m_data.lowerProfile(0);
00157 }
00158
00159 inline Scalar coeff(Index row, Index col) const {
00160 const Index outer = IsRowMajor ? row : col;
00161 const Index inner = IsRowMajor ? col : row;
00162
00163 eigen_assert(outer < outerSize());
00164 eigen_assert(inner < innerSize());
00165
00166 if (outer == inner)
00167 return this->m_data.diag(outer);
00168
00169 if (IsRowMajor) {
00170 if (inner > outer)
00171 {
00172 const Index minOuterIndex = inner - m_data.upperProfile(inner);
00173 if (outer >= minOuterIndex)
00174 return this->m_data.upper(m_colStartIndex[inner] + outer - (inner - m_data.upperProfile(inner)));
00175 else
00176 return Scalar(0);
00177 }
00178 if (inner < outer)
00179 {
00180 const Index minInnerIndex = outer - m_data.lowerProfile(outer);
00181 if (inner >= minInnerIndex)
00182 return this->m_data.lower(m_rowStartIndex[outer] + inner - (outer - m_data.lowerProfile(outer)));
00183 else
00184 return Scalar(0);
00185 }
00186 return m_data.upper(m_colStartIndex[inner] + outer - inner);
00187 } else {
00188 if (outer > inner)
00189 {
00190 const Index maxOuterIndex = inner + m_data.upperProfile(inner);
00191 if (outer <= maxOuterIndex)
00192 return this->m_data.upper(m_colStartIndex[inner] + (outer - inner));
00193 else
00194 return Scalar(0);
00195 }
00196 if (outer < inner)
00197 {
00198 const Index maxInnerIndex = outer + m_data.lowerProfile(outer);
00199
00200 if (inner <= maxInnerIndex)
00201 return this->m_data.lower(m_rowStartIndex[outer] + (inner - outer));
00202 else
00203 return Scalar(0);
00204 }
00205 }
00206 }
00207
00208 inline Scalar& coeffRef(Index row, Index col) {
00209 const Index outer = IsRowMajor ? row : col;
00210 const Index inner = IsRowMajor ? col : row;
00211
00212 eigen_assert(outer < outerSize());
00213 eigen_assert(inner < innerSize());
00214
00215 if (outer == inner)
00216 return this->m_data.diag(outer);
00217
00218 if (IsRowMajor) {
00219 if (col > row)
00220 {
00221 const Index minOuterIndex = inner - m_data.upperProfile(inner);
00222 eigen_assert(outer >= minOuterIndex && "you try to acces a coeff that do not exist in the storage");
00223 return this->m_data.upper(m_colStartIndex[inner] + outer - (inner - m_data.upperProfile(inner)));
00224 }
00225 if (col < row)
00226 {
00227 const Index minInnerIndex = outer - m_data.lowerProfile(outer);
00228 eigen_assert(inner >= minInnerIndex && "you try to acces a coeff that do not exist in the storage");
00229 return this->m_data.lower(m_rowStartIndex[outer] + inner - (outer - m_data.lowerProfile(outer)));
00230 }
00231 } else {
00232 if (outer > inner)
00233 {
00234 const Index maxOuterIndex = inner + m_data.upperProfile(inner);
00235 eigen_assert(outer <= maxOuterIndex && "you try to acces a coeff that do not exist in the storage");
00236 return this->m_data.upper(m_colStartIndex[inner] + (outer - inner));
00237 }
00238 if (outer < inner)
00239 {
00240 const Index maxInnerIndex = outer + m_data.lowerProfile(outer);
00241 eigen_assert(inner <= maxInnerIndex && "you try to acces a coeff that do not exist in the storage");
00242 return this->m_data.lower(m_rowStartIndex[outer] + (inner - outer));
00243 }
00244 }
00245 }
00246
00247 inline Scalar coeffDiag(Index idx) const {
00248 eigen_assert(idx < outerSize());
00249 eigen_assert(idx < innerSize());
00250 return this->m_data.diag(idx);
00251 }
00252
00253 inline Scalar coeffLower(Index row, Index col) const {
00254 const Index outer = IsRowMajor ? row : col;
00255 const Index inner = IsRowMajor ? col : row;
00256
00257 eigen_assert(outer < outerSize());
00258 eigen_assert(inner < innerSize());
00259 eigen_assert(inner != outer);
00260
00261 if (IsRowMajor) {
00262 const Index minInnerIndex = outer - m_data.lowerProfile(outer);
00263 if (inner >= minInnerIndex)
00264 return this->m_data.lower(m_rowStartIndex[outer] + inner - (outer - m_data.lowerProfile(outer)));
00265 else
00266 return Scalar(0);
00267
00268 } else {
00269 const Index maxInnerIndex = outer + m_data.lowerProfile(outer);
00270 if (inner <= maxInnerIndex)
00271 return this->m_data.lower(m_rowStartIndex[outer] + (inner - outer));
00272 else
00273 return Scalar(0);
00274 }
00275 }
00276
00277 inline Scalar coeffUpper(Index row, Index col) const {
00278 const Index outer = IsRowMajor ? row : col;
00279 const Index inner = IsRowMajor ? col : row;
00280
00281 eigen_assert(outer < outerSize());
00282 eigen_assert(inner < innerSize());
00283 eigen_assert(inner != outer);
00284
00285 if (IsRowMajor) {
00286 const Index minOuterIndex = inner - m_data.upperProfile(inner);
00287 if (outer >= minOuterIndex)
00288 return this->m_data.upper(m_colStartIndex[inner] + outer - (inner - m_data.upperProfile(inner)));
00289 else
00290 return Scalar(0);
00291 } else {
00292 const Index maxOuterIndex = inner + m_data.upperProfile(inner);
00293 if (outer <= maxOuterIndex)
00294 return this->m_data.upper(m_colStartIndex[inner] + (outer - inner));
00295 else
00296 return Scalar(0);
00297 }
00298 }
00299
00300 inline Scalar& coeffRefDiag(Index idx) {
00301 eigen_assert(idx < outerSize());
00302 eigen_assert(idx < innerSize());
00303 return this->m_data.diag(idx);
00304 }
00305
00306 inline Scalar& coeffRefLower(Index row, Index col) {
00307 const Index outer = IsRowMajor ? row : col;
00308 const Index inner = IsRowMajor ? col : row;
00309
00310 eigen_assert(outer < outerSize());
00311 eigen_assert(inner < innerSize());
00312 eigen_assert(inner != outer);
00313
00314 if (IsRowMajor) {
00315 const Index minInnerIndex = outer - m_data.lowerProfile(outer);
00316 eigen_assert(inner >= minInnerIndex && "you try to acces a coeff that do not exist in the storage");
00317 return this->m_data.lower(m_rowStartIndex[outer] + inner - (outer - m_data.lowerProfile(outer)));
00318 } else {
00319 const Index maxInnerIndex = outer + m_data.lowerProfile(outer);
00320 eigen_assert(inner <= maxInnerIndex && "you try to acces a coeff that do not exist in the storage");
00321 return this->m_data.lower(m_rowStartIndex[outer] + (inner - outer));
00322 }
00323 }
00324
00325 inline bool coeffExistLower(Index row, Index col) {
00326 const Index outer = IsRowMajor ? row : col;
00327 const Index inner = IsRowMajor ? col : row;
00328
00329 eigen_assert(outer < outerSize());
00330 eigen_assert(inner < innerSize());
00331 eigen_assert(inner != outer);
00332
00333 if (IsRowMajor) {
00334 const Index minInnerIndex = outer - m_data.lowerProfile(outer);
00335 return inner >= minInnerIndex;
00336 } else {
00337 const Index maxInnerIndex = outer + m_data.lowerProfile(outer);
00338 return inner <= maxInnerIndex;
00339 }
00340 }
00341
00342 inline Scalar& coeffRefUpper(Index row, Index col) {
00343 const Index outer = IsRowMajor ? row : col;
00344 const Index inner = IsRowMajor ? col : row;
00345
00346 eigen_assert(outer < outerSize());
00347 eigen_assert(inner < innerSize());
00348 eigen_assert(inner != outer);
00349
00350 if (IsRowMajor) {
00351 const Index minOuterIndex = inner - m_data.upperProfile(inner);
00352 eigen_assert(outer >= minOuterIndex && "you try to acces a coeff that do not exist in the storage");
00353 return this->m_data.upper(m_colStartIndex[inner] + outer - (inner - m_data.upperProfile(inner)));
00354 } else {
00355 const Index maxOuterIndex = inner + m_data.upperProfile(inner);
00356 eigen_assert(outer <= maxOuterIndex && "you try to acces a coeff that do not exist in the storage");
00357 return this->m_data.upper(m_colStartIndex[inner] + (outer - inner));
00358 }
00359 }
00360
00361 inline bool coeffExistUpper(Index row, Index col) {
00362 const Index outer = IsRowMajor ? row : col;
00363 const Index inner = IsRowMajor ? col : row;
00364
00365 eigen_assert(outer < outerSize());
00366 eigen_assert(inner < innerSize());
00367 eigen_assert(inner != outer);
00368
00369 if (IsRowMajor) {
00370 const Index minOuterIndex = inner - m_data.upperProfile(inner);
00371 return outer >= minOuterIndex;
00372 } else {
00373 const Index maxOuterIndex = inner + m_data.upperProfile(inner);
00374 return outer <= maxOuterIndex;
00375 }
00376 }
00377
00378
00379 protected:
00380
00381 public:
00382 class InnerUpperIterator;
00383 class InnerLowerIterator;
00384
00385 class OuterUpperIterator;
00386 class OuterLowerIterator;
00387
00389 inline void setZero() {
00390 m_data.clear();
00391 memset(m_colStartIndex, 0, (m_outerSize + 1) * sizeof (Index));
00392 memset(m_rowStartIndex, 0, (m_outerSize + 1) * sizeof (Index));
00393 }
00394
00396 inline Index nonZeros() const {
00397 return m_data.diagSize() + m_data.upperSize() + m_data.lowerSize();
00398 }
00399
00401 inline void reserve(Index reserveSize, Index reserveUpperSize, Index reserveLowerSize) {
00402 m_data.reserve(reserveSize, reserveUpperSize, reserveLowerSize);
00403 }
00404
00413 EIGEN_DONT_INLINE Scalar & insert(Index row, Index col) {
00414 const Index outer = IsRowMajor ? row : col;
00415 const Index inner = IsRowMajor ? col : row;
00416
00417 eigen_assert(outer < outerSize());
00418 eigen_assert(inner < innerSize());
00419
00420 if (outer == inner)
00421 return m_data.diag(col);
00422
00423 if (IsRowMajor) {
00424 if (outer < inner)
00425 {
00426 Index minOuterIndex = 0;
00427 minOuterIndex = inner - m_data.upperProfile(inner);
00428
00429 if (outer < minOuterIndex)
00430 {
00431 const Index previousProfile = m_data.upperProfile(inner);
00432
00433 m_data.upperProfile(inner) = inner - outer;
00434
00435
00436 const Index bandIncrement = m_data.upperProfile(inner) - previousProfile;
00437
00438 const Index stop = m_colStartIndex[cols()];
00439 const Index start = m_colStartIndex[inner];
00440
00441
00442 for (Index innerIdx = stop; innerIdx >= start; innerIdx--) {
00443 m_data.upper(innerIdx + bandIncrement) = m_data.upper(innerIdx);
00444 }
00445
00446 for (Index innerIdx = cols(); innerIdx > inner; innerIdx--) {
00447 m_colStartIndex[innerIdx] += bandIncrement;
00448 }
00449
00450
00451 memset(this->_upperPtr() + start, 0, (bandIncrement - 1) * sizeof (Scalar));
00452
00453 return m_data.upper(m_colStartIndex[inner]);
00454 } else {
00455 return m_data.upper(m_colStartIndex[inner] + outer - (inner - m_data.upperProfile(inner)));
00456 }
00457 }
00458
00459 if (outer > inner)
00460 {
00461 const Index minInnerIndex = outer - m_data.lowerProfile(outer);
00462 if (inner < minInnerIndex)
00463 {
00464 const Index previousProfile = m_data.lowerProfile(outer);
00465 m_data.lowerProfile(outer) = outer - inner;
00466
00467 const Index bandIncrement = m_data.lowerProfile(outer) - previousProfile;
00468
00469 const Index stop = m_rowStartIndex[rows()];
00470 const Index start = m_rowStartIndex[outer];
00471
00472
00473 for (Index innerIdx = stop; innerIdx >= start; innerIdx--) {
00474 m_data.lower(innerIdx + bandIncrement) = m_data.lower(innerIdx);
00475 }
00476
00477 for (Index innerIdx = rows(); innerIdx > outer; innerIdx--) {
00478 m_rowStartIndex[innerIdx] += bandIncrement;
00479 }
00480
00481
00482 memset(this->_lowerPtr() + start, 0, (bandIncrement - 1) * sizeof (Scalar));
00483 return m_data.lower(m_rowStartIndex[outer]);
00484 } else {
00485 return m_data.lower(m_rowStartIndex[outer] + inner - (outer - m_data.lowerProfile(outer)));
00486 }
00487 }
00488 } else {
00489 if (outer > inner)
00490 {
00491 const Index maxOuterIndex = inner + m_data.upperProfile(inner);
00492 if (outer > maxOuterIndex)
00493 {
00494 const Index previousProfile = m_data.upperProfile(inner);
00495 m_data.upperProfile(inner) = outer - inner;
00496
00497 const Index bandIncrement = m_data.upperProfile(inner) - previousProfile;
00498
00499 const Index stop = m_rowStartIndex[rows()];
00500 const Index start = m_rowStartIndex[inner + 1];
00501
00502 for (Index innerIdx = stop; innerIdx >= start; innerIdx--) {
00503 m_data.upper(innerIdx + bandIncrement) = m_data.upper(innerIdx);
00504 }
00505
00506 for (Index innerIdx = inner + 1; innerIdx < outerSize() + 1; innerIdx++) {
00507 m_rowStartIndex[innerIdx] += bandIncrement;
00508 }
00509 memset(this->_upperPtr() + m_rowStartIndex[inner] + previousProfile + 1, 0, (bandIncrement - 1) * sizeof (Scalar));
00510 return m_data.upper(m_rowStartIndex[inner] + m_data.upperProfile(inner));
00511 } else {
00512 return m_data.upper(m_rowStartIndex[inner] + (outer - inner));
00513 }
00514 }
00515
00516 if (outer < inner)
00517 {
00518 const Index maxInnerIndex = outer + m_data.lowerProfile(outer);
00519 if (inner > maxInnerIndex)
00520 {
00521 const Index previousProfile = m_data.lowerProfile(outer);
00522 m_data.lowerProfile(outer) = inner - outer;
00523
00524 const Index bandIncrement = m_data.lowerProfile(outer) - previousProfile;
00525
00526 const Index stop = m_colStartIndex[cols()];
00527 const Index start = m_colStartIndex[outer + 1];
00528
00529 for (Index innerIdx = stop; innerIdx >= start; innerIdx--) {
00530 m_data.lower(innerIdx + bandIncrement) = m_data.lower(innerIdx);
00531 }
00532
00533 for (Index innerIdx = outer + 1; innerIdx < outerSize() + 1; innerIdx++) {
00534 m_colStartIndex[innerIdx] += bandIncrement;
00535 }
00536 memset(this->_lowerPtr() + m_colStartIndex[outer] + previousProfile + 1, 0, (bandIncrement - 1) * sizeof (Scalar));
00537 return m_data.lower(m_colStartIndex[outer] + m_data.lowerProfile(outer));
00538 } else {
00539 return m_data.lower(m_colStartIndex[outer] + (inner - outer));
00540 }
00541 }
00542 }
00543 }
00544
00547 inline void finalize() {
00548 if (IsRowMajor) {
00549 if (rows() > cols())
00550 m_data.resize(cols(), cols(), rows(), m_colStartIndex[cols()] + 1, m_rowStartIndex[rows()] + 1);
00551 else
00552 m_data.resize(rows(), cols(), rows(), m_colStartIndex[cols()] + 1, m_rowStartIndex[rows()] + 1);
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 } else {
00583 if (rows() > cols())
00584 m_data.resize(cols(), rows(), cols(), m_rowStartIndex[cols()] + 1, m_colStartIndex[cols()] + 1);
00585 else
00586 m_data.resize(rows(), rows(), cols(), m_rowStartIndex[rows()] + 1, m_colStartIndex[rows()] + 1);
00587 }
00588 }
00589
00590 inline void squeeze() {
00591 finalize();
00592 m_data.squeeze();
00593 }
00594
00595 void prune(Scalar reference, RealScalar epsilon = dummy_precision<RealScalar > ()) {
00596
00597 }
00598
00602 void resize(size_t rows, size_t cols) {
00603 const Index diagSize = rows > cols ? cols : rows;
00604 m_innerSize = IsRowMajor ? cols : rows;
00605
00606 eigen_assert(rows == cols && "Skyline matrix must be square matrix");
00607
00608 if (diagSize % 2) {
00609 const Index k = (diagSize - 1) / 2;
00610
00611 m_data.resize(diagSize, IsRowMajor ? cols : rows, IsRowMajor ? rows : cols,
00612 2 * k * k + k + 1,
00613 2 * k * k + k + 1);
00614
00615 } else
00616 {
00617 const Index k = diagSize / 2;
00618 m_data.resize(diagSize, IsRowMajor ? cols : rows, IsRowMajor ? rows : cols,
00619 2 * k * k - k + 1,
00620 2 * k * k - k + 1);
00621 }
00622
00623 if (m_colStartIndex && m_rowStartIndex) {
00624 delete[] m_colStartIndex;
00625 delete[] m_rowStartIndex;
00626 }
00627 m_colStartIndex = new Index [cols + 1];
00628 m_rowStartIndex = new Index [rows + 1];
00629 m_outerSize = diagSize;
00630
00631 m_data.reset();
00632 m_data.clear();
00633
00634 m_outerSize = diagSize;
00635 memset(m_colStartIndex, 0, (cols + 1) * sizeof (Index));
00636 memset(m_rowStartIndex, 0, (rows + 1) * sizeof (Index));
00637 }
00638
00639 void resizeNonZeros(Index size) {
00640 m_data.resize(size);
00641 }
00642
00643 inline SkylineMatrix()
00644 : m_outerSize(-1), m_innerSize(0), m_colStartIndex(0), m_rowStartIndex(0) {
00645 resize(0, 0);
00646 }
00647
00648 inline SkylineMatrix(size_t rows, size_t cols)
00649 : m_outerSize(0), m_innerSize(0), m_colStartIndex(0), m_rowStartIndex(0) {
00650 resize(rows, cols);
00651 }
00652
00653 template<typename OtherDerived>
00654 inline SkylineMatrix(const SkylineMatrixBase<OtherDerived>& other)
00655 : m_outerSize(0), m_innerSize(0), m_colStartIndex(0), m_rowStartIndex(0) {
00656 *this = other.derived();
00657 }
00658
00659 inline SkylineMatrix(const SkylineMatrix & other)
00660 : Base(), m_outerSize(0), m_innerSize(0), m_colStartIndex(0), m_rowStartIndex(0) {
00661 *this = other.derived();
00662 }
00663
00664 inline void swap(SkylineMatrix & other) {
00665
00666 std::swap(m_colStartIndex, other.m_colStartIndex);
00667 std::swap(m_rowStartIndex, other.m_rowStartIndex);
00668 std::swap(m_innerSize, other.m_innerSize);
00669 std::swap(m_outerSize, other.m_outerSize);
00670 m_data.swap(other.m_data);
00671 }
00672
00673 inline SkylineMatrix & operator=(const SkylineMatrix & other) {
00674 std::cout << "SkylineMatrix& operator=(const SkylineMatrix& other)\n";
00675 if (other.isRValue()) {
00676 swap(other.const_cast_derived());
00677 } else {
00678 resize(other.rows(), other.cols());
00679 memcpy(m_colStartIndex, other.m_colStartIndex, (m_outerSize + 1) * sizeof (Index));
00680 memcpy(m_rowStartIndex, other.m_rowStartIndex, (m_outerSize + 1) * sizeof (Index));
00681 m_data = other.m_data;
00682 }
00683 return *this;
00684 }
00685
00686 template<typename OtherDerived>
00687 inline SkylineMatrix & operator=(const SkylineMatrixBase<OtherDerived>& other) {
00688 const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
00689 if (needToTranspose) {
00690
00691
00692 } else {
00693
00694 return SkylineMatrixBase<SkylineMatrix>::operator=(other.derived());
00695 }
00696 }
00697
00698 friend std::ostream & operator <<(std::ostream & s, const SkylineMatrix & m) {
00699
00700 EIGEN_DBG_SKYLINE(
00701 std::cout << "upper elements : " << std::endl;
00702 for (Index i = 0; i < m.m_data.upperSize(); i++)
00703 std::cout << m.m_data.upper(i) << "\t";
00704 std::cout << std::endl;
00705 std::cout << "upper profile : " << std::endl;
00706 for (Index i = 0; i < m.m_data.upperProfileSize(); i++)
00707 std::cout << m.m_data.upperProfile(i) << "\t";
00708 std::cout << std::endl;
00709 std::cout << "lower startIdx : " << std::endl;
00710 for (Index i = 0; i < m.m_data.upperProfileSize(); i++)
00711 std::cout << (IsRowMajor ? m.m_colStartIndex[i] : m.m_rowStartIndex[i]) << "\t";
00712 std::cout << std::endl;
00713
00714
00715 std::cout << "lower elements : " << std::endl;
00716 for (Index i = 0; i < m.m_data.lowerSize(); i++)
00717 std::cout << m.m_data.lower(i) << "\t";
00718 std::cout << std::endl;
00719 std::cout << "lower profile : " << std::endl;
00720 for (Index i = 0; i < m.m_data.lowerProfileSize(); i++)
00721 std::cout << m.m_data.lowerProfile(i) << "\t";
00722 std::cout << std::endl;
00723 std::cout << "lower startIdx : " << std::endl;
00724 for (Index i = 0; i < m.m_data.lowerProfileSize(); i++)
00725 std::cout << (IsRowMajor ? m.m_rowStartIndex[i] : m.m_colStartIndex[i]) << "\t";
00726 std::cout << std::endl;
00727 );
00728 for (Index rowIdx = 0; rowIdx < m.rows(); rowIdx++) {
00729 for (Index colIdx = 0; colIdx < m.cols(); colIdx++) {
00730 s << m.coeff(rowIdx, colIdx) << "\t";
00731 }
00732 s << std::endl;
00733 }
00734 return s;
00735 }
00736
00738 inline ~SkylineMatrix() {
00739 delete[] m_colStartIndex;
00740 delete[] m_rowStartIndex;
00741 }
00742
00744 Scalar sum() const;
00745 };
00746
00747 template<typename Scalar, int _Options>
00748 class SkylineMatrix<Scalar, _Options>::InnerUpperIterator {
00749 public:
00750
00751 InnerUpperIterator(const SkylineMatrix& mat, Index outer)
00752 : m_matrix(mat), m_outer(outer),
00753 m_id(_Options == RowMajor ? mat.m_colStartIndex[outer] : mat.m_rowStartIndex[outer] + 1),
00754 m_start(m_id),
00755 m_end(_Options == RowMajor ? mat.m_colStartIndex[outer + 1] : mat.m_rowStartIndex[outer + 1] + 1) {
00756 }
00757
00758 inline InnerUpperIterator & operator++() {
00759 m_id++;
00760 return *this;
00761 }
00762
00763 inline InnerUpperIterator & operator+=(Index shift) {
00764 m_id += shift;
00765 return *this;
00766 }
00767
00768 inline Scalar value() const {
00769 return m_matrix.m_data.upper(m_id);
00770 }
00771
00772 inline Scalar* valuePtr() {
00773 return const_cast<Scalar*> (&(m_matrix.m_data.upper(m_id)));
00774 }
00775
00776 inline Scalar& valueRef() {
00777 return const_cast<Scalar&> (m_matrix.m_data.upper(m_id));
00778 }
00779
00780 inline Index index() const {
00781 return IsRowMajor ? m_outer - m_matrix.m_data.upperProfile(m_outer) + (m_id - m_start) :
00782 m_outer + (m_id - m_start) + 1;
00783 }
00784
00785 inline Index row() const {
00786 return IsRowMajor ? index() : m_outer;
00787 }
00788
00789 inline Index col() const {
00790 return IsRowMajor ? m_outer : index();
00791 }
00792
00793 inline size_t size() const {
00794 return m_matrix.m_data.upperProfile(m_outer);
00795 }
00796
00797 inline operator bool() const {
00798 return (m_id < m_end) && (m_id >= m_start);
00799 }
00800
00801 protected:
00802 const SkylineMatrix& m_matrix;
00803 const Index m_outer;
00804 Index m_id;
00805 const Index m_start;
00806 const Index m_end;
00807 };
00808
00809 template<typename Scalar, int _Options>
00810 class SkylineMatrix<Scalar, _Options>::InnerLowerIterator {
00811 public:
00812
00813 InnerLowerIterator(const SkylineMatrix& mat, Index outer)
00814 : m_matrix(mat),
00815 m_outer(outer),
00816 m_id(_Options == RowMajor ? mat.m_rowStartIndex[outer] : mat.m_colStartIndex[outer] + 1),
00817 m_start(m_id),
00818 m_end(_Options == RowMajor ? mat.m_rowStartIndex[outer + 1] : mat.m_colStartIndex[outer + 1] + 1) {
00819 }
00820
00821 inline InnerLowerIterator & operator++() {
00822 m_id++;
00823 return *this;
00824 }
00825
00826 inline InnerLowerIterator & operator+=(Index shift) {
00827 m_id += shift;
00828 return *this;
00829 }
00830
00831 inline Scalar value() const {
00832 return m_matrix.m_data.lower(m_id);
00833 }
00834
00835 inline Scalar* valuePtr() {
00836 return const_cast<Scalar*> (&(m_matrix.m_data.lower(m_id)));
00837 }
00838
00839 inline Scalar& valueRef() {
00840 return const_cast<Scalar&> (m_matrix.m_data.lower(m_id));
00841 }
00842
00843 inline Index index() const {
00844 return IsRowMajor ? m_outer - m_matrix.m_data.lowerProfile(m_outer) + (m_id - m_start) :
00845 m_outer + (m_id - m_start) + 1;
00846 ;
00847 }
00848
00849 inline Index row() const {
00850 return IsRowMajor ? m_outer : index();
00851 }
00852
00853 inline Index col() const {
00854 return IsRowMajor ? index() : m_outer;
00855 }
00856
00857 inline size_t size() const {
00858 return m_matrix.m_data.lowerProfile(m_outer);
00859 }
00860
00861 inline operator bool() const {
00862 return (m_id < m_end) && (m_id >= m_start);
00863 }
00864
00865 protected:
00866 const SkylineMatrix& m_matrix;
00867 const Index m_outer;
00868 Index m_id;
00869 const Index m_start;
00870 const Index m_end;
00871 };
00872
00873 #endif // EIGEN_SkylineMatrix_H