00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
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
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 == '+') )
00470 {
00471 return arma_vec_norm_max(A);
00472 }
00473 else
00474 if(sig == '-')
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 == '+') )
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