fn_norm.hpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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