RowMatrixT.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. /*
  2. * NICE-Core - efficient algebra and computer vision methods
  3. * - libbasicvector - A simple vector library
  4. * See file License for license information.
  5. */
  6. #ifndef _EROWMATRIX_BASICVECTOR_H
  7. #define _EROWMATRIX_BASICVECTOR_H
  8. #include <cstdlib>
  9. #include <string>
  10. #include <sstream>
  11. #include <stdexcept>
  12. #include <core/basics/numerictools.h>
  13. #ifdef NICE_USELIB_LINAL
  14. #include <LinAl/matrixCF.h>
  15. #endif
  16. #include "core/vector/MatrixBase.h"
  17. #include "core/vector/VectorT.h"
  18. namespace NICE {
  19. /**
  20. * @brief RowMatrixT is a simple row matrix template class
  21. * @author Frank Mattern (based on \c MatrixT)
  22. *
  23. * This is a row major variant of MatrixT. If you don't know whether to choose
  24. * MatrixT or RowMatrixT, you should take MatrixT.
  25. *
  26. * \c RowMatrixT is a simple matrix class which provides the (optional) ability
  27. * to use externally allocated memory as storage.
  28. * The main features are:
  29. * - In concept an efficient implementation of a mathematical matrix
  30. * - An array-like storage class
  31. * - Support for externally allocated memory
  32. * - Ability to get pointer to internal memory
  33. * - Thus the ability to <b>directly</b> interface with other libraries such as
  34. * LinAl without time consuming data copying. HOWEVER: LinAl in column major.
  35. * MatrixT is better for interfacing with LinAl.
  36. *
  37. * @note
  38. * This class is in a preliminary state!
  39. * Todo: is the distinction between shallow and deep copy always clear?
  40. */
  41. template<class ElementType>
  42. class RowMatrixT : public MatrixBase {
  43. public:
  44. //! STL-like typedef for type of elements
  45. typedef ElementType value_type;
  46. //! STL-like typedef for const element reference
  47. typedef const ElementType& const_reference;
  48. //! STL-like typedef for iterator
  49. typedef ElementType* iterator;
  50. //! STL-like typedef for const iterator
  51. typedef const ElementType* const_iterator;
  52. //! STL-like typedef for element reference
  53. typedef ElementType& reference;
  54. /**
  55. * @brief Create an empty \c RowMatrixT with size zero.
  56. *
  57. * Such an object is actually useless, but sometimes you may need to have
  58. * such instances to initalize some data structure.
  59. * The only way to turn such an object into something useful is operator=().
  60. */
  61. RowMatrixT();
  62. /**
  63. * @brief Create an \c RowMatrixT with size \c size.
  64. * Data will not be initialized.
  65. * @param rows number of rows
  66. * @param cols number of cols
  67. */
  68. explicit RowMatrixT(const size_t rows, const size_t cols);
  69. /**
  70. * @brief Create an \c RowMatrixT with size \c size.
  71. * Data will be initialized to \c element.
  72. * @param rows number of rows
  73. * @param cols number of cols
  74. * @param element initial value of all elements
  75. */
  76. RowMatrixT(const size_t rows, const size_t cols, const ElementType& element);
  77. /**
  78. * @brief Create an \c RowMatrixT of size \c size.
  79. * It will be initialized with the data pointed to by \c _data.
  80. *
  81. * That is the first \c size elements of \c _data will be copied.
  82. * @param _data data to be copied
  83. * @param rows number of rows
  84. * @param cols number of cols
  85. */
  86. RowMatrixT(const ElementType* _data, const size_t rows, const size_t cols);
  87. /**
  88. * @brief Create an \c RowMatrixT of size \c size
  89. * with optionally external storage.
  90. *
  91. * It will be initialized with the data pointed to by \c _data.
  92. * The parameter _external control whether the data will be copied or
  93. * the pointer \c _data is directly kept as storage for the \c RowMatrixT.
  94. * In case of external storage the data will not be deleted in the destructor.
  95. * @param _data External data storage
  96. * @param rows number of rows of the external storage
  97. * @param cols number of cols of the external storage
  98. * @param mode Storage mode: keep external memory or copy data.
  99. */
  100. RowMatrixT(ElementType* _data, const size_t rows, const size_t cols,
  101. const MatrixBase::Mode mode = copy);
  102. // /**
  103. // * @brief Read from input stream.
  104. // * @param input Read from here
  105. // */
  106. //explicit RowMatrixT(std::istream& input);
  107. /**
  108. * @brief copy constructor
  109. * @param v RowMatrixT where to copy data from
  110. */
  111. RowMatrixT(const RowMatrixT<ElementType>& v);
  112. virtual ~RowMatrixT();
  113. /**
  114. * @brief Create a const RowMatrixT of size \c size
  115. * with <b>external</b> storage.
  116. *
  117. * It will be initialized with the data pointed to by %_data.
  118. * The data will not be deleted in the destructor.
  119. * @param _data External data storage
  120. * @param rows number of rows of the external storage
  121. * @param cols number of cols of the external storage
  122. */
  123. inline static const RowMatrixT<ElementType>* createConst(
  124. const ElementType* _data,
  125. const size_t rows,
  126. const size_t cols);
  127. /**
  128. * @brief Read access to elements.
  129. * @param row row to access
  130. * @param col col to access
  131. * @return Element (as const reference)
  132. */
  133. inline const_reference operator()(const ptrdiff_t row,
  134. const ptrdiff_t col) const {
  135. return constData[col + row * cols()];
  136. }
  137. /**
  138. * @brief Read access to elements.
  139. * @param row row to access
  140. * @param col col to access
  141. * @return Element (as const reference)
  142. */
  143. inline reference operator()(const ptrdiff_t row,
  144. const ptrdiff_t col) {
  145. return data[col + row * cols()];
  146. }
  147. /**
  148. * @brief Get a const pointer to the internal memory.
  149. */
  150. // operator ElementType const* () const { return constData; }
  151. /**
  152. * @brief Get a const_iterator pointing to the first element.
  153. *
  154. * (Actually the same as \c getDataPointer())
  155. */
  156. inline const_iterator begin() const { return constData; }
  157. /**
  158. * @brief Get an iterator pointing beyond the last element.
  159. */
  160. inline const_iterator end() const { return constData + rows() * cols(); }
  161. /**
  162. * @brief Return the number of rows of this RowMatrixT.
  163. * @return Size of this RowMatrixT.
  164. */
  165. inline size_t rows() const { return m_rows; }
  166. /**
  167. * @brief Return the number of columns of this RowMatrixT.
  168. * @return Size of this RowMatrixT.
  169. */
  170. inline size_t cols() const { return m_cols; }
  171. /**
  172. * @brief Compare \c v with \c this.
  173. * @pre Size of \c v and \c this must be equal
  174. * @param v data to compare with
  175. * @return true if \c v and \c this are equal
  176. */
  177. inline bool operator== (const RowMatrixT<ElementType>& v) const;
  178. /**
  179. * @brief Compare \c v with \c this.
  180. * @pre Size of \c v and \c this must be equal
  181. * @param v data to compare with
  182. * @return \c *this
  183. * @return true if \c v and \c this are not equal
  184. */
  185. inline bool operator!= (const RowMatrixT<ElementType>& v) const;
  186. /**
  187. * @brief Change the number of RowMatrixT elements
  188. * @param rows number of rows of the \c RowMatrixT
  189. * @param cols number of cols of the \c RowMatrixT
  190. * @throw std::runtime_error if using external storage and \c size > \c size()
  191. * @note Changing the size of the vector invalidates all iterators
  192. * and pointers held to the data.
  193. */
  194. inline void resize(size_t rows, size_t cols);
  195. /**
  196. * @brief Transpose a quadratic RowMatrixT.
  197. * @throw Exception if matrix is not square.
  198. */
  199. inline void transposeInplace();
  200. /**
  201. * @brief return a transposed RowMatrixT.
  202. * @return transposed matrix
  203. */
  204. RowMatrixT<ElementType> transpose();
  205. /**
  206. * @brief Copy data from \c v to \c this.
  207. * @param v New data
  208. * @return \c *this
  209. */
  210. inline RowMatrixT<ElementType>& operator=(const RowMatrixT<ElementType>& v);
  211. /**
  212. * @brief Set all elements to value \c element
  213. * @param element New value of all elements
  214. */
  215. inline RowMatrixT<ElementType>& operator=(const ElementType& element);
  216. /**
  217. * @brief Set all elements to value \c element
  218. * @param element New value of all elements
  219. */
  220. inline void set(const ElementType& element) {
  221. *this = element;
  222. }
  223. /**
  224. * @brief Get a pointer to the internal memory.
  225. */
  226. // inline operator ElementType* () { return data; }
  227. /**
  228. * @brief Get a pointer to the internal memory.
  229. */
  230. inline ElementType* getDataPointer() { return data; }
  231. /**
  232. * @brief Get the ith row of the matrix and return an VectorT with is a reference to the internal memory.
  233. * @param i number of row
  234. */
  235. inline const VectorT<ElementType> getRowRef(uint i) const;
  236. /**
  237. * @brief Get the ith row of the matrix and return an VectorT with is a reference to the internal memory.
  238. * @param i number of row
  239. */
  240. inline VectorT<ElementType> getRowRef(uint i);
  241. /**
  242. * @brief Get the ith column of the matrix and return it as VectorT.
  243. * @param i number of column
  244. */
  245. inline VectorT<ElementType> getColumn(uint i) const;
  246. /**
  247. * @brief Get the ith row of the matrix and return it as VectorT.
  248. * @param i number of row
  249. */
  250. inline VectorT<ElementType> getRow(uint i) const;
  251. /**
  252. * @brief Get a const pointer to the internal memory.
  253. */
  254. inline const ElementType* getDataPointer() const { return constData; }
  255. /**
  256. * @brief Get an iterator pointing to the first element.
  257. *
  258. * (Actually the same as \c getDataPointer())
  259. */
  260. inline iterator begin() { return data; }
  261. /**
  262. * @brief Get an iterator pointing beyond the last element.
  263. */
  264. inline iterator end() { return data + rows() * cols(); }
  265. /**
  266. * @brief Add \c e to each element of \c this.
  267. * @param e value
  268. * @return \c *this
  269. */
  270. inline RowMatrixT<ElementType>& operator+= (const ElementType& e);
  271. /**
  272. * @brief Subtract \c e from each element of \c this.
  273. * @param e value
  274. * @return \c *this
  275. */
  276. inline RowMatrixT<ElementType>& operator-= (const ElementType& e);
  277. /**
  278. * @brief Multiply each element of \c this with \c e.
  279. * @param e value
  280. * @return \c *this
  281. */
  282. inline RowMatrixT<ElementType>& operator*= (const ElementType& e);
  283. /**
  284. * @brief Divide each element of \c this through \c e.
  285. * @param e value
  286. * @return \c *this
  287. */
  288. inline RowMatrixT<ElementType>& operator/= (const ElementType& e);
  289. /**
  290. * @brief Add \c v to \c this.
  291. * @pre Size of \c v and \c this must be equal
  292. * @param v New data
  293. * @return \c *this
  294. */
  295. inline RowMatrixT<ElementType>& operator+= (const RowMatrixT<ElementType>& v);
  296. /**
  297. * @brief Subtract \c v from \c this.
  298. * @pre Size of \c v and \c this must be equal
  299. * @param v New data
  300. * @return \c *this
  301. */
  302. inline RowMatrixT<ElementType>& operator-= (const RowMatrixT<ElementType>& v);
  303. // /**
  304. // * @brief Multiplicate elementwise \c v to \c this.
  305. // * @pre Size of \c v and \c this must be equal
  306. // * @param v New data
  307. // * @return \c *this
  308. // */
  309. // inline RowMatrixT<ElementType>& operator*= (const RowMatrixT<ElementType>& v);
  310. // /**
  311. // * @brief Divide elementwise \c v from \c this.
  312. // * @pre Size of \c v and \c this must be equal
  313. // * @param v New data
  314. // * @return \c *this
  315. // */
  316. // inline RowMatrixT<ElementType>& operator/= (const RowMatrixT<ElementType>& v);
  317. /**
  318. * Set this matrix to be the identity matrix
  319. */
  320. inline void setIdentity() {
  321. *this = ElementType(0);
  322. unsigned int m = std::min(rows(), cols());
  323. for (unsigned int i = 0; i < m; i++) {
  324. (*this)(i, i) = ElementType(1);
  325. }
  326. }
  327. /**
  328. * Matrix multiplication: this = a^{T if atranspose} * b^{T if btranspose}.
  329. * The formats of this, a and b must be consistent.
  330. * If this is empty (size 0x0), it will be resize.
  331. * @param a matrix to multiply (must NOT be the same object as \c this !)
  332. * @param b matrix to multiply (must NOT be the same object as \c this !)
  333. * @param atranspose use a.transpose() instead of a
  334. * @param btranspose use b.transpose() instead of b
  335. * @throw Exception if formats are inconsistent
  336. */
  337. void multiply(const RowMatrixT<ElementType>& a, const RowMatrixT<ElementType>& b, bool atranspose=false, bool btranspose=false);
  338. /**
  339. * Is an entry NaN?
  340. * @note This method is defined on floating point matrices only!
  341. */
  342. bool containsNaN() const;
  343. /**
  344. * @brief Returns 'true' if the memory is allocated externally
  345. * @return true if external storage
  346. */
  347. inline bool isExternal() const { return externalStorage; }
  348. /**
  349. * @brief Compare \c v with \c this.
  350. * @pre Size of \c v and \c this must be equal
  351. * @param a data to compare with
  352. * @param threshold difference of each entry which can be neglected
  353. * @return true if \c v and \c this are equal
  354. */
  355. inline bool isEqual(const RowMatrixT<ElementType> &a, ElementType threshold=static_cast<ElementType>(0)) const;
  356. /**
  357. * Square of the frobenius norm of this matrix.
  358. * Only defined for numerical ElementType.
  359. */
  360. ElementType squaredFrobeniusNorm() const;
  361. /**
  362. * Frobenius norm of this matrix. Only defined for numerical ElementType.
  363. */
  364. inline ElementType frobeniusNorm() const {
  365. return sqrt(squaredFrobeniusNorm());
  366. }
  367. #ifdef NICE_USELIB_LINAL
  368. RowMatrixT(const LinAl::Matrix<ElementType>& m);
  369. inline LinAl::MatrixCF<ElementType> linal() {
  370. return LinAl::MatrixCF<ElementType>(data, rows(), cols(), true);
  371. }
  372. inline LinAl::MatrixCF<ElementType> linal() const {
  373. return LinAl::MatrixCF<ElementType>(data, rows(), cols());
  374. }
  375. #endif // NICE_USELIB_LINAL
  376. protected:
  377. /**
  378. * Are we using external storage?
  379. */
  380. bool externalStorage;
  381. /**
  382. * Const pointer to the data.
  383. */
  384. const ElementType* constData;
  385. /**
  386. * Pointer to the data.
  387. * @note This has to point to the same adress as constData!
  388. * (NULL is only const data is available)
  389. */
  390. ElementType* data;
  391. /**
  392. * Size of the vector
  393. */
  394. size_t m_rows;
  395. size_t m_cols;
  396. inline void setDataPointer(ElementType* _data, size_t rows, size_t cols,
  397. bool _externalStorage) {
  398. data = _data;
  399. constData = _data;
  400. m_rows = rows;
  401. m_cols = cols;
  402. externalStorage = _externalStorage;
  403. }
  404. inline void setConstDataPointer(const ElementType* _data,
  405. size_t rows, size_t cols) {
  406. data = NULL;
  407. constData = _data;
  408. m_rows = rows;
  409. m_cols = cols;
  410. externalStorage = true;
  411. }
  412. };
  413. template <class ElementType>
  414. inline std::istream&
  415. operator >> (std::istream& input, RowMatrixT<ElementType>& v) {
  416. size_t w, h;
  417. char c;
  418. input >> w >> c >> h;
  419. v.resize(w, h);
  420. for (size_t r = 0; r < v.rows(); r++) {
  421. for (size_t c = 0; c < v.cols(); c++) {
  422. input >> v(r, c);
  423. }
  424. }
  425. return input;
  426. }
  427. template <class ElementType>
  428. inline std::ostream&
  429. operator << (std::ostream& output, const RowMatrixT<ElementType>& v) {
  430. output << v.rows() << " x " << v.cols() << std::endl;
  431. for (size_t r = 0; r < v.rows(); r++) {
  432. for (size_t c = 0; c < v.cols(); c++) {
  433. output << v(r, c) << " ";
  434. }
  435. output << std::endl;
  436. }
  437. return output;
  438. }
  439. typedef RowMatrixT<int> IntRowMatrix;
  440. typedef RowMatrixT<float> FloatRowMatrix;
  441. typedef RowMatrixT<double> DoubleRowMatrix;
  442. typedef RowMatrixT<char> CharRowMatrix;
  443. }
  444. //#ifdef __GNUC__
  445. #include "core/vector/RowMatrixT.tcc"
  446. //#endif
  447. #endif // _EROWMATRIX_BASICVECTOR_H