/external/eigen/unsupported/Eigen/src/Skyline/SkylineMatrix.h

https://bitbucket.org/rlyspn/androidrr · C Header · 862 lines · 635 code · 147 blank · 80 comment · 103 complexity · 2efac347bce0237002d9eafe921ad2de MD5 · raw file

  1. // This file is part of Eigen, a lightweight C++ template library
  2. // for linear algebra.
  3. //
  4. // Copyright (C) 2008-2009 Guillaume Saupin <guillaume.saupin@cea.fr>
  5. //
  6. // This Source Code Form is subject to the terms of the Mozilla
  7. // Public License v. 2.0. If a copy of the MPL was not distributed
  8. // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
  9. #ifndef EIGEN_SKYLINEMATRIX_H
  10. #define EIGEN_SKYLINEMATRIX_H
  11. #include "SkylineStorage.h"
  12. #include "SkylineMatrixBase.h"
  13. namespace Eigen {
  14. /** \ingroup Skyline_Module
  15. *
  16. * \class SkylineMatrix
  17. *
  18. * \brief The main skyline matrix class
  19. *
  20. * This class implements a skyline matrix using the very uncommon storage
  21. * scheme.
  22. *
  23. * \param _Scalar the scalar type, i.e. the type of the coefficients
  24. * \param _Options Union of bit flags controlling the storage scheme. Currently the only possibility
  25. * is RowMajor. The default is 0 which means column-major.
  26. *
  27. *
  28. */
  29. namespace internal {
  30. template<typename _Scalar, int _Options>
  31. struct traits<SkylineMatrix<_Scalar, _Options> > {
  32. typedef _Scalar Scalar;
  33. typedef Sparse StorageKind;
  34. enum {
  35. RowsAtCompileTime = Dynamic,
  36. ColsAtCompileTime = Dynamic,
  37. MaxRowsAtCompileTime = Dynamic,
  38. MaxColsAtCompileTime = Dynamic,
  39. Flags = SkylineBit | _Options,
  40. CoeffReadCost = NumTraits<Scalar>::ReadCost,
  41. };
  42. };
  43. }
  44. template<typename _Scalar, int _Options>
  45. class SkylineMatrix
  46. : public SkylineMatrixBase<SkylineMatrix<_Scalar, _Options> > {
  47. public:
  48. EIGEN_SKYLINE_GENERIC_PUBLIC_INTERFACE(SkylineMatrix)
  49. EIGEN_SKYLINE_INHERIT_ASSIGNMENT_OPERATOR(SkylineMatrix, +=)
  50. EIGEN_SKYLINE_INHERIT_ASSIGNMENT_OPERATOR(SkylineMatrix, -=)
  51. using Base::IsRowMajor;
  52. protected:
  53. typedef SkylineMatrix<Scalar, (Flags&~RowMajorBit) | (IsRowMajor ? RowMajorBit : 0) > TransposedSkylineMatrix;
  54. Index m_outerSize;
  55. Index m_innerSize;
  56. public:
  57. Index* m_colStartIndex;
  58. Index* m_rowStartIndex;
  59. SkylineStorage<Scalar> m_data;
  60. public:
  61. inline Index rows() const {
  62. return IsRowMajor ? m_outerSize : m_innerSize;
  63. }
  64. inline Index cols() const {
  65. return IsRowMajor ? m_innerSize : m_outerSize;
  66. }
  67. inline Index innerSize() const {
  68. return m_innerSize;
  69. }
  70. inline Index outerSize() const {
  71. return m_outerSize;
  72. }
  73. inline Index upperNonZeros() const {
  74. return m_data.upperSize();
  75. }
  76. inline Index lowerNonZeros() const {
  77. return m_data.lowerSize();
  78. }
  79. inline Index upperNonZeros(Index j) const {
  80. return m_colStartIndex[j + 1] - m_colStartIndex[j];
  81. }
  82. inline Index lowerNonZeros(Index j) const {
  83. return m_rowStartIndex[j + 1] - m_rowStartIndex[j];
  84. }
  85. inline const Scalar* _diagPtr() const {
  86. return &m_data.diag(0);
  87. }
  88. inline Scalar* _diagPtr() {
  89. return &m_data.diag(0);
  90. }
  91. inline const Scalar* _upperPtr() const {
  92. return &m_data.upper(0);
  93. }
  94. inline Scalar* _upperPtr() {
  95. return &m_data.upper(0);
  96. }
  97. inline const Scalar* _lowerPtr() const {
  98. return &m_data.lower(0);
  99. }
  100. inline Scalar* _lowerPtr() {
  101. return &m_data.lower(0);
  102. }
  103. inline const Index* _upperProfilePtr() const {
  104. return &m_data.upperProfile(0);
  105. }
  106. inline Index* _upperProfilePtr() {
  107. return &m_data.upperProfile(0);
  108. }
  109. inline const Index* _lowerProfilePtr() const {
  110. return &m_data.lowerProfile(0);
  111. }
  112. inline Index* _lowerProfilePtr() {
  113. return &m_data.lowerProfile(0);
  114. }
  115. inline Scalar coeff(Index row, Index col) const {
  116. const Index outer = IsRowMajor ? row : col;
  117. const Index inner = IsRowMajor ? col : row;
  118. eigen_assert(outer < outerSize());
  119. eigen_assert(inner < innerSize());
  120. if (outer == inner)
  121. return this->m_data.diag(outer);
  122. if (IsRowMajor) {
  123. if (inner > outer) //upper matrix
  124. {
  125. const Index minOuterIndex = inner - m_data.upperProfile(inner);
  126. if (outer >= minOuterIndex)
  127. return this->m_data.upper(m_colStartIndex[inner] + outer - (inner - m_data.upperProfile(inner)));
  128. else
  129. return Scalar(0);
  130. }
  131. if (inner < outer) //lower matrix
  132. {
  133. const Index minInnerIndex = outer - m_data.lowerProfile(outer);
  134. if (inner >= minInnerIndex)
  135. return this->m_data.lower(m_rowStartIndex[outer] + inner - (outer - m_data.lowerProfile(outer)));
  136. else
  137. return Scalar(0);
  138. }
  139. return m_data.upper(m_colStartIndex[inner] + outer - inner);
  140. } else {
  141. if (outer > inner) //upper matrix
  142. {
  143. const Index maxOuterIndex = inner + m_data.upperProfile(inner);
  144. if (outer <= maxOuterIndex)
  145. return this->m_data.upper(m_colStartIndex[inner] + (outer - inner));
  146. else
  147. return Scalar(0);
  148. }
  149. if (outer < inner) //lower matrix
  150. {
  151. const Index maxInnerIndex = outer + m_data.lowerProfile(outer);
  152. if (inner <= maxInnerIndex)
  153. return this->m_data.lower(m_rowStartIndex[outer] + (inner - outer));
  154. else
  155. return Scalar(0);
  156. }
  157. }
  158. }
  159. inline Scalar& coeffRef(Index row, Index col) {
  160. const Index outer = IsRowMajor ? row : col;
  161. const Index inner = IsRowMajor ? col : row;
  162. eigen_assert(outer < outerSize());
  163. eigen_assert(inner < innerSize());
  164. if (outer == inner)
  165. return this->m_data.diag(outer);
  166. if (IsRowMajor) {
  167. if (col > row) //upper matrix
  168. {
  169. const Index minOuterIndex = inner - m_data.upperProfile(inner);
  170. eigen_assert(outer >= minOuterIndex && "you try to acces a coeff that do not exist in the storage");
  171. return this->m_data.upper(m_colStartIndex[inner] + outer - (inner - m_data.upperProfile(inner)));
  172. }
  173. if (col < row) //lower matrix
  174. {
  175. const Index minInnerIndex = outer - m_data.lowerProfile(outer);
  176. eigen_assert(inner >= minInnerIndex && "you try to acces a coeff that do not exist in the storage");
  177. return this->m_data.lower(m_rowStartIndex[outer] + inner - (outer - m_data.lowerProfile(outer)));
  178. }
  179. } else {
  180. if (outer > inner) //upper matrix
  181. {
  182. const Index maxOuterIndex = inner + m_data.upperProfile(inner);
  183. eigen_assert(outer <= maxOuterIndex && "you try to acces a coeff that do not exist in the storage");
  184. return this->m_data.upper(m_colStartIndex[inner] + (outer - inner));
  185. }
  186. if (outer < inner) //lower matrix
  187. {
  188. const Index maxInnerIndex = outer + m_data.lowerProfile(outer);
  189. eigen_assert(inner <= maxInnerIndex && "you try to acces a coeff that do not exist in the storage");
  190. return this->m_data.lower(m_rowStartIndex[outer] + (inner - outer));
  191. }
  192. }
  193. }
  194. inline Scalar coeffDiag(Index idx) const {
  195. eigen_assert(idx < outerSize());
  196. eigen_assert(idx < innerSize());
  197. return this->m_data.diag(idx);
  198. }
  199. inline Scalar coeffLower(Index row, Index col) const {
  200. const Index outer = IsRowMajor ? row : col;
  201. const Index inner = IsRowMajor ? col : row;
  202. eigen_assert(outer < outerSize());
  203. eigen_assert(inner < innerSize());
  204. eigen_assert(inner != outer);
  205. if (IsRowMajor) {
  206. const Index minInnerIndex = outer - m_data.lowerProfile(outer);
  207. if (inner >= minInnerIndex)
  208. return this->m_data.lower(m_rowStartIndex[outer] + inner - (outer - m_data.lowerProfile(outer)));
  209. else
  210. return Scalar(0);
  211. } else {
  212. const Index maxInnerIndex = outer + m_data.lowerProfile(outer);
  213. if (inner <= maxInnerIndex)
  214. return this->m_data.lower(m_rowStartIndex[outer] + (inner - outer));
  215. else
  216. return Scalar(0);
  217. }
  218. }
  219. inline Scalar coeffUpper(Index row, Index col) const {
  220. const Index outer = IsRowMajor ? row : col;
  221. const Index inner = IsRowMajor ? col : row;
  222. eigen_assert(outer < outerSize());
  223. eigen_assert(inner < innerSize());
  224. eigen_assert(inner != outer);
  225. if (IsRowMajor) {
  226. const Index minOuterIndex = inner - m_data.upperProfile(inner);
  227. if (outer >= minOuterIndex)
  228. return this->m_data.upper(m_colStartIndex[inner] + outer - (inner - m_data.upperProfile(inner)));
  229. else
  230. return Scalar(0);
  231. } else {
  232. const Index maxOuterIndex = inner + m_data.upperProfile(inner);
  233. if (outer <= maxOuterIndex)
  234. return this->m_data.upper(m_colStartIndex[inner] + (outer - inner));
  235. else
  236. return Scalar(0);
  237. }
  238. }
  239. inline Scalar& coeffRefDiag(Index idx) {
  240. eigen_assert(idx < outerSize());
  241. eigen_assert(idx < innerSize());
  242. return this->m_data.diag(idx);
  243. }
  244. inline Scalar& coeffRefLower(Index row, Index col) {
  245. const Index outer = IsRowMajor ? row : col;
  246. const Index inner = IsRowMajor ? col : row;
  247. eigen_assert(outer < outerSize());
  248. eigen_assert(inner < innerSize());
  249. eigen_assert(inner != outer);
  250. if (IsRowMajor) {
  251. const Index minInnerIndex = outer - m_data.lowerProfile(outer);
  252. eigen_assert(inner >= minInnerIndex && "you try to acces a coeff that do not exist in the storage");
  253. return this->m_data.lower(m_rowStartIndex[outer] + inner - (outer - m_data.lowerProfile(outer)));
  254. } else {
  255. const Index maxInnerIndex = outer + m_data.lowerProfile(outer);
  256. eigen_assert(inner <= maxInnerIndex && "you try to acces a coeff that do not exist in the storage");
  257. return this->m_data.lower(m_rowStartIndex[outer] + (inner - outer));
  258. }
  259. }
  260. inline bool coeffExistLower(Index row, Index col) {
  261. const Index outer = IsRowMajor ? row : col;
  262. const Index inner = IsRowMajor ? col : row;
  263. eigen_assert(outer < outerSize());
  264. eigen_assert(inner < innerSize());
  265. eigen_assert(inner != outer);
  266. if (IsRowMajor) {
  267. const Index minInnerIndex = outer - m_data.lowerProfile(outer);
  268. return inner >= minInnerIndex;
  269. } else {
  270. const Index maxInnerIndex = outer + m_data.lowerProfile(outer);
  271. return inner <= maxInnerIndex;
  272. }
  273. }
  274. inline Scalar& coeffRefUpper(Index row, Index col) {
  275. const Index outer = IsRowMajor ? row : col;
  276. const Index inner = IsRowMajor ? col : row;
  277. eigen_assert(outer < outerSize());
  278. eigen_assert(inner < innerSize());
  279. eigen_assert(inner != outer);
  280. if (IsRowMajor) {
  281. const Index minOuterIndex = inner - m_data.upperProfile(inner);
  282. eigen_assert(outer >= minOuterIndex && "you try to acces a coeff that do not exist in the storage");
  283. return this->m_data.upper(m_colStartIndex[inner] + outer - (inner - m_data.upperProfile(inner)));
  284. } else {
  285. const Index maxOuterIndex = inner + m_data.upperProfile(inner);
  286. eigen_assert(outer <= maxOuterIndex && "you try to acces a coeff that do not exist in the storage");
  287. return this->m_data.upper(m_colStartIndex[inner] + (outer - inner));
  288. }
  289. }
  290. inline bool coeffExistUpper(Index row, Index col) {
  291. const Index outer = IsRowMajor ? row : col;
  292. const Index inner = IsRowMajor ? col : row;
  293. eigen_assert(outer < outerSize());
  294. eigen_assert(inner < innerSize());
  295. eigen_assert(inner != outer);
  296. if (IsRowMajor) {
  297. const Index minOuterIndex = inner - m_data.upperProfile(inner);
  298. return outer >= minOuterIndex;
  299. } else {
  300. const Index maxOuterIndex = inner + m_data.upperProfile(inner);
  301. return outer <= maxOuterIndex;
  302. }
  303. }
  304. protected:
  305. public:
  306. class InnerUpperIterator;
  307. class InnerLowerIterator;
  308. class OuterUpperIterator;
  309. class OuterLowerIterator;
  310. /** Removes all non zeros */
  311. inline void setZero() {
  312. m_data.clear();
  313. memset(m_colStartIndex, 0, (m_outerSize + 1) * sizeof (Index));
  314. memset(m_rowStartIndex, 0, (m_outerSize + 1) * sizeof (Index));
  315. }
  316. /** \returns the number of non zero coefficients */
  317. inline Index nonZeros() const {
  318. return m_data.diagSize() + m_data.upperSize() + m_data.lowerSize();
  319. }
  320. /** Preallocates \a reserveSize non zeros */
  321. inline void reserve(Index reserveSize, Index reserveUpperSize, Index reserveLowerSize) {
  322. m_data.reserve(reserveSize, reserveUpperSize, reserveLowerSize);
  323. }
  324. /** \returns a reference to a novel non zero coefficient with coordinates \a row x \a col.
  325. *
  326. * \warning This function can be extremely slow if the non zero coefficients
  327. * are not inserted in a coherent order.
  328. *
  329. * After an insertion session, you should call the finalize() function.
  330. */
  331. EIGEN_DONT_INLINE Scalar & insert(Index row, Index col) {
  332. const Index outer = IsRowMajor ? row : col;
  333. const Index inner = IsRowMajor ? col : row;
  334. eigen_assert(outer < outerSize());
  335. eigen_assert(inner < innerSize());
  336. if (outer == inner)
  337. return m_data.diag(col);
  338. if (IsRowMajor) {
  339. if (outer < inner) //upper matrix
  340. {
  341. Index minOuterIndex = 0;
  342. minOuterIndex = inner - m_data.upperProfile(inner);
  343. if (outer < minOuterIndex) //The value does not yet exist
  344. {
  345. const Index previousProfile = m_data.upperProfile(inner);
  346. m_data.upperProfile(inner) = inner - outer;
  347. const Index bandIncrement = m_data.upperProfile(inner) - previousProfile;
  348. //shift data stored after this new one
  349. const Index stop = m_colStartIndex[cols()];
  350. const Index start = m_colStartIndex[inner];
  351. for (Index innerIdx = stop; innerIdx >= start; innerIdx--) {
  352. m_data.upper(innerIdx + bandIncrement) = m_data.upper(innerIdx);
  353. }
  354. for (Index innerIdx = cols(); innerIdx > inner; innerIdx--) {
  355. m_colStartIndex[innerIdx] += bandIncrement;
  356. }
  357. //zeros new data
  358. memset(this->_upperPtr() + start, 0, (bandIncrement - 1) * sizeof (Scalar));
  359. return m_data.upper(m_colStartIndex[inner]);
  360. } else {
  361. return m_data.upper(m_colStartIndex[inner] + outer - (inner - m_data.upperProfile(inner)));
  362. }
  363. }
  364. if (outer > inner) //lower matrix
  365. {
  366. const Index minInnerIndex = outer - m_data.lowerProfile(outer);
  367. if (inner < minInnerIndex) //The value does not yet exist
  368. {
  369. const Index previousProfile = m_data.lowerProfile(outer);
  370. m_data.lowerProfile(outer) = outer - inner;
  371. const Index bandIncrement = m_data.lowerProfile(outer) - previousProfile;
  372. //shift data stored after this new one
  373. const Index stop = m_rowStartIndex[rows()];
  374. const Index start = m_rowStartIndex[outer];
  375. for (Index innerIdx = stop; innerIdx >= start; innerIdx--) {
  376. m_data.lower(innerIdx + bandIncrement) = m_data.lower(innerIdx);
  377. }
  378. for (Index innerIdx = rows(); innerIdx > outer; innerIdx--) {
  379. m_rowStartIndex[innerIdx] += bandIncrement;
  380. }
  381. //zeros new data
  382. memset(this->_lowerPtr() + start, 0, (bandIncrement - 1) * sizeof (Scalar));
  383. return m_data.lower(m_rowStartIndex[outer]);
  384. } else {
  385. return m_data.lower(m_rowStartIndex[outer] + inner - (outer - m_data.lowerProfile(outer)));
  386. }
  387. }
  388. } else {
  389. if (outer > inner) //upper matrix
  390. {
  391. const Index maxOuterIndex = inner + m_data.upperProfile(inner);
  392. if (outer > maxOuterIndex) //The value does not yet exist
  393. {
  394. const Index previousProfile = m_data.upperProfile(inner);
  395. m_data.upperProfile(inner) = outer - inner;
  396. const Index bandIncrement = m_data.upperProfile(inner) - previousProfile;
  397. //shift data stored after this new one
  398. const Index stop = m_rowStartIndex[rows()];
  399. const Index start = m_rowStartIndex[inner + 1];
  400. for (Index innerIdx = stop; innerIdx >= start; innerIdx--) {
  401. m_data.upper(innerIdx + bandIncrement) = m_data.upper(innerIdx);
  402. }
  403. for (Index innerIdx = inner + 1; innerIdx < outerSize() + 1; innerIdx++) {
  404. m_rowStartIndex[innerIdx] += bandIncrement;
  405. }
  406. memset(this->_upperPtr() + m_rowStartIndex[inner] + previousProfile + 1, 0, (bandIncrement - 1) * sizeof (Scalar));
  407. return m_data.upper(m_rowStartIndex[inner] + m_data.upperProfile(inner));
  408. } else {
  409. return m_data.upper(m_rowStartIndex[inner] + (outer - inner));
  410. }
  411. }
  412. if (outer < inner) //lower matrix
  413. {
  414. const Index maxInnerIndex = outer + m_data.lowerProfile(outer);
  415. if (inner > maxInnerIndex) //The value does not yet exist
  416. {
  417. const Index previousProfile = m_data.lowerProfile(outer);
  418. m_data.lowerProfile(outer) = inner - outer;
  419. const Index bandIncrement = m_data.lowerProfile(outer) - previousProfile;
  420. //shift data stored after this new one
  421. const Index stop = m_colStartIndex[cols()];
  422. const Index start = m_colStartIndex[outer + 1];
  423. for (Index innerIdx = stop; innerIdx >= start; innerIdx--) {
  424. m_data.lower(innerIdx + bandIncrement) = m_data.lower(innerIdx);
  425. }
  426. for (Index innerIdx = outer + 1; innerIdx < outerSize() + 1; innerIdx++) {
  427. m_colStartIndex[innerIdx] += bandIncrement;
  428. }
  429. memset(this->_lowerPtr() + m_colStartIndex[outer] + previousProfile + 1, 0, (bandIncrement - 1) * sizeof (Scalar));
  430. return m_data.lower(m_colStartIndex[outer] + m_data.lowerProfile(outer));
  431. } else {
  432. return m_data.lower(m_colStartIndex[outer] + (inner - outer));
  433. }
  434. }
  435. }
  436. }
  437. /** Must be called after inserting a set of non zero entries.
  438. */
  439. inline void finalize() {
  440. if (IsRowMajor) {
  441. if (rows() > cols())
  442. m_data.resize(cols(), cols(), rows(), m_colStartIndex[cols()] + 1, m_rowStartIndex[rows()] + 1);
  443. else
  444. m_data.resize(rows(), cols(), rows(), m_colStartIndex[cols()] + 1, m_rowStartIndex[rows()] + 1);
  445. // eigen_assert(rows() == cols() && "memory reorganisatrion only works with suare matrix");
  446. //
  447. // Scalar* newArray = new Scalar[m_colStartIndex[cols()] + 1 + m_rowStartIndex[rows()] + 1];
  448. // Index dataIdx = 0;
  449. // for (Index row = 0; row < rows(); row++) {
  450. //
  451. // const Index nbLowerElts = m_rowStartIndex[row + 1] - m_rowStartIndex[row];
  452. // // std::cout << "nbLowerElts" << nbLowerElts << std::endl;
  453. // memcpy(newArray + dataIdx, m_data.m_lower + m_rowStartIndex[row], nbLowerElts * sizeof (Scalar));
  454. // m_rowStartIndex[row] = dataIdx;
  455. // dataIdx += nbLowerElts;
  456. //
  457. // const Index nbUpperElts = m_colStartIndex[row + 1] - m_colStartIndex[row];
  458. // memcpy(newArray + dataIdx, m_data.m_upper + m_colStartIndex[row], nbUpperElts * sizeof (Scalar));
  459. // m_colStartIndex[row] = dataIdx;
  460. // dataIdx += nbUpperElts;
  461. //
  462. //
  463. // }
  464. // //todo : don't access m_data profile directly : add an accessor from SkylineMatrix
  465. // m_rowStartIndex[rows()] = m_rowStartIndex[rows()-1] + m_data.lowerProfile(rows()-1);
  466. // m_colStartIndex[cols()] = m_colStartIndex[cols()-1] + m_data.upperProfile(cols()-1);
  467. //
  468. // delete[] m_data.m_lower;
  469. // delete[] m_data.m_upper;
  470. //
  471. // m_data.m_lower = newArray;
  472. // m_data.m_upper = newArray;
  473. } else {
  474. if (rows() > cols())
  475. m_data.resize(cols(), rows(), cols(), m_rowStartIndex[cols()] + 1, m_colStartIndex[cols()] + 1);
  476. else
  477. m_data.resize(rows(), rows(), cols(), m_rowStartIndex[rows()] + 1, m_colStartIndex[rows()] + 1);
  478. }
  479. }
  480. inline void squeeze() {
  481. finalize();
  482. m_data.squeeze();
  483. }
  484. void prune(Scalar reference, RealScalar epsilon = dummy_precision<RealScalar > ()) {
  485. //TODO
  486. }
  487. /** Resizes the matrix to a \a rows x \a cols matrix and initializes it to zero
  488. * \sa resizeNonZeros(Index), reserve(), setZero()
  489. */
  490. void resize(size_t rows, size_t cols) {
  491. const Index diagSize = rows > cols ? cols : rows;
  492. m_innerSize = IsRowMajor ? cols : rows;
  493. eigen_assert(rows == cols && "Skyline matrix must be square matrix");
  494. if (diagSize % 2) { // diagSize is odd
  495. const Index k = (diagSize - 1) / 2;
  496. m_data.resize(diagSize, IsRowMajor ? cols : rows, IsRowMajor ? rows : cols,
  497. 2 * k * k + k + 1,
  498. 2 * k * k + k + 1);
  499. } else // diagSize is even
  500. {
  501. const Index k = diagSize / 2;
  502. m_data.resize(diagSize, IsRowMajor ? cols : rows, IsRowMajor ? rows : cols,
  503. 2 * k * k - k + 1,
  504. 2 * k * k - k + 1);
  505. }
  506. if (m_colStartIndex && m_rowStartIndex) {
  507. delete[] m_colStartIndex;
  508. delete[] m_rowStartIndex;
  509. }
  510. m_colStartIndex = new Index [cols + 1];
  511. m_rowStartIndex = new Index [rows + 1];
  512. m_outerSize = diagSize;
  513. m_data.reset();
  514. m_data.clear();
  515. m_outerSize = diagSize;
  516. memset(m_colStartIndex, 0, (cols + 1) * sizeof (Index));
  517. memset(m_rowStartIndex, 0, (rows + 1) * sizeof (Index));
  518. }
  519. void resizeNonZeros(Index size) {
  520. m_data.resize(size);
  521. }
  522. inline SkylineMatrix()
  523. : m_outerSize(-1), m_innerSize(0), m_colStartIndex(0), m_rowStartIndex(0) {
  524. resize(0, 0);
  525. }
  526. inline SkylineMatrix(size_t rows, size_t cols)
  527. : m_outerSize(0), m_innerSize(0), m_colStartIndex(0), m_rowStartIndex(0) {
  528. resize(rows, cols);
  529. }
  530. template<typename OtherDerived>
  531. inline SkylineMatrix(const SkylineMatrixBase<OtherDerived>& other)
  532. : m_outerSize(0), m_innerSize(0), m_colStartIndex(0), m_rowStartIndex(0) {
  533. *this = other.derived();
  534. }
  535. inline SkylineMatrix(const SkylineMatrix & other)
  536. : Base(), m_outerSize(0), m_innerSize(0), m_colStartIndex(0), m_rowStartIndex(0) {
  537. *this = other.derived();
  538. }
  539. inline void swap(SkylineMatrix & other) {
  540. //EIGEN_DBG_SKYLINE(std::cout << "SkylineMatrix:: swap\n");
  541. std::swap(m_colStartIndex, other.m_colStartIndex);
  542. std::swap(m_rowStartIndex, other.m_rowStartIndex);
  543. std::swap(m_innerSize, other.m_innerSize);
  544. std::swap(m_outerSize, other.m_outerSize);
  545. m_data.swap(other.m_data);
  546. }
  547. inline SkylineMatrix & operator=(const SkylineMatrix & other) {
  548. std::cout << "SkylineMatrix& operator=(const SkylineMatrix& other)\n";
  549. if (other.isRValue()) {
  550. swap(other.const_cast_derived());
  551. } else {
  552. resize(other.rows(), other.cols());
  553. memcpy(m_colStartIndex, other.m_colStartIndex, (m_outerSize + 1) * sizeof (Index));
  554. memcpy(m_rowStartIndex, other.m_rowStartIndex, (m_outerSize + 1) * sizeof (Index));
  555. m_data = other.m_data;
  556. }
  557. return *this;
  558. }
  559. template<typename OtherDerived>
  560. inline SkylineMatrix & operator=(const SkylineMatrixBase<OtherDerived>& other) {
  561. const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
  562. if (needToTranspose) {
  563. // TODO
  564. // return *this;
  565. } else {
  566. // there is no special optimization
  567. return SkylineMatrixBase<SkylineMatrix>::operator=(other.derived());
  568. }
  569. }
  570. friend std::ostream & operator <<(std::ostream & s, const SkylineMatrix & m) {
  571. EIGEN_DBG_SKYLINE(
  572. std::cout << "upper elements : " << std::endl;
  573. for (Index i = 0; i < m.m_data.upperSize(); i++)
  574. std::cout << m.m_data.upper(i) << "\t";
  575. std::cout << std::endl;
  576. std::cout << "upper profile : " << std::endl;
  577. for (Index i = 0; i < m.m_data.upperProfileSize(); i++)
  578. std::cout << m.m_data.upperProfile(i) << "\t";
  579. std::cout << std::endl;
  580. std::cout << "lower startIdx : " << std::endl;
  581. for (Index i = 0; i < m.m_data.upperProfileSize(); i++)
  582. std::cout << (IsRowMajor ? m.m_colStartIndex[i] : m.m_rowStartIndex[i]) << "\t";
  583. std::cout << std::endl;
  584. std::cout << "lower elements : " << std::endl;
  585. for (Index i = 0; i < m.m_data.lowerSize(); i++)
  586. std::cout << m.m_data.lower(i) << "\t";
  587. std::cout << std::endl;
  588. std::cout << "lower profile : " << std::endl;
  589. for (Index i = 0; i < m.m_data.lowerProfileSize(); i++)
  590. std::cout << m.m_data.lowerProfile(i) << "\t";
  591. std::cout << std::endl;
  592. std::cout << "lower startIdx : " << std::endl;
  593. for (Index i = 0; i < m.m_data.lowerProfileSize(); i++)
  594. std::cout << (IsRowMajor ? m.m_rowStartIndex[i] : m.m_colStartIndex[i]) << "\t";
  595. std::cout << std::endl;
  596. );
  597. for (Index rowIdx = 0; rowIdx < m.rows(); rowIdx++) {
  598. for (Index colIdx = 0; colIdx < m.cols(); colIdx++) {
  599. s << m.coeff(rowIdx, colIdx) << "\t";
  600. }
  601. s << std::endl;
  602. }
  603. return s;
  604. }
  605. /** Destructor */
  606. inline ~SkylineMatrix() {
  607. delete[] m_colStartIndex;
  608. delete[] m_rowStartIndex;
  609. }
  610. /** Overloaded for performance */
  611. Scalar sum() const;
  612. };
  613. template<typename Scalar, int _Options>
  614. class SkylineMatrix<Scalar, _Options>::InnerUpperIterator {
  615. public:
  616. InnerUpperIterator(const SkylineMatrix& mat, Index outer)
  617. : m_matrix(mat), m_outer(outer),
  618. m_id(_Options == RowMajor ? mat.m_colStartIndex[outer] : mat.m_rowStartIndex[outer] + 1),
  619. m_start(m_id),
  620. m_end(_Options == RowMajor ? mat.m_colStartIndex[outer + 1] : mat.m_rowStartIndex[outer + 1] + 1) {
  621. }
  622. inline InnerUpperIterator & operator++() {
  623. m_id++;
  624. return *this;
  625. }
  626. inline InnerUpperIterator & operator+=(Index shift) {
  627. m_id += shift;
  628. return *this;
  629. }
  630. inline Scalar value() const {
  631. return m_matrix.m_data.upper(m_id);
  632. }
  633. inline Scalar* valuePtr() {
  634. return const_cast<Scalar*> (&(m_matrix.m_data.upper(m_id)));
  635. }
  636. inline Scalar& valueRef() {
  637. return const_cast<Scalar&> (m_matrix.m_data.upper(m_id));
  638. }
  639. inline Index index() const {
  640. return IsRowMajor ? m_outer - m_matrix.m_data.upperProfile(m_outer) + (m_id - m_start) :
  641. m_outer + (m_id - m_start) + 1;
  642. }
  643. inline Index row() const {
  644. return IsRowMajor ? index() : m_outer;
  645. }
  646. inline Index col() const {
  647. return IsRowMajor ? m_outer : index();
  648. }
  649. inline size_t size() const {
  650. return m_matrix.m_data.upperProfile(m_outer);
  651. }
  652. inline operator bool() const {
  653. return (m_id < m_end) && (m_id >= m_start);
  654. }
  655. protected:
  656. const SkylineMatrix& m_matrix;
  657. const Index m_outer;
  658. Index m_id;
  659. const Index m_start;
  660. const Index m_end;
  661. };
  662. template<typename Scalar, int _Options>
  663. class SkylineMatrix<Scalar, _Options>::InnerLowerIterator {
  664. public:
  665. InnerLowerIterator(const SkylineMatrix& mat, Index outer)
  666. : m_matrix(mat),
  667. m_outer(outer),
  668. m_id(_Options == RowMajor ? mat.m_rowStartIndex[outer] : mat.m_colStartIndex[outer] + 1),
  669. m_start(m_id),
  670. m_end(_Options == RowMajor ? mat.m_rowStartIndex[outer + 1] : mat.m_colStartIndex[outer + 1] + 1) {
  671. }
  672. inline InnerLowerIterator & operator++() {
  673. m_id++;
  674. return *this;
  675. }
  676. inline InnerLowerIterator & operator+=(Index shift) {
  677. m_id += shift;
  678. return *this;
  679. }
  680. inline Scalar value() const {
  681. return m_matrix.m_data.lower(m_id);
  682. }
  683. inline Scalar* valuePtr() {
  684. return const_cast<Scalar*> (&(m_matrix.m_data.lower(m_id)));
  685. }
  686. inline Scalar& valueRef() {
  687. return const_cast<Scalar&> (m_matrix.m_data.lower(m_id));
  688. }
  689. inline Index index() const {
  690. return IsRowMajor ? m_outer - m_matrix.m_data.lowerProfile(m_outer) + (m_id - m_start) :
  691. m_outer + (m_id - m_start) + 1;
  692. ;
  693. }
  694. inline Index row() const {
  695. return IsRowMajor ? m_outer : index();
  696. }
  697. inline Index col() const {
  698. return IsRowMajor ? index() : m_outer;
  699. }
  700. inline size_t size() const {
  701. return m_matrix.m_data.lowerProfile(m_outer);
  702. }
  703. inline operator bool() const {
  704. return (m_id < m_end) && (m_id >= m_start);
  705. }
  706. protected:
  707. const SkylineMatrix& m_matrix;
  708. const Index m_outer;
  709. Index m_id;
  710. const Index m_start;
  711. const Index m_end;
  712. };
  713. } // end namespace Eigen
  714. #endif // EIGEN_SkylineMatrix_H