op_max_meat.hpp 27 KB

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