annotate armadillo-3.900.4/include/armadillo_bits/op_min_meat.hpp @ 84:55a047986812 tip

Update library URI so as not to be document-local
author Chris Cannam
date Wed, 22 Apr 2020 14:21:57 +0100
parents 1ec0e2823891
children
rev   line source
Chris@49 1 // Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
Chris@49 2 // Copyright (C) 2008-2012 Conrad Sanderson
Chris@49 3 //
Chris@49 4 // This Source Code Form is subject to the terms of the Mozilla Public
Chris@49 5 // License, v. 2.0. If a copy of the MPL was not distributed with this
Chris@49 6 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
Chris@49 7
Chris@49 8
Chris@49 9 //! \addtogroup op_min
Chris@49 10 //! @{
Chris@49 11
Chris@49 12
Chris@49 13
Chris@49 14 //! \brief
Chris@49 15 //! For each row or for each column, find the minimum value.
Chris@49 16 //! The result is stored in a dense matrix that has either one column or one row.
Chris@49 17 //! The dimension, for which the minima are found, is set via the min() function.
Chris@49 18 template<typename T1>
Chris@49 19 inline void op_min::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_min>& in)
Chris@49 20 {
Chris@49 21 arma_extra_debug_sigprint();
Chris@49 22
Chris@49 23 typedef typename T1::elem_type eT;
Chris@49 24
Chris@49 25 const unwrap_check<T1> tmp(in.m, out);
Chris@49 26 const Mat<eT>& X = tmp.M;
Chris@49 27
Chris@49 28 const uword dim = in.aux_uword_a;
Chris@49 29 arma_debug_check( (dim > 1), "min(): incorrect usage. dim must be 0 or 1");
Chris@49 30
Chris@49 31 const uword X_n_rows = X.n_rows;
Chris@49 32 const uword X_n_cols = X.n_cols;
Chris@49 33
Chris@49 34 if(dim == 0) // min in each column
Chris@49 35 {
Chris@49 36 arma_extra_debug_print("op_min::apply(), dim = 0");
Chris@49 37
Chris@49 38 arma_debug_check( (X_n_rows == 0), "min(): given object has zero rows" );
Chris@49 39
Chris@49 40 out.set_size(1, X_n_cols);
Chris@49 41
Chris@49 42 eT* out_mem = out.memptr();
Chris@49 43
Chris@49 44 for(uword col=0; col<X_n_cols; ++col)
Chris@49 45 {
Chris@49 46 out_mem[col] = op_min::direct_min( X.colptr(col), X_n_rows );
Chris@49 47 }
Chris@49 48 }
Chris@49 49 else
Chris@49 50 if(dim == 1) // min in each row
Chris@49 51 {
Chris@49 52 arma_extra_debug_print("op_min::apply(), dim = 1");
Chris@49 53
Chris@49 54 arma_debug_check( (X_n_cols == 0), "min(): given object has zero columns" );
Chris@49 55
Chris@49 56 out.set_size(X_n_rows, 1);
Chris@49 57
Chris@49 58 eT* out_mem = out.memptr();
Chris@49 59
Chris@49 60 for(uword row=0; row<X_n_rows; ++row)
Chris@49 61 {
Chris@49 62 out_mem[row] = op_min::direct_min( X, row );
Chris@49 63 }
Chris@49 64 }
Chris@49 65 }
Chris@49 66
Chris@49 67
Chris@49 68
Chris@49 69 template<typename eT>
Chris@49 70 arma_pure
Chris@49 71 inline
Chris@49 72 eT
Chris@49 73 op_min::direct_min(const eT* const X, const uword n_elem)
Chris@49 74 {
Chris@49 75 arma_extra_debug_sigprint();
Chris@49 76
Chris@49 77 eT min_val = priv::most_pos<eT>();
Chris@49 78
Chris@49 79 uword i,j;
Chris@49 80 for(i=0, j=1; j<n_elem; i+=2, j+=2)
Chris@49 81 {
Chris@49 82 const eT X_i = X[i];
Chris@49 83 const eT X_j = X[j];
Chris@49 84
Chris@49 85 if(X_i < min_val) { min_val = X_i; }
Chris@49 86 if(X_j < min_val) { min_val = X_j; }
Chris@49 87 }
Chris@49 88
Chris@49 89 if(i < n_elem)
Chris@49 90 {
Chris@49 91 const eT X_i = X[i];
Chris@49 92
Chris@49 93 if(X_i < min_val) { min_val = X_i; }
Chris@49 94 }
Chris@49 95
Chris@49 96 return min_val;
Chris@49 97 }
Chris@49 98
Chris@49 99
Chris@49 100
Chris@49 101 template<typename eT>
Chris@49 102 inline
Chris@49 103 eT
Chris@49 104 op_min::direct_min(const eT* const X, const uword n_elem, uword& index_of_min_val)
Chris@49 105 {
Chris@49 106 arma_extra_debug_sigprint();
Chris@49 107
Chris@49 108 eT min_val = priv::most_pos<eT>();
Chris@49 109
Chris@49 110 uword best_index = 0;
Chris@49 111
Chris@49 112 uword i,j;
Chris@49 113 for(i=0, j=1; j<n_elem; i+=2, j+=2)
Chris@49 114 {
Chris@49 115 const eT X_i = X[i];
Chris@49 116 const eT X_j = X[j];
Chris@49 117
Chris@49 118 if(X_i < min_val)
Chris@49 119 {
Chris@49 120 min_val = X_i;
Chris@49 121 best_index = i;
Chris@49 122 }
Chris@49 123
Chris@49 124 if(X_j < min_val)
Chris@49 125 {
Chris@49 126 min_val = X_j;
Chris@49 127 best_index = j;
Chris@49 128 }
Chris@49 129 }
Chris@49 130
Chris@49 131 if(i < n_elem)
Chris@49 132 {
Chris@49 133 const eT X_i = X[i];
Chris@49 134
Chris@49 135 if(X_i < min_val)
Chris@49 136 {
Chris@49 137 min_val = X_i;
Chris@49 138 best_index = i;
Chris@49 139 }
Chris@49 140 }
Chris@49 141
Chris@49 142 index_of_min_val = best_index;
Chris@49 143
Chris@49 144 return min_val;
Chris@49 145 }
Chris@49 146
Chris@49 147
Chris@49 148
Chris@49 149 template<typename eT>
Chris@49 150 inline
Chris@49 151 eT
Chris@49 152 op_min::direct_min(const Mat<eT>& X, const uword row)
Chris@49 153 {
Chris@49 154 arma_extra_debug_sigprint();
Chris@49 155
Chris@49 156 const uword X_n_cols = X.n_cols;
Chris@49 157
Chris@49 158 eT min_val = priv::most_pos<eT>();
Chris@49 159
Chris@49 160 uword i,j;
Chris@49 161 for(i=0, j=1; j < X_n_cols; i+=2, j+=2)
Chris@49 162 {
Chris@49 163 const eT tmp_i = X.at(row,i);
Chris@49 164 const eT tmp_j = X.at(row,j);
Chris@49 165
Chris@49 166 if(tmp_i < min_val) { min_val = tmp_i; }
Chris@49 167 if(tmp_j < min_val) { min_val = tmp_j; }
Chris@49 168 }
Chris@49 169
Chris@49 170 if(i < X_n_cols)
Chris@49 171 {
Chris@49 172 const eT tmp_i = X.at(row,i);
Chris@49 173
Chris@49 174 if(tmp_i < min_val) { min_val = tmp_i; }
Chris@49 175 }
Chris@49 176
Chris@49 177 return min_val;
Chris@49 178 }
Chris@49 179
Chris@49 180
Chris@49 181
Chris@49 182 template<typename eT>
Chris@49 183 inline
Chris@49 184 eT
Chris@49 185 op_min::min(const subview<eT>& X)
Chris@49 186 {
Chris@49 187 arma_extra_debug_sigprint();
Chris@49 188
Chris@49 189 arma_debug_check( (X.n_elem == 0), "min(): given object has no elements" );
Chris@49 190
Chris@49 191 const uword X_n_rows = X.n_rows;
Chris@49 192 const uword X_n_cols = X.n_cols;
Chris@49 193
Chris@49 194 eT min_val = priv::most_pos<eT>();
Chris@49 195
Chris@49 196 if(X_n_rows == 1)
Chris@49 197 {
Chris@49 198 const Mat<eT>& A = X.m;
Chris@49 199
Chris@49 200 const uword start_row = X.aux_row1;
Chris@49 201 const uword start_col = X.aux_col1;
Chris@49 202
Chris@49 203 const uword end_col_p1 = start_col + X_n_cols;
Chris@49 204
Chris@49 205 uword i,j;
Chris@49 206 for(i=start_col, j=start_col+1; j < end_col_p1; i+=2, j+=2)
Chris@49 207 {
Chris@49 208 const eT tmp_i = A.at(start_row, i);
Chris@49 209 const eT tmp_j = A.at(start_row, j);
Chris@49 210
Chris@49 211 if(tmp_i < min_val) { min_val = tmp_i; }
Chris@49 212 if(tmp_j < min_val) { min_val = tmp_j; }
Chris@49 213 }
Chris@49 214
Chris@49 215 if(i < end_col_p1)
Chris@49 216 {
Chris@49 217 const eT tmp_i = A.at(start_row, i);
Chris@49 218
Chris@49 219 if(tmp_i < min_val) { min_val = tmp_i; }
Chris@49 220 }
Chris@49 221 }
Chris@49 222 else
Chris@49 223 {
Chris@49 224 for(uword col=0; col < X_n_cols; ++col)
Chris@49 225 {
Chris@49 226 eT tmp_val = op_min::direct_min(X.colptr(col), X_n_rows);
Chris@49 227
Chris@49 228 if(tmp_val < min_val) { min_val = tmp_val; }
Chris@49 229 }
Chris@49 230 }
Chris@49 231
Chris@49 232 return min_val;
Chris@49 233 }
Chris@49 234
Chris@49 235
Chris@49 236
Chris@49 237 template<typename T1>
Chris@49 238 inline
Chris@49 239 typename arma_not_cx<typename T1::elem_type>::result
Chris@49 240 op_min::min(const Base<typename T1::elem_type,T1>& X)
Chris@49 241 {
Chris@49 242 arma_extra_debug_sigprint();
Chris@49 243
Chris@49 244 typedef typename T1::elem_type eT;
Chris@49 245
Chris@49 246 const Proxy<T1> P(X.get_ref());
Chris@49 247
Chris@49 248 const uword n_elem = P.get_n_elem();
Chris@49 249
Chris@49 250 arma_debug_check( (n_elem == 0), "min(): given object has no elements" );
Chris@49 251
Chris@49 252 eT min_val = priv::most_pos<eT>();
Chris@49 253
Chris@49 254 if(Proxy<T1>::prefer_at_accessor == false)
Chris@49 255 {
Chris@49 256 typedef typename Proxy<T1>::ea_type ea_type;
Chris@49 257
Chris@49 258 ea_type A = P.get_ea();
Chris@49 259
Chris@49 260 uword i,j;
Chris@49 261
Chris@49 262 for(i=0, j=1; j<n_elem; i+=2, j+=2)
Chris@49 263 {
Chris@49 264 const eT tmp_i = A[i];
Chris@49 265 const eT tmp_j = A[j];
Chris@49 266
Chris@49 267 if(tmp_i < min_val) { min_val = tmp_i; }
Chris@49 268 if(tmp_j < min_val) { min_val = tmp_j; }
Chris@49 269 }
Chris@49 270
Chris@49 271 if(i < n_elem)
Chris@49 272 {
Chris@49 273 const eT tmp_i = A[i];
Chris@49 274
Chris@49 275 if(tmp_i < min_val) { min_val = tmp_i; }
Chris@49 276 }
Chris@49 277 }
Chris@49 278 else
Chris@49 279 {
Chris@49 280 const uword n_rows = P.get_n_rows();
Chris@49 281 const uword n_cols = P.get_n_cols();
Chris@49 282
Chris@49 283 if(n_rows == 1)
Chris@49 284 {
Chris@49 285 uword i,j;
Chris@49 286 for(i=0, j=1; j < n_cols; i+=2, j+=2)
Chris@49 287 {
Chris@49 288 const eT tmp_i = P.at(0,i);
Chris@49 289 const eT tmp_j = P.at(0,j);
Chris@49 290
Chris@49 291 if(tmp_i < min_val) { min_val = tmp_i; }
Chris@49 292 if(tmp_j < min_val) { min_val = tmp_j; }
Chris@49 293 }
Chris@49 294
Chris@49 295 if(i < n_cols)
Chris@49 296 {
Chris@49 297 const eT tmp_i = P.at(0,i);
Chris@49 298
Chris@49 299 if(tmp_i < min_val) { min_val = tmp_i; }
Chris@49 300 }
Chris@49 301 }
Chris@49 302 else
Chris@49 303 {
Chris@49 304 for(uword col=0; col < n_cols; ++col)
Chris@49 305 {
Chris@49 306 uword i,j;
Chris@49 307 for(i=0, j=1; j < n_rows; i+=2, j+=2)
Chris@49 308 {
Chris@49 309 const eT tmp_i = P.at(i,col);
Chris@49 310 const eT tmp_j = P.at(j,col);
Chris@49 311
Chris@49 312 if(tmp_i < min_val) { min_val = tmp_i; }
Chris@49 313 if(tmp_j < min_val) { min_val = tmp_j; }
Chris@49 314 }
Chris@49 315
Chris@49 316 if(i < n_rows)
Chris@49 317 {
Chris@49 318 const eT tmp_i = P.at(i,col);
Chris@49 319
Chris@49 320 if(tmp_i < min_val) { min_val = tmp_i; }
Chris@49 321 }
Chris@49 322 }
Chris@49 323 }
Chris@49 324 }
Chris@49 325
Chris@49 326 return min_val;
Chris@49 327 }
Chris@49 328
Chris@49 329
Chris@49 330
Chris@49 331 template<typename T>
Chris@49 332 inline
Chris@49 333 std::complex<T>
Chris@49 334 op_min::direct_min(const std::complex<T>* const X, const uword n_elem)
Chris@49 335 {
Chris@49 336 arma_extra_debug_sigprint();
Chris@49 337
Chris@49 338 uword index = 0;
Chris@49 339 T min_val = priv::most_pos<T>();
Chris@49 340
Chris@49 341 for(uword i=0; i<n_elem; ++i)
Chris@49 342 {
Chris@49 343 const T tmp_val = std::abs(X[i]);
Chris@49 344
Chris@49 345 if(tmp_val < min_val)
Chris@49 346 {
Chris@49 347 min_val = tmp_val;
Chris@49 348 index = i;
Chris@49 349 }
Chris@49 350 }
Chris@49 351
Chris@49 352 return X[index];
Chris@49 353 }
Chris@49 354
Chris@49 355
Chris@49 356
Chris@49 357 template<typename T>
Chris@49 358 inline
Chris@49 359 std::complex<T>
Chris@49 360 op_min::direct_min(const std::complex<T>* const X, const uword n_elem, uword& index_of_min_val)
Chris@49 361 {
Chris@49 362 arma_extra_debug_sigprint();
Chris@49 363
Chris@49 364 uword index = 0;
Chris@49 365 T min_val = priv::most_pos<T>();
Chris@49 366
Chris@49 367 for(uword i=0; i<n_elem; ++i)
Chris@49 368 {
Chris@49 369 const T tmp_val = std::abs(X[i]);
Chris@49 370
Chris@49 371 if(tmp_val < min_val)
Chris@49 372 {
Chris@49 373 min_val = tmp_val;
Chris@49 374 index = i;
Chris@49 375 }
Chris@49 376 }
Chris@49 377
Chris@49 378 index_of_min_val = index;
Chris@49 379
Chris@49 380 return X[index];
Chris@49 381 }
Chris@49 382
Chris@49 383
Chris@49 384
Chris@49 385 template<typename T>
Chris@49 386 inline
Chris@49 387 std::complex<T>
Chris@49 388 op_min::direct_min(const Mat< std::complex<T> >& X, const uword row)
Chris@49 389 {
Chris@49 390 arma_extra_debug_sigprint();
Chris@49 391
Chris@49 392 const uword X_n_cols = X.n_cols;
Chris@49 393
Chris@49 394 uword index = 0;
Chris@49 395 T min_val = priv::most_pos<T>();
Chris@49 396
Chris@49 397 for(uword col=0; col<X_n_cols; ++col)
Chris@49 398 {
Chris@49 399 const T tmp_val = std::abs(X.at(row,col));
Chris@49 400
Chris@49 401 if(tmp_val < min_val)
Chris@49 402 {
Chris@49 403 min_val = tmp_val;
Chris@49 404 index = col;
Chris@49 405 }
Chris@49 406 }
Chris@49 407
Chris@49 408 return X.at(row,index);
Chris@49 409 }
Chris@49 410
Chris@49 411
Chris@49 412
Chris@49 413 template<typename T>
Chris@49 414 inline
Chris@49 415 std::complex<T>
Chris@49 416 op_min::min(const subview< std::complex<T> >& X)
Chris@49 417 {
Chris@49 418 arma_extra_debug_sigprint();
Chris@49 419
Chris@49 420 arma_debug_check( (X.n_elem == 0), "min(): given object has no elements" );
Chris@49 421
Chris@49 422 const Mat< std::complex<T> >& A = X.m;
Chris@49 423
Chris@49 424 const uword X_n_rows = X.n_rows;
Chris@49 425 const uword X_n_cols = X.n_cols;
Chris@49 426
Chris@49 427 const uword start_row = X.aux_row1;
Chris@49 428 const uword start_col = X.aux_col1;
Chris@49 429
Chris@49 430 const uword end_row_p1 = start_row + X_n_rows;
Chris@49 431 const uword end_col_p1 = start_col + X_n_cols;
Chris@49 432
Chris@49 433 T min_val = priv::most_pos<T>();
Chris@49 434
Chris@49 435 uword best_row = 0;
Chris@49 436 uword best_col = 0;
Chris@49 437
Chris@49 438 if(X_n_rows == 1)
Chris@49 439 {
Chris@49 440 best_col = 0;
Chris@49 441
Chris@49 442 for(uword col=start_col; col < end_col_p1; ++col)
Chris@49 443 {
Chris@49 444 const T tmp_val = std::abs( A.at(start_row, col) );
Chris@49 445
Chris@49 446 if(tmp_val < min_val)
Chris@49 447 {
Chris@49 448 min_val = tmp_val;
Chris@49 449 best_col = col;
Chris@49 450 }
Chris@49 451 }
Chris@49 452
Chris@49 453 best_row = start_row;
Chris@49 454 }
Chris@49 455 else
Chris@49 456 {
Chris@49 457 for(uword col=start_col; col < end_col_p1; ++col)
Chris@49 458 for(uword row=start_row; row < end_row_p1; ++row)
Chris@49 459 {
Chris@49 460 const T tmp_val = std::abs( A.at(row, col) );
Chris@49 461
Chris@49 462 if(tmp_val < min_val)
Chris@49 463 {
Chris@49 464 min_val = tmp_val;
Chris@49 465 best_row = row;
Chris@49 466 best_col = col;
Chris@49 467 }
Chris@49 468 }
Chris@49 469 }
Chris@49 470
Chris@49 471 return A.at(best_row, best_col);
Chris@49 472 }
Chris@49 473
Chris@49 474
Chris@49 475
Chris@49 476 template<typename T1>
Chris@49 477 inline
Chris@49 478 typename arma_cx_only<typename T1::elem_type>::result
Chris@49 479 op_min::min(const Base<typename T1::elem_type,T1>& X)
Chris@49 480 {
Chris@49 481 arma_extra_debug_sigprint();
Chris@49 482
Chris@49 483 typedef typename T1::elem_type eT;
Chris@49 484 typedef typename get_pod_type<eT>::result T;
Chris@49 485
Chris@49 486 const Proxy<T1> P(X.get_ref());
Chris@49 487
Chris@49 488 const uword n_elem = P.get_n_elem();
Chris@49 489
Chris@49 490 arma_debug_check( (n_elem == 0), "min(): given object has no elements" );
Chris@49 491
Chris@49 492 T min_val = priv::most_pos<T>();
Chris@49 493
Chris@49 494 if(Proxy<T1>::prefer_at_accessor == false)
Chris@49 495 {
Chris@49 496 typedef typename Proxy<T1>::ea_type ea_type;
Chris@49 497
Chris@49 498 ea_type A = P.get_ea();
Chris@49 499
Chris@49 500 uword index = 0;
Chris@49 501
Chris@49 502 for(uword i=0; i<n_elem; ++i)
Chris@49 503 {
Chris@49 504 const T tmp = std::abs(A[i]);
Chris@49 505
Chris@49 506 if(tmp < min_val)
Chris@49 507 {
Chris@49 508 min_val = tmp;
Chris@49 509 index = i;
Chris@49 510 }
Chris@49 511 }
Chris@49 512
Chris@49 513 return( A[index] );
Chris@49 514 }
Chris@49 515 else
Chris@49 516 {
Chris@49 517 const uword n_rows = P.get_n_rows();
Chris@49 518 const uword n_cols = P.get_n_cols();
Chris@49 519
Chris@49 520 uword best_row = 0;
Chris@49 521 uword best_col = 0;
Chris@49 522
Chris@49 523 if(n_rows == 1)
Chris@49 524 {
Chris@49 525 for(uword col=0; col < n_cols; ++col)
Chris@49 526 {
Chris@49 527 const T tmp = std::abs(P.at(0,col));
Chris@49 528
Chris@49 529 if(tmp < min_val)
Chris@49 530 {
Chris@49 531 min_val = tmp;
Chris@49 532 best_col = col;
Chris@49 533 }
Chris@49 534 }
Chris@49 535 }
Chris@49 536 else
Chris@49 537 {
Chris@49 538 for(uword col=0; col < n_cols; ++col)
Chris@49 539 for(uword row=0; row < n_rows; ++row)
Chris@49 540 {
Chris@49 541 const T tmp = std::abs(P.at(row,col));
Chris@49 542
Chris@49 543 if(tmp < min_val)
Chris@49 544 {
Chris@49 545 min_val = tmp;
Chris@49 546
Chris@49 547 best_row = row;
Chris@49 548 best_col = col;
Chris@49 549 }
Chris@49 550 }
Chris@49 551 }
Chris@49 552
Chris@49 553 return P.at(best_row, best_col);
Chris@49 554 }
Chris@49 555 }
Chris@49 556
Chris@49 557
Chris@49 558
Chris@49 559 //! @}