00001 /** 00002 \file Robots/LoBot/util/LoStats.H 00003 \brief Some statistics related functions. 00004 */ 00005 00006 // //////////////////////////////////////////////////////////////////// // 00007 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00008 // by the University of Southern California (USC) and the iLab at USC. // 00009 // See http://iLab.usc.edu for information about this project. // 00010 // //////////////////////////////////////////////////////////////////// // 00011 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00012 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00013 // in Visual Environments, and Applications'' by Christof Koch and // 00014 // Laurent Itti, California Institute of Technology, 2001 (patent // 00015 // pending; application number 09/912,225 filed July 23, 2001; see // 00016 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00017 // //////////////////////////////////////////////////////////////////// // 00018 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00019 // // 00020 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00021 // redistribute it and/or modify it under the terms of the GNU General // 00022 // Public License as published by the Free Software Foundation; either // 00023 // version 2 of the License, or (at your option) any later version. // 00024 // // 00025 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00026 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00027 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00028 // PURPOSE. See the GNU General Public License for more details. // 00029 // // 00030 // You should have received a copy of the GNU General Public License // 00031 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00032 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00033 // Boston, MA 02111-1307 USA. // 00034 // //////////////////////////////////////////////////////////////////// // 00035 // 00036 // Primary maintainer for this file: mviswana usc edu 00037 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Robots/LoBot/util/LoStats.H $ 00038 // $Id: LoStats.H 14285 2010-12-01 17:33:15Z mviswana $ 00039 // 00040 00041 #ifndef LOBOT_STATISTICS_UTILITIES_DOT_H 00042 #define LOBOT_STATISTICS_UTILITIES_DOT_H 00043 00044 //------------------------------ HEADERS -------------------------------- 00045 00046 // lobot headers 00047 #include "Robots/LoBot/util/LoMath.H" 00048 00049 // Standard C++ headers 00050 #include <utility> 00051 00052 //----------------------------- NAMESPACE ------------------------------- 00053 00054 namespace lobot { 00055 00056 //--------------------------- "FULL" STATS ------------------------------ 00057 00058 /** 00059 \class lobot::generic_stats 00060 \brief A structure to hold several descriptive statistics together. 00061 00062 In some situations, we might want to know more than just the mean and 00063 standard deviation of the values held by a container. The 00064 lobot::generic_stats structure holds several other useful values in 00065 addition to the mean and standard deviation. 00066 */ 00067 template<typename T> 00068 struct generic_stats { 00069 int n ; //< number of elements from which mean and stdev are computed 00070 T sum ; //< sum of all the values from which mean and stdev are computed 00071 T ssq ; //< sum of squares of all values 00072 T mean ; //< arithmetic mean 00073 T stdev; //< standard deviation 00074 00075 /// Constructor. 00076 generic_stats(int n = 0, T sum = 0, T ssq = 0, T mean = 0, T stdev = 0) ; 00077 } ; 00078 00079 template<typename T> 00080 generic_stats<T>::generic_stats(int N, T S, T SS, T mu, T sigma) 00081 : n(N), sum(S), ssq(SS), mean(mu), stdev(sigma) 00082 {} 00083 00084 /// This function computes the mean and standard deviation of a sequence 00085 /// of elements contained within the sequence pointed to by the supplied 00086 /// input iterators. Additionally, it also returns the number of elements 00087 /// in the sequence, the sum of all the elements in the sequence and the 00088 /// sum of the squares of all the elements. All this information is 00089 /// returned via a lobot::generic_stats structure. 00090 /// 00091 /// NOTE: Since type T does not figure in the function's argument list, 00092 /// automatic type deduction will not work with this function. However, 00093 /// the input_iterator can be deduced automatically. Therefore, this 00094 /// function should be invoked as compute_stats<T>(...). 00095 template<typename T, typename input_iterator> 00096 generic_stats<T> 00097 compute_stats(input_iterator begin, input_iterator end) 00098 { 00099 T sum = T() ; 00100 T ssq = T() ; // sum of squares 00101 int N = 0 ; 00102 for (input_iterator i = begin; i != end; ++i, ++N) { 00103 T x = *i ; 00104 sum += x ; 00105 ssq += sqr(x) ; 00106 } 00107 return generic_stats<T>(N, sum, ssq, sum/N, sqrt(N * ssq - sqr(sum))/N) ; 00108 } 00109 00110 /// This function computes the mean and standard deviation of a sequence 00111 /// of elements contained within the sequence pointed to by the supplied 00112 /// input iterators. The type for the mean and standard deviation do not 00113 /// have to be the same as the type of elements in the container. 00114 /// However, it must be possible to "convert" each contained element to 00115 /// an object of type T. This "conversion" will be performed by a helper 00116 /// function or function object of type converter_function. Generally, 00117 /// the converter_function will be something like the adapter returned by 00118 /// std::mem_fun_ref. 00119 /// 00120 /// The mean and standard deviation are returned along with the number of 00121 /// elements in the sequence, the sum of all the elements and the sum of 00122 /// the squares in a lobot::generic_stats<T> structure. 00123 /// 00124 /// NOTE: Since type T does not figure in the function's argument list, 00125 /// automatic type deduction will not work with this function. However, 00126 /// types input_iterator and converter_function can be deduced 00127 /// automatically. Therefore, this function should be invoked as 00128 /// compute_stats<T>(...). 00129 template<typename T, typename input_iterator, typename converter_function> 00130 generic_stats<T> 00131 compute_stats(input_iterator begin, input_iterator end, converter_function F) 00132 { 00133 T sum = T() ; 00134 T ssq = T() ; // sum of squares 00135 int N = 0 ; 00136 for (input_iterator i = begin; i != end; ++i, ++N) { 00137 T x = F(*i) ; 00138 sum += x ; 00139 ssq += sqr(x); 00140 } 00141 return generic_stats<T>(N, sum, ssq, sum/N, sqrt(N * ssq - sqr(sum))/N) ; 00142 } 00143 00144 //-------------------- MEAN AND STANDARD DEVIATION ---------------------- 00145 00146 /// This function computes the average of all the elements in the 00147 /// sequence specified by the supplied iterators. It is assumed that T is 00148 /// the type of elements contained within the sequence and that 00149 /// dereferencing the iterators yields objects of type T. Furthermore, 00150 /// type T must support the += and / operators. Finally, the default 00151 /// constructor for type T must yield a T initialized to zero. 00152 /// 00153 /// NOTE: Since type T does not figure in the function's argument list, 00154 /// automatic type deduction will not work with this function. However, 00155 /// the input_iterator type can be deduced automatically. Therefore, this 00156 /// function should be invoked as mean<T>(...). 00157 template<typename T, typename input_iterator> 00158 T mean(input_iterator begin, input_iterator end) 00159 { 00160 T sum = T() ; 00161 int N = 0 ; 00162 for (input_iterator i = begin; i != end; ++i, ++N) 00163 sum += *i ; 00164 return sum/N ; 00165 } 00166 00167 /// This function computes the average of all the elements in the 00168 /// sequence specified by the supplied iterators. It is not necessary 00169 /// that T be the type of elements contained within the sequence. 00170 /// However, there must be some way of "converting" the contained type to 00171 /// T. Therefore, a function or function object that performs this 00172 /// "conversion" is required by this function. This "converter" function 00173 /// will be passed the result of dereferencing the iterator type. 00174 /// Generally speaking, the "converter" will be something like what is 00175 /// returned by std::mem_fun_ref. 00176 /// 00177 /// Type T must support the += and / operators. T's default constructor 00178 /// must yield a T initialized to zero. 00179 /// 00180 /// NOTE: Since type T does not figure in the function's argument list, 00181 /// automatic type deduction will not work with this function. However, 00182 /// input_iterator and converter_function types can be deduced 00183 /// automatically. Therefore, this function should be invoked as 00184 /// mean<T>(...). 00185 template<typename T, typename input_iterator, typename converter_function> 00186 T mean(input_iterator begin, input_iterator end, converter_function F) 00187 { 00188 T sum = T() ; 00189 int N = 0 ; 00190 for (input_iterator i = begin; i != end; ++i, ++N) 00191 sum += F(*i) ; 00192 return sum/N ; 00193 } 00194 00195 /// This function computes the standard deviation of all the elements in 00196 /// the sequence specified by the supplied iterators. It is assumed that 00197 /// T is the type of elements contained within the sequence and that 00198 /// dereferencing the iterators yields objects of type T. Furthermore, 00199 /// type T must support the += and / operators and be compatible with the 00200 /// sqrt function. Finally, the default constructor for type T must yield 00201 /// a T initialized to zero. 00202 /// 00203 /// NOTE: Since type T does not figure in the function's argument list, 00204 /// automatic type deduction will not work with this function. However, 00205 /// the input_iterator type can be deduced automatically. Therefore, this 00206 /// function should be invoked as stdev<T>(...). 00207 template<typename T, typename input_iterator> 00208 T stdev(input_iterator begin, input_iterator end) 00209 { 00210 return compute_stats<T>(begin, end).stdev ; 00211 } 00212 00213 /// This function computes the standard deviation of all the elements in 00214 /// the sequence specified by the supplied iterators. It is not necessary 00215 /// that T be the type of elements contained within the sequence. 00216 /// However, there must be some way of "converting" the contained type to 00217 /// T. Therefore, a function or function object that performs this 00218 /// "conversion" is required by this function. The "converter" function 00219 /// will be passed the result of dereferencing the iterator type. 00220 /// Generally speaking, the "converter" will be something like what is 00221 /// returned by std::mem_fun_ref. 00222 /// 00223 /// Type T must support the += and / operators. It must be compatible 00224 /// with the sqrt function. And T's default constructor must yield a T 00225 /// initialized to zero. 00226 /// 00227 /// NOTE: Since type T does not figure in the function's argument list, 00228 /// automatic type deduction will not work with this function. However, 00229 /// types input_iterator and converter_function can be deduced 00230 /// automatically. Therefore, this function should be invoked as 00231 /// stdev<T>(...). 00232 template<typename T, typename input_iterator, typename converter_function> 00233 T stdev(input_iterator begin, input_iterator end, converter_function F) 00234 { 00235 return compute_stats<T>(begin, end, F).stdev ; 00236 } 00237 00238 /// This function computes the mean and standard deviation for a sequence 00239 /// of elements of type T contained within the container pointed to by 00240 /// input_iterator. The two quantities computed by this function are 00241 /// returned via an std::pair<T,T> with the mean being the first element 00242 /// of the pair and the standard deviation being the second element. 00243 /// 00244 /// NOTE: Since type T does not figure in the function's argument list, 00245 /// automatic type deduction will not work with this function. However, 00246 /// the input_iterator can be deduced automatically. Therefore, this 00247 /// function should be invoked as mean_stdev<T>(...). 00248 template<typename T, typename input_iterator> 00249 std::pair<T, T> 00250 mean_stdev(input_iterator begin, input_iterator end) 00251 { 00252 generic_stats<T> s = compute_stats<T>(begin, end) ; 00253 return std::make_pair(s.mean, s.stdev) ; 00254 } 00255 00256 /// This function computes the mean and standard deviation of a sequence 00257 /// of elements contained within the sequence pointed to by the input 00258 /// iterators. The type for the mean and standard deviation do not have 00259 /// to be the same as the type of elements in the container. However, it 00260 /// must be possible to "convert" each contained element to an object of 00261 /// type T. This "conversion" will be performed by a helper function or 00262 /// function object of type converter_function. Generally, the 00263 /// converter_function will be something like the adapter returned by 00264 /// std::mem_fun_ref. 00265 /// 00266 /// The mean and standard deviation are returned in an std::pair<T,T> 00267 /// wherein the first element is the mean and the second one the standard 00268 /// deviation. 00269 /// 00270 /// NOTE: Since type T does not figure in the function's argument list, 00271 /// automatic type deduction will not work with this function. However, 00272 /// types input_iterator and converter_function can be deduced 00273 /// automatically. Therefore, this function should be invoked as 00274 /// mean_stdev<T>(...). 00275 template<typename T, typename input_iterator, typename converter_function> 00276 std::pair<T, T> 00277 mean_stdev(input_iterator begin, input_iterator end, converter_function F) 00278 { 00279 generic_stats<T> s = compute_stats<T>(begin, end, F) ; 00280 return std::make_pair(s.mean, s.stdev) ; 00281 } 00282 00283 //----------------------------------------------------------------------- 00284 00285 } // end of namespace encapsulating this file's definitions 00286 00287 #endif 00288 00289 /* So things look consistent in everyone's emacs... */ 00290 /* Local Variables: */ 00291 /* indent-tabs-mode: nil */ 00292 /* End: */