annotate armadillo-3.900.4/include/armadillo_bits/fn_norm.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 fn_norm
Chris@49 10 //! @{
Chris@49 11
Chris@49 12
Chris@49 13
Chris@49 14 template<typename T1>
Chris@49 15 arma_hot
Chris@49 16 inline
Chris@49 17 typename T1::pod_type
Chris@49 18 arma_vec_norm_1(const Proxy<T1>& P)
Chris@49 19 {
Chris@49 20 arma_extra_debug_sigprint();
Chris@49 21
Chris@49 22 typedef typename T1::pod_type T;
Chris@49 23
Chris@49 24 T acc = T(0);
Chris@49 25
Chris@49 26 if(Proxy<T1>::prefer_at_accessor == false)
Chris@49 27 {
Chris@49 28 typename Proxy<T1>::ea_type A = P.get_ea();
Chris@49 29
Chris@49 30 const uword N = P.get_n_elem();
Chris@49 31
Chris@49 32 T acc1 = T(0);
Chris@49 33 T acc2 = T(0);
Chris@49 34
Chris@49 35 uword i,j;
Chris@49 36 for(i=0, j=1; j<N; i+=2, j+=2)
Chris@49 37 {
Chris@49 38 acc1 += std::abs(A[i]);
Chris@49 39 acc2 += std::abs(A[j]);
Chris@49 40 }
Chris@49 41
Chris@49 42 if(i < N)
Chris@49 43 {
Chris@49 44 acc1 += std::abs(A[i]);
Chris@49 45 }
Chris@49 46
Chris@49 47 acc = acc1 + acc2;
Chris@49 48 }
Chris@49 49 else
Chris@49 50 {
Chris@49 51 const uword n_rows = P.get_n_rows();
Chris@49 52 const uword n_cols = P.get_n_cols();
Chris@49 53
Chris@49 54 if(n_rows == 1)
Chris@49 55 {
Chris@49 56 for(uword col=0; col<n_cols; ++col)
Chris@49 57 {
Chris@49 58 acc += std::abs(P.at(0,col));
Chris@49 59 }
Chris@49 60 }
Chris@49 61 else
Chris@49 62 {
Chris@49 63 for(uword col=0; col<n_cols; ++col)
Chris@49 64 {
Chris@49 65 uword i,j;
Chris@49 66
Chris@49 67 for(i=0, j=1; j<n_rows; i+=2, j+=2)
Chris@49 68 {
Chris@49 69 acc += std::abs(P.at(i,col));
Chris@49 70 acc += std::abs(P.at(j,col));
Chris@49 71 }
Chris@49 72
Chris@49 73 if(i < n_rows)
Chris@49 74 {
Chris@49 75 acc += std::abs(P.at(i,col));
Chris@49 76 }
Chris@49 77 }
Chris@49 78 }
Chris@49 79 }
Chris@49 80
Chris@49 81 return acc;
Chris@49 82 }
Chris@49 83
Chris@49 84
Chris@49 85
Chris@49 86 template<typename T1>
Chris@49 87 arma_hot
Chris@49 88 inline
Chris@49 89 typename T1::pod_type
Chris@49 90 arma_vec_norm_2
Chris@49 91 (
Chris@49 92 const Proxy<T1>& P,
Chris@49 93 const typename arma_not_cx<typename T1::elem_type>::result* junk = 0
Chris@49 94 )
Chris@49 95 {
Chris@49 96 arma_extra_debug_sigprint();
Chris@49 97 arma_ignore(junk);
Chris@49 98
Chris@49 99 typedef typename T1::pod_type T;
Chris@49 100
Chris@49 101 T acc = T(0);
Chris@49 102
Chris@49 103 if(Proxy<T1>::prefer_at_accessor == false)
Chris@49 104 {
Chris@49 105 typename Proxy<T1>::ea_type A = P.get_ea();
Chris@49 106
Chris@49 107 const uword N = P.get_n_elem();
Chris@49 108
Chris@49 109 T acc1 = T(0);
Chris@49 110 T acc2 = T(0);
Chris@49 111
Chris@49 112 uword i,j;
Chris@49 113
Chris@49 114 for(i=0, j=1; j<N; i+=2, j+=2)
Chris@49 115 {
Chris@49 116 const T tmp_i = A[i];
Chris@49 117 const T tmp_j = A[j];
Chris@49 118
Chris@49 119 acc1 += tmp_i * tmp_i;
Chris@49 120 acc2 += tmp_j * tmp_j;
Chris@49 121 }
Chris@49 122
Chris@49 123 if(i < N)
Chris@49 124 {
Chris@49 125 const T tmp_i = A[i];
Chris@49 126
Chris@49 127 acc1 += tmp_i * tmp_i;
Chris@49 128 }
Chris@49 129
Chris@49 130 acc = acc1 + acc2;
Chris@49 131 }
Chris@49 132 else
Chris@49 133 {
Chris@49 134 const uword n_rows = P.get_n_rows();
Chris@49 135 const uword n_cols = P.get_n_cols();
Chris@49 136
Chris@49 137 if(n_rows == 1)
Chris@49 138 {
Chris@49 139 for(uword col=0; col<n_cols; ++col)
Chris@49 140 {
Chris@49 141 const T tmp = P.at(0,col);
Chris@49 142
Chris@49 143 acc += tmp * tmp;
Chris@49 144 }
Chris@49 145 }
Chris@49 146 else
Chris@49 147 {
Chris@49 148 for(uword col=0; col<n_cols; ++col)
Chris@49 149 {
Chris@49 150 uword i,j;
Chris@49 151 for(i=0, j=1; j<n_rows; i+=2, j+=2)
Chris@49 152 {
Chris@49 153 const T tmp_i = P.at(i,col);
Chris@49 154 const T tmp_j = P.at(j,col);
Chris@49 155
Chris@49 156 acc += tmp_i * tmp_i;
Chris@49 157 acc += tmp_j * tmp_j;
Chris@49 158 }
Chris@49 159
Chris@49 160 if(i < n_rows)
Chris@49 161 {
Chris@49 162 const T tmp_i = P.at(i,col);
Chris@49 163
Chris@49 164 acc += tmp_i * tmp_i;
Chris@49 165 }
Chris@49 166 }
Chris@49 167 }
Chris@49 168 }
Chris@49 169
Chris@49 170 return std::sqrt(acc);
Chris@49 171 }
Chris@49 172
Chris@49 173
Chris@49 174
Chris@49 175 template<typename T1>
Chris@49 176 arma_hot
Chris@49 177 inline
Chris@49 178 typename T1::pod_type
Chris@49 179 arma_vec_norm_2
Chris@49 180 (
Chris@49 181 const Proxy<T1>& P,
Chris@49 182 const typename arma_cx_only<typename T1::elem_type>::result* junk = 0
Chris@49 183 )
Chris@49 184 {
Chris@49 185 arma_extra_debug_sigprint();
Chris@49 186 arma_ignore(junk);
Chris@49 187
Chris@49 188 typedef typename T1::pod_type T;
Chris@49 189
Chris@49 190 T acc = T(0);
Chris@49 191
Chris@49 192 if(Proxy<T1>::prefer_at_accessor == false)
Chris@49 193 {
Chris@49 194 typename Proxy<T1>::ea_type A = P.get_ea();
Chris@49 195
Chris@49 196 const uword N = P.get_n_elem();
Chris@49 197
Chris@49 198 for(uword i=0; i<N; ++i)
Chris@49 199 {
Chris@49 200 const T tmp = std::abs(A[i]);
Chris@49 201 acc += tmp*tmp;
Chris@49 202 }
Chris@49 203 }
Chris@49 204 else
Chris@49 205 {
Chris@49 206 const uword n_rows = P.get_n_rows();
Chris@49 207 const uword n_cols = P.get_n_cols();
Chris@49 208
Chris@49 209 if(n_rows == 1)
Chris@49 210 {
Chris@49 211 for(uword col=0; col<n_cols; ++col)
Chris@49 212 {
Chris@49 213 const T tmp = std::abs(P.at(0,col));
Chris@49 214 acc += tmp*tmp;
Chris@49 215 }
Chris@49 216 }
Chris@49 217 else
Chris@49 218 {
Chris@49 219 for(uword col=0; col<n_cols; ++col)
Chris@49 220 for(uword row=0; row<n_rows; ++row)
Chris@49 221 {
Chris@49 222 const T tmp = std::abs(P.at(row,col));
Chris@49 223 acc += tmp*tmp;
Chris@49 224 }
Chris@49 225 }
Chris@49 226 }
Chris@49 227
Chris@49 228 return std::sqrt(acc);
Chris@49 229 }
Chris@49 230
Chris@49 231
Chris@49 232
Chris@49 233 template<typename T1>
Chris@49 234 arma_hot
Chris@49 235 inline
Chris@49 236 typename T1::pod_type
Chris@49 237 arma_vec_norm_k
Chris@49 238 (
Chris@49 239 const Proxy<T1>& P,
Chris@49 240 const int k
Chris@49 241 )
Chris@49 242 {
Chris@49 243 arma_extra_debug_sigprint();
Chris@49 244
Chris@49 245 typedef typename T1::pod_type T;
Chris@49 246
Chris@49 247 T acc = T(0);
Chris@49 248
Chris@49 249 if(Proxy<T1>::prefer_at_accessor == false)
Chris@49 250 {
Chris@49 251 typename Proxy<T1>::ea_type A = P.get_ea();
Chris@49 252
Chris@49 253 const uword N = P.get_n_elem();
Chris@49 254
Chris@49 255 uword i,j;
Chris@49 256
Chris@49 257 for(i=0, j=1; j<N; i+=2, j+=2)
Chris@49 258 {
Chris@49 259 acc += std::pow(std::abs(A[i]), k);
Chris@49 260 acc += std::pow(std::abs(A[j]), k);
Chris@49 261 }
Chris@49 262
Chris@49 263 if(i < N)
Chris@49 264 {
Chris@49 265 acc += std::pow(std::abs(A[i]), k);
Chris@49 266 }
Chris@49 267 }
Chris@49 268 else
Chris@49 269 {
Chris@49 270 const uword n_rows = P.get_n_rows();
Chris@49 271 const uword n_cols = P.get_n_cols();
Chris@49 272
Chris@49 273 if(n_rows != 1)
Chris@49 274 {
Chris@49 275 for(uword col=0; col < n_cols; ++col)
Chris@49 276 for(uword row=0; row < n_rows; ++row)
Chris@49 277 {
Chris@49 278 acc += std::pow(std::abs(P.at(row,col)), k);
Chris@49 279 }
Chris@49 280 }
Chris@49 281 else
Chris@49 282 {
Chris@49 283 for(uword col=0; col < n_cols; ++col)
Chris@49 284 {
Chris@49 285 acc += std::pow(std::abs(P.at(0,col)), k);
Chris@49 286 }
Chris@49 287 }
Chris@49 288 }
Chris@49 289
Chris@49 290 return std::pow(acc, T(1)/T(k));
Chris@49 291 }
Chris@49 292
Chris@49 293
Chris@49 294
Chris@49 295 template<typename T1>
Chris@49 296 arma_hot
Chris@49 297 inline
Chris@49 298 typename T1::pod_type
Chris@49 299 arma_vec_norm_max(const Proxy<T1>& P)
Chris@49 300 {
Chris@49 301 arma_extra_debug_sigprint();
Chris@49 302
Chris@49 303 typedef typename T1::pod_type T;
Chris@49 304
Chris@49 305 const uword N = P.get_n_elem();
Chris@49 306
Chris@49 307 T max_val = (N != 1) ? priv::most_neg<T>() : std::abs(P[0]);
Chris@49 308
Chris@49 309 if(Proxy<T1>::prefer_at_accessor == false)
Chris@49 310 {
Chris@49 311 typename Proxy<T1>::ea_type A = P.get_ea();
Chris@49 312
Chris@49 313 uword i,j;
Chris@49 314 for(i=0, j=1; j<N; i+=2, j+=2)
Chris@49 315 {
Chris@49 316 const T tmp_i = std::abs(A[i]);
Chris@49 317 const T tmp_j = std::abs(A[j]);
Chris@49 318
Chris@49 319 if(max_val < tmp_i) { max_val = tmp_i; }
Chris@49 320 if(max_val < tmp_j) { max_val = tmp_j; }
Chris@49 321 }
Chris@49 322
Chris@49 323 if(i < N)
Chris@49 324 {
Chris@49 325 const T tmp_i = std::abs(A[i]);
Chris@49 326
Chris@49 327 if(max_val < tmp_i) { max_val = tmp_i; }
Chris@49 328 }
Chris@49 329 }
Chris@49 330 else
Chris@49 331 {
Chris@49 332 const uword n_rows = P.get_n_rows();
Chris@49 333 const uword n_cols = P.get_n_cols();
Chris@49 334
Chris@49 335 if(n_rows != 1)
Chris@49 336 {
Chris@49 337 for(uword col=0; col < n_cols; ++col)
Chris@49 338 for(uword row=0; row < n_rows; ++row)
Chris@49 339 {
Chris@49 340 const T tmp = std::abs(P.at(row,col));
Chris@49 341
Chris@49 342 if(max_val < tmp) { max_val = tmp; }
Chris@49 343 }
Chris@49 344 }
Chris@49 345 else
Chris@49 346 {
Chris@49 347 for(uword col=0; col < n_cols; ++col)
Chris@49 348 {
Chris@49 349 const T tmp = std::abs(P.at(0,col));
Chris@49 350
Chris@49 351 if(max_val < tmp) { max_val = tmp; }
Chris@49 352 }
Chris@49 353 }
Chris@49 354 }
Chris@49 355
Chris@49 356 return max_val;
Chris@49 357 }
Chris@49 358
Chris@49 359
Chris@49 360
Chris@49 361 template<typename T1>
Chris@49 362 arma_hot
Chris@49 363 inline
Chris@49 364 typename T1::pod_type
Chris@49 365 arma_vec_norm_min(const Proxy<T1>& P)
Chris@49 366 {
Chris@49 367 arma_extra_debug_sigprint();
Chris@49 368
Chris@49 369 typedef typename T1::pod_type T;
Chris@49 370
Chris@49 371 const uword N = P.get_n_elem();
Chris@49 372
Chris@49 373 T min_val = (N != 1) ? priv::most_pos<T>() : std::abs(P[0]);
Chris@49 374
Chris@49 375 if(Proxy<T1>::prefer_at_accessor == false)
Chris@49 376 {
Chris@49 377 typename Proxy<T1>::ea_type A = P.get_ea();
Chris@49 378
Chris@49 379 uword i,j;
Chris@49 380 for(i=0, j=1; j<N; i+=2, j+=2)
Chris@49 381 {
Chris@49 382 const T tmp_i = std::abs(A[i]);
Chris@49 383 const T tmp_j = std::abs(A[j]);
Chris@49 384
Chris@49 385 if(min_val > tmp_i) { min_val = tmp_i; }
Chris@49 386 if(min_val > tmp_j) { min_val = tmp_j; }
Chris@49 387 }
Chris@49 388
Chris@49 389 if(i < N)
Chris@49 390 {
Chris@49 391 const T tmp_i = std::abs(A[i]);
Chris@49 392
Chris@49 393 if(min_val > tmp_i) { min_val = tmp_i; }
Chris@49 394 }
Chris@49 395 }
Chris@49 396 else
Chris@49 397 {
Chris@49 398 const uword n_rows = P.get_n_rows();
Chris@49 399 const uword n_cols = P.get_n_cols();
Chris@49 400
Chris@49 401 if(n_rows != 1)
Chris@49 402 {
Chris@49 403 for(uword col=0; col < n_cols; ++col)
Chris@49 404 for(uword row=0; row < n_rows; ++row)
Chris@49 405 {
Chris@49 406 const T tmp = std::abs(P.at(row,col));
Chris@49 407
Chris@49 408 if(min_val > tmp) { min_val = tmp; }
Chris@49 409 }
Chris@49 410 }
Chris@49 411 else
Chris@49 412 {
Chris@49 413 for(uword col=0; col < n_cols; ++col)
Chris@49 414 {
Chris@49 415 const T tmp = std::abs(P.at(0,col));
Chris@49 416
Chris@49 417 if(min_val > tmp) { min_val = tmp; }
Chris@49 418 }
Chris@49 419 }
Chris@49 420 }
Chris@49 421
Chris@49 422 return min_val;
Chris@49 423 }
Chris@49 424
Chris@49 425
Chris@49 426
Chris@49 427 template<typename T1>
Chris@49 428 inline
Chris@49 429 typename T1::pod_type
Chris@49 430 arma_mat_norm_1(const Proxy<T1>& P)
Chris@49 431 {
Chris@49 432 arma_extra_debug_sigprint();
Chris@49 433
Chris@49 434 // TODO: this can be sped up with a dedicated implementation
Chris@49 435 return as_scalar( max( sum(abs(P.Q), 0), 1) );
Chris@49 436 }
Chris@49 437
Chris@49 438
Chris@49 439
Chris@49 440 template<typename T1>
Chris@49 441 inline
Chris@49 442 typename T1::pod_type
Chris@49 443 arma_mat_norm_2(const Proxy<T1>& P)
Chris@49 444 {
Chris@49 445 arma_extra_debug_sigprint();
Chris@49 446
Chris@49 447 typedef typename T1::pod_type T;
Chris@49 448
Chris@49 449 // TODO: is the SVD based approach only valid for square matrices?
Chris@49 450
Chris@49 451 Col<T> S;
Chris@49 452 svd(S, P.Q);
Chris@49 453
Chris@49 454 return (S.n_elem > 0) ? max(S) : T(0);
Chris@49 455 }
Chris@49 456
Chris@49 457
Chris@49 458
Chris@49 459 template<typename T1>
Chris@49 460 inline
Chris@49 461 typename T1::pod_type
Chris@49 462 arma_mat_norm_inf(const Proxy<T1>& P)
Chris@49 463 {
Chris@49 464 arma_extra_debug_sigprint();
Chris@49 465
Chris@49 466 // TODO: this can be sped up with a dedicated implementation
Chris@49 467 return as_scalar( max( sum(abs(P.Q), 1), 0) );
Chris@49 468 }
Chris@49 469
Chris@49 470
Chris@49 471
Chris@49 472 template<typename T1>
Chris@49 473 inline
Chris@49 474 arma_warn_unused
Chris@49 475 typename enable_if2< is_arma_type<T1>::value, typename T1::pod_type >::result
Chris@49 476 norm
Chris@49 477 (
Chris@49 478 const T1& X,
Chris@49 479 const uword k,
Chris@49 480 const typename arma_real_or_cx_only<typename T1::elem_type>::result* junk = 0
Chris@49 481 )
Chris@49 482 {
Chris@49 483 arma_extra_debug_sigprint();
Chris@49 484 arma_ignore(junk);
Chris@49 485
Chris@49 486 typedef typename T1::pod_type T;
Chris@49 487
Chris@49 488 const Proxy<T1> P(X);
Chris@49 489
Chris@49 490 if(P.get_n_elem() == 0)
Chris@49 491 {
Chris@49 492 return T(0);
Chris@49 493 }
Chris@49 494
Chris@49 495 const bool is_vec = (P.get_n_rows() == 1) || (P.get_n_cols() == 1);
Chris@49 496
Chris@49 497 if(is_vec == true)
Chris@49 498 {
Chris@49 499 switch(k)
Chris@49 500 {
Chris@49 501 case 1:
Chris@49 502 return arma_vec_norm_1(P);
Chris@49 503 break;
Chris@49 504
Chris@49 505 case 2:
Chris@49 506 return arma_vec_norm_2(P);
Chris@49 507 break;
Chris@49 508
Chris@49 509 default:
Chris@49 510 {
Chris@49 511 arma_debug_check( (k == 0), "norm(): k must be greater than zero" );
Chris@49 512 return arma_vec_norm_k(P, int(k));
Chris@49 513 }
Chris@49 514 }
Chris@49 515 }
Chris@49 516 else
Chris@49 517 {
Chris@49 518 switch(k)
Chris@49 519 {
Chris@49 520 case 1:
Chris@49 521 return arma_mat_norm_1(P);
Chris@49 522 break;
Chris@49 523
Chris@49 524 case 2:
Chris@49 525 return arma_mat_norm_2(P);
Chris@49 526 break;
Chris@49 527
Chris@49 528 default:
Chris@49 529 arma_stop("norm(): unsupported matrix norm type");
Chris@49 530 return T(0);
Chris@49 531 }
Chris@49 532 }
Chris@49 533 }
Chris@49 534
Chris@49 535
Chris@49 536
Chris@49 537 template<typename T1>
Chris@49 538 inline
Chris@49 539 arma_warn_unused
Chris@49 540 typename enable_if2< is_arma_type<T1>::value, typename T1::pod_type >::result
Chris@49 541 norm
Chris@49 542 (
Chris@49 543 const T1& X,
Chris@49 544 const char* method,
Chris@49 545 const typename arma_real_or_cx_only<typename T1::elem_type>::result* junk = 0
Chris@49 546 )
Chris@49 547 {
Chris@49 548 arma_extra_debug_sigprint();
Chris@49 549 arma_ignore(junk);
Chris@49 550
Chris@49 551 typedef typename T1::pod_type T;
Chris@49 552
Chris@49 553 const Proxy<T1> P(X);
Chris@49 554
Chris@49 555 if(P.get_n_elem() == 0)
Chris@49 556 {
Chris@49 557 return T(0);
Chris@49 558 }
Chris@49 559
Chris@49 560 const char sig = method[0];
Chris@49 561 const bool is_vec = (P.get_n_rows() == 1) || (P.get_n_cols() == 1);
Chris@49 562
Chris@49 563 if(is_vec == true)
Chris@49 564 {
Chris@49 565 if( (sig == 'i') || (sig == 'I') || (sig == '+') ) // max norm
Chris@49 566 {
Chris@49 567 return arma_vec_norm_max(P);
Chris@49 568 }
Chris@49 569 else
Chris@49 570 if(sig == '-') // min norm
Chris@49 571 {
Chris@49 572 return arma_vec_norm_min(P);
Chris@49 573 }
Chris@49 574 else
Chris@49 575 if( (sig == 'f') || (sig == 'F') )
Chris@49 576 {
Chris@49 577 return arma_vec_norm_2(P);
Chris@49 578 }
Chris@49 579 else
Chris@49 580 {
Chris@49 581 arma_stop("norm(): unsupported vector norm type");
Chris@49 582 return T(0);
Chris@49 583 }
Chris@49 584 }
Chris@49 585 else
Chris@49 586 {
Chris@49 587 if( (sig == 'i') || (sig == 'I') || (sig == '+') ) // inf norm
Chris@49 588 {
Chris@49 589 return arma_mat_norm_inf(P);
Chris@49 590 }
Chris@49 591 else
Chris@49 592 if( (sig == 'f') || (sig == 'F') )
Chris@49 593 {
Chris@49 594 return arma_vec_norm_2(P);
Chris@49 595 }
Chris@49 596 else
Chris@49 597 {
Chris@49 598 arma_stop("norm(): unsupported matrix norm type");
Chris@49 599 return T(0);
Chris@49 600 }
Chris@49 601 }
Chris@49 602 }
Chris@49 603
Chris@49 604
Chris@49 605
Chris@49 606 //
Chris@49 607 // norms for sparse matrices
Chris@49 608
Chris@49 609
Chris@49 610
Chris@49 611 template<typename T1>
Chris@49 612 inline
Chris@49 613 typename T1::pod_type
Chris@49 614 arma_mat_norm_1(const SpProxy<T1>& P)
Chris@49 615 {
Chris@49 616 arma_extra_debug_sigprint();
Chris@49 617
Chris@49 618 // TODO: this can be sped up with a dedicated implementation
Chris@49 619 return as_scalar( max( sum(abs(P.Q), 0), 1) );
Chris@49 620 }
Chris@49 621
Chris@49 622
Chris@49 623
Chris@49 624 // template<typename T1>
Chris@49 625 // inline
Chris@49 626 // typename T1::pod_type
Chris@49 627 // arma_mat_norm_2(const SpProxy<T1>& P)
Chris@49 628 // {
Chris@49 629 // arma_extra_debug_sigprint();
Chris@49 630 //
Chris@49 631 // // TODO: norm = sqrt( largest eigenvalue of (A^H)*A ), where ^H is the conjugate transpose
Chris@49 632 // // TODO: can use ARPACK or directly implement the Arnoldi iteration
Chris@49 633 // // http://math.stackexchange.com/questions/4368/computing-the-largest-eigenvalue-of-a-very-large-sparse-matrix
Chris@49 634 // }
Chris@49 635
Chris@49 636
Chris@49 637
Chris@49 638 template<typename T1>
Chris@49 639 inline
Chris@49 640 typename T1::pod_type
Chris@49 641 arma_mat_norm_inf(const SpProxy<T1>& P)
Chris@49 642 {
Chris@49 643 arma_extra_debug_sigprint();
Chris@49 644
Chris@49 645 // TODO: this can be sped up with a dedicated implementation
Chris@49 646 return as_scalar( max( sum(abs(P.Q), 1), 0) );
Chris@49 647 }
Chris@49 648
Chris@49 649
Chris@49 650
Chris@49 651 template<typename T1>
Chris@49 652 inline
Chris@49 653 arma_warn_unused
Chris@49 654 typename enable_if2< is_arma_sparse_type<T1>::value, typename T1::pod_type >::result
Chris@49 655 norm
Chris@49 656 (
Chris@49 657 const T1& X,
Chris@49 658 const uword k,
Chris@49 659 const typename arma_real_or_cx_only<typename T1::elem_type>::result* junk = 0
Chris@49 660 )
Chris@49 661 {
Chris@49 662 arma_extra_debug_sigprint();
Chris@49 663 arma_ignore(junk);
Chris@49 664
Chris@49 665 typedef typename T1::elem_type eT;
Chris@49 666 typedef typename T1::pod_type T;
Chris@49 667
Chris@49 668 const SpProxy<T1> P(X);
Chris@49 669
Chris@49 670 if(P.get_n_nonzero() == 0)
Chris@49 671 {
Chris@49 672 return T(0);
Chris@49 673 }
Chris@49 674
Chris@49 675 const bool is_vec = (P.get_n_rows() == 1) || (P.get_n_cols() == 1);
Chris@49 676
Chris@49 677 if(is_vec == true)
Chris@49 678 {
Chris@49 679 const unwrap_spmat<typename SpProxy<T1>::stored_type> tmp(P.Q);
Chris@49 680 const SpMat<eT>& A = tmp.M;
Chris@49 681
Chris@49 682 // create a fake dense vector to allow reuse of code for dense vectors
Chris@49 683 Col<eT> fake_vector( access::rwp(A.values), A.n_nonzero, false );
Chris@49 684
Chris@49 685 const Proxy< Col<eT> > P_fake_vector(fake_vector);
Chris@49 686
Chris@49 687 switch(k)
Chris@49 688 {
Chris@49 689 case 1:
Chris@49 690 return arma_vec_norm_1(P_fake_vector);
Chris@49 691 break;
Chris@49 692
Chris@49 693 case 2:
Chris@49 694 return arma_vec_norm_2(P_fake_vector);
Chris@49 695 break;
Chris@49 696
Chris@49 697 default:
Chris@49 698 {
Chris@49 699 arma_debug_check( (k == 0), "norm(): k must be greater than zero" );
Chris@49 700 return arma_vec_norm_k(P_fake_vector, int(k));
Chris@49 701 }
Chris@49 702 }
Chris@49 703 }
Chris@49 704 else
Chris@49 705 {
Chris@49 706 switch(k)
Chris@49 707 {
Chris@49 708 case 1:
Chris@49 709 return arma_mat_norm_1(P);
Chris@49 710 break;
Chris@49 711
Chris@49 712 // case 2:
Chris@49 713 // return arma_mat_norm_2(P);
Chris@49 714 // break;
Chris@49 715
Chris@49 716 default:
Chris@49 717 arma_stop("norm(): unsupported or unimplemented norm type for sparse matrices");
Chris@49 718 return T(0);
Chris@49 719 }
Chris@49 720 }
Chris@49 721 }
Chris@49 722
Chris@49 723
Chris@49 724
Chris@49 725 template<typename T1>
Chris@49 726 inline
Chris@49 727 arma_warn_unused
Chris@49 728 typename enable_if2< is_arma_sparse_type<T1>::value, typename T1::pod_type >::result
Chris@49 729 norm
Chris@49 730 (
Chris@49 731 const T1& X,
Chris@49 732 const char* method,
Chris@49 733 const typename arma_real_or_cx_only<typename T1::elem_type>::result* junk = 0
Chris@49 734 )
Chris@49 735 {
Chris@49 736 arma_extra_debug_sigprint();
Chris@49 737 arma_ignore(junk);
Chris@49 738
Chris@49 739 typedef typename T1::elem_type eT;
Chris@49 740 typedef typename T1::pod_type T;
Chris@49 741
Chris@49 742 const SpProxy<T1> P(X);
Chris@49 743
Chris@49 744 if(P.get_n_nonzero() == 0)
Chris@49 745 {
Chris@49 746 return T(0);
Chris@49 747 }
Chris@49 748
Chris@49 749
Chris@49 750 const unwrap_spmat<typename SpProxy<T1>::stored_type> tmp(P.Q);
Chris@49 751 const SpMat<eT>& A = tmp.M;
Chris@49 752
Chris@49 753 // create a fake dense vector to allow reuse of code for dense vectors
Chris@49 754 Col<eT> fake_vector( access::rwp(A.values), A.n_nonzero, false );
Chris@49 755
Chris@49 756 const Proxy< Col<eT> > P_fake_vector(fake_vector);
Chris@49 757
Chris@49 758
Chris@49 759 const char sig = method[0];
Chris@49 760 const bool is_vec = (P.get_n_rows() == 1) || (P.get_n_cols() == 1);
Chris@49 761
Chris@49 762 if(is_vec == true)
Chris@49 763 {
Chris@49 764 if( (sig == 'i') || (sig == 'I') || (sig == '+') ) // max norm
Chris@49 765 {
Chris@49 766 return arma_vec_norm_max(P_fake_vector);
Chris@49 767 }
Chris@49 768 else
Chris@49 769 if(sig == '-') // min norm
Chris@49 770 {
Chris@49 771 const T val = arma_vec_norm_min(P_fake_vector);
Chris@49 772
Chris@49 773 if( P.get_n_nonzero() < P.get_n_elem() )
Chris@49 774 {
Chris@49 775 return (std::min)(T(0), val);
Chris@49 776 }
Chris@49 777 else
Chris@49 778 {
Chris@49 779 return val;
Chris@49 780 }
Chris@49 781 }
Chris@49 782 else
Chris@49 783 if( (sig == 'f') || (sig == 'F') )
Chris@49 784 {
Chris@49 785 return arma_vec_norm_2(P_fake_vector);
Chris@49 786 }
Chris@49 787 else
Chris@49 788 {
Chris@49 789 arma_stop("norm(): unsupported vector norm type");
Chris@49 790 return T(0);
Chris@49 791 }
Chris@49 792 }
Chris@49 793 else
Chris@49 794 {
Chris@49 795 if( (sig == 'i') || (sig == 'I') || (sig == '+') ) // inf norm
Chris@49 796 {
Chris@49 797 return arma_mat_norm_inf(P);
Chris@49 798 }
Chris@49 799 else
Chris@49 800 if( (sig == 'f') || (sig == 'F') )
Chris@49 801 {
Chris@49 802 return arma_vec_norm_2(P_fake_vector);
Chris@49 803 }
Chris@49 804 else
Chris@49 805 {
Chris@49 806 arma_stop("norm(): unsupported matrix norm type");
Chris@49 807 return T(0);
Chris@49 808 }
Chris@49 809 }
Chris@49 810 }
Chris@49 811
Chris@49 812
Chris@49 813
Chris@49 814 //! @}