MathTL
|
00001 // -*- c++ -*- 00002 00003 // +--------------------------------------------------------------------+ 00004 // | This file is part of MathTL - the Mathematical Template Library | 00005 // | | 00006 // | Copyright (c) 2002-2009 | 00007 // | Thorsten Raasch, Manuel Werner | 00008 // +--------------------------------------------------------------------+ 00009 00010 #ifndef _MATHTL_VECTOR_NORMS_H 00011 #define _MATHTL_VECTOR_NORMS_H 00012 00013 #include <algorithm> 00014 #include <cmath> 00015 #include <iostream> 00016 00017 namespace MathTL 00018 { 00019 /* 00020 computation of different (quasi-)norms for generic VECTOR classes 00021 with a standard signature like std::vector<T> 00022 00023 You can use template specialization to speed up the norm computation 00024 for specific VECTOR classes. 00025 */ 00026 00030 template <class VECTOR> 00031 const double linfty_norm(const VECTOR& v) 00032 { 00033 double r(0.0); 00034 00035 for (typename VECTOR::const_iterator it(v.begin()), itend(v.end()); 00036 it != itend; ++it) 00037 r = std::max(fabs(*it), r); 00038 00039 return r; 00040 } 00041 00045 template <class VECTOR> 00046 const double linfty_norm(const VECTOR& v, unsigned int& i) 00047 { 00048 double r(0.0); 00049 unsigned int j = 0; 00050 00051 for (typename VECTOR::const_iterator it(v.begin()), itend(v.end()); 00052 it != itend; ++it, ++j) { 00053 if (fabs(*it) > r) { 00054 r = std::max(fabs(*it), r); 00055 i = j; 00056 } 00057 } 00058 00059 return r; 00060 } 00061 00065 template <class VECTOR> 00066 const double l1_norm(const VECTOR& v) 00067 { 00068 double r(0.0); 00069 00070 for (typename VECTOR::const_iterator it(v.begin()), itend(v.end()); 00071 it != itend; ++it) 00072 r += fabs(*it); 00073 00074 return r; 00075 } 00076 00080 template <class VECTOR> 00081 const double l2_norm_sqr(const VECTOR& v) 00082 { 00083 double r(0.0); 00084 00085 for (typename VECTOR::const_iterator it(v.begin()), itend(v.end()); 00086 it != itend; ++it) 00087 r += *it * *it; 00088 00089 return r; 00090 } 00091 00095 template <class VECTOR> 00096 const double l2_norm(const VECTOR& v) 00097 { 00098 return sqrt(l2_norm_sqr(v)); 00099 } 00100 00104 template <class VECTOR> 00105 const double lp_norm(const VECTOR& v, const double p) 00106 { 00107 double r(0.0); 00108 00109 for (typename VECTOR::const_iterator it(v.begin()), itend(v.end()); 00110 it != itend; ++it) 00111 r += std::pow(fabs(*it), p); 00112 00113 return std::pow(r, 1.0/p); 00114 } 00115 00119 template <class VECTOR> 00120 const unsigned int l0_norm(const VECTOR& v) 00121 { 00122 unsigned int r(0); 00123 00124 for (typename VECTOR::const_iterator it(v.begin()), itend(v.end()); 00125 it != itend; ++it) 00126 if (fabs(*it)>0) r++; 00127 00128 return r; 00129 } 00130 } 00131 00132 #endif