fn_norm.hpp

Go to the documentation of this file.
00001 // Copyright (C) 2010 NICTA and the authors listed below
00002 // http://nicta.com.au
00003 // 
00004 // Authors:
00005 // - Conrad Sanderson (conradsand at ieee dot org)
00006 // 
00007 // This file is part of the Armadillo C++ library.
00008 // It is provided without any warranty of fitness
00009 // for any purpose. You can redistribute this file
00010 // and/or modify it under the terms of the GNU
00011 // Lesser General Public License (LGPL) as published
00012 // by the Free Software Foundation, either version 3
00013 // of the License or (at your option) any later version.
00014 // (see http://www.opensource.org/licenses for more info)
00015 
00016 
00017 //! \addtogroup fn_norm
00018 //! @{
00019 
00020 
00021 
00022 template<typename T1>
00023 arma_hot
00024 inline
00025 typename T1::elem_type
00026 norm_unwrap(const Base<typename T1::elem_type,T1>& X, const u32 k)
00027   {
00028   arma_extra_debug_sigprint();
00029   
00030   typedef typename T1::elem_type eT;
00031   
00032   const unwrap<T1>   tmp(X.get_ref());
00033   const Mat<eT>& A = tmp.M;
00034 
00035   arma_debug_check(    (A.n_elem == 0),                      "norm(): given object has no elements"  );
00036   arma_debug_check( !( (A.n_rows == 1) || (A.n_cols == 1) ), "norm(): given object must be a vector" );
00037   arma_debug_check(    (k == 0),                             "norm(): k must be greater than zero"   );
00038 
00039   const eT* A_mem = A.memptr();
00040   const u32 N     = A.n_elem;
00041 
00042   if(k==1)
00043     {
00044     eT acc = eT(0);
00045     
00046     for(u32 i=0; i<N; ++i)
00047       {
00048       acc += std::abs(A_mem[i]);
00049       }
00050     
00051     return acc;
00052     }
00053   else
00054   if(k==2)
00055     {
00056     if(is_complex<eT>::value == false)
00057       {
00058       eT acc = eT(0);
00059       
00060       for(u32 i=0; i<N; ++i)
00061         {
00062         const eT tmp = A_mem[i];
00063         acc += tmp*tmp;
00064         }
00065       
00066       return std::sqrt(acc);
00067       }
00068     else
00069       {
00070       eT acc = eT(0);
00071       
00072       for(u32 i=0; i<N; ++i)
00073         {
00074         acc += std::abs(A_mem[i]);
00075         }
00076       
00077       return std::sqrt(acc);
00078       }
00079     }
00080   else
00081     {
00082     eT acc = eT(0);
00083     
00084     for(u32 i=0; i<N; ++i)
00085       {
00086       acc += std::pow(std::abs(A_mem[i]), int(k));
00087       }
00088     
00089     return std::pow(acc, eT(1)/eT(k));
00090     }
00091   
00092   }
00093 
00094 
00095 
00096 template<typename T1>
00097 arma_hot
00098 inline
00099 typename T1::elem_type
00100 norm_proxy(const Base<typename T1::elem_type,T1>& X, const u32 k)
00101   {
00102   arma_extra_debug_sigprint();
00103   
00104   typedef typename T1::elem_type eT;
00105   
00106   const Proxy<T1> A(X.get_ref());
00107   
00108   arma_debug_check(    (A.n_elem == 0),                      "norm(): given object has no elements"  );
00109   arma_debug_check( !( (A.n_rows == 1) || (A.n_cols == 1) ), "norm(): given object must be a vector" );
00110   arma_debug_check(    (k == 0),                             "norm(): k must be greater than zero"   );
00111   
00112   const u32 N = A.n_elem;
00113   
00114   if(k==1)
00115     {
00116     eT acc = eT(0);
00117     
00118     for(u32 i=0; i<N; ++i)
00119       {
00120       acc += std::abs(A[i]);
00121       }
00122     
00123     return acc;
00124     }
00125   else
00126   if(k==2)
00127     {
00128     if(is_complex<eT>::value == false)
00129       {
00130       eT acc = eT(0);
00131       
00132       for(u32 i=0; i<N; ++i)
00133         {
00134         const eT tmp = A[i];
00135         acc += tmp*tmp;
00136         }
00137       
00138       return std::sqrt(acc);
00139       }
00140     else
00141       {
00142       eT acc = eT(0);
00143       
00144       for(u32 i=0; i<N; ++i)
00145         {
00146         acc += std::abs(A[i]);
00147         }
00148       
00149       return std::sqrt(acc);
00150       
00151       }
00152     }
00153   else
00154     {
00155     eT acc = eT(0);
00156     
00157     for(u32 i=0; i<N; ++i)
00158       {
00159       acc += std::pow(std::abs(A[i]), int(k));
00160       }
00161     
00162     return std::pow(acc, eT(1)/eT(k));
00163     }
00164   
00165   }
00166 
00167 
00168 
00169 template<typename T1>
00170 arma_inline
00171 arma_warn_unused
00172 typename T1::elem_type
00173 norm(const Base<typename T1::elem_type,T1>& X, const u32 k)
00174   {
00175   arma_extra_debug_sigprint();
00176   
00177   if(is_Mat<T1>::value == true)
00178     {
00179     return norm_unwrap(X, k);
00180     }
00181   else
00182     {
00183     return norm_proxy(X, k);
00184     }
00185   }
00186 
00187 
00188 
00189 //! @}