fn_norm.hpp
Go to the documentation of this file.
00001 // Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
00002 // Copyright (C) 2008-2011 Conrad Sanderson
00003 // 
00004 // This file is part of the Armadillo C++ library.
00005 // It is provided without any warranty of fitness
00006 // for any purpose. You can redistribute this file
00007 // and/or modify it under the terms of the GNU
00008 // Lesser General Public License (LGPL) as published
00009 // by the Free Software Foundation, either version 3
00010 // of the License or (at your option) any later version.
00011 // (see http://www.opensource.org/licenses for more info)
00012 
00013 
00016 
00017 
00018 
00019 template<typename T1>
00020 arma_hot
00021 inline
00022 typename T1::pod_type
00023 arma_vec_norm_1(const Proxy<T1>& A)
00024   {
00025   arma_extra_debug_sigprint();
00026   
00027   typedef typename T1::pod_type T;
00028 
00029   T acc = T(0);
00030     
00031   if(Proxy<T1>::prefer_at_accessor == false)
00032     {
00033     typename Proxy<T1>::ea_type P = A.get_ea();
00034     
00035     const uword N = A.get_n_elem();
00036     
00037     uword i,j;
00038     
00039     for(i=0, j=1; j<N; i+=2, j+=2)
00040       {
00041       acc += std::abs(P[i]);
00042       acc += std::abs(P[j]);
00043       }
00044     
00045     if(i < N)
00046       {
00047       acc += std::abs(P[i]);
00048       }
00049     }
00050   else
00051     {
00052     const uword n_rows = A.get_n_rows();
00053     const uword n_cols = A.get_n_cols();
00054     
00055     for(uword col=0; col<n_cols; ++col)
00056       {
00057       uword i,j;
00058       
00059       for(i=0, j=1; j<n_rows; i+=2, j+=2)
00060         {
00061         acc += std::abs(A.at(i,col));
00062         acc += std::abs(A.at(j,col));
00063         }
00064       
00065       if(i < n_rows)
00066         {
00067         acc += std::abs(A.at(i,col));
00068         }
00069       }
00070     }
00071     
00072   return acc;
00073   }
00074 
00075 
00076 
00077 template<typename T1>
00078 arma_hot
00079 inline
00080 typename T1::pod_type
00081 arma_vec_norm_2(const Proxy<T1>& A, const typename arma_not_cx<typename T1::elem_type>::result* junk = 0)
00082   {
00083   arma_extra_debug_sigprint();
00084   arma_ignore(junk);
00085   
00086   typedef typename T1::pod_type T;
00087   
00088   T acc = T(0);
00089   
00090   if(Proxy<T1>::prefer_at_accessor == false)
00091     {
00092     typename Proxy<T1>::ea_type P = A.get_ea();
00093     
00094     const uword N = A.get_n_elem();
00095     
00096     uword i,j;
00097     
00098     for(i=0, j=1; j<N; i+=2, j+=2)
00099       {
00100       const T tmp_i = P[i];
00101       const T tmp_j = P[j];
00102       
00103       acc += tmp_i * tmp_i;
00104       acc += tmp_j * tmp_j;
00105       }
00106     
00107     if(i < N)
00108       {
00109       const T tmp_i = P[i];
00110       
00111       acc += tmp_i * tmp_i;
00112       }
00113     }
00114   else
00115     {
00116     const uword n_rows = A.get_n_rows();
00117     const uword n_cols = A.get_n_cols();
00118     
00119     for(uword col=0; col<n_cols; ++col)
00120       {
00121       uword i,j;
00122       
00123       for(i=0, j=1; j<n_rows; i+=2, j+=2)
00124         {
00125         const T tmp_i = A.at(i,col);
00126         const T tmp_j = A.at(j,col);
00127         
00128         acc += tmp_i * tmp_i;
00129         acc += tmp_j * tmp_j;
00130         }
00131       
00132       if(i < n_rows)
00133         {
00134         const T tmp_i = A.at(i,col);
00135         
00136         acc += tmp_i * tmp_i;
00137         }
00138       }
00139     }
00140   
00141   return std::sqrt(acc);
00142   }
00143 
00144 
00145 
00146 template<typename T1>
00147 arma_hot
00148 inline
00149 typename T1::pod_type
00150 arma_vec_norm_2(const Proxy<T1>& A, const typename arma_cx_only<typename T1::elem_type>::result* junk = 0)
00151   {
00152   arma_extra_debug_sigprint();
00153   arma_ignore(junk);
00154   
00155   typedef typename T1::pod_type T;
00156   
00157   T acc = T(0);
00158   
00159   if(Proxy<T1>::prefer_at_accessor == false)
00160     {
00161     typename Proxy<T1>::ea_type P = A.get_ea();
00162     
00163     const uword N = A.get_n_elem();
00164     
00165     for(uword i=0; i<N; ++i)
00166       {
00167       const T tmp = std::abs(P[i]);
00168       acc += tmp*tmp;
00169       }
00170     }
00171   else
00172     {
00173     const uword n_rows = A.get_n_rows();
00174     const uword n_cols = A.get_n_cols();
00175     
00176     for(uword col=0; col<n_cols; ++col)
00177     for(uword row=0; row<n_rows; ++row)
00178       {
00179       const T tmp = std::abs(A.at(row,col));
00180       acc += tmp*tmp;
00181       }
00182     }
00183   
00184   return std::sqrt(acc);
00185   }
00186 
00187 
00188 
00189 template<typename T1>
00190 arma_hot
00191 inline
00192 typename T1::pod_type
00193 arma_vec_norm_k(const Proxy<T1>& A, const int k)
00194   {
00195   arma_extra_debug_sigprint();
00196   
00197   typedef typename T1::pod_type T;
00198   
00199   T acc = T(0);
00200   
00201   if(Proxy<T1>::prefer_at_accessor == false)
00202     {
00203     typename Proxy<T1>::ea_type P = A.get_ea();
00204     
00205     const uword N = A.get_n_elem();
00206     
00207     uword i,j;
00208     
00209     for(i=0, j=1; j<N; i+=2, j+=2)
00210       {
00211       acc += std::pow(std::abs(P[i]), k);
00212       acc += std::pow(std::abs(P[j]), k);
00213       }
00214     
00215     if(i < N)
00216       {
00217       acc += std::pow(std::abs(P[i]), k);
00218       }
00219     }
00220   else
00221     {
00222     const uword n_rows = A.get_n_rows();
00223     const uword n_cols = A.get_n_cols();
00224     
00225     for(uword col=0; col<n_cols; ++col)
00226     for(uword row=0; row<n_rows; ++row)
00227       {
00228       acc += std::pow(std::abs(A.at(row,col)), k);
00229       }
00230     }
00231   
00232   return std::pow(acc, T(1)/T(k));
00233   }
00234 
00235 
00236 
00237 template<typename T1>
00238 arma_hot
00239 inline
00240 typename T1::pod_type
00241 arma_vec_norm_max(const Proxy<T1>& A)
00242   {
00243   arma_extra_debug_sigprint();
00244   
00245   typedef typename T1::pod_type       T;
00246   typedef typename Proxy<T1>::ea_type ea_type;
00247   
00248         ea_type P = A.get_ea();
00249   const uword     N = A.get_n_elem();
00250   
00251   T max_val = (N != 1) ? priv::most_neg<T>() : std::abs(P[0]);
00252   
00253   uword i,j;
00254   
00255   for(i=0, j=1; j<N; i+=2, j+=2)
00256     {
00257     const T tmp_i = std::abs(P[i]);
00258     const T tmp_j = std::abs(P[j]);
00259     
00260     if(max_val < tmp_i) { max_val = tmp_i; }
00261     if(max_val < tmp_j) { max_val = tmp_j; }
00262     }
00263   
00264   if(i < N)
00265     {
00266     const T tmp_i = std::abs(P[i]);
00267     
00268     if(max_val < tmp_i) { max_val = tmp_i; }
00269     }
00270   
00271   return max_val;
00272   }
00273 
00274 
00275 
00276 template<typename T1>
00277 arma_hot
00278 inline
00279 typename T1::pod_type
00280 arma_vec_norm_min(const Proxy<T1>& A)
00281   {
00282   arma_extra_debug_sigprint();
00283   
00284   typedef typename T1::pod_type       T;
00285   typedef typename Proxy<T1>::ea_type ea_type;
00286   
00287         ea_type P = A.get_ea();
00288   const uword     N = A.get_n_elem();
00289   
00290   T min_val = (N != 1) ? priv::most_pos<T>() : std::abs(P[0]);
00291   
00292   uword i,j;
00293   
00294   for(i=0, j=1; j<N; i+=2, j+=2)
00295     {
00296     const T tmp_i = std::abs(P[i]);
00297     const T tmp_j = std::abs(P[j]);
00298     
00299     if(min_val > tmp_i) { min_val = tmp_i; }
00300     if(min_val > tmp_j) { min_val = tmp_j; }
00301     }
00302   
00303   if(i < N)
00304     {
00305     const T tmp_i = std::abs(P[i]);
00306     
00307     if(min_val > tmp_i) { min_val = tmp_i; }
00308     }
00309   
00310   return min_val;
00311   }
00312 
00313 
00314 
00315 template<typename T1>
00316 inline
00317 typename T1::pod_type
00318 arma_mat_norm_1(const Proxy<T1>& A)
00319   {
00320   arma_extra_debug_sigprint();
00321   
00322   typedef typename T1::elem_type eT;
00323   typedef typename T1::pod_type   T;
00324   
00325   const unwrap<typename Proxy<T1>::stored_type> tmp(A.Q);
00326   const Mat<eT>& X = tmp.M;
00327   
00328   // TODO: this can be sped up with a dedicated implementation
00329   return as_scalar( max( sum(abs(X)), 1) );
00330   }
00331 
00332 
00333 
00334 template<typename T1>
00335 inline
00336 typename T1::pod_type
00337 arma_mat_norm_2(const Proxy<T1>& A)
00338   {
00339   arma_extra_debug_sigprint();
00340   
00341   typedef typename T1::elem_type eT;
00342   typedef typename T1::pod_type   T;
00343   
00344   const unwrap<typename Proxy<T1>::stored_type> tmp(A.Q);
00345   const Mat<eT>& X = tmp.M;
00346   
00347   Col<T> S;
00348   svd(S, X);
00349   
00350   return (S.n_elem > 0) ? max(S) : T(0);
00351   }
00352 
00353 
00354 
00355 template<typename T1>
00356 inline
00357 typename T1::pod_type
00358 arma_mat_norm_inf(const Proxy<T1>& A)
00359   {
00360   arma_extra_debug_sigprint();
00361   
00362   typedef typename T1::elem_type eT;
00363   typedef typename T1::pod_type   T;
00364   
00365   const unwrap<typename Proxy<T1>::stored_type> tmp(A.Q);
00366   const Mat<eT>& X = tmp.M;
00367   
00368   // TODO: this can be sped up with a dedicated implementation
00369   return as_scalar( max( sum(abs(X),1) ) );
00370   }
00371 
00372 
00373 
00374 template<typename T1>
00375 inline
00376 arma_warn_unused
00377 typename T1::pod_type
00378 norm
00379   (
00380   const Base<typename T1::elem_type,T1>& X,
00381   const uword k,
00382   const typename arma_float_or_cx_only<typename T1::elem_type>::result* junk = 0
00383   )
00384   {
00385   arma_extra_debug_sigprint();
00386   arma_ignore(junk);
00387   
00388   typedef typename T1::elem_type eT;
00389   typedef typename T1::pod_type   T;
00390   
00391   const Proxy<T1> A(X.get_ref());
00392   
00393   if(A.get_n_elem() == 0)
00394     {
00395     return T(0);
00396     }
00397   
00398   const bool is_vec = (A.get_n_rows() == 1) || (A.get_n_cols() == 1);
00399   
00400   if(is_vec == true)
00401     {
00402     switch(k)
00403       {
00404       case 1:
00405         return arma_vec_norm_1(A);
00406         break;
00407       
00408       case 2:
00409         return arma_vec_norm_2(A);
00410         break;
00411       
00412       default:
00413         {
00414         arma_debug_check( (k == 0), "norm(): k must be greater than zero"   );
00415         return arma_vec_norm_k(A, int(k));
00416         }
00417       }
00418     }
00419   else
00420     {
00421     switch(k)
00422       {
00423       case 1:
00424         return arma_mat_norm_1(A);
00425         break;
00426       
00427       case 2:
00428         return arma_mat_norm_2(A);
00429         break;
00430       
00431       default:
00432         arma_stop("norm(): unsupported matrix norm type");
00433         return T(0);
00434       }
00435     }
00436   }
00437 
00438 
00439 
00440 template<typename T1>
00441 inline
00442 arma_warn_unused
00443 typename T1::pod_type
00444 norm
00445   (
00446   const Base<typename T1::elem_type,T1>& X,
00447   const char* method,
00448   const typename arma_float_or_cx_only<typename T1::elem_type>::result* junk = 0
00449   )
00450   {
00451   arma_extra_debug_sigprint();
00452   arma_ignore(junk);
00453   
00454   typedef typename T1::elem_type eT;
00455   typedef typename T1::pod_type   T;
00456   
00457   const Proxy<T1> A(X.get_ref());
00458   
00459   if(A.get_n_elem() == 0)
00460     {
00461     return T(0);
00462     }
00463   
00464   const char sig    = method[0];
00465   const bool is_vec = (A.get_n_rows() == 1) || (A.get_n_cols() == 1);
00466   
00467   if(is_vec == true)
00468     {
00469     if( (sig == 'i') || (sig == 'I') || (sig == '+') )   // max norm
00470       {
00471       return arma_vec_norm_max(A);
00472       }
00473     else
00474     if(sig == '-')   // min norm
00475       {
00476       return arma_vec_norm_min(A);
00477       }
00478     else
00479     if( (sig == 'f') || (sig == 'F') )
00480       {
00481       return arma_vec_norm_2(A);
00482       }
00483     else
00484       {
00485       arma_stop("norm(): unsupported vector norm type");
00486       return T(0);
00487       }
00488     }
00489   else
00490     {
00491     if( (sig == 'i') || (sig == 'I') || (sig == '+') )   // inf norm
00492       {
00493       return arma_mat_norm_inf(A);
00494       }
00495     else
00496     if( (sig == 'f') || (sig == 'F') )
00497       {
00498       return arma_vec_norm_2(A);
00499       }
00500     else
00501       {
00502       arma_stop("norm(): unsupported matrix norm type");
00503       return T(0);
00504       }
00505     }
00506   }
00507 
00508 
00509 


armadillo_matrix
Author(s): Conrad Sanderson - NICTA (www.nicta.com.au), (Wrapper by Sjoerd van den Dries)
autogenerated on Tue Jan 7 2014 11:42:04