subview_each_meat.hpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401
  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_each
  16. //! @{
  17. //
  18. //
  19. // subview_each_common
  20. template<typename parent, unsigned int mode>
  21. inline
  22. subview_each_common<parent,mode>::subview_each_common(const parent& in_P)
  23. : P(in_P)
  24. {
  25. arma_extra_debug_sigprint();
  26. }
  27. template<typename parent, unsigned int mode>
  28. arma_inline
  29. const Mat<typename parent::elem_type>&
  30. subview_each_common<parent,mode>::get_mat_ref_helper(const Mat<typename parent::elem_type>& X) const
  31. {
  32. return X;
  33. }
  34. template<typename parent, unsigned int mode>
  35. arma_inline
  36. const Mat<typename parent::elem_type>&
  37. subview_each_common<parent,mode>::get_mat_ref_helper(const subview<typename parent::elem_type>& X) const
  38. {
  39. return X.m;
  40. }
  41. template<typename parent, unsigned int mode>
  42. arma_inline
  43. const Mat<typename parent::elem_type>&
  44. subview_each_common<parent,mode>::get_mat_ref() const
  45. {
  46. return get_mat_ref_helper(P);
  47. }
  48. template<typename parent, unsigned int mode>
  49. inline
  50. void
  51. subview_each_common<parent,mode>::check_size(const Mat<typename parent::elem_type>& A) const
  52. {
  53. if(arma_config::debug == true)
  54. {
  55. if(mode == 0)
  56. {
  57. if( (A.n_rows != P.n_rows) || (A.n_cols != 1) )
  58. {
  59. arma_stop_logic_error( incompat_size_string(A) );
  60. }
  61. }
  62. else
  63. {
  64. if( (A.n_rows != 1) || (A.n_cols != P.n_cols) )
  65. {
  66. arma_stop_logic_error( incompat_size_string(A) );
  67. }
  68. }
  69. }
  70. }
  71. template<typename parent, unsigned int mode>
  72. arma_cold
  73. inline
  74. const std::string
  75. subview_each_common<parent,mode>::incompat_size_string(const Mat<typename parent::elem_type>& A) const
  76. {
  77. std::ostringstream tmp;
  78. if(mode == 0)
  79. {
  80. tmp << "each_col(): incompatible size; expected " << P.n_rows << "x1" << ", got " << A.n_rows << 'x' << A.n_cols;
  81. }
  82. else
  83. {
  84. tmp << "each_row(): incompatible size; expected 1x" << P.n_cols << ", got " << A.n_rows << 'x' << A.n_cols;
  85. }
  86. return tmp.str();
  87. }
  88. //
  89. //
  90. // subview_each1
  91. template<typename parent, unsigned int mode>
  92. inline
  93. subview_each1<parent,mode>::~subview_each1()
  94. {
  95. arma_extra_debug_sigprint();
  96. }
  97. template<typename parent, unsigned int mode>
  98. inline
  99. subview_each1<parent,mode>::subview_each1(const parent& in_P)
  100. : subview_each_common<parent,mode>::subview_each_common(in_P)
  101. {
  102. arma_extra_debug_sigprint();
  103. }
  104. template<typename parent, unsigned int mode>
  105. template<typename T1>
  106. inline
  107. void
  108. subview_each1<parent,mode>::operator= (const Base<eT,T1>& in)
  109. {
  110. arma_extra_debug_sigprint();
  111. parent& p = access::rw(subview_each_common<parent,mode>::P);
  112. const unwrap_check<T1> tmp( in.get_ref(), (*this).get_mat_ref() );
  113. const Mat<eT>& A = tmp.M;
  114. subview_each_common<parent,mode>::check_size(A);
  115. const eT* A_mem = A.memptr();
  116. const uword p_n_rows = p.n_rows;
  117. const uword p_n_cols = p.n_cols;
  118. if(mode == 0) // each column
  119. {
  120. for(uword i=0; i < p_n_cols; ++i)
  121. {
  122. arrayops::copy( p.colptr(i), A_mem, p_n_rows );
  123. }
  124. }
  125. else // each row
  126. {
  127. for(uword i=0; i < p_n_cols; ++i)
  128. {
  129. arrayops::inplace_set( p.colptr(i), A_mem[i], p_n_rows);
  130. }
  131. }
  132. }
  133. template<typename parent, unsigned int mode>
  134. template<typename T1>
  135. inline
  136. void
  137. subview_each1<parent,mode>::operator+= (const Base<eT,T1>& in)
  138. {
  139. arma_extra_debug_sigprint();
  140. parent& p = access::rw(subview_each_common<parent,mode>::P);
  141. const unwrap_check<T1> tmp( in.get_ref(), (*this).get_mat_ref() );
  142. const Mat<eT>& A = tmp.M;
  143. subview_each_common<parent,mode>::check_size(A);
  144. const eT* A_mem = A.memptr();
  145. const uword p_n_rows = p.n_rows;
  146. const uword p_n_cols = p.n_cols;
  147. if(mode == 0) // each column
  148. {
  149. for(uword i=0; i < p_n_cols; ++i)
  150. {
  151. arrayops::inplace_plus( p.colptr(i), A_mem, p_n_rows );
  152. }
  153. }
  154. else // each row
  155. {
  156. for(uword i=0; i < p_n_cols; ++i)
  157. {
  158. arrayops::inplace_plus( p.colptr(i), A_mem[i], p_n_rows);
  159. }
  160. }
  161. }
  162. template<typename parent, unsigned int mode>
  163. template<typename T1>
  164. inline
  165. void
  166. subview_each1<parent,mode>::operator-= (const Base<eT,T1>& in)
  167. {
  168. arma_extra_debug_sigprint();
  169. parent& p = access::rw(subview_each_common<parent,mode>::P);
  170. const unwrap_check<T1> tmp( in.get_ref(), (*this).get_mat_ref() );
  171. const Mat<eT>& A = tmp.M;
  172. subview_each_common<parent,mode>::check_size(A);
  173. const eT* A_mem = A.memptr();
  174. const uword p_n_rows = p.n_rows;
  175. const uword p_n_cols = p.n_cols;
  176. if(mode == 0) // each column
  177. {
  178. for(uword i=0; i < p_n_cols; ++i)
  179. {
  180. arrayops::inplace_minus( p.colptr(i), A_mem, p_n_rows );
  181. }
  182. }
  183. else // each row
  184. {
  185. for(uword i=0; i < p_n_cols; ++i)
  186. {
  187. arrayops::inplace_minus( p.colptr(i), A_mem[i], p_n_rows);
  188. }
  189. }
  190. }
  191. template<typename parent, unsigned int mode>
  192. template<typename T1>
  193. inline
  194. void
  195. subview_each1<parent,mode>::operator%= (const Base<eT,T1>& in)
  196. {
  197. arma_extra_debug_sigprint();
  198. parent& p = access::rw(subview_each_common<parent,mode>::P);
  199. const unwrap_check<T1> tmp( in.get_ref(), (*this).get_mat_ref() );
  200. const Mat<eT>& A = tmp.M;
  201. subview_each_common<parent,mode>::check_size(A);
  202. const eT* A_mem = A.memptr();
  203. const uword p_n_rows = p.n_rows;
  204. const uword p_n_cols = p.n_cols;
  205. if(mode == 0) // each column
  206. {
  207. for(uword i=0; i < p_n_cols; ++i)
  208. {
  209. arrayops::inplace_mul( p.colptr(i), A_mem, p_n_rows );
  210. }
  211. }
  212. else // each row
  213. {
  214. for(uword i=0; i < p_n_cols; ++i)
  215. {
  216. arrayops::inplace_mul( p.colptr(i), A_mem[i], p_n_rows);
  217. }
  218. }
  219. }
  220. template<typename parent, unsigned int mode>
  221. template<typename T1>
  222. inline
  223. void
  224. subview_each1<parent,mode>::operator/= (const Base<eT,T1>& in)
  225. {
  226. arma_extra_debug_sigprint();
  227. parent& p = access::rw(subview_each_common<parent,mode>::P);
  228. const unwrap_check<T1> tmp( in.get_ref(), (*this).get_mat_ref() );
  229. const Mat<eT>& A = tmp.M;
  230. subview_each_common<parent,mode>::check_size(A);
  231. const eT* A_mem = A.memptr();
  232. const uword p_n_rows = p.n_rows;
  233. const uword p_n_cols = p.n_cols;
  234. if(mode == 0) // each column
  235. {
  236. for(uword i=0; i < p_n_cols; ++i)
  237. {
  238. arrayops::inplace_div( p.colptr(i), A_mem, p_n_rows );
  239. }
  240. }
  241. else // each row
  242. {
  243. for(uword i=0; i < p_n_cols; ++i)
  244. {
  245. arrayops::inplace_div( p.colptr(i), A_mem[i], p_n_rows);
  246. }
  247. }
  248. }
  249. //
  250. //
  251. // subview_each2
  252. template<typename parent, unsigned int mode, typename TB>
  253. inline
  254. subview_each2<parent,mode,TB>::~subview_each2()
  255. {
  256. arma_extra_debug_sigprint();
  257. }
  258. template<typename parent, unsigned int mode, typename TB>
  259. inline
  260. subview_each2<parent,mode,TB>::subview_each2(const parent& in_P, const Base<uword, TB>& in_indices)
  261. : subview_each_common<parent,mode>::subview_each_common(in_P)
  262. , base_indices(in_indices)
  263. {
  264. arma_extra_debug_sigprint();
  265. }
  266. template<typename parent, unsigned int mode, typename TB>
  267. inline
  268. void
  269. subview_each2<parent,mode,TB>::check_indices(const Mat<uword>& indices) const
  270. {
  271. if(mode == 0)
  272. {
  273. arma_debug_check( ((indices.is_vec() == false) && (indices.is_empty() == false)), "each_col(): list of indices must be a vector" );
  274. }
  275. else
  276. {
  277. arma_debug_check( ((indices.is_vec() == false) && (indices.is_empty() == false)), "each_row(): list of indices must be a vector" );
  278. }
  279. }
  280. template<typename parent, unsigned int mode, typename TB>
  281. template<typename T1>
  282. inline
  283. void
  284. subview_each2<parent,mode,TB>::operator= (const Base<eT,T1>& in)
  285. {
  286. arma_extra_debug_sigprint();
  287. parent& p = access::rw(subview_each_common<parent,mode>::P);
  288. const unwrap_check<T1> tmp( in.get_ref(), (*this).get_mat_ref() );
  289. const Mat<eT>& A = tmp.M;
  290. subview_each_common<parent,mode>::check_size(A);
  291. const unwrap_check_mixed<TB> U( base_indices.get_ref(), (*this).get_mat_ref() );
  292. check_indices(U.M);
  293. const eT* A_mem = A.memptr();
  294. const uword p_n_rows = p.n_rows;
  295. const uword p_n_cols = p.n_cols;
  296. const uword* indices_mem = U.M.memptr();
  297. const uword N = U.M.n_elem;
  298. if(mode == 0) // each column
  299. {
  300. for(uword i=0; i < N; ++i)
  301. {
  302. const uword col = indices_mem[i];
  303. arma_debug_check( (col >= p_n_cols), "each_col(): index out of bounds" );
  304. arrayops::copy( p.colptr(col), A_mem, p_n_rows );
  305. }
  306. }
  307. else // each row
  308. {
  309. for(uword i=0; i < N; ++i)
  310. {
  311. const uword row = indices_mem[i];
  312. arma_debug_check( (row >= p_n_rows), "each_row(): index out of bounds" );
  313. for(uword col=0; col < p_n_cols; ++col)
  314. {
  315. p.at(row,col) = A_mem[col];
  316. }
  317. }
  318. }
  319. }
  320. template<typename parent, unsigned int mode, typename TB>
  321. template<typename T1>
  322. inline
  323. void
  324. subview_each2<parent,mode,TB>::operator+= (const Base<eT,T1>& in)
  325. {
  326. arma_extra_debug_sigprint();
  327. parent& p = access::rw(subview_each_common<parent,mode>::P);
  328. const unwrap_check<T1> tmp( in.get_ref(), (*this).get_mat_ref() );
  329. const Mat<eT>& A = tmp.M;
  330. subview_each_common<parent,mode>::check_size(A);
  331. const unwrap_check_mixed<TB> U( base_indices.get_ref(), (*this).get_mat_ref() );
  332. check_indices(U.M);
  333. const uword p_n_rows = p.n_rows;
  334. const uword p_n_cols = p.n_cols;
  335. const uword* indices_mem = U.M.memptr();
  336. const uword N = U.M.n_elem;
  337. if(mode == 0) // each column
  338. {
  339. const eT* A_mem = A.memptr();
  340. for(uword i=0; i < N; ++i)
  341. {
  342. const uword col = indices_mem[i];
  343. arma_debug_check( (col >= p_n_cols), "each_col(): index out of bounds" );
  344. arrayops::inplace_plus( p.colptr(col), A_mem, p_n_rows );
  345. }
  346. }
  347. else // each row
  348. {
  349. for(uword i=0; i < N; ++i)
  350. {
  351. const uword row = indices_mem[i];
  352. arma_debug_check( (row >= p_n_rows), "each_row(): index out of bounds" );
  353. p.row(row) += A;
  354. }
  355. }
  356. }
  357. template<typename parent, unsigned int mode, typename TB>
  358. template<typename T1>
  359. inline
  360. void
  361. subview_each2<parent,mode,TB>::operator-= (const Base<eT,T1>& in)
  362. {
  363. arma_extra_debug_sigprint();
  364. parent& p = access::rw(subview_each_common<parent,mode>::P);
  365. const unwrap_check<T1> tmp( in.get_ref(), (*this).get_mat_ref() );
  366. const Mat<eT>& A = tmp.M;
  367. subview_each_common<parent,mode>::check_size(A);
  368. const unwrap_check_mixed<TB> U( base_indices.get_ref(), (*this).get_mat_ref() );
  369. check_indices(U.M);
  370. const uword p_n_rows = p.n_rows;
  371. const uword p_n_cols = p.n_cols;
  372. const uword* indices_mem = U.M.memptr();
  373. const uword N = U.M.n_elem;
  374. if(mode == 0) // each column
  375. {
  376. const eT* A_mem = A.memptr();
  377. for(uword i=0; i < N; ++i)
  378. {
  379. const uword col = indices_mem[i];
  380. arma_debug_check( (col >= p_n_cols), "each_col(): index out of bounds" );
  381. arrayops::inplace_minus( p.colptr(col), A_mem, p_n_rows );
  382. }
  383. }
  384. else // each row
  385. {
  386. for(uword i=0; i < N; ++i)
  387. {
  388. const uword row = indices_mem[i];
  389. arma_debug_check( (row >= p_n_rows), "each_row(): index out of bounds" );
  390. p.row(row) -= A;
  391. }
  392. }
  393. }
  394. template<typename parent, unsigned int mode, typename TB>
  395. template<typename T1>
  396. inline
  397. void
  398. subview_each2<parent,mode,TB>::operator%= (const Base<eT,T1>& in)
  399. {
  400. arma_extra_debug_sigprint();
  401. parent& p = access::rw(subview_each_common<parent,mode>::P);
  402. const unwrap_check<T1> tmp( in.get_ref(), (*this).get_mat_ref() );
  403. const Mat<eT>& A = tmp.M;
  404. subview_each_common<parent,mode>::check_size(A);
  405. const unwrap_check_mixed<TB> U( base_indices.get_ref(), (*this).get_mat_ref() );
  406. check_indices(U.M);
  407. const uword p_n_rows = p.n_rows;
  408. const uword p_n_cols = p.n_cols;
  409. const uword* indices_mem = U.M.memptr();
  410. const uword N = U.M.n_elem;
  411. if(mode == 0) // each column
  412. {
  413. const eT* A_mem = A.memptr();
  414. for(uword i=0; i < N; ++i)
  415. {
  416. const uword col = indices_mem[i];
  417. arma_debug_check( (col >= p_n_cols), "each_col(): index out of bounds" );
  418. arrayops::inplace_mul( p.colptr(col), A_mem, p_n_rows );
  419. }
  420. }
  421. else // each row
  422. {
  423. for(uword i=0; i < N; ++i)
  424. {
  425. const uword row = indices_mem[i];
  426. arma_debug_check( (row >= p_n_rows), "each_row(): index out of bounds" );
  427. p.row(row) %= A;
  428. }
  429. }
  430. }
  431. template<typename parent, unsigned int mode, typename TB>
  432. template<typename T1>
  433. inline
  434. void
  435. subview_each2<parent,mode,TB>::operator/= (const Base<eT,T1>& in)
  436. {
  437. arma_extra_debug_sigprint();
  438. parent& p = access::rw(subview_each_common<parent,mode>::P);
  439. const unwrap_check<T1> tmp( in.get_ref(), (*this).get_mat_ref() );
  440. const Mat<eT>& A = tmp.M;
  441. subview_each_common<parent,mode>::check_size(A);
  442. const unwrap_check_mixed<TB> U( base_indices.get_ref(), (*this).get_mat_ref() );
  443. check_indices(U.M);
  444. const uword p_n_rows = p.n_rows;
  445. const uword p_n_cols = p.n_cols;
  446. const uword* indices_mem = U.M.memptr();
  447. const uword N = U.M.n_elem;
  448. if(mode == 0) // each column
  449. {
  450. const eT* A_mem = A.memptr();
  451. for(uword i=0; i < N; ++i)
  452. {
  453. const uword col = indices_mem[i];
  454. arma_debug_check( (col >= p_n_cols), "each_col(): index out of bounds" );
  455. arrayops::inplace_div( p.colptr(col), A_mem, p_n_rows );
  456. }
  457. }
  458. else // each row
  459. {
  460. for(uword i=0; i < N; ++i)
  461. {
  462. const uword row = indices_mem[i];
  463. arma_debug_check( (row >= p_n_rows), "each_row(): index out of bounds" );
  464. p.row(row) /= A;
  465. }
  466. }
  467. }
  468. //
  469. //
  470. // subview_each1_aux
  471. template<typename parent, unsigned int mode, typename T2>
  472. inline
  473. Mat<typename parent::elem_type>
  474. subview_each1_aux::operator_plus
  475. (
  476. const subview_each1<parent,mode>& X,
  477. const Base<typename parent::elem_type,T2>& Y
  478. )
  479. {
  480. arma_extra_debug_sigprint();
  481. typedef typename parent::elem_type eT;
  482. const parent& p = X.P;
  483. const uword p_n_rows = p.n_rows;
  484. const uword p_n_cols = p.n_cols;
  485. Mat<eT> out(p_n_rows, p_n_cols);
  486. const quasi_unwrap<T2> tmp(Y.get_ref());
  487. const Mat<eT>& A = tmp.M;
  488. X.check_size(A);
  489. const eT* A_mem = A.memptr();
  490. if(mode == 0) // each column
  491. {
  492. for(uword i=0; i < p_n_cols; ++i)
  493. {
  494. const eT* p_mem = p.colptr(i);
  495. eT* out_mem = out.colptr(i);
  496. for(uword row=0; row < p_n_rows; ++row)
  497. {
  498. out_mem[row] = p_mem[row] + A_mem[row];
  499. }
  500. }
  501. }
  502. if(mode == 1) // each row
  503. {
  504. for(uword i=0; i < p_n_cols; ++i)
  505. {
  506. const eT* p_mem = p.colptr(i);
  507. eT* out_mem = out.colptr(i);
  508. const eT A_val = A_mem[i];
  509. for(uword row=0; row < p_n_rows; ++row)
  510. {
  511. out_mem[row] = p_mem[row] + A_val;
  512. }
  513. }
  514. }
  515. return out;
  516. }
  517. template<typename parent, unsigned int mode, typename T2>
  518. inline
  519. Mat<typename parent::elem_type>
  520. subview_each1_aux::operator_minus
  521. (
  522. const subview_each1<parent,mode>& X,
  523. const Base<typename parent::elem_type,T2>& Y
  524. )
  525. {
  526. arma_extra_debug_sigprint();
  527. typedef typename parent::elem_type eT;
  528. const parent& p = X.P;
  529. const uword p_n_rows = p.n_rows;
  530. const uword p_n_cols = p.n_cols;
  531. Mat<eT> out(p_n_rows, p_n_cols);
  532. const quasi_unwrap<T2> tmp(Y.get_ref());
  533. const Mat<eT>& A = tmp.M;
  534. X.check_size(A);
  535. const eT* A_mem = A.memptr();
  536. if(mode == 0) // each column
  537. {
  538. for(uword i=0; i < p_n_cols; ++i)
  539. {
  540. const eT* p_mem = p.colptr(i);
  541. eT* out_mem = out.colptr(i);
  542. for(uword row=0; row < p_n_rows; ++row)
  543. {
  544. out_mem[row] = p_mem[row] - A_mem[row];
  545. }
  546. }
  547. }
  548. if(mode == 1) // each row
  549. {
  550. for(uword i=0; i < p_n_cols; ++i)
  551. {
  552. const eT* p_mem = p.colptr(i);
  553. eT* out_mem = out.colptr(i);
  554. const eT A_val = A_mem[i];
  555. for(uword row=0; row < p_n_rows; ++row)
  556. {
  557. out_mem[row] = p_mem[row] - A_val;
  558. }
  559. }
  560. }
  561. return out;
  562. }
  563. template<typename T1, typename parent, unsigned int mode>
  564. inline
  565. Mat<typename parent::elem_type>
  566. subview_each1_aux::operator_minus
  567. (
  568. const Base<typename parent::elem_type,T1>& X,
  569. const subview_each1<parent,mode>& Y
  570. )
  571. {
  572. arma_extra_debug_sigprint();
  573. typedef typename parent::elem_type eT;
  574. const parent& p = Y.P;
  575. const uword p_n_rows = p.n_rows;
  576. const uword p_n_cols = p.n_cols;
  577. Mat<eT> out(p_n_rows, p_n_cols);
  578. const quasi_unwrap<T1> tmp(X.get_ref());
  579. const Mat<eT>& A = tmp.M;
  580. Y.check_size(A);
  581. const eT* A_mem = A.memptr();
  582. if(mode == 0) // each column
  583. {
  584. for(uword i=0; i < p_n_cols; ++i)
  585. {
  586. const eT* p_mem = p.colptr(i);
  587. eT* out_mem = out.colptr(i);
  588. for(uword row=0; row < p_n_rows; ++row)
  589. {
  590. out_mem[row] = A_mem[row] - p_mem[row];
  591. }
  592. }
  593. }
  594. if(mode == 1) // each row
  595. {
  596. for(uword i=0; i < p_n_cols; ++i)
  597. {
  598. const eT* p_mem = p.colptr(i);
  599. eT* out_mem = out.colptr(i);
  600. const eT A_val = A_mem[i];
  601. for(uword row=0; row < p_n_rows; ++row)
  602. {
  603. out_mem[row] = A_val - p_mem[row];
  604. }
  605. }
  606. }
  607. return out;
  608. }
  609. template<typename parent, unsigned int mode, typename T2>
  610. inline
  611. Mat<typename parent::elem_type>
  612. subview_each1_aux::operator_schur
  613. (
  614. const subview_each1<parent,mode>& X,
  615. const Base<typename parent::elem_type,T2>& Y
  616. )
  617. {
  618. arma_extra_debug_sigprint();
  619. typedef typename parent::elem_type eT;
  620. const parent& p = X.P;
  621. const uword p_n_rows = p.n_rows;
  622. const uword p_n_cols = p.n_cols;
  623. Mat<eT> out(p_n_rows, p_n_cols);
  624. const quasi_unwrap<T2> tmp(Y.get_ref());
  625. const Mat<eT>& A = tmp.M;
  626. X.check_size(A);
  627. const eT* A_mem = A.memptr();
  628. if(mode == 0) // each column
  629. {
  630. for(uword i=0; i < p_n_cols; ++i)
  631. {
  632. const eT* p_mem = p.colptr(i);
  633. eT* out_mem = out.colptr(i);
  634. for(uword row=0; row < p_n_rows; ++row)
  635. {
  636. out_mem[row] = p_mem[row] * A_mem[row];
  637. }
  638. }
  639. }
  640. if(mode == 1) // each row
  641. {
  642. for(uword i=0; i < p_n_cols; ++i)
  643. {
  644. const eT* p_mem = p.colptr(i);
  645. eT* out_mem = out.colptr(i);
  646. const eT A_val = A_mem[i];
  647. for(uword row=0; row < p_n_rows; ++row)
  648. {
  649. out_mem[row] = p_mem[row] * A_val;
  650. }
  651. }
  652. }
  653. return out;
  654. }
  655. template<typename parent, unsigned int mode, typename T2>
  656. inline
  657. Mat<typename parent::elem_type>
  658. subview_each1_aux::operator_div
  659. (
  660. const subview_each1<parent,mode>& X,
  661. const Base<typename parent::elem_type,T2>& Y
  662. )
  663. {
  664. arma_extra_debug_sigprint();
  665. typedef typename parent::elem_type eT;
  666. const parent& p = X.P;
  667. const uword p_n_rows = p.n_rows;
  668. const uword p_n_cols = p.n_cols;
  669. Mat<eT> out(p_n_rows, p_n_cols);
  670. const quasi_unwrap<T2> tmp(Y.get_ref());
  671. const Mat<eT>& A = tmp.M;
  672. X.check_size(A);
  673. const eT* A_mem = A.memptr();
  674. if(mode == 0) // each column
  675. {
  676. for(uword i=0; i < p_n_cols; ++i)
  677. {
  678. const eT* p_mem = p.colptr(i);
  679. eT* out_mem = out.colptr(i);
  680. for(uword row=0; row < p_n_rows; ++row)
  681. {
  682. out_mem[row] = p_mem[row] / A_mem[row];
  683. }
  684. }
  685. }
  686. if(mode == 1) // each row
  687. {
  688. for(uword i=0; i < p_n_cols; ++i)
  689. {
  690. const eT* p_mem = p.colptr(i);
  691. eT* out_mem = out.colptr(i);
  692. const eT A_val = A_mem[i];
  693. for(uword row=0; row < p_n_rows; ++row)
  694. {
  695. out_mem[row] = p_mem[row] / A_val;
  696. }
  697. }
  698. }
  699. return out;
  700. }
  701. template<typename T1, typename parent, unsigned int mode>
  702. inline
  703. Mat<typename parent::elem_type>
  704. subview_each1_aux::operator_div
  705. (
  706. const Base<typename parent::elem_type,T1>& X,
  707. const subview_each1<parent,mode>& Y
  708. )
  709. {
  710. arma_extra_debug_sigprint();
  711. typedef typename parent::elem_type eT;
  712. const parent& p = Y.P;
  713. const uword p_n_rows = p.n_rows;
  714. const uword p_n_cols = p.n_cols;
  715. Mat<eT> out(p_n_rows, p_n_cols);
  716. const quasi_unwrap<T1> tmp(X.get_ref());
  717. const Mat<eT>& A = tmp.M;
  718. Y.check_size(A);
  719. const eT* A_mem = A.memptr();
  720. if(mode == 0) // each column
  721. {
  722. for(uword i=0; i < p_n_cols; ++i)
  723. {
  724. const eT* p_mem = p.colptr(i);
  725. eT* out_mem = out.colptr(i);
  726. for(uword row=0; row < p_n_rows; ++row)
  727. {
  728. out_mem[row] = A_mem[row] / p_mem[row];
  729. }
  730. }
  731. }
  732. if(mode == 1) // each row
  733. {
  734. for(uword i=0; i < p_n_cols; ++i)
  735. {
  736. const eT* p_mem = p.colptr(i);
  737. eT* out_mem = out.colptr(i);
  738. const eT A_val = A_mem[i];
  739. for(uword row=0; row < p_n_rows; ++row)
  740. {
  741. out_mem[row] = A_val / p_mem[row];
  742. }
  743. }
  744. }
  745. return out;
  746. }
  747. //
  748. //
  749. // subview_each2_aux
  750. template<typename parent, unsigned int mode, typename TB, typename T2>
  751. inline
  752. Mat<typename parent::elem_type>
  753. subview_each2_aux::operator_plus
  754. (
  755. const subview_each2<parent,mode,TB>& X,
  756. const Base<typename parent::elem_type,T2>& Y
  757. )
  758. {
  759. arma_extra_debug_sigprint();
  760. typedef typename parent::elem_type eT;
  761. const parent& p = X.P;
  762. const uword p_n_rows = p.n_rows;
  763. const uword p_n_cols = p.n_cols;
  764. Mat<eT> out = p;
  765. const quasi_unwrap<T2> tmp(Y.get_ref());
  766. const Mat<eT>& A = tmp.M;
  767. const unwrap<TB> U(X.base_indices.get_ref());
  768. X.check_size(A);
  769. X.check_indices(U.M);
  770. const uword* indices_mem = U.M.memptr();
  771. const uword N = U.M.n_elem;
  772. if(mode == 0) // process columns
  773. {
  774. const eT* A_mem = A.memptr();
  775. for(uword i=0; i < N; ++i)
  776. {
  777. const uword col = indices_mem[i];
  778. arma_debug_check( (col >= p_n_cols), "each_col(): index out of bounds" );
  779. arrayops::inplace_plus( out.colptr(col), A_mem, p_n_rows );
  780. }
  781. }
  782. if(mode == 1) // process rows
  783. {
  784. for(uword i=0; i < N; ++i)
  785. {
  786. const uword row = indices_mem[i];
  787. arma_debug_check( (row >= p_n_rows), "each_row(): index out of bounds" );
  788. out.row(row) += A;
  789. }
  790. }
  791. return out;
  792. }
  793. template<typename parent, unsigned int mode, typename TB, typename T2>
  794. inline
  795. Mat<typename parent::elem_type>
  796. subview_each2_aux::operator_minus
  797. (
  798. const subview_each2<parent,mode,TB>& X,
  799. const Base<typename parent::elem_type,T2>& Y
  800. )
  801. {
  802. arma_extra_debug_sigprint();
  803. typedef typename parent::elem_type eT;
  804. const parent& p = X.P;
  805. const uword p_n_rows = p.n_rows;
  806. const uword p_n_cols = p.n_cols;
  807. Mat<eT> out = p;
  808. const quasi_unwrap<T2> tmp(Y.get_ref());
  809. const Mat<eT>& A = tmp.M;
  810. const unwrap<TB> U(X.base_indices.get_ref());
  811. X.check_size(A);
  812. X.check_indices(U.M);
  813. const uword* indices_mem = U.M.memptr();
  814. const uword N = U.M.n_elem;
  815. if(mode == 0) // process columns
  816. {
  817. const eT* A_mem = A.memptr();
  818. for(uword i=0; i < N; ++i)
  819. {
  820. const uword col = indices_mem[i];
  821. arma_debug_check( (col >= p_n_cols), "each_col(): index out of bounds" );
  822. arrayops::inplace_minus( out.colptr(col), A_mem, p_n_rows );
  823. }
  824. }
  825. if(mode == 1) // process rows
  826. {
  827. for(uword i=0; i < N; ++i)
  828. {
  829. const uword row = indices_mem[i];
  830. arma_debug_check( (row >= p_n_rows), "each_row(): index out of bounds" );
  831. out.row(row) -= A;
  832. }
  833. }
  834. return out;
  835. }
  836. template<typename T1, typename parent, unsigned int mode, typename TB>
  837. inline
  838. Mat<typename parent::elem_type>
  839. subview_each2_aux::operator_minus
  840. (
  841. const Base<typename parent::elem_type,T1>& X,
  842. const subview_each2<parent,mode,TB>& Y
  843. )
  844. {
  845. arma_extra_debug_sigprint();
  846. typedef typename parent::elem_type eT;
  847. const parent& p = Y.P;
  848. const uword p_n_rows = p.n_rows;
  849. const uword p_n_cols = p.n_cols;
  850. Mat<eT> out = p;
  851. const quasi_unwrap<T1> tmp(X.get_ref());
  852. const Mat<eT>& A = tmp.M;
  853. const unwrap<TB> U(Y.base_indices.get_ref());
  854. Y.check_size(A);
  855. Y.check_indices(U.M);
  856. const uword* indices_mem = U.M.memptr();
  857. const uword N = U.M.n_elem;
  858. if(mode == 0) // process columns
  859. {
  860. const eT* A_mem = A.memptr();
  861. for(uword i=0; i < N; ++i)
  862. {
  863. const uword col = indices_mem[i];
  864. arma_debug_check( (col >= p_n_cols), "each_col(): index out of bounds" );
  865. const eT* p_mem = p.colptr(col);
  866. eT* out_mem = out.colptr(col);
  867. for(uword row=0; row < p_n_rows; ++row)
  868. {
  869. out_mem[row] = A_mem[row] - p_mem[row];
  870. }
  871. }
  872. }
  873. if(mode == 1) // process rows
  874. {
  875. for(uword i=0; i < N; ++i)
  876. {
  877. const uword row = indices_mem[i];
  878. arma_debug_check( (row >= p_n_rows), "each_row(): index out of bounds" );
  879. out.row(row) = A - p.row(row);
  880. }
  881. }
  882. return out;
  883. }
  884. template<typename parent, unsigned int mode, typename TB, typename T2>
  885. inline
  886. Mat<typename parent::elem_type>
  887. subview_each2_aux::operator_schur
  888. (
  889. const subview_each2<parent,mode,TB>& X,
  890. const Base<typename parent::elem_type,T2>& Y
  891. )
  892. {
  893. arma_extra_debug_sigprint();
  894. typedef typename parent::elem_type eT;
  895. const parent& p = X.P;
  896. const uword p_n_rows = p.n_rows;
  897. const uword p_n_cols = p.n_cols;
  898. Mat<eT> out = p;
  899. const quasi_unwrap<T2> tmp(Y.get_ref());
  900. const Mat<eT>& A = tmp.M;
  901. const unwrap<TB> U(X.base_indices.get_ref());
  902. X.check_size(A);
  903. X.check_indices(U.M);
  904. const uword* indices_mem = U.M.memptr();
  905. const uword N = U.M.n_elem;
  906. if(mode == 0) // process columns
  907. {
  908. const eT* A_mem = A.memptr();
  909. for(uword i=0; i < N; ++i)
  910. {
  911. const uword col = indices_mem[i];
  912. arma_debug_check( (col >= p_n_cols), "each_col(): index out of bounds" );
  913. arrayops::inplace_mul( out.colptr(col), A_mem, p_n_rows );
  914. }
  915. }
  916. if(mode == 1) // process rows
  917. {
  918. for(uword i=0; i < N; ++i)
  919. {
  920. const uword row = indices_mem[i];
  921. arma_debug_check( (row >= p_n_rows), "each_row(): index out of bounds" );
  922. out.row(row) %= A;
  923. }
  924. }
  925. return out;
  926. }
  927. template<typename parent, unsigned int mode, typename TB, typename T2>
  928. inline
  929. Mat<typename parent::elem_type>
  930. subview_each2_aux::operator_div
  931. (
  932. const subview_each2<parent,mode,TB>& X,
  933. const Base<typename parent::elem_type,T2>& Y
  934. )
  935. {
  936. arma_extra_debug_sigprint();
  937. typedef typename parent::elem_type eT;
  938. const parent& p = X.P;
  939. const uword p_n_rows = p.n_rows;
  940. const uword p_n_cols = p.n_cols;
  941. Mat<eT> out = p;
  942. const quasi_unwrap<T2> tmp(Y.get_ref());
  943. const Mat<eT>& A = tmp.M;
  944. const unwrap<TB> U(X.base_indices.get_ref());
  945. X.check_size(A);
  946. X.check_indices(U.M);
  947. const uword* indices_mem = U.M.memptr();
  948. const uword N = U.M.n_elem;
  949. if(mode == 0) // process columns
  950. {
  951. const eT* A_mem = A.memptr();
  952. for(uword i=0; i < N; ++i)
  953. {
  954. const uword col = indices_mem[i];
  955. arma_debug_check( (col >= p_n_cols), "each_col(): index out of bounds" );
  956. arrayops::inplace_div( out.colptr(col), A_mem, p_n_rows );
  957. }
  958. }
  959. if(mode == 1) // process rows
  960. {
  961. for(uword i=0; i < N; ++i)
  962. {
  963. const uword row = indices_mem[i];
  964. arma_debug_check( (row >= p_n_rows), "each_row(): index out of bounds" );
  965. out.row(row) /= A;
  966. }
  967. }
  968. return out;
  969. }
  970. template<typename T1, typename parent, unsigned int mode, typename TB>
  971. inline
  972. Mat<typename parent::elem_type>
  973. subview_each2_aux::operator_div
  974. (
  975. const Base<typename parent::elem_type,T1>& X,
  976. const subview_each2<parent,mode,TB>& Y
  977. )
  978. {
  979. arma_extra_debug_sigprint();
  980. typedef typename parent::elem_type eT;
  981. const parent& p = Y.P;
  982. const uword p_n_rows = p.n_rows;
  983. const uword p_n_cols = p.n_cols;
  984. Mat<eT> out = p;
  985. const quasi_unwrap<T1> tmp(X.get_ref());
  986. const Mat<eT>& A = tmp.M;
  987. const unwrap<TB> U(Y.base_indices.get_ref());
  988. Y.check_size(A);
  989. Y.check_indices(U.M);
  990. const uword* indices_mem = U.M.memptr();
  991. const uword N = U.M.n_elem;
  992. if(mode == 0) // process columns
  993. {
  994. const eT* A_mem = A.memptr();
  995. for(uword i=0; i < N; ++i)
  996. {
  997. const uword col = indices_mem[i];
  998. arma_debug_check( (col >= p_n_cols), "each_col(): index out of bounds" );
  999. const eT* p_mem = p.colptr(col);
  1000. eT* out_mem = out.colptr(col);
  1001. for(uword row=0; row < p_n_rows; ++row)
  1002. {
  1003. out_mem[row] = A_mem[row] / p_mem[row];
  1004. }
  1005. }
  1006. }
  1007. if(mode == 1) // process rows
  1008. {
  1009. for(uword i=0; i < N; ++i)
  1010. {
  1011. const uword row = indices_mem[i];
  1012. arma_debug_check( (row >= p_n_rows), "each_row(): index out of bounds" );
  1013. out.row(row) = A / p.row(row);
  1014. }
  1015. }
  1016. return out;
  1017. }
  1018. //! @}