comparison armadillo-2.4.4/include/armadillo_bits/fn_norm.hpp @ 0:8b6102e2a9b0

Armadillo Library
author maxzanoni76 <max.zanoni@eecs.qmul.ac.uk>
date Wed, 11 Apr 2012 09:27:06 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:8b6102e2a9b0
1 // Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
2 // Copyright (C) 2008-2011 Conrad Sanderson
3 //
4 // This file is part of the Armadillo C++ library.
5 // It is provided without any warranty of fitness
6 // for any purpose. You can redistribute this file
7 // and/or modify it under the terms of the GNU
8 // Lesser General Public License (LGPL) as published
9 // by the Free Software Foundation, either version 3
10 // of the License or (at your option) any later version.
11 // (see http://www.opensource.org/licenses for more info)
12
13
14 //! \addtogroup fn_norm
15 //! @{
16
17
18
19 template<typename T1>
20 arma_hot
21 inline
22 typename T1::pod_type
23 arma_vec_norm_1(const Proxy<T1>& A)
24 {
25 arma_extra_debug_sigprint();
26
27 typedef typename T1::pod_type T;
28
29 T acc = T(0);
30
31 if(Proxy<T1>::prefer_at_accessor == false)
32 {
33 typename Proxy<T1>::ea_type P = A.get_ea();
34
35 const uword N = A.get_n_elem();
36
37 uword i,j;
38
39 for(i=0, j=1; j<N; i+=2, j+=2)
40 {
41 acc += std::abs(P[i]);
42 acc += std::abs(P[j]);
43 }
44
45 if(i < N)
46 {
47 acc += std::abs(P[i]);
48 }
49 }
50 else
51 {
52 const uword n_rows = A.get_n_rows();
53 const uword n_cols = A.get_n_cols();
54
55 for(uword col=0; col<n_cols; ++col)
56 {
57 uword i,j;
58
59 for(i=0, j=1; j<n_rows; i+=2, j+=2)
60 {
61 acc += std::abs(A.at(i,col));
62 acc += std::abs(A.at(j,col));
63 }
64
65 if(i < n_rows)
66 {
67 acc += std::abs(A.at(i,col));
68 }
69 }
70 }
71
72 return acc;
73 }
74
75
76
77 template<typename T1>
78 arma_hot
79 inline
80 typename T1::pod_type
81 arma_vec_norm_2(const Proxy<T1>& A, const typename arma_not_cx<typename T1::elem_type>::result* junk = 0)
82 {
83 arma_extra_debug_sigprint();
84 arma_ignore(junk);
85
86 typedef typename T1::pod_type T;
87
88 T acc = T(0);
89
90 if(Proxy<T1>::prefer_at_accessor == false)
91 {
92 typename Proxy<T1>::ea_type P = A.get_ea();
93
94 const uword N = A.get_n_elem();
95
96 uword i,j;
97
98 for(i=0, j=1; j<N; i+=2, j+=2)
99 {
100 const T tmp_i = P[i];
101 const T tmp_j = P[j];
102
103 acc += tmp_i * tmp_i;
104 acc += tmp_j * tmp_j;
105 }
106
107 if(i < N)
108 {
109 const T tmp_i = P[i];
110
111 acc += tmp_i * tmp_i;
112 }
113 }
114 else
115 {
116 const uword n_rows = A.get_n_rows();
117 const uword n_cols = A.get_n_cols();
118
119 for(uword col=0; col<n_cols; ++col)
120 {
121 uword i,j;
122
123 for(i=0, j=1; j<n_rows; i+=2, j+=2)
124 {
125 const T tmp_i = A.at(i,col);
126 const T tmp_j = A.at(j,col);
127
128 acc += tmp_i * tmp_i;
129 acc += tmp_j * tmp_j;
130 }
131
132 if(i < n_rows)
133 {
134 const T tmp_i = A.at(i,col);
135
136 acc += tmp_i * tmp_i;
137 }
138 }
139 }
140
141 return std::sqrt(acc);
142 }
143
144
145
146 template<typename T1>
147 arma_hot
148 inline
149 typename T1::pod_type
150 arma_vec_norm_2(const Proxy<T1>& A, const typename arma_cx_only<typename T1::elem_type>::result* junk = 0)
151 {
152 arma_extra_debug_sigprint();
153 arma_ignore(junk);
154
155 typedef typename T1::pod_type T;
156
157 T acc = T(0);
158
159 if(Proxy<T1>::prefer_at_accessor == false)
160 {
161 typename Proxy<T1>::ea_type P = A.get_ea();
162
163 const uword N = A.get_n_elem();
164
165 for(uword i=0; i<N; ++i)
166 {
167 const T tmp = std::abs(P[i]);
168 acc += tmp*tmp;
169 }
170 }
171 else
172 {
173 const uword n_rows = A.get_n_rows();
174 const uword n_cols = A.get_n_cols();
175
176 for(uword col=0; col<n_cols; ++col)
177 for(uword row=0; row<n_rows; ++row)
178 {
179 const T tmp = std::abs(A.at(row,col));
180 acc += tmp*tmp;
181 }
182 }
183
184 return std::sqrt(acc);
185 }
186
187
188
189 template<typename T1>
190 arma_hot
191 inline
192 typename T1::pod_type
193 arma_vec_norm_k(const Proxy<T1>& A, const int k)
194 {
195 arma_extra_debug_sigprint();
196
197 typedef typename T1::pod_type T;
198
199 T acc = T(0);
200
201 if(Proxy<T1>::prefer_at_accessor == false)
202 {
203 typename Proxy<T1>::ea_type P = A.get_ea();
204
205 const uword N = A.get_n_elem();
206
207 uword i,j;
208
209 for(i=0, j=1; j<N; i+=2, j+=2)
210 {
211 acc += std::pow(std::abs(P[i]), k);
212 acc += std::pow(std::abs(P[j]), k);
213 }
214
215 if(i < N)
216 {
217 acc += std::pow(std::abs(P[i]), k);
218 }
219 }
220 else
221 {
222 const uword n_rows = A.get_n_rows();
223 const uword n_cols = A.get_n_cols();
224
225 for(uword col=0; col<n_cols; ++col)
226 for(uword row=0; row<n_rows; ++row)
227 {
228 acc += std::pow(std::abs(A.at(row,col)), k);
229 }
230 }
231
232 return std::pow(acc, T(1)/T(k));
233 }
234
235
236
237 template<typename T1>
238 arma_hot
239 inline
240 typename T1::pod_type
241 arma_vec_norm_max(const Proxy<T1>& A)
242 {
243 arma_extra_debug_sigprint();
244
245 typedef typename T1::pod_type T;
246 typedef typename Proxy<T1>::ea_type ea_type;
247
248 ea_type P = A.get_ea();
249 const uword N = A.get_n_elem();
250
251 T max_val = (N != 1) ? priv::most_neg<T>() : std::abs(P[0]);
252
253 uword i,j;
254
255 for(i=0, j=1; j<N; i+=2, j+=2)
256 {
257 const T tmp_i = std::abs(P[i]);
258 const T tmp_j = std::abs(P[j]);
259
260 if(max_val < tmp_i) { max_val = tmp_i; }
261 if(max_val < tmp_j) { max_val = tmp_j; }
262 }
263
264 if(i < N)
265 {
266 const T tmp_i = std::abs(P[i]);
267
268 if(max_val < tmp_i) { max_val = tmp_i; }
269 }
270
271 return max_val;
272 }
273
274
275
276 template<typename T1>
277 arma_hot
278 inline
279 typename T1::pod_type
280 arma_vec_norm_min(const Proxy<T1>& A)
281 {
282 arma_extra_debug_sigprint();
283
284 typedef typename T1::pod_type T;
285 typedef typename Proxy<T1>::ea_type ea_type;
286
287 ea_type P = A.get_ea();
288 const uword N = A.get_n_elem();
289
290 T min_val = (N != 1) ? priv::most_pos<T>() : std::abs(P[0]);
291
292 uword i,j;
293
294 for(i=0, j=1; j<N; i+=2, j+=2)
295 {
296 const T tmp_i = std::abs(P[i]);
297 const T tmp_j = std::abs(P[j]);
298
299 if(min_val > tmp_i) { min_val = tmp_i; }
300 if(min_val > tmp_j) { min_val = tmp_j; }
301 }
302
303 if(i < N)
304 {
305 const T tmp_i = std::abs(P[i]);
306
307 if(min_val > tmp_i) { min_val = tmp_i; }
308 }
309
310 return min_val;
311 }
312
313
314
315 template<typename T1>
316 inline
317 typename T1::pod_type
318 arma_mat_norm_1(const Proxy<T1>& A)
319 {
320 arma_extra_debug_sigprint();
321
322 typedef typename T1::elem_type eT;
323 typedef typename T1::pod_type T;
324
325 const unwrap<typename Proxy<T1>::stored_type> tmp(A.Q);
326 const Mat<eT>& X = tmp.M;
327
328 // TODO: this can be sped up with a dedicated implementation
329 return as_scalar( max( sum(abs(X)), 1) );
330 }
331
332
333
334 template<typename T1>
335 inline
336 typename T1::pod_type
337 arma_mat_norm_2(const Proxy<T1>& A)
338 {
339 arma_extra_debug_sigprint();
340
341 typedef typename T1::elem_type eT;
342 typedef typename T1::pod_type T;
343
344 const unwrap<typename Proxy<T1>::stored_type> tmp(A.Q);
345 const Mat<eT>& X = tmp.M;
346
347 Col<T> S;
348 svd(S, X);
349
350 return (S.n_elem > 0) ? max(S) : T(0);
351 }
352
353
354
355 template<typename T1>
356 inline
357 typename T1::pod_type
358 arma_mat_norm_inf(const Proxy<T1>& A)
359 {
360 arma_extra_debug_sigprint();
361
362 typedef typename T1::elem_type eT;
363 typedef typename T1::pod_type T;
364
365 const unwrap<typename Proxy<T1>::stored_type> tmp(A.Q);
366 const Mat<eT>& X = tmp.M;
367
368 // TODO: this can be sped up with a dedicated implementation
369 return as_scalar( max( sum(abs(X),1) ) );
370 }
371
372
373
374 template<typename T1>
375 inline
376 arma_warn_unused
377 typename T1::pod_type
378 norm
379 (
380 const Base<typename T1::elem_type,T1>& X,
381 const uword k,
382 const typename arma_float_or_cx_only<typename T1::elem_type>::result* junk = 0
383 )
384 {
385 arma_extra_debug_sigprint();
386 arma_ignore(junk);
387
388 typedef typename T1::elem_type eT;
389 typedef typename T1::pod_type T;
390
391 const Proxy<T1> A(X.get_ref());
392
393 if(A.get_n_elem() == 0)
394 {
395 return T(0);
396 }
397
398 const bool is_vec = (A.get_n_rows() == 1) || (A.get_n_cols() == 1);
399
400 if(is_vec == true)
401 {
402 switch(k)
403 {
404 case 1:
405 return arma_vec_norm_1(A);
406 break;
407
408 case 2:
409 return arma_vec_norm_2(A);
410 break;
411
412 default:
413 {
414 arma_debug_check( (k == 0), "norm(): k must be greater than zero" );
415 return arma_vec_norm_k(A, int(k));
416 }
417 }
418 }
419 else
420 {
421 switch(k)
422 {
423 case 1:
424 return arma_mat_norm_1(A);
425 break;
426
427 case 2:
428 return arma_mat_norm_2(A);
429 break;
430
431 default:
432 arma_stop("norm(): unsupported matrix norm type");
433 return T(0);
434 }
435 }
436 }
437
438
439
440 template<typename T1>
441 inline
442 arma_warn_unused
443 typename T1::pod_type
444 norm
445 (
446 const Base<typename T1::elem_type,T1>& X,
447 const char* method,
448 const typename arma_float_or_cx_only<typename T1::elem_type>::result* junk = 0
449 )
450 {
451 arma_extra_debug_sigprint();
452 arma_ignore(junk);
453
454 typedef typename T1::elem_type eT;
455 typedef typename T1::pod_type T;
456
457 const Proxy<T1> A(X.get_ref());
458
459 if(A.get_n_elem() == 0)
460 {
461 return T(0);
462 }
463
464 const char sig = method[0];
465 const bool is_vec = (A.get_n_rows() == 1) || (A.get_n_cols() == 1);
466
467 if(is_vec == true)
468 {
469 if( (sig == 'i') || (sig == 'I') || (sig == '+') ) // max norm
470 {
471 return arma_vec_norm_max(A);
472 }
473 else
474 if(sig == '-') // min norm
475 {
476 return arma_vec_norm_min(A);
477 }
478 else
479 if( (sig == 'f') || (sig == 'F') )
480 {
481 return arma_vec_norm_2(A);
482 }
483 else
484 {
485 arma_stop("norm(): unsupported vector norm type");
486 return T(0);
487 }
488 }
489 else
490 {
491 if( (sig == 'i') || (sig == 'I') || (sig == '+') ) // inf norm
492 {
493 return arma_mat_norm_inf(A);
494 }
495 else
496 if( (sig == 'f') || (sig == 'F') )
497 {
498 return arma_vec_norm_2(A);
499 }
500 else
501 {
502 arma_stop("norm(): unsupported matrix norm type");
503 return T(0);
504 }
505 }
506 }
507
508
509
510 //! @}