SpProxy.hpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  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 SpProxy
  16. //! @{
  17. // TODO: clarify and check which variables and functions are valid when 'use_iterator' is either true or false
  18. // within each specialisation of the Proxy class:
  19. //
  20. // elem_type = the type of the elements obtained from object Q
  21. // pod_type = the underlying type of elements if elem_type is std::complex
  22. // stored_type = the type of the Q object
  23. //
  24. // const_iterator_type = the type of iterator provided by begin() and begin_col()
  25. // const_row_iterator_type = the type of iterator provided by begin_row()
  26. //
  27. // use_iterator = boolean indicating that the provided iterators must be used for accessing elements
  28. // Q_is_generated = boolean indicating that the Q object was generated by SpProxy
  29. //
  30. // is_row = boolean indicating whether the Q object can be treated a row vector
  31. // is_col = boolean indicating whether the Q object can be treated a column vector
  32. // is_xvec = boolean indicating whether the Q object is a vector with unknown orientation
  33. //
  34. // Q = object that can be unwrapped via the unwrap_spmat family of classes (ie. Q must be convertible to SpMat)
  35. //
  36. // get_n_rows() = return the number of rows in Q
  37. // get_n_cols() = return the number of columns in Q
  38. // get_n_elem() = return the number of elements in Q
  39. // get_n_nonzero() = return the number of non-zero elements in Q
  40. //
  41. // operator[i] = linear element accessor; valid only if the 'use_iterator' boolean is false
  42. // at(row,col) = access elements via (row,col); valid only if the 'use_iterator' boolean is false
  43. //
  44. // get_values() = return pointer to the CSC values array in Q; valid only if the 'use_iterator' boolean is false
  45. // get_row_indices() = return pointer to the CSC row indices array in Q; valid only if the 'use_iterator' boolean is false
  46. // get_col_ptrs() = return pointer to the CSC column pointers array in Q; valid only if the 'use_iterator' boolean is false
  47. //
  48. // begin() = column-wise iterator indicating the first element in Q
  49. // begin_col(col_num) = column-wise iterator indicating the first element in column 'col_num' in Q
  50. // begin_row(row_num = 0) = row-wise iterator indicating the first element in row 'row_num' in Q
  51. //
  52. // end() = column-wise iterator indicating the "one-past-end" element in Q
  53. // end_row() = row-wise iterator indicating the "one-past-end" element in Q
  54. // end_row(row_num) = row-wise iterator indicating the "one-past-end" element in row 'row_num' in Q
  55. //
  56. // is_alias(X) = return true/false indicating whether the Q object aliases matrix X
  57. template<typename eT>
  58. class SpProxy< SpMat<eT> >
  59. {
  60. public:
  61. typedef eT elem_type;
  62. typedef typename get_pod_type<elem_type>::result pod_type;
  63. typedef SpMat<eT> stored_type;
  64. typedef typename SpMat<eT>::const_iterator const_iterator_type;
  65. typedef typename SpMat<eT>::const_row_iterator const_row_iterator_type;
  66. static const bool use_iterator = false;
  67. static const bool Q_is_generated = false;
  68. static const bool is_row = false;
  69. static const bool is_col = false;
  70. static const bool is_xvec = false;
  71. arma_aligned const SpMat<eT>& Q;
  72. inline explicit SpProxy(const SpMat<eT>& A)
  73. : Q(A)
  74. {
  75. arma_extra_debug_sigprint();
  76. Q.sync();
  77. }
  78. arma_inline uword get_n_rows() const { return Q.n_rows; }
  79. arma_inline uword get_n_cols() const { return Q.n_cols; }
  80. arma_inline uword get_n_elem() const { return Q.n_elem; }
  81. arma_inline uword get_n_nonzero() const { return Q.n_nonzero; }
  82. arma_inline elem_type operator[](const uword i) const { return Q[i]; }
  83. arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row, col); }
  84. arma_inline const eT* get_values() const { return Q.values; }
  85. arma_inline const uword* get_row_indices() const { return Q.row_indices; }
  86. arma_inline const uword* get_col_ptrs() const { return Q.col_ptrs; }
  87. arma_inline const_iterator_type begin() const { return Q.begin(); }
  88. arma_inline const_iterator_type begin_col(const uword col_num) const { return Q.begin_col(col_num); }
  89. arma_inline const_row_iterator_type begin_row(const uword row_num = 0) const { return Q.begin_row(row_num); }
  90. arma_inline const_iterator_type end() const { return Q.end(); }
  91. arma_inline const_row_iterator_type end_row() const { return Q.end_row(); }
  92. arma_inline const_row_iterator_type end_row(const uword row_num) const { return Q.end_row(row_num); }
  93. template<typename eT2>
  94. arma_inline bool is_alias(const SpMat<eT2>& X) const { return (void_ptr(&Q) == void_ptr(&X)); }
  95. };
  96. template<typename eT>
  97. class SpProxy< SpCol<eT> >
  98. {
  99. public:
  100. typedef eT elem_type;
  101. typedef typename get_pod_type<elem_type>::result pod_type;
  102. typedef SpCol<eT> stored_type;
  103. typedef typename SpCol<eT>::const_iterator const_iterator_type;
  104. typedef typename SpCol<eT>::const_row_iterator const_row_iterator_type;
  105. static const bool use_iterator = false;
  106. static const bool Q_is_generated = false;
  107. static const bool is_row = false;
  108. static const bool is_col = true;
  109. static const bool is_xvec = false;
  110. arma_aligned const SpCol<eT>& Q;
  111. inline explicit SpProxy(const SpCol<eT>& A)
  112. : Q(A)
  113. {
  114. arma_extra_debug_sigprint();
  115. Q.sync();
  116. }
  117. arma_inline uword get_n_rows() const { return Q.n_rows; }
  118. arma_inline uword get_n_cols() const { return 1; }
  119. arma_inline uword get_n_elem() const { return Q.n_elem; }
  120. arma_inline uword get_n_nonzero() const { return Q.n_nonzero; }
  121. arma_inline elem_type operator[](const uword i) const { return Q[i]; }
  122. arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row, col); }
  123. arma_inline const eT* get_values() const { return Q.values; }
  124. arma_inline const uword* get_row_indices() const { return Q.row_indices; }
  125. arma_inline const uword* get_col_ptrs() const { return Q.col_ptrs; }
  126. arma_inline const_iterator_type begin() const { return Q.begin(); }
  127. arma_inline const_iterator_type begin_col(const uword) const { return Q.begin(); }
  128. arma_inline const_row_iterator_type begin_row(const uword row_num = 0) const { return Q.begin_row(row_num); }
  129. arma_inline const_iterator_type end() const { return Q.end(); }
  130. arma_inline const_row_iterator_type end_row() const { return Q.end_row(); }
  131. arma_inline const_row_iterator_type end_row(const uword row_num) const { return Q.end_row(row_num); }
  132. template<typename eT2>
  133. arma_inline bool is_alias(const SpMat<eT2>& X) const { return (void_ptr(&Q) == void_ptr(&X)); }
  134. };
  135. template<typename eT>
  136. class SpProxy< SpRow<eT> >
  137. {
  138. public:
  139. typedef eT elem_type;
  140. typedef typename get_pod_type<elem_type>::result pod_type;
  141. typedef SpRow<eT> stored_type;
  142. typedef typename SpRow<eT>::const_iterator const_iterator_type;
  143. typedef typename SpRow<eT>::const_row_iterator const_row_iterator_type;
  144. static const bool use_iterator = false;
  145. static const bool Q_is_generated = false;
  146. static const bool is_row = true;
  147. static const bool is_col = false;
  148. static const bool is_xvec = false;
  149. arma_aligned const SpRow<eT>& Q;
  150. inline explicit SpProxy(const SpRow<eT>& A)
  151. : Q(A)
  152. {
  153. arma_extra_debug_sigprint();
  154. Q.sync();
  155. }
  156. arma_inline uword get_n_rows() const { return 1; }
  157. arma_inline uword get_n_cols() const { return Q.n_cols; }
  158. arma_inline uword get_n_elem() const { return Q.n_elem; }
  159. arma_inline uword get_n_nonzero() const { return Q.n_nonzero; }
  160. arma_inline elem_type operator[](const uword i) const { return Q[i]; }
  161. arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row, col); }
  162. arma_inline const eT* get_values() const { return Q.values; }
  163. arma_inline const uword* get_row_indices() const { return Q.row_indices; }
  164. arma_inline const uword* get_col_ptrs() const { return Q.col_ptrs; }
  165. arma_inline const_iterator_type begin() const { return Q.begin(); }
  166. arma_inline const_iterator_type begin_col(const uword col_num) const { return Q.begin_col(col_num); }
  167. arma_inline const_row_iterator_type begin_row(const uword row_num = 0) const { return Q.begin_row(row_num); }
  168. arma_inline const_iterator_type end() const { return Q.end(); }
  169. arma_inline const_row_iterator_type end_row() const { return Q.end_row(); }
  170. arma_inline const_row_iterator_type end_row(const uword row_num) const { return Q.end_row(row_num); }
  171. template<typename eT2>
  172. arma_inline bool is_alias(const SpMat<eT2>& X) const { return (void_ptr(&Q) == void_ptr(&X)); }
  173. };
  174. template<typename eT>
  175. class SpProxy< SpSubview<eT> >
  176. {
  177. public:
  178. typedef eT elem_type;
  179. typedef typename get_pod_type<elem_type>::result pod_type;
  180. typedef SpSubview<eT> stored_type;
  181. typedef typename SpSubview<eT>::const_iterator const_iterator_type;
  182. typedef typename SpSubview<eT>::const_row_iterator const_row_iterator_type;
  183. static const bool use_iterator = true;
  184. static const bool Q_is_generated = false;
  185. static const bool is_row = false;
  186. static const bool is_col = false;
  187. static const bool is_xvec = false;
  188. arma_aligned const SpSubview<eT>& Q;
  189. inline explicit SpProxy(const SpSubview<eT>& A)
  190. : Q(A)
  191. {
  192. arma_extra_debug_sigprint();
  193. Q.m.sync();
  194. }
  195. arma_inline uword get_n_rows() const { return Q.n_rows; }
  196. arma_inline uword get_n_cols() const { return Q.n_cols; }
  197. arma_inline uword get_n_elem() const { return Q.n_elem; }
  198. arma_inline uword get_n_nonzero() const { return Q.n_nonzero; }
  199. arma_inline elem_type operator[](const uword i) const { return Q[i]; }
  200. arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row, col); }
  201. arma_inline const eT* get_values() const { return Q.m.values; }
  202. arma_inline const uword* get_row_indices() const { return Q.m.row_indices; }
  203. arma_inline const uword* get_col_ptrs() const { return Q.m.col_ptrs; }
  204. arma_inline const_iterator_type begin() const { return Q.begin(); }
  205. arma_inline const_iterator_type begin_col(const uword col_num) const { return Q.begin_col(col_num); }
  206. arma_inline const_row_iterator_type begin_row(const uword row_num = 0) const { return Q.begin_row(row_num); }
  207. arma_inline const_iterator_type end() const { return Q.end(); }
  208. arma_inline const_row_iterator_type end_row() const { return Q.end_row(); }
  209. arma_inline const_row_iterator_type end_row(const uword row_num) const { return Q.end_row(row_num); }
  210. template<typename eT2>
  211. arma_inline bool is_alias(const SpMat<eT2>& X) const { return (void_ptr(&Q.m) == void_ptr(&X)); }
  212. };
  213. template<typename eT>
  214. class SpProxy< SpSubview_col<eT> >
  215. {
  216. public:
  217. typedef eT elem_type;
  218. typedef typename get_pod_type<elem_type>::result pod_type;
  219. typedef SpSubview_col<eT> stored_type;
  220. typedef typename SpSubview<eT>::const_iterator const_iterator_type;
  221. typedef typename SpSubview<eT>::const_row_iterator const_row_iterator_type;
  222. static const bool use_iterator = true;
  223. static const bool Q_is_generated = false;
  224. static const bool is_row = false;
  225. static const bool is_col = true;
  226. static const bool is_xvec = false;
  227. arma_aligned const SpSubview_col<eT>& Q;
  228. inline explicit SpProxy(const SpSubview_col<eT>& A)
  229. : Q(A)
  230. {
  231. arma_extra_debug_sigprint();
  232. Q.m.sync();
  233. }
  234. arma_inline uword get_n_rows() const { return Q.n_rows; }
  235. arma_inline uword get_n_cols() const { return 1; }
  236. arma_inline uword get_n_elem() const { return Q.n_elem; }
  237. arma_inline uword get_n_nonzero() const { return Q.n_nonzero; }
  238. arma_inline elem_type operator[](const uword i) const { return Q.at(i, 0); }
  239. arma_inline elem_type at (const uword row, const uword) const { return Q.at(row, 0); }
  240. arma_inline const eT* get_values() const { return Q.m.values; }
  241. arma_inline const uword* get_row_indices() const { return Q.m.row_indices; }
  242. arma_inline const uword* get_col_ptrs() const { return Q.m.col_ptrs; }
  243. arma_inline const_iterator_type begin() const { return Q.begin(); }
  244. arma_inline const_iterator_type begin_col(const uword col_num) const { return Q.begin_col(col_num); }
  245. arma_inline const_row_iterator_type begin_row(const uword row_num = 0) const { return Q.begin_row(row_num); }
  246. arma_inline const_iterator_type end() const { return Q.end(); }
  247. arma_inline const_row_iterator_type end_row() const { return Q.end_row(); }
  248. arma_inline const_row_iterator_type end_row(const uword row_num) const { return Q.end_row(row_num); }
  249. template<typename eT2>
  250. arma_inline bool is_alias(const SpMat<eT2>& X) const { return (void_ptr(&Q.m) == void_ptr(&X)); }
  251. };
  252. template<typename eT>
  253. class SpProxy< SpSubview_row<eT> >
  254. {
  255. public:
  256. typedef eT elem_type;
  257. typedef typename get_pod_type<elem_type>::result pod_type;
  258. typedef SpSubview_row<eT> stored_type;
  259. typedef typename SpSubview<eT>::const_iterator const_iterator_type;
  260. typedef typename SpSubview<eT>::const_row_iterator const_row_iterator_type;
  261. static const bool use_iterator = true;
  262. static const bool Q_is_generated = false;
  263. static const bool is_row = true;
  264. static const bool is_col = false;
  265. static const bool is_xvec = false;
  266. arma_aligned const SpSubview_row<eT>& Q;
  267. inline explicit SpProxy(const SpSubview_row<eT>& A)
  268. : Q(A)
  269. {
  270. arma_extra_debug_sigprint();
  271. Q.m.sync();
  272. }
  273. arma_inline uword get_n_rows() const { return 1; }
  274. arma_inline uword get_n_cols() const { return Q.n_cols; }
  275. arma_inline uword get_n_elem() const { return Q.n_elem; }
  276. arma_inline uword get_n_nonzero() const { return Q.n_nonzero; }
  277. arma_inline elem_type operator[](const uword i) const { return Q.at(0, i ); }
  278. arma_inline elem_type at (const uword, const uword col) const { return Q.at(0, col); }
  279. arma_inline const eT* get_values() const { return Q.m.values; }
  280. arma_inline const uword* get_row_indices() const { return Q.m.row_indices; }
  281. arma_inline const uword* get_col_ptrs() const { return Q.m.col_ptrs; }
  282. arma_inline const_iterator_type begin() const { return Q.begin(); }
  283. arma_inline const_iterator_type begin_col(const uword col_num) const { return Q.begin_col(col_num); }
  284. arma_inline const_row_iterator_type begin_row(const uword row_num = 0) const { return Q.begin_row(row_num); }
  285. arma_inline const_iterator_type end() const { return Q.end(); }
  286. arma_inline const_row_iterator_type end_row() const { return Q.end_row(); }
  287. arma_inline const_row_iterator_type end_row(const uword row_num) const { return Q.end_row(row_num); }
  288. template<typename eT2>
  289. arma_inline bool is_alias(const SpMat<eT2>& X) const { return (void_ptr(&Q.m) == void_ptr(&X)); }
  290. };
  291. template<typename eT>
  292. class SpProxy< spdiagview<eT> >
  293. {
  294. public:
  295. typedef eT elem_type;
  296. typedef typename get_pod_type<elem_type>::result pod_type;
  297. typedef SpMat<eT> stored_type;
  298. typedef typename SpMat<eT>::const_iterator const_iterator_type;
  299. typedef typename SpMat<eT>::const_row_iterator const_row_iterator_type;
  300. static const bool use_iterator = false;
  301. static const bool Q_is_generated = true;
  302. static const bool is_row = false;
  303. static const bool is_col = true;
  304. static const bool is_xvec = false;
  305. arma_aligned const SpMat<eT> Q;
  306. inline explicit SpProxy(const spdiagview<eT>& A)
  307. : Q(A)
  308. {
  309. arma_extra_debug_sigprint();
  310. }
  311. arma_inline uword get_n_rows() const { return Q.n_rows; }
  312. arma_inline uword get_n_cols() const { return 1; }
  313. arma_inline uword get_n_elem() const { return Q.n_elem; }
  314. arma_inline uword get_n_nonzero() const { return Q.n_nonzero; }
  315. arma_inline elem_type operator[](const uword i) const { return Q[i]; }
  316. arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row, col); }
  317. arma_inline const eT* get_values() const { return Q.values; }
  318. arma_inline const uword* get_row_indices() const { return Q.row_indices; }
  319. arma_inline const uword* get_col_ptrs() const { return Q.col_ptrs; }
  320. arma_inline const_iterator_type begin() const { return Q.begin(); }
  321. arma_inline const_iterator_type begin_col(const uword col_num) const { return Q.begin_col(col_num); }
  322. arma_inline const_row_iterator_type begin_row(const uword row_num = 0) const { return Q.begin_row(row_num); }
  323. arma_inline const_iterator_type end() const { return Q.end(); }
  324. arma_inline const_row_iterator_type end_row() const { return Q.end_row(); }
  325. arma_inline const_row_iterator_type end_row(const uword row_num) const { return Q.end_row(row_num); }
  326. template<typename eT2>
  327. arma_inline bool is_alias(const SpMat<eT2>&) const { return false; }
  328. };
  329. template<typename T1, typename spop_type>
  330. class SpProxy< SpOp<T1, spop_type> >
  331. {
  332. public:
  333. typedef typename T1::elem_type elem_type;
  334. typedef typename T1::elem_type eT;
  335. typedef typename get_pod_type<elem_type>::result pod_type;
  336. typedef SpMat<eT> stored_type;
  337. typedef typename SpMat<eT>::const_iterator const_iterator_type;
  338. typedef typename SpMat<eT>::const_row_iterator const_row_iterator_type;
  339. static const bool use_iterator = false;
  340. static const bool Q_is_generated = true;
  341. static const bool is_row = SpOp<T1, spop_type>::is_row;
  342. static const bool is_col = SpOp<T1, spop_type>::is_col;
  343. static const bool is_xvec = SpOp<T1, spop_type>::is_xvec;
  344. arma_aligned const SpMat<eT> Q;
  345. inline explicit SpProxy(const SpOp<T1, spop_type>& A)
  346. : Q(A)
  347. {
  348. arma_extra_debug_sigprint();
  349. }
  350. arma_inline uword get_n_rows() const { return is_row ? 1 : Q.n_rows; }
  351. arma_inline uword get_n_cols() const { return is_col ? 1 : Q.n_cols; }
  352. arma_inline uword get_n_elem() const { return Q.n_elem; }
  353. arma_inline uword get_n_nonzero() const { return Q.n_nonzero; }
  354. arma_inline elem_type operator[](const uword i) const { return Q[i]; }
  355. arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row, col); }
  356. arma_inline const eT* get_values() const { return Q.values; }
  357. arma_inline const uword* get_row_indices() const { return Q.row_indices; }
  358. arma_inline const uword* get_col_ptrs() const { return Q.col_ptrs; }
  359. arma_inline const_iterator_type begin() const { return Q.begin(); }
  360. arma_inline const_iterator_type begin_col(const uword col_num) const { return Q.begin_col(col_num); }
  361. arma_inline const_row_iterator_type begin_row(const uword row_num = 0) const { return Q.begin_row(row_num); }
  362. arma_inline const_iterator_type end() const { return Q.end(); }
  363. arma_inline const_row_iterator_type end_row() const { return Q.end_row(); }
  364. arma_inline const_row_iterator_type end_row(const uword row_num) const { return Q.end_row(row_num); }
  365. template<typename eT2>
  366. arma_inline bool is_alias(const SpMat<eT2>&) const { return false; }
  367. };
  368. template<typename T1, typename T2, typename spglue_type>
  369. class SpProxy< SpGlue<T1, T2, spglue_type> >
  370. {
  371. public:
  372. typedef typename T1::elem_type elem_type;
  373. typedef typename T1::elem_type eT;
  374. typedef typename get_pod_type<elem_type>::result pod_type;
  375. typedef SpMat<eT> stored_type;
  376. typedef typename SpMat<eT>::const_iterator const_iterator_type;
  377. typedef typename SpMat<eT>::const_row_iterator const_row_iterator_type;
  378. static const bool use_iterator = false;
  379. static const bool Q_is_generated = true;
  380. static const bool is_row = SpGlue<T1, T2, spglue_type>::is_row;
  381. static const bool is_col = SpGlue<T1, T2, spglue_type>::is_col;
  382. static const bool is_xvec = SpGlue<T1, T2, spglue_type>::is_xvec;
  383. arma_aligned const SpMat<eT> Q;
  384. inline explicit SpProxy(const SpGlue<T1, T2, spglue_type>& A)
  385. : Q(A)
  386. {
  387. arma_extra_debug_sigprint();
  388. }
  389. arma_inline uword get_n_rows() const { return is_row ? 1 : Q.n_rows; }
  390. arma_inline uword get_n_cols() const { return is_col ? 1 : Q.n_cols; }
  391. arma_inline uword get_n_elem() const { return Q.n_elem; }
  392. arma_inline uword get_n_nonzero() const { return Q.n_nonzero; }
  393. arma_inline elem_type operator[](const uword i) const { return Q[i]; }
  394. arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row, col); }
  395. arma_inline const eT* get_values() const { return Q.values; }
  396. arma_inline const uword* get_row_indices() const { return Q.row_indices; }
  397. arma_inline const uword* get_col_ptrs() const { return Q.col_ptrs; }
  398. arma_inline const_iterator_type begin() const { return Q.begin(); }
  399. arma_inline const_iterator_type begin_col(const uword col_num) const { return Q.begin_col(col_num); }
  400. arma_inline const_row_iterator_type begin_row(const uword row_num = 0) const { return Q.begin_row(row_num); }
  401. arma_inline const_iterator_type end() const { return Q.end(); }
  402. arma_inline const_row_iterator_type end_row() const { return Q.end_row(); }
  403. arma_inline const_row_iterator_type end_row(const uword row_num) const { return Q.end_row(row_num); }
  404. template<typename eT2>
  405. arma_inline bool is_alias(const SpMat<eT2>&) const { return false; }
  406. };
  407. template<typename out_eT, typename T1, typename spop_type>
  408. class SpProxy< mtSpOp<out_eT, T1, spop_type> >
  409. {
  410. public:
  411. typedef out_eT elem_type;
  412. typedef typename get_pod_type<elem_type>::result pod_type;
  413. typedef SpMat<out_eT> stored_type;
  414. typedef typename SpMat<out_eT>::const_iterator const_iterator_type;
  415. typedef typename SpMat<out_eT>::const_row_iterator const_row_iterator_type;
  416. static const bool use_iterator = false;
  417. static const bool Q_is_generated = true;
  418. static const bool is_row = mtSpOp<out_eT, T1, spop_type>::is_row;
  419. static const bool is_col = mtSpOp<out_eT, T1, spop_type>::is_col;
  420. static const bool is_xvec = mtSpOp<out_eT, T1, spop_type>::is_xvec;
  421. arma_aligned const SpMat<out_eT> Q;
  422. inline explicit SpProxy(const mtSpOp<out_eT, T1, spop_type>& A)
  423. : Q(A)
  424. {
  425. arma_extra_debug_sigprint();
  426. }
  427. arma_inline uword get_n_rows() const { return is_row ? 1 : Q.n_rows; }
  428. arma_inline uword get_n_cols() const { return is_col ? 1 : Q.n_cols; }
  429. arma_inline uword get_n_elem() const { return Q.n_elem; }
  430. arma_inline uword get_n_nonzero() const { return Q.n_nonzero; }
  431. arma_inline elem_type operator[](const uword i) const { return Q[i]; }
  432. arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row, col); }
  433. arma_inline const out_eT* get_values() const { return Q.values; }
  434. arma_inline const uword* get_row_indices() const { return Q.row_indices; }
  435. arma_inline const uword* get_col_ptrs() const { return Q.col_ptrs; }
  436. arma_inline const_iterator_type begin() const { return Q.begin(); }
  437. arma_inline const_iterator_type begin_col(const uword col_num) const { return Q.begin_col(col_num); }
  438. arma_inline const_row_iterator_type begin_row(const uword row_num = 0) const { return Q.begin_row(row_num); }
  439. arma_inline const_iterator_type end() const { return Q.end(); }
  440. arma_inline const_row_iterator_type end_row() const { return Q.end_row(); }
  441. arma_inline const_row_iterator_type end_row(const uword row_num) const { return Q.end_row(row_num); }
  442. template<typename eT2>
  443. arma_inline bool is_alias(const SpMat<eT2>&) const { return false; }
  444. };
  445. template<typename out_eT, typename T1, typename T2, typename spglue_type>
  446. class SpProxy< mtSpGlue<out_eT, T1, T2, spglue_type> >
  447. {
  448. public:
  449. typedef out_eT elem_type;
  450. typedef typename get_pod_type<elem_type>::result pod_type;
  451. typedef SpMat<out_eT> stored_type;
  452. typedef typename SpMat<out_eT>::const_iterator const_iterator_type;
  453. typedef typename SpMat<out_eT>::const_row_iterator const_row_iterator_type;
  454. static const bool use_iterator = false;
  455. static const bool Q_is_generated = true;
  456. static const bool is_row = mtSpGlue<out_eT, T1, T2, spglue_type>::is_row;
  457. static const bool is_col = mtSpGlue<out_eT, T1, T2, spglue_type>::is_col;
  458. static const bool is_xvec = mtSpGlue<out_eT, T1, T2, spglue_type>::is_xvec;
  459. arma_aligned const SpMat<out_eT> Q;
  460. inline explicit SpProxy(const mtSpGlue<out_eT, T1, T2, spglue_type>& A)
  461. : Q(A)
  462. {
  463. arma_extra_debug_sigprint();
  464. }
  465. arma_inline uword get_n_rows() const { return is_row ? 1 : Q.n_rows; }
  466. arma_inline uword get_n_cols() const { return is_col ? 1 : Q.n_cols; }
  467. arma_inline uword get_n_elem() const { return Q.n_elem; }
  468. arma_inline uword get_n_nonzero() const { return Q.n_nonzero; }
  469. arma_inline elem_type operator[](const uword i) const { return Q[i]; }
  470. arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row, col); }
  471. arma_inline const out_eT* get_values() const { return Q.values; }
  472. arma_inline const uword* get_row_indices() const { return Q.row_indices; }
  473. arma_inline const uword* get_col_ptrs() const { return Q.col_ptrs; }
  474. arma_inline const_iterator_type begin() const { return Q.begin(); }
  475. arma_inline const_iterator_type begin_col(const uword col_num) const { return Q.begin_col(col_num); }
  476. arma_inline const_row_iterator_type begin_row(const uword row_num = 0) const { return Q.begin_row(row_num); }
  477. arma_inline const_iterator_type end() const { return Q.end(); }
  478. arma_inline const_row_iterator_type end_row() const { return Q.end_row(); }
  479. arma_inline const_row_iterator_type end_row(const uword row_num) const { return Q.end_row(row_num); }
  480. template<typename eT2>
  481. arma_inline bool is_alias(const SpMat<eT2>&) const { return false; }
  482. };
  483. //! @}