10 #ifndef EIGEN_SKYLINEMATRIX_H 11 #define EIGEN_SKYLINEMATRIX_H 13 #include "SkylineStorage.h" 14 #include "SkylineMatrixBase.h" 34 template<
typename _Scalar,
int _Options>
36 typedef _Scalar Scalar;
44 Flags = SkylineBit | _Options,
50 template<
typename _Scalar,
int _Options>
58 using Base::IsRowMajor;
68 Index* m_colStartIndex;
69 Index* m_rowStartIndex;
74 inline Index rows()
const {
75 return IsRowMajor ? m_outerSize : m_innerSize;
78 inline Index cols()
const {
79 return IsRowMajor ? m_innerSize : m_outerSize;
82 inline Index innerSize()
const {
86 inline Index outerSize()
const {
90 inline Index upperNonZeros()
const {
91 return m_data.upperSize();
94 inline Index lowerNonZeros()
const {
95 return m_data.lowerSize();
99 return m_colStartIndex[j + 1] - m_colStartIndex[j];
103 return m_rowStartIndex[j + 1] - m_rowStartIndex[j];
106 inline const Scalar* _diagPtr()
const {
107 return &m_data.diag(0);
110 inline Scalar* _diagPtr() {
111 return &m_data.diag(0);
114 inline const Scalar* _upperPtr()
const {
115 return &m_data.upper(0);
118 inline Scalar* _upperPtr() {
119 return &m_data.upper(0);
122 inline const Scalar* _lowerPtr()
const {
123 return &m_data.lower(0);
126 inline Scalar* _lowerPtr() {
127 return &m_data.lower(0);
130 inline const Index* _upperProfilePtr()
const {
131 return &m_data.upperProfile(0);
134 inline Index* _upperProfilePtr() {
135 return &m_data.upperProfile(0);
138 inline const Index* _lowerProfilePtr()
const {
139 return &m_data.lowerProfile(0);
142 inline Index* _lowerProfilePtr() {
143 return &m_data.lowerProfile(0);
146 inline Scalar coeff(
Index row,
Index col)
const {
147 const Index outer = IsRowMajor ? row : col;
148 const Index inner = IsRowMajor ? col : row;
150 eigen_assert(outer < outerSize());
151 eigen_assert(inner < innerSize());
154 return this->m_data.diag(outer);
159 const Index minOuterIndex = inner - m_data.upperProfile(inner);
160 if (outer >= minOuterIndex)
161 return this->m_data.upper(m_colStartIndex[inner] + outer - (inner - m_data.upperProfile(inner)));
167 const Index minInnerIndex = outer - m_data.lowerProfile(outer);
168 if (inner >= minInnerIndex)
169 return this->m_data.lower(m_rowStartIndex[outer] + inner - (outer - m_data.lowerProfile(outer)));
173 return m_data.upper(m_colStartIndex[inner] + outer - inner);
177 const Index maxOuterIndex = inner + m_data.upperProfile(inner);
178 if (outer <= maxOuterIndex)
179 return this->m_data.upper(m_colStartIndex[inner] + (outer - inner));
185 const Index maxInnerIndex = outer + m_data.lowerProfile(outer);
187 if (inner <= maxInnerIndex)
188 return this->m_data.lower(m_rowStartIndex[outer] + (inner - outer));
195 inline Scalar& coeffRef(
Index row,
Index col) {
196 const Index outer = IsRowMajor ? row : col;
197 const Index inner = IsRowMajor ? col : row;
199 eigen_assert(outer < outerSize());
200 eigen_assert(inner < innerSize());
203 return this->m_data.diag(outer);
208 const Index minOuterIndex = inner - m_data.upperProfile(inner);
209 eigen_assert(outer >= minOuterIndex &&
"you try to acces a coeff that do not exist in the storage");
210 return this->m_data.upper(m_colStartIndex[inner] + outer - (inner - m_data.upperProfile(inner)));
214 const Index minInnerIndex = outer - m_data.lowerProfile(outer);
215 eigen_assert(inner >= minInnerIndex &&
"you try to acces a coeff that do not exist in the storage");
216 return this->m_data.lower(m_rowStartIndex[outer] + inner - (outer - m_data.lowerProfile(outer)));
221 const Index maxOuterIndex = inner + m_data.upperProfile(inner);
222 eigen_assert(outer <= maxOuterIndex &&
"you try to acces a coeff that do not exist in the storage");
223 return this->m_data.upper(m_colStartIndex[inner] + (outer - inner));
227 const Index maxInnerIndex = outer + m_data.lowerProfile(outer);
228 eigen_assert(inner <= maxInnerIndex &&
"you try to acces a coeff that do not exist in the storage");
229 return this->m_data.lower(m_rowStartIndex[outer] + (inner - outer));
234 inline Scalar coeffDiag(
Index idx)
const {
235 eigen_assert(idx < outerSize());
236 eigen_assert(idx < innerSize());
237 return this->m_data.diag(idx);
240 inline Scalar coeffLower(
Index row,
Index col)
const {
241 const Index outer = IsRowMajor ? row : col;
242 const Index inner = IsRowMajor ? col : row;
244 eigen_assert(outer < outerSize());
245 eigen_assert(inner < innerSize());
246 eigen_assert(inner != outer);
249 const Index minInnerIndex = outer - m_data.lowerProfile(outer);
250 if (inner >= minInnerIndex)
251 return this->m_data.lower(m_rowStartIndex[outer] + inner - (outer - m_data.lowerProfile(outer)));
256 const Index maxInnerIndex = outer + m_data.lowerProfile(outer);
257 if (inner <= maxInnerIndex)
258 return this->m_data.lower(m_rowStartIndex[outer] + (inner - outer));
264 inline Scalar coeffUpper(
Index row,
Index col)
const {
265 const Index outer = IsRowMajor ? row : col;
266 const Index inner = IsRowMajor ? col : row;
268 eigen_assert(outer < outerSize());
269 eigen_assert(inner < innerSize());
270 eigen_assert(inner != outer);
273 const Index minOuterIndex = inner - m_data.upperProfile(inner);
274 if (outer >= minOuterIndex)
275 return this->m_data.upper(m_colStartIndex[inner] + outer - (inner - m_data.upperProfile(inner)));
279 const Index maxOuterIndex = inner + m_data.upperProfile(inner);
280 if (outer <= maxOuterIndex)
281 return this->m_data.upper(m_colStartIndex[inner] + (outer - inner));
287 inline Scalar& coeffRefDiag(
Index idx) {
288 eigen_assert(idx < outerSize());
289 eigen_assert(idx < innerSize());
290 return this->m_data.diag(idx);
293 inline Scalar& coeffRefLower(
Index row,
Index col) {
294 const Index outer = IsRowMajor ? row : col;
295 const Index inner = IsRowMajor ? col : row;
297 eigen_assert(outer < outerSize());
298 eigen_assert(inner < innerSize());
299 eigen_assert(inner != outer);
302 const Index minInnerIndex = outer - m_data.lowerProfile(outer);
303 eigen_assert(inner >= minInnerIndex &&
"you try to acces a coeff that do not exist in the storage");
304 return this->m_data.lower(m_rowStartIndex[outer] + inner - (outer - m_data.lowerProfile(outer)));
306 const Index maxInnerIndex = outer + m_data.lowerProfile(outer);
307 eigen_assert(inner <= maxInnerIndex &&
"you try to acces a coeff that do not exist in the storage");
308 return this->m_data.lower(m_rowStartIndex[outer] + (inner - outer));
312 inline bool coeffExistLower(
Index row,
Index col) {
313 const Index outer = IsRowMajor ? row : col;
314 const Index inner = IsRowMajor ? col : row;
316 eigen_assert(outer < outerSize());
317 eigen_assert(inner < innerSize());
318 eigen_assert(inner != outer);
321 const Index minInnerIndex = outer - m_data.lowerProfile(outer);
322 return inner >= minInnerIndex;
324 const Index maxInnerIndex = outer + m_data.lowerProfile(outer);
325 return inner <= maxInnerIndex;
329 inline Scalar& coeffRefUpper(
Index row,
Index col) {
330 const Index outer = IsRowMajor ? row : col;
331 const Index inner = IsRowMajor ? col : row;
333 eigen_assert(outer < outerSize());
334 eigen_assert(inner < innerSize());
335 eigen_assert(inner != outer);
338 const Index minOuterIndex = inner - m_data.upperProfile(inner);
339 eigen_assert(outer >= minOuterIndex &&
"you try to acces a coeff that do not exist in the storage");
340 return this->m_data.upper(m_colStartIndex[inner] + outer - (inner - m_data.upperProfile(inner)));
342 const Index maxOuterIndex = inner + m_data.upperProfile(inner);
343 eigen_assert(outer <= maxOuterIndex &&
"you try to acces a coeff that do not exist in the storage");
344 return this->m_data.upper(m_colStartIndex[inner] + (outer - inner));
348 inline bool coeffExistUpper(
Index row,
Index col) {
349 const Index outer = IsRowMajor ? row : col;
350 const Index inner = IsRowMajor ? col : row;
352 eigen_assert(outer < outerSize());
353 eigen_assert(inner < innerSize());
354 eigen_assert(inner != outer);
357 const Index minOuterIndex = inner - m_data.upperProfile(inner);
358 return outer >= minOuterIndex;
360 const Index maxOuterIndex = inner + m_data.upperProfile(inner);
361 return outer <= maxOuterIndex;
372 class OuterUpperIterator;
373 class OuterLowerIterator;
378 memset(m_colStartIndex, 0, (m_outerSize + 1) *
sizeof (
Index));
379 memset(m_rowStartIndex, 0, (m_outerSize + 1) *
sizeof (
Index));
384 return m_data.diagSize() + m_data.upperSize() + m_data.lowerSize();
389 m_data.reserve(reserveSize, reserveUpperSize, reserveLowerSize);
401 const Index outer = IsRowMajor ? row : col;
402 const Index inner = IsRowMajor ? col : row;
404 eigen_assert(outer < outerSize());
405 eigen_assert(inner < innerSize());
408 return m_data.diag(col);
413 Index minOuterIndex = 0;
414 minOuterIndex = inner - m_data.upperProfile(inner);
416 if (outer < minOuterIndex)
418 const Index previousProfile = m_data.upperProfile(inner);
420 m_data.upperProfile(inner) = inner - outer;
423 const Index bandIncrement = m_data.upperProfile(inner) - previousProfile;
425 const Index stop = m_colStartIndex[cols()];
426 const Index start = m_colStartIndex[inner];
429 for (
Index innerIdx = stop; innerIdx >= start; innerIdx--) {
430 m_data.upper(innerIdx + bandIncrement) = m_data.upper(innerIdx);
433 for (
Index innerIdx = cols(); innerIdx > inner; innerIdx--) {
434 m_colStartIndex[innerIdx] += bandIncrement;
438 memset(this->_upperPtr() + start, 0, (bandIncrement - 1) *
sizeof (Scalar));
440 return m_data.upper(m_colStartIndex[inner]);
442 return m_data.upper(m_colStartIndex[inner] + outer - (inner - m_data.upperProfile(inner)));
448 const Index minInnerIndex = outer - m_data.lowerProfile(outer);
449 if (inner < minInnerIndex)
451 const Index previousProfile = m_data.lowerProfile(outer);
452 m_data.lowerProfile(outer) = outer - inner;
454 const Index bandIncrement = m_data.lowerProfile(outer) - previousProfile;
456 const Index stop = m_rowStartIndex[rows()];
457 const Index start = m_rowStartIndex[outer];
460 for (
Index innerIdx = stop; innerIdx >= start; innerIdx--) {
461 m_data.lower(innerIdx + bandIncrement) = m_data.lower(innerIdx);
464 for (
Index innerIdx = rows(); innerIdx > outer; innerIdx--) {
465 m_rowStartIndex[innerIdx] += bandIncrement;
469 memset(this->_lowerPtr() + start, 0, (bandIncrement - 1) *
sizeof (Scalar));
470 return m_data.lower(m_rowStartIndex[outer]);
472 return m_data.lower(m_rowStartIndex[outer] + inner - (outer - m_data.lowerProfile(outer)));
478 const Index maxOuterIndex = inner + m_data.upperProfile(inner);
479 if (outer > maxOuterIndex)
481 const Index previousProfile = m_data.upperProfile(inner);
482 m_data.upperProfile(inner) = outer - inner;
484 const Index bandIncrement = m_data.upperProfile(inner) - previousProfile;
486 const Index stop = m_rowStartIndex[rows()];
487 const Index start = m_rowStartIndex[inner + 1];
489 for (
Index innerIdx = stop; innerIdx >= start; innerIdx--) {
490 m_data.upper(innerIdx + bandIncrement) = m_data.upper(innerIdx);
493 for (
Index innerIdx = inner + 1; innerIdx < outerSize() + 1; innerIdx++) {
494 m_rowStartIndex[innerIdx] += bandIncrement;
496 memset(this->_upperPtr() + m_rowStartIndex[inner] + previousProfile + 1, 0, (bandIncrement - 1) *
sizeof (Scalar));
497 return m_data.upper(m_rowStartIndex[inner] + m_data.upperProfile(inner));
499 return m_data.upper(m_rowStartIndex[inner] + (outer - inner));
505 const Index maxInnerIndex = outer + m_data.lowerProfile(outer);
506 if (inner > maxInnerIndex)
508 const Index previousProfile = m_data.lowerProfile(outer);
509 m_data.lowerProfile(outer) = inner - outer;
511 const Index bandIncrement = m_data.lowerProfile(outer) - previousProfile;
513 const Index stop = m_colStartIndex[cols()];
514 const Index start = m_colStartIndex[outer + 1];
516 for (
Index innerIdx = stop; innerIdx >= start; innerIdx--) {
517 m_data.lower(innerIdx + bandIncrement) = m_data.lower(innerIdx);
520 for (
Index innerIdx = outer + 1; innerIdx < outerSize() + 1; innerIdx++) {
521 m_colStartIndex[innerIdx] += bandIncrement;
523 memset(this->_lowerPtr() + m_colStartIndex[outer] + previousProfile + 1, 0, (bandIncrement - 1) *
sizeof (Scalar));
524 return m_data.lower(m_colStartIndex[outer] + m_data.lowerProfile(outer));
526 return m_data.lower(m_colStartIndex[outer] + (inner - outer));
537 m_data.resize(cols(), cols(), rows(), m_colStartIndex[cols()] + 1, m_rowStartIndex[rows()] + 1);
539 m_data.resize(rows(), cols(), rows(), m_colStartIndex[cols()] + 1, m_rowStartIndex[rows()] + 1);
571 m_data.resize(cols(), rows(), cols(), m_rowStartIndex[cols()] + 1, m_colStartIndex[cols()] + 1);
573 m_data.resize(rows(), rows(), cols(), m_rowStartIndex[rows()] + 1, m_colStartIndex[rows()] + 1);
577 inline void squeeze() {
582 void prune(Scalar reference,
RealScalar epsilon = dummy_precision<RealScalar > ()) {
590 const Index diagSize = rows > cols ? cols : rows;
591 m_innerSize = IsRowMajor ? cols : rows;
593 eigen_assert(rows == cols &&
"Skyline matrix must be square matrix");
596 const Index k = (diagSize - 1) / 2;
598 m_data.resize(diagSize, IsRowMajor ? cols : rows, IsRowMajor ? rows : cols,
604 const Index k = diagSize / 2;
605 m_data.resize(diagSize, IsRowMajor ? cols : rows, IsRowMajor ? rows : cols,
610 if (m_colStartIndex && m_rowStartIndex) {
611 delete[] m_colStartIndex;
612 delete[] m_rowStartIndex;
614 m_colStartIndex =
new Index [cols + 1];
615 m_rowStartIndex =
new Index [rows + 1];
616 m_outerSize = diagSize;
621 m_outerSize = diagSize;
622 memset(m_colStartIndex, 0, (cols + 1) *
sizeof (
Index));
623 memset(m_rowStartIndex, 0, (rows + 1) *
sizeof (
Index));
626 void resizeNonZeros(
Index size) {
631 : m_outerSize(-1), m_innerSize(0), m_colStartIndex(0), m_rowStartIndex(0) {
636 : m_outerSize(0), m_innerSize(0), m_colStartIndex(0), m_rowStartIndex(0) {
640 template<
typename OtherDerived>
642 : m_outerSize(0), m_innerSize(0), m_colStartIndex(0), m_rowStartIndex(0) {
643 *
this = other.derived();
647 : Base(), m_outerSize(0), m_innerSize(0), m_colStartIndex(0), m_rowStartIndex(0) {
648 *
this = other.derived();
653 std::swap(m_colStartIndex, other.m_colStartIndex);
654 std::swap(m_rowStartIndex, other.m_rowStartIndex);
655 std::swap(m_innerSize, other.m_innerSize);
656 std::swap(m_outerSize, other.m_outerSize);
657 m_data.swap(other.m_data);
661 std::cout <<
"SkylineMatrix& operator=(const SkylineMatrix& other)\n";
662 if (other.isRValue()) {
663 swap(other.const_cast_derived());
665 resize(other.rows(), other.cols());
666 memcpy(m_colStartIndex, other.m_colStartIndex, (m_outerSize + 1) * sizeof (
Index));
667 memcpy(m_rowStartIndex, other.m_rowStartIndex, (m_outerSize + 1) * sizeof (
Index));
668 m_data = other.m_data;
673 template<
typename OtherDerived>
676 if (needToTranspose) {
685 friend std::ostream & operator <<(std::ostream & s,
const SkylineMatrix & m) {
688 std::cout <<
"upper elements : " << std::endl;
689 for (
Index i = 0; i < m.m_data.upperSize(); i++)
690 std::cout << m.m_data.upper(i) <<
"\t";
691 std::cout << std::endl;
692 std::cout <<
"upper profile : " << std::endl;
693 for (
Index i = 0; i < m.m_data.upperProfileSize(); i++)
694 std::cout << m.m_data.upperProfile(i) <<
"\t";
695 std::cout << std::endl;
696 std::cout <<
"lower startIdx : " << std::endl;
697 for (
Index i = 0; i < m.m_data.upperProfileSize(); i++)
698 std::cout << (IsRowMajor ? m.m_colStartIndex[i] : m.m_rowStartIndex[i]) <<
"\t";
699 std::cout << std::endl;
702 std::cout <<
"lower elements : " << std::endl;
703 for (
Index i = 0; i < m.m_data.lowerSize(); i++)
704 std::cout << m.m_data.lower(i) <<
"\t";
705 std::cout << std::endl;
706 std::cout <<
"lower profile : " << std::endl;
707 for (
Index i = 0; i < m.m_data.lowerProfileSize(); i++)
708 std::cout << m.m_data.lowerProfile(i) <<
"\t";
709 std::cout << std::endl;
710 std::cout <<
"lower startIdx : " << std::endl;
711 for (
Index i = 0; i < m.m_data.lowerProfileSize(); i++)
712 std::cout << (IsRowMajor ? m.m_rowStartIndex[i] : m.m_colStartIndex[i]) <<
"\t";
713 std::cout << std::endl;
715 for (
Index rowIdx = 0; rowIdx < m.rows(); rowIdx++) {
716 for (
Index colIdx = 0; colIdx < m.cols(); colIdx++) {
717 s << m.coeff(rowIdx, colIdx) <<
"\t";
726 delete[] m_colStartIndex;
727 delete[] m_rowStartIndex;
734 template<
typename Scalar,
int _Options>
739 : m_matrix(mat), m_outer(outer),
740 m_id(_Options ==
RowMajor ? mat.m_colStartIndex[outer] : mat.m_rowStartIndex[outer] + 1),
742 m_end(_Options ==
RowMajor ? mat.m_colStartIndex[outer + 1] : mat.m_rowStartIndex[outer + 1] + 1) {
755 inline Scalar value()
const {
756 return m_matrix.m_data.upper(m_id);
759 inline Scalar* valuePtr() {
760 return const_cast<Scalar*
> (&(m_matrix.m_data.upper(m_id)));
763 inline Scalar& valueRef() {
764 return const_cast<Scalar&
> (m_matrix.m_data.upper(m_id));
767 inline Index index()
const {
768 return IsRowMajor ? m_outer - m_matrix.m_data.upperProfile(m_outer) + (m_id - m_start) :
769 m_outer + (m_id - m_start) + 1;
772 inline Index row()
const {
773 return IsRowMajor ? index() : m_outer;
776 inline Index col()
const {
777 return IsRowMajor ? m_outer : index();
780 inline size_t size()
const {
781 return m_matrix.m_data.upperProfile(m_outer);
784 inline operator bool()
const {
785 return (m_id < m_end) && (m_id >= m_start);
796 template<
typename Scalar,
int _Options>
803 m_id(_Options ==
RowMajor ? mat.m_rowStartIndex[outer] : mat.m_colStartIndex[outer] + 1),
805 m_end(_Options ==
RowMajor ? mat.m_rowStartIndex[outer + 1] : mat.m_colStartIndex[outer + 1] + 1) {
818 inline Scalar value()
const {
819 return m_matrix.m_data.lower(m_id);
822 inline Scalar* valuePtr() {
823 return const_cast<Scalar*
> (&(m_matrix.m_data.lower(m_id)));
826 inline Scalar& valueRef() {
827 return const_cast<Scalar&
> (m_matrix.m_data.lower(m_id));
830 inline Index index()
const {
831 return IsRowMajor ? m_outer - m_matrix.m_data.lowerProfile(m_outer) + (m_id - m_start) :
832 m_outer + (m_id - m_start) + 1;
836 inline Index row()
const {
837 return IsRowMajor ? m_outer : index();
840 inline Index col()
const {
841 return IsRowMajor ? index() : m_outer;
844 inline size_t size()
const {
845 return m_matrix.m_data.lowerProfile(m_outer);
848 inline operator bool()
const {
849 return (m_id < m_end) && (m_id >= m_start);
862 #endif // EIGEN_SkylineMatrix_H Stores a skyline set of values in three structures : The diagonal elements The upper elements The low...
Definition: SkylineStorage.h:22
void setZero()
Removes all non zeros.
Definition: SkylineMatrix.h:376
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:85
Index nonZeros() const
Definition: SkylineMatrix.h:383
Holds information about the various numeric (i.e.
Definition: NumTraits.h:150
void resize(size_t rows, size_t cols)
Resizes the matrix to a rows x cols matrix and initializes it to zero.
Definition: SkylineMatrix.h:589
Eigen::Index Index
The interface type of indices.
Definition: EigenBase.h:37
const unsigned int RowMajorBit
for a matrix, this means that the storage order is row-major.
Definition: Constants.h:61
void reserve(Index reserveSize, Index reserveUpperSize, Index reserveLowerSize)
Preallocates reserveSize non zeros.
Definition: SkylineMatrix.h:388
EIGEN_DONT_INLINE Scalar & insert(Index row, Index col)
Definition: SkylineMatrix.h:400
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:33
The type used to identify a general sparse storage.
Definition: Constants.h:494
void finalize()
Must be called after inserting a set of non zero entries.
Definition: SkylineMatrix.h:534
Definition: BandTriangularSolver.h:13
Storage order is row major (see TopicStorageOrders).
Definition: Constants.h:322
Base class of any skyline matrices or skyline expressions.
Definition: SkylineMatrixBase.h:26
The main skyline matrix class.
Definition: SkylineMatrix.h:51
Definition: SkylineMatrix.h:735
const int Dynamic
This value means that a positive quantity (e.g., a size) is not known at compile-time, and that instead the value is stored in some runtime variable.
Definition: Constants.h:21
~SkylineMatrix()
Destructor.
Definition: SkylineMatrix.h:725
NumTraits< Scalar >::Real RealScalar
This is the "real scalar" type; if the Scalar type is already real numbers (e.g.
Definition: SkylineMatrixBase.h:85
Definition: ForwardDeclarations.h:17
Definition: SkylineMatrix.h:797