SpRow_meat.hpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au)
  2. // Copyright 2008-2016 National ICT Australia (NICTA)
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // ------------------------------------------------------------------------
  15. //! \addtogroup SpRow
  16. //! @{
  17. template<typename eT>
  18. inline
  19. SpRow<eT>::SpRow()
  20. : SpMat<eT>(arma_vec_indicator(), 2)
  21. {
  22. arma_extra_debug_sigprint();
  23. }
  24. template<typename eT>
  25. inline
  26. SpRow<eT>::SpRow(const uword in_n_elem)
  27. : SpMat<eT>(arma_vec_indicator(), 1, in_n_elem, 2)
  28. {
  29. arma_extra_debug_sigprint();
  30. }
  31. template<typename eT>
  32. inline
  33. SpRow<eT>::SpRow(const uword in_n_rows, const uword in_n_cols)
  34. : SpMat<eT>(arma_vec_indicator(), in_n_rows, in_n_cols, 2)
  35. {
  36. arma_extra_debug_sigprint();
  37. }
  38. template<typename eT>
  39. inline
  40. SpRow<eT>::SpRow(const SizeMat& s)
  41. : SpMat<eT>(arma_vec_indicator(), 0, 0, 2)
  42. {
  43. arma_extra_debug_sigprint();
  44. SpMat<eT>::init(s.n_rows, s.n_cols);
  45. }
  46. template<typename eT>
  47. inline
  48. SpRow<eT>::SpRow(const char* text)
  49. : SpMat<eT>(arma_vec_indicator(), 2)
  50. {
  51. arma_extra_debug_sigprint();
  52. SpMat<eT>::init(std::string(text));
  53. }
  54. template<typename eT>
  55. inline
  56. SpRow<eT>&
  57. SpRow<eT>::operator=(const char* text)
  58. {
  59. arma_extra_debug_sigprint();
  60. SpMat<eT>::init(std::string(text));
  61. return *this;
  62. }
  63. template<typename eT>
  64. inline
  65. SpRow<eT>::SpRow(const std::string& text)
  66. : SpMat<eT>(arma_vec_indicator(), 2)
  67. {
  68. arma_extra_debug_sigprint();
  69. SpMat<eT>::init(text);
  70. }
  71. template<typename eT>
  72. inline
  73. SpRow<eT>&
  74. SpRow<eT>::operator=(const std::string& text)
  75. {
  76. arma_extra_debug_sigprint();
  77. SpMat<eT>::init(text);
  78. return *this;
  79. }
  80. template<typename eT>
  81. inline
  82. SpRow<eT>&
  83. SpRow<eT>::operator=(const eT val)
  84. {
  85. arma_extra_debug_sigprint();
  86. SpMat<eT>::operator=(val);
  87. return *this;
  88. }
  89. template<typename eT>
  90. template<typename T1>
  91. inline
  92. SpRow<eT>::SpRow(const Base<eT,T1>& X)
  93. : SpMat<eT>(arma_vec_indicator(), 2)
  94. {
  95. arma_extra_debug_sigprint();
  96. SpMat<eT>::operator=(X.get_ref());
  97. }
  98. template<typename eT>
  99. template<typename T1>
  100. inline
  101. SpRow<eT>&
  102. SpRow<eT>::operator=(const Base<eT,T1>& X)
  103. {
  104. arma_extra_debug_sigprint();
  105. SpMat<eT>::operator=(X.get_ref());
  106. return *this;
  107. }
  108. template<typename eT>
  109. template<typename T1>
  110. inline
  111. SpRow<eT>::SpRow(const SpBase<eT,T1>& X)
  112. : SpMat<eT>(arma_vec_indicator(), 2)
  113. {
  114. arma_extra_debug_sigprint();
  115. SpMat<eT>::operator=(X.get_ref());
  116. }
  117. template<typename eT>
  118. template<typename T1>
  119. inline
  120. SpRow<eT>&
  121. SpRow<eT>::operator=(const SpBase<eT,T1>& X)
  122. {
  123. arma_extra_debug_sigprint();
  124. SpMat<eT>::operator=(X.get_ref());
  125. return *this;
  126. }
  127. template<typename eT>
  128. template<typename T1, typename T2>
  129. inline
  130. SpRow<eT>::SpRow
  131. (
  132. const SpBase<typename SpRow<eT>::pod_type, T1>& A,
  133. const SpBase<typename SpRow<eT>::pod_type, T2>& B
  134. )
  135. : SpMat<eT>(arma_vec_indicator(), 2)
  136. {
  137. arma_extra_debug_sigprint();
  138. SpMat<eT>::init(A,B);
  139. }
  140. template<typename eT>
  141. inline
  142. const SpOp<SpRow<eT>,spop_htrans>
  143. SpRow<eT>::t() const
  144. {
  145. return SpOp<SpRow<eT>,spop_htrans>(*this);
  146. }
  147. template<typename eT>
  148. inline
  149. const SpOp<SpRow<eT>,spop_htrans>
  150. SpRow<eT>::ht() const
  151. {
  152. return SpOp<SpRow<eT>,spop_htrans>(*this);
  153. }
  154. template<typename eT>
  155. inline
  156. const SpOp<SpRow<eT>,spop_strans>
  157. SpRow<eT>::st() const
  158. {
  159. return SpOp<SpRow<eT>,spop_strans>(*this);
  160. }
  161. //! remove specified columns
  162. template<typename eT>
  163. inline
  164. void
  165. SpRow<eT>::shed_col(const uword col_num)
  166. {
  167. arma_extra_debug_sigprint();
  168. arma_debug_check( col_num >= SpMat<eT>::n_cols, "SpRow::shed_col(): out of bounds");
  169. shed_cols(col_num, col_num);
  170. }
  171. //! remove specified columns
  172. template<typename eT>
  173. inline
  174. void
  175. SpRow<eT>::shed_cols(const uword in_col1, const uword in_col2)
  176. {
  177. arma_extra_debug_sigprint();
  178. arma_debug_check
  179. (
  180. (in_col1 > in_col2) || (in_col2 >= SpMat<eT>::n_cols),
  181. "SpRow::shed_cols(): indices out of bounds or incorrectly used"
  182. );
  183. SpMat<eT>::sync_csc();
  184. const uword diff = (in_col2 - in_col1 + 1);
  185. // This is doubleplus easy because we have all the column pointers stored.
  186. const uword start = SpMat<eT>::col_ptrs[in_col1];
  187. const uword end = SpMat<eT>::col_ptrs[in_col2 + 1];
  188. if (start != end)
  189. {
  190. const uword elem_diff = end - start;
  191. eT* new_values = memory::acquire<eT> (SpMat<eT>::n_nonzero - elem_diff);
  192. uword* new_row_indices = memory::acquire<uword>(SpMat<eT>::n_nonzero - elem_diff);
  193. // Copy first set of elements, if necessary.
  194. if (start > 0)
  195. {
  196. arrayops::copy(new_values, SpMat<eT>::values, start);
  197. arrayops::copy(new_row_indices, SpMat<eT>::row_indices, start);
  198. }
  199. // Copy last set of elements, if necessary.
  200. if (end != SpMat<eT>::n_nonzero)
  201. {
  202. arrayops::copy(new_values + start, SpMat<eT>::values + end, (SpMat<eT>::n_nonzero - end));
  203. arrayops::copy(new_row_indices + start, SpMat<eT>::row_indices + end, (SpMat<eT>::n_nonzero - end));
  204. }
  205. memory::release(SpMat<eT>::values);
  206. memory::release(SpMat<eT>::row_indices);
  207. access::rw(SpMat<eT>::values) = new_values;
  208. access::rw(SpMat<eT>::row_indices) = new_row_indices;
  209. access::rw(SpMat<eT>::n_nonzero) -= elem_diff;
  210. }
  211. // Update column pointers.
  212. uword* new_col_ptrs = memory::acquire<uword>(SpMat<eT>::n_cols - diff + 1);
  213. // Copy first part of column pointers.
  214. if (in_col1 > 0)
  215. {
  216. arrayops::copy(new_col_ptrs, SpMat<eT>::col_ptrs, in_col1);
  217. }
  218. // Copy last part of column pointers (and adjust their values as necessary).
  219. if (in_col2 < SpMat<eT>::n_cols - 1)
  220. {
  221. arrayops::copy(new_col_ptrs + in_col1, SpMat<eT>::col_ptrs + in_col2 + 1, SpMat<eT>::n_cols - in_col2);
  222. // Modify their values.
  223. arrayops::inplace_minus(new_col_ptrs + in_col1, (end - start), SpMat<eT>::n_cols - in_col2);
  224. }
  225. memory::release(SpMat<eT>::col_ptrs);
  226. access::rw(SpMat<eT>::col_ptrs) = new_col_ptrs;
  227. access::rw(SpMat<eT>::n_cols) -= diff;
  228. access::rw(SpMat<eT>::n_elem) -= diff;
  229. SpMat<eT>::invalidate_cache();
  230. }
  231. // //! insert N cols at the specified col position,
  232. // //! optionally setting the elements of the inserted cols to zero
  233. // template<typename eT>
  234. // inline
  235. // void
  236. // SpRow<eT>::insert_cols(const uword col_num, const uword N, const bool set_to_zero)
  237. // {
  238. // arma_extra_debug_sigprint();
  239. //
  240. // // insertion at col_num == n_cols is in effect an append operation
  241. // arma_debug_check( (col_num > SpMat<eT>::n_cols), "SpRow::insert_cols(): out of bounds");
  242. //
  243. // arma_debug_check( (set_to_zero == false), "SpRow::insert_cols(): cannot set elements to nonzero values");
  244. //
  245. // uword newVal = (col_num == 0) ? 0 : SpMat<eT>::col_ptrs[col_num];
  246. // SpMat<eT>::col_ptrs.insert(col_num, N, newVal);
  247. // uword* new_col_ptrs = memory::acquire<uword>(SpMat<eT>::n_cols + N);
  248. //
  249. // arrayops::copy(new_col_ptrs, SpMat<eT>::col_ptrs, col_num);
  250. //
  251. // uword fill_value = (col_num == 0) ? 0 : SpMat<eT>::col_ptrs[col_num - 1];
  252. // arrayops::inplace_set(new_col_ptrs + col_num, fill_value, N);
  253. //
  254. // arrayops::copy(new_col_ptrs + col_num + N, SpMat<eT>::col_ptrs + col_num, SpMat<eT>::n_cols - col_num);
  255. //
  256. // access::rw(SpMat<eT>::n_cols) += N;
  257. // access::rw(SpMat<eT>::n_elem) += N;
  258. // }
  259. template<typename eT>
  260. inline
  261. typename SpRow<eT>::row_iterator
  262. SpRow<eT>::begin_row(const uword row_num)
  263. {
  264. arma_extra_debug_sigprint();
  265. // Since this is a row, row_num can only be 0. But the option is provided for
  266. // compatibility.
  267. arma_debug_check((row_num >= 1), "SpRow::begin_row(): index out of bounds");
  268. return SpMat<eT>::begin();
  269. }
  270. template<typename eT>
  271. inline
  272. typename SpRow<eT>::const_row_iterator
  273. SpRow<eT>::begin_row(const uword row_num) const
  274. {
  275. arma_extra_debug_sigprint();
  276. // Since this is a row, row_num can only be 0. But the option is provided for
  277. // compatibility.
  278. arma_debug_check((row_num >= 1), "SpRow::begin_row(): index out of bounds");
  279. return SpMat<eT>::begin();
  280. }
  281. template<typename eT>
  282. inline
  283. typename SpRow<eT>::row_iterator
  284. SpRow<eT>::end_row(const uword row_num)
  285. {
  286. arma_extra_debug_sigprint();
  287. // Since this is a row, row_num can only be 0. But the option is provided for
  288. // compatibility.
  289. arma_debug_check((row_num >= 1), "SpRow::end_row(): index out of bounds");
  290. return SpMat<eT>::end();
  291. }
  292. template<typename eT>
  293. inline
  294. typename SpRow<eT>::const_row_iterator
  295. SpRow<eT>::end_row(const uword row_num) const
  296. {
  297. arma_extra_debug_sigprint();
  298. // Since this is a row, row_num can only be 0. But the option is provided for
  299. // compatibility.
  300. arma_debug_check((row_num >= 1), "SpRow::end_row(): index out of bounds");
  301. return SpMat<eT>::end();
  302. }
  303. #ifdef ARMA_EXTRA_SPROW_MEAT
  304. #include ARMA_INCFILE_WRAP(ARMA_EXTRA_SPROW_MEAT)
  305. #endif
  306. //! @}