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