subview_elem1_meat.hpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921
  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 subview_elem1
  16. //! @{
  17. template<typename eT, typename T1>
  18. inline
  19. subview_elem1<eT,T1>::~subview_elem1()
  20. {
  21. arma_extra_debug_sigprint();
  22. }
  23. template<typename eT, typename T1>
  24. arma_inline
  25. subview_elem1<eT,T1>::subview_elem1(const Mat<eT>& in_m, const Base<uword,T1>& in_a)
  26. : m(in_m)
  27. , a(in_a)
  28. {
  29. arma_extra_debug_sigprint();
  30. // TODO: refactor to unwrap 'in_a' instead of storing a ref to it; this will allow removal of carrying T1 around and repetition of size checks
  31. }
  32. template<typename eT, typename T1>
  33. arma_inline
  34. subview_elem1<eT,T1>::subview_elem1(const Cube<eT>& in_q, const Base<uword,T1>& in_a)
  35. : fake_m( const_cast< eT* >(in_q.memptr()), in_q.n_elem, 1, false )
  36. , m( fake_m )
  37. , a( in_a )
  38. {
  39. arma_extra_debug_sigprint();
  40. }
  41. template<typename eT, typename T1>
  42. template<typename op_type>
  43. inline
  44. void
  45. subview_elem1<eT,T1>::inplace_op(const eT val)
  46. {
  47. arma_extra_debug_sigprint();
  48. Mat<eT>& m_local = const_cast< Mat<eT>& >(m);
  49. eT* m_mem = m_local.memptr();
  50. const uword m_n_elem = m_local.n_elem;
  51. const unwrap_check_mixed<T1> tmp(a.get_ref(), m_local);
  52. const umat& aa = tmp.M;
  53. arma_debug_check
  54. (
  55. ( (aa.is_vec() == false) && (aa.is_empty() == false) ),
  56. "Mat::elem(): given object is not a vector"
  57. );
  58. const uword* aa_mem = aa.memptr();
  59. const uword aa_n_elem = aa.n_elem;
  60. uword iq,jq;
  61. for(iq=0, jq=1; jq < aa_n_elem; iq+=2, jq+=2)
  62. {
  63. const uword ii = aa_mem[iq];
  64. const uword jj = aa_mem[jq];
  65. arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" );
  66. if(is_same_type<op_type, op_internal_equ >::yes) { m_mem[ii] = val; m_mem[jj] = val; }
  67. if(is_same_type<op_type, op_internal_plus >::yes) { m_mem[ii] += val; m_mem[jj] += val; }
  68. if(is_same_type<op_type, op_internal_minus>::yes) { m_mem[ii] -= val; m_mem[jj] -= val; }
  69. if(is_same_type<op_type, op_internal_schur>::yes) { m_mem[ii] *= val; m_mem[jj] *= val; }
  70. if(is_same_type<op_type, op_internal_div >::yes) { m_mem[ii] /= val; m_mem[jj] /= val; }
  71. }
  72. if(iq < aa_n_elem)
  73. {
  74. const uword ii = aa_mem[iq];
  75. arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" );
  76. if(is_same_type<op_type, op_internal_equ >::yes) { m_mem[ii] = val; }
  77. if(is_same_type<op_type, op_internal_plus >::yes) { m_mem[ii] += val; }
  78. if(is_same_type<op_type, op_internal_minus>::yes) { m_mem[ii] -= val; }
  79. if(is_same_type<op_type, op_internal_schur>::yes) { m_mem[ii] *= val; }
  80. if(is_same_type<op_type, op_internal_div >::yes) { m_mem[ii] /= val; }
  81. }
  82. }
  83. template<typename eT, typename T1>
  84. template<typename op_type, typename T2>
  85. inline
  86. void
  87. subview_elem1<eT,T1>::inplace_op(const subview_elem1<eT,T2>& x)
  88. {
  89. arma_extra_debug_sigprint();
  90. subview_elem1<eT,T1>& s = *this;
  91. if(&(s.m) == &(x.m))
  92. {
  93. arma_extra_debug_print("subview_elem1::inplace_op(): aliasing detected");
  94. const Mat<eT> tmp(x);
  95. if(is_same_type<op_type, op_internal_equ >::yes) { s.operator= (tmp); }
  96. if(is_same_type<op_type, op_internal_plus >::yes) { s.operator+=(tmp); }
  97. if(is_same_type<op_type, op_internal_minus>::yes) { s.operator-=(tmp); }
  98. if(is_same_type<op_type, op_internal_schur>::yes) { s.operator%=(tmp); }
  99. if(is_same_type<op_type, op_internal_div >::yes) { s.operator/=(tmp); }
  100. }
  101. else
  102. {
  103. Mat<eT>& s_m_local = const_cast< Mat<eT>& >(s.m);
  104. const Mat<eT>& x_m_local = x.m;
  105. const unwrap_check_mixed<T1> s_tmp(s.a.get_ref(), s_m_local);
  106. const unwrap_check_mixed<T2> x_tmp(x.a.get_ref(), s_m_local);
  107. const umat& s_aa = s_tmp.M;
  108. const umat& x_aa = x_tmp.M;
  109. arma_debug_check
  110. (
  111. ( ((s_aa.is_vec() == false) && (s_aa.is_empty() == false)) || ((x_aa.is_vec() == false) && (x_aa.is_empty() == false)) ),
  112. "Mat::elem(): given object is not a vector"
  113. );
  114. const uword* s_aa_mem = s_aa.memptr();
  115. const uword* x_aa_mem = x_aa.memptr();
  116. const uword s_aa_n_elem = s_aa.n_elem;
  117. arma_debug_check( (s_aa_n_elem != x_aa.n_elem), "Mat::elem(): size mismatch" );
  118. eT* s_m_mem = s_m_local.memptr();
  119. const uword s_m_n_elem = s_m_local.n_elem;
  120. const eT* x_m_mem = x_m_local.memptr();
  121. const uword x_m_n_elem = x_m_local.n_elem;
  122. uword iq,jq;
  123. for(iq=0, jq=1; jq < s_aa_n_elem; iq+=2, jq+=2)
  124. {
  125. const uword s_ii = s_aa_mem[iq];
  126. const uword s_jj = s_aa_mem[jq];
  127. const uword x_ii = x_aa_mem[iq];
  128. const uword x_jj = x_aa_mem[jq];
  129. arma_debug_check
  130. (
  131. (s_ii >= s_m_n_elem) || (s_jj >= s_m_n_elem) || (x_ii >= x_m_n_elem) || (x_jj >= x_m_n_elem),
  132. "Mat::elem(): index out of bounds"
  133. );
  134. if(is_same_type<op_type, op_internal_equ >::yes) { s_m_mem[s_ii] = x_m_mem[x_ii]; s_m_mem[s_jj] = x_m_mem[x_jj]; }
  135. if(is_same_type<op_type, op_internal_plus >::yes) { s_m_mem[s_ii] += x_m_mem[x_ii]; s_m_mem[s_jj] += x_m_mem[x_jj]; }
  136. if(is_same_type<op_type, op_internal_minus>::yes) { s_m_mem[s_ii] -= x_m_mem[x_ii]; s_m_mem[s_jj] -= x_m_mem[x_jj]; }
  137. if(is_same_type<op_type, op_internal_schur>::yes) { s_m_mem[s_ii] *= x_m_mem[x_ii]; s_m_mem[s_jj] *= x_m_mem[x_jj]; }
  138. if(is_same_type<op_type, op_internal_div >::yes) { s_m_mem[s_ii] /= x_m_mem[x_ii]; s_m_mem[s_jj] /= x_m_mem[x_jj]; }
  139. }
  140. if(iq < s_aa_n_elem)
  141. {
  142. const uword s_ii = s_aa_mem[iq];
  143. const uword x_ii = x_aa_mem[iq];
  144. arma_debug_check
  145. (
  146. ( (s_ii >= s_m_n_elem) || (x_ii >= x_m_n_elem) ),
  147. "Mat::elem(): index out of bounds"
  148. );
  149. if(is_same_type<op_type, op_internal_equ >::yes) { s_m_mem[s_ii] = x_m_mem[x_ii]; }
  150. if(is_same_type<op_type, op_internal_plus >::yes) { s_m_mem[s_ii] += x_m_mem[x_ii]; }
  151. if(is_same_type<op_type, op_internal_minus>::yes) { s_m_mem[s_ii] -= x_m_mem[x_ii]; }
  152. if(is_same_type<op_type, op_internal_schur>::yes) { s_m_mem[s_ii] *= x_m_mem[x_ii]; }
  153. if(is_same_type<op_type, op_internal_div >::yes) { s_m_mem[s_ii] /= x_m_mem[x_ii]; }
  154. }
  155. }
  156. }
  157. template<typename eT, typename T1>
  158. template<typename op_type, typename T2>
  159. inline
  160. void
  161. subview_elem1<eT,T1>::inplace_op(const Base<eT,T2>& x)
  162. {
  163. arma_extra_debug_sigprint();
  164. Mat<eT>& m_local = const_cast< Mat<eT>& >(m);
  165. eT* m_mem = m_local.memptr();
  166. const uword m_n_elem = m_local.n_elem;
  167. const unwrap_check_mixed<T1> aa_tmp(a.get_ref(), m_local);
  168. const umat& aa = aa_tmp.M;
  169. arma_debug_check
  170. (
  171. ( (aa.is_vec() == false) && (aa.is_empty() == false) ),
  172. "Mat::elem(): given object is not a vector"
  173. );
  174. const uword* aa_mem = aa.memptr();
  175. const uword aa_n_elem = aa.n_elem;
  176. const Proxy<T2> P(x.get_ref());
  177. arma_debug_check( (aa_n_elem != P.get_n_elem()), "Mat::elem(): size mismatch" );
  178. const bool is_alias = P.is_alias(m);
  179. if( (is_alias == false) && (Proxy<T2>::use_at == false) )
  180. {
  181. typename Proxy<T2>::ea_type X = P.get_ea();
  182. uword iq,jq;
  183. for(iq=0, jq=1; jq < aa_n_elem; iq+=2, jq+=2)
  184. {
  185. const uword ii = aa_mem[iq];
  186. const uword jj = aa_mem[jq];
  187. arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" );
  188. if(is_same_type<op_type, op_internal_equ >::yes) { m_mem[ii] = X[iq]; m_mem[jj] = X[jq]; }
  189. if(is_same_type<op_type, op_internal_plus >::yes) { m_mem[ii] += X[iq]; m_mem[jj] += X[jq]; }
  190. if(is_same_type<op_type, op_internal_minus>::yes) { m_mem[ii] -= X[iq]; m_mem[jj] -= X[jq]; }
  191. if(is_same_type<op_type, op_internal_schur>::yes) { m_mem[ii] *= X[iq]; m_mem[jj] *= X[jq]; }
  192. if(is_same_type<op_type, op_internal_div >::yes) { m_mem[ii] /= X[iq]; m_mem[jj] /= X[jq]; }
  193. }
  194. if(iq < aa_n_elem)
  195. {
  196. const uword ii = aa_mem[iq];
  197. arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" );
  198. if(is_same_type<op_type, op_internal_equ >::yes) { m_mem[ii] = X[iq]; }
  199. if(is_same_type<op_type, op_internal_plus >::yes) { m_mem[ii] += X[iq]; }
  200. if(is_same_type<op_type, op_internal_minus>::yes) { m_mem[ii] -= X[iq]; }
  201. if(is_same_type<op_type, op_internal_schur>::yes) { m_mem[ii] *= X[iq]; }
  202. if(is_same_type<op_type, op_internal_div >::yes) { m_mem[ii] /= X[iq]; }
  203. }
  204. }
  205. else
  206. {
  207. arma_extra_debug_print("subview_elem1::inplace_op(): aliasing or use_at detected");
  208. const unwrap_check<typename Proxy<T2>::stored_type> tmp(P.Q, is_alias);
  209. const Mat<eT>& M = tmp.M;
  210. const eT* X = M.memptr();
  211. uword iq,jq;
  212. for(iq=0, jq=1; jq < aa_n_elem; iq+=2, jq+=2)
  213. {
  214. const uword ii = aa_mem[iq];
  215. const uword jj = aa_mem[jq];
  216. arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" );
  217. if(is_same_type<op_type, op_internal_equ >::yes) { m_mem[ii] = X[iq]; m_mem[jj] = X[jq]; }
  218. if(is_same_type<op_type, op_internal_plus >::yes) { m_mem[ii] += X[iq]; m_mem[jj] += X[jq]; }
  219. if(is_same_type<op_type, op_internal_minus>::yes) { m_mem[ii] -= X[iq]; m_mem[jj] -= X[jq]; }
  220. if(is_same_type<op_type, op_internal_schur>::yes) { m_mem[ii] *= X[iq]; m_mem[jj] *= X[jq]; }
  221. if(is_same_type<op_type, op_internal_div >::yes) { m_mem[ii] /= X[iq]; m_mem[jj] /= X[jq]; }
  222. }
  223. if(iq < aa_n_elem)
  224. {
  225. const uword ii = aa_mem[iq];
  226. arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" );
  227. if(is_same_type<op_type, op_internal_equ >::yes) { m_mem[ii] = X[iq]; }
  228. if(is_same_type<op_type, op_internal_plus >::yes) { m_mem[ii] += X[iq]; }
  229. if(is_same_type<op_type, op_internal_minus>::yes) { m_mem[ii] -= X[iq]; }
  230. if(is_same_type<op_type, op_internal_schur>::yes) { m_mem[ii] *= X[iq]; }
  231. if(is_same_type<op_type, op_internal_div >::yes) { m_mem[ii] /= X[iq]; }
  232. }
  233. }
  234. }
  235. //
  236. //
  237. template<typename eT, typename T1>
  238. arma_inline
  239. const Op<subview_elem1<eT,T1>,op_htrans>
  240. subview_elem1<eT,T1>::t() const
  241. {
  242. return Op<subview_elem1<eT,T1>,op_htrans>(*this);
  243. }
  244. template<typename eT, typename T1>
  245. arma_inline
  246. const Op<subview_elem1<eT,T1>,op_htrans>
  247. subview_elem1<eT,T1>::ht() const
  248. {
  249. return Op<subview_elem1<eT,T1>,op_htrans>(*this);
  250. }
  251. template<typename eT, typename T1>
  252. arma_inline
  253. const Op<subview_elem1<eT,T1>,op_strans>
  254. subview_elem1<eT,T1>::st() const
  255. {
  256. return Op<subview_elem1<eT,T1>,op_strans>(*this);
  257. }
  258. template<typename eT, typename T1>
  259. inline
  260. void
  261. subview_elem1<eT,T1>::replace(const eT old_val, const eT new_val)
  262. {
  263. arma_extra_debug_sigprint();
  264. Mat<eT>& m_local = const_cast< Mat<eT>& >(m);
  265. eT* m_mem = m_local.memptr();
  266. const uword m_n_elem = m_local.n_elem;
  267. const unwrap_check_mixed<T1> tmp(a.get_ref(), m_local);
  268. const umat& aa = tmp.M;
  269. arma_debug_check
  270. (
  271. ( (aa.is_vec() == false) && (aa.is_empty() == false) ),
  272. "Mat::elem(): given object is not a vector"
  273. );
  274. const uword* aa_mem = aa.memptr();
  275. const uword aa_n_elem = aa.n_elem;
  276. if(arma_isnan(old_val))
  277. {
  278. for(uword iq=0; iq < aa_n_elem; ++iq)
  279. {
  280. const uword ii = aa_mem[iq];
  281. arma_debug_check( (ii >= m_n_elem), "Mat::elem(): index out of bounds" );
  282. eT& val = m_mem[ii];
  283. val = (arma_isnan(val)) ? new_val : val;
  284. }
  285. }
  286. else
  287. {
  288. for(uword iq=0; iq < aa_n_elem; ++iq)
  289. {
  290. const uword ii = aa_mem[iq];
  291. arma_debug_check( (ii >= m_n_elem), "Mat::elem(): index out of bounds" );
  292. eT& val = m_mem[ii];
  293. val = (val == old_val) ? new_val : val;
  294. }
  295. }
  296. }
  297. template<typename eT, typename T1>
  298. inline
  299. void
  300. subview_elem1<eT,T1>::fill(const eT val)
  301. {
  302. arma_extra_debug_sigprint();
  303. inplace_op<op_internal_equ>(val);
  304. }
  305. template<typename eT, typename T1>
  306. inline
  307. void
  308. subview_elem1<eT,T1>::zeros()
  309. {
  310. arma_extra_debug_sigprint();
  311. inplace_op<op_internal_equ>(eT(0));
  312. }
  313. template<typename eT, typename T1>
  314. inline
  315. void
  316. subview_elem1<eT,T1>::ones()
  317. {
  318. arma_extra_debug_sigprint();
  319. inplace_op<op_internal_equ>(eT(1));
  320. }
  321. template<typename eT, typename T1>
  322. inline
  323. void
  324. subview_elem1<eT,T1>::randu()
  325. {
  326. arma_extra_debug_sigprint();
  327. Mat<eT>& m_local = const_cast< Mat<eT>& >(m);
  328. eT* m_mem = m_local.memptr();
  329. const uword m_n_elem = m_local.n_elem;
  330. const unwrap_check_mixed<T1> tmp(a.get_ref(), m_local);
  331. const umat& aa = tmp.M;
  332. arma_debug_check
  333. (
  334. ( (aa.is_vec() == false) && (aa.is_empty() == false) ),
  335. "Mat::elem(): given object is not a vector"
  336. );
  337. const uword* aa_mem = aa.memptr();
  338. const uword aa_n_elem = aa.n_elem;
  339. uword iq,jq;
  340. for(iq=0, jq=1; jq < aa_n_elem; iq+=2, jq+=2)
  341. {
  342. const uword ii = aa_mem[iq];
  343. const uword jj = aa_mem[jq];
  344. arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" );
  345. const eT val1 = eT(arma_rng::randu<eT>());
  346. const eT val2 = eT(arma_rng::randu<eT>());
  347. m_mem[ii] = val1;
  348. m_mem[jj] = val2;
  349. }
  350. if(iq < aa_n_elem)
  351. {
  352. const uword ii = aa_mem[iq];
  353. arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" );
  354. m_mem[ii] = eT(arma_rng::randu<eT>());
  355. }
  356. }
  357. template<typename eT, typename T1>
  358. inline
  359. void
  360. subview_elem1<eT,T1>::randn()
  361. {
  362. arma_extra_debug_sigprint();
  363. Mat<eT>& m_local = const_cast< Mat<eT>& >(m);
  364. eT* m_mem = m_local.memptr();
  365. const uword m_n_elem = m_local.n_elem;
  366. const unwrap_check_mixed<T1> tmp(a.get_ref(), m_local);
  367. const umat& aa = tmp.M;
  368. arma_debug_check
  369. (
  370. ( (aa.is_vec() == false) && (aa.is_empty() == false) ),
  371. "Mat::elem(): given object is not a vector"
  372. );
  373. const uword* aa_mem = aa.memptr();
  374. const uword aa_n_elem = aa.n_elem;
  375. uword iq,jq;
  376. for(iq=0, jq=1; jq < aa_n_elem; iq+=2, jq+=2)
  377. {
  378. const uword ii = aa_mem[iq];
  379. const uword jj = aa_mem[jq];
  380. arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" );
  381. arma_rng::randn<eT>::dual_val( m_mem[ii], m_mem[jj] );
  382. }
  383. if(iq < aa_n_elem)
  384. {
  385. const uword ii = aa_mem[iq];
  386. arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" );
  387. m_mem[ii] = eT(arma_rng::randn<eT>());
  388. }
  389. }
  390. template<typename eT, typename T1>
  391. inline
  392. void
  393. subview_elem1<eT,T1>::operator+= (const eT val)
  394. {
  395. arma_extra_debug_sigprint();
  396. inplace_op<op_internal_plus>(val);
  397. }
  398. template<typename eT, typename T1>
  399. inline
  400. void
  401. subview_elem1<eT,T1>::operator-= (const eT val)
  402. {
  403. arma_extra_debug_sigprint();
  404. inplace_op<op_internal_minus>(val);
  405. }
  406. template<typename eT, typename T1>
  407. inline
  408. void
  409. subview_elem1<eT,T1>::operator*= (const eT val)
  410. {
  411. arma_extra_debug_sigprint();
  412. inplace_op<op_internal_schur>(val);
  413. }
  414. template<typename eT, typename T1>
  415. inline
  416. void
  417. subview_elem1<eT,T1>::operator/= (const eT val)
  418. {
  419. arma_extra_debug_sigprint();
  420. inplace_op<op_internal_div>(val);
  421. }
  422. //
  423. //
  424. template<typename eT, typename T1>
  425. template<typename T2>
  426. inline
  427. void
  428. subview_elem1<eT,T1>::operator_equ(const subview_elem1<eT,T2>& x)
  429. {
  430. arma_extra_debug_sigprint();
  431. inplace_op<op_internal_equ>(x);
  432. }
  433. template<typename eT, typename T1>
  434. template<typename T2>
  435. inline
  436. void
  437. subview_elem1<eT,T1>::operator= (const subview_elem1<eT,T2>& x)
  438. {
  439. arma_extra_debug_sigprint();
  440. (*this).operator_equ(x);
  441. }
  442. //! work around compiler bugs
  443. template<typename eT, typename T1>
  444. inline
  445. void
  446. subview_elem1<eT,T1>::operator= (const subview_elem1<eT,T1>& x)
  447. {
  448. arma_extra_debug_sigprint();
  449. (*this).operator_equ(x);
  450. }
  451. template<typename eT, typename T1>
  452. template<typename T2>
  453. inline
  454. void
  455. subview_elem1<eT,T1>::operator+= (const subview_elem1<eT,T2>& x)
  456. {
  457. arma_extra_debug_sigprint();
  458. inplace_op<op_internal_plus>(x);
  459. }
  460. template<typename eT, typename T1>
  461. template<typename T2>
  462. inline
  463. void
  464. subview_elem1<eT,T1>::operator-= (const subview_elem1<eT,T2>& x)
  465. {
  466. arma_extra_debug_sigprint();
  467. inplace_op<op_internal_minus>(x);
  468. }
  469. template<typename eT, typename T1>
  470. template<typename T2>
  471. inline
  472. void
  473. subview_elem1<eT,T1>::operator%= (const subview_elem1<eT,T2>& x)
  474. {
  475. arma_extra_debug_sigprint();
  476. inplace_op<op_internal_schur>(x);
  477. }
  478. template<typename eT, typename T1>
  479. template<typename T2>
  480. inline
  481. void
  482. subview_elem1<eT,T1>::operator/= (const subview_elem1<eT,T2>& x)
  483. {
  484. arma_extra_debug_sigprint();
  485. inplace_op<op_internal_div>(x);
  486. }
  487. template<typename eT, typename T1>
  488. template<typename T2>
  489. inline
  490. void
  491. subview_elem1<eT,T1>::operator= (const Base<eT,T2>& x)
  492. {
  493. arma_extra_debug_sigprint();
  494. inplace_op<op_internal_equ>(x);
  495. }
  496. template<typename eT, typename T1>
  497. template<typename T2>
  498. inline
  499. void
  500. subview_elem1<eT,T1>::operator+= (const Base<eT,T2>& x)
  501. {
  502. arma_extra_debug_sigprint();
  503. inplace_op<op_internal_plus>(x);
  504. }
  505. template<typename eT, typename T1>
  506. template<typename T2>
  507. inline
  508. void
  509. subview_elem1<eT,T1>::operator-= (const Base<eT,T2>& x)
  510. {
  511. arma_extra_debug_sigprint();
  512. inplace_op<op_internal_minus>(x);
  513. }
  514. template<typename eT, typename T1>
  515. template<typename T2>
  516. inline
  517. void
  518. subview_elem1<eT,T1>::operator%= (const Base<eT,T2>& x)
  519. {
  520. arma_extra_debug_sigprint();
  521. inplace_op<op_internal_schur>(x);
  522. }
  523. template<typename eT, typename T1>
  524. template<typename T2>
  525. inline
  526. void
  527. subview_elem1<eT,T1>::operator/= (const Base<eT,T2>& x)
  528. {
  529. arma_extra_debug_sigprint();
  530. inplace_op<op_internal_div>(x);
  531. }
  532. //
  533. //
  534. template<typename eT, typename T1>
  535. inline
  536. void
  537. subview_elem1<eT,T1>::extract(Mat<eT>& actual_out, const subview_elem1<eT,T1>& in)
  538. {
  539. arma_extra_debug_sigprint();
  540. const unwrap_check_mixed<T1> tmp1(in.a.get_ref(), actual_out);
  541. const umat& aa = tmp1.M;
  542. arma_debug_check
  543. (
  544. ( (aa.is_vec() == false) && (aa.is_empty() == false) ),
  545. "Mat::elem(): given object is not a vector"
  546. );
  547. const uword* aa_mem = aa.memptr();
  548. const uword aa_n_elem = aa.n_elem;
  549. const Mat<eT>& m_local = in.m;
  550. const eT* m_mem = m_local.memptr();
  551. const uword m_n_elem = m_local.n_elem;
  552. const bool alias = (&actual_out == &m_local);
  553. if(alias) { arma_extra_debug_print("subview_elem1::extract(): aliasing detected"); }
  554. Mat<eT>* tmp_out = alias ? new Mat<eT>() : 0;
  555. Mat<eT>& out = alias ? *tmp_out : actual_out;
  556. out.set_size(aa_n_elem, 1);
  557. eT* out_mem = out.memptr();
  558. uword i,j;
  559. for(i=0, j=1; j<aa_n_elem; i+=2, j+=2)
  560. {
  561. const uword ii = aa_mem[i];
  562. const uword jj = aa_mem[j];
  563. arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" );
  564. out_mem[i] = m_mem[ii];
  565. out_mem[j] = m_mem[jj];
  566. }
  567. if(i < aa_n_elem)
  568. {
  569. const uword ii = aa_mem[i];
  570. arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" );
  571. out_mem[i] = m_mem[ii];
  572. }
  573. if(alias)
  574. {
  575. actual_out.steal_mem(out);
  576. delete tmp_out;
  577. }
  578. }
  579. template<typename eT, typename T1>
  580. template<typename op_type>
  581. inline
  582. void
  583. subview_elem1<eT,T1>::mat_inplace_op(Mat<eT>& out, const subview_elem1& in)
  584. {
  585. arma_extra_debug_sigprint();
  586. const unwrap<T1> tmp1(in.a.get_ref());
  587. const umat& aa = tmp1.M;
  588. arma_debug_check
  589. (
  590. ( (aa.is_vec() == false) && (aa.is_empty() == false) ),
  591. "Mat::elem(): given object is not a vector"
  592. );
  593. const uword* aa_mem = aa.memptr();
  594. const uword aa_n_elem = aa.n_elem;
  595. const unwrap_check< Mat<eT> > tmp2(in.m, out);
  596. const Mat<eT>& m_local = tmp2.M;
  597. const eT* m_mem = m_local.memptr();
  598. const uword m_n_elem = m_local.n_elem;
  599. arma_debug_check( (out.n_elem != aa_n_elem), "Mat::elem(): size mismatch" );
  600. eT* out_mem = out.memptr();
  601. uword i,j;
  602. for(i=0, j=1; j<aa_n_elem; i+=2, j+=2)
  603. {
  604. const uword ii = aa_mem[i];
  605. const uword jj = aa_mem[j];
  606. arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" );
  607. if(is_same_type<op_type, op_internal_plus >::yes) { out_mem[i] += m_mem[ii]; out_mem[j] += m_mem[jj]; }
  608. if(is_same_type<op_type, op_internal_minus>::yes) { out_mem[i] -= m_mem[ii]; out_mem[j] -= m_mem[jj]; }
  609. if(is_same_type<op_type, op_internal_schur>::yes) { out_mem[i] *= m_mem[ii]; out_mem[j] *= m_mem[jj]; }
  610. if(is_same_type<op_type, op_internal_div >::yes) { out_mem[i] /= m_mem[ii]; out_mem[j] /= m_mem[jj]; }
  611. }
  612. if(i < aa_n_elem)
  613. {
  614. const uword ii = aa_mem[i];
  615. arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" );
  616. if(is_same_type<op_type, op_internal_plus >::yes) { out_mem[i] += m_mem[ii]; }
  617. if(is_same_type<op_type, op_internal_minus>::yes) { out_mem[i] -= m_mem[ii]; }
  618. if(is_same_type<op_type, op_internal_schur>::yes) { out_mem[i] *= m_mem[ii]; }
  619. if(is_same_type<op_type, op_internal_div >::yes) { out_mem[i] /= m_mem[ii]; }
  620. }
  621. }
  622. template<typename eT, typename T1>
  623. inline
  624. void
  625. subview_elem1<eT,T1>::plus_inplace(Mat<eT>& out, const subview_elem1& in)
  626. {
  627. arma_extra_debug_sigprint();
  628. mat_inplace_op<op_internal_plus>(out, in);
  629. }
  630. template<typename eT, typename T1>
  631. inline
  632. void
  633. subview_elem1<eT,T1>::minus_inplace(Mat<eT>& out, const subview_elem1& in)
  634. {
  635. arma_extra_debug_sigprint();
  636. mat_inplace_op<op_internal_minus>(out, in);
  637. }
  638. template<typename eT, typename T1>
  639. inline
  640. void
  641. subview_elem1<eT,T1>::schur_inplace(Mat<eT>& out, const subview_elem1& in)
  642. {
  643. arma_extra_debug_sigprint();
  644. mat_inplace_op<op_internal_schur>(out, in);
  645. }
  646. template<typename eT, typename T1>
  647. inline
  648. void
  649. subview_elem1<eT,T1>::div_inplace(Mat<eT>& out, const subview_elem1& in)
  650. {
  651. arma_extra_debug_sigprint();
  652. mat_inplace_op<op_internal_div>(out, in);
  653. }
  654. //! @}