templatevalueanalysation.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2005-2009 by Robot Group Leipzig                        *
00003  *    martius@informatik.uni-leipzig.de                                    *
00004  *    fhesse@informatik.uni-leipzig.de                                     *
00005  *    der@informatik.uni-leipzig.de                                        *
00006  *    guettler@informatik.uni-leipzig.de                                   *
00007  *    jhoffmann@informatik.uni-leipzig.de                                  *
00008  *    joergweide84@aol.com (robot12)                                       *
00009  *                                                                         *
00010  *   This program is free software; you can redistribute it and/or modify  *
00011  *   it under the terms of the GNU General Public License as published by  *
00012  *   the Free Software Foundation; either version 2 of the License, or     *
00013  *   (at your option) any later version.                                   *
00014  *                                                                         *
00015  *   This program is distributed in the hope that it will be useful,       *
00016  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00017  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00018  *   GNU General Public License for more details.                          *
00019  *                                                                         *
00020  *   You should have received a copy of the GNU General Public License     *
00021  *   along with this program; if not, write to the                         *
00022  *   Free Software Foundation, Inc.,                                       *
00023  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00024  ***************************************************************************
00025  *                                                                         *
00026  *   This template class is for statistical calculations.                  *
00027  *                                                                         *
00028  *   $Log: templatevalueanalysation.h,v $
00029  *   Revision 1.3  2009/07/21 08:47:33  robot12
00030  *   add some comments
00031  *
00032  *   Revision 1.2  2009/06/29 12:38:16  robot12
00033  *   add the templatevalueanalysation for calculating some statistical values. Is a new part of the statistictools.
00034  *
00035  *
00036  ***************************************************************************/
00037 
00038 #ifndef TEMPLATEVALUEANALYSATION_H_
00039 #define TEMPLATEVALUEANALYSATION_H_
00040 
00041 //macros
00042 #define ANALYSATION_CONTEXT TemplateValueAnalysation<type,zero,lower,higher,doubleDiv,doubleMul,add,sub,mul,div>
00043 #define DOUBLE_ANALYSATION_CONTEXT TemplateValueAnalysation<double,defaultZero>
00044 
00045 //includes
00046 #include <vector>
00047 #include <list>
00048 
00049 /**
00050  * default function for "lower as" operation.
00051  * @param a operator a
00052  * @param b operator b
00053  * @return (bool) true if a lower than b
00054  */
00055 template
00056 <class type>
00057 bool defaultLower(const type& a, const type& b) {
00058         if(a<b)
00059                 return true;
00060 
00061         return false;
00062 }
00063 
00064 /**
00065  * default function for divide by a double value.
00066  * @param a operator a
00067  * @param b (double) the double value
00068  * @return the result of the division
00069  */
00070 template
00071 <class type>
00072 type defaultDoubleDiv(const type& a, const double& b) {
00073         return a/b;
00074 }
00075 
00076 /**
00077  * default function for mul. with a double value.
00078  * @param a operator a
00079  * @param b (double) the double value
00080  * @return the result of the mul.
00081  */
00082 template
00083 <class type>
00084 type defaultDoubleMul(const type& a, const double& b) {
00085         return a*b;
00086 }
00087 
00088 /**
00089  * default function for "higher than" operation.
00090  * @param a operator a
00091  * @param b operator b
00092  * @return (bool) true if a higher than b
00093  */
00094 template
00095 <class type>
00096 bool defaultHigher(const type& a,const type& b) {
00097         if(a>b)
00098                 return true;
00099 
00100         return false;
00101 }
00102 
00103 /**
00104  * default function for add two values
00105  * @param a operator a
00106  * @param b operator b
00107  * @return the result of the add.
00108  */
00109 template
00110 <class type>
00111 type defaultAdd(const type& a, const type& b) {
00112         return a+b;
00113 }
00114 
00115 /**
00116  * default function for sub. two values
00117  * @param a operator a
00118  * @param b operator b
00119  * @return the result of the sub.
00120  */
00121 template
00122 <class type>
00123 type defaultSub(const type& a, const type& b) {
00124         return a-b;
00125 }
00126 
00127 /**
00128  * default function for mul. of two values
00129  * @param a operator a
00130  * @param b operator b
00131  * @return the result of the mul.
00132  */
00133 template
00134 <class type>
00135 type defaultMul(const type& a, const type& b) {
00136         return a*b;
00137 }
00138 
00139 /**
00140  * default function for div. of two values
00141  * @param a operator a
00142  * @param b operator b
00143  * @return the result of the div.
00144  */
00145 template
00146 <class type>
00147 type defaultDiv(const type& a, const type& b) {
00148         return a/b;
00149 }
00150 
00151 /**
00152  * default function for zero double value
00153  * @return (double) 0.0
00154  */
00155 double defaultZero();
00156 
00157 /**
00158  * This template class give you some methods to calculate some statistical values like average, min, max, upper quartil,
00159  * lower quartil and many more.
00160  *
00161  * All functions are implemented in the header because by generating the library it isn't known which type are later used.
00162  * And a later compiling needs the implementation two!
00163  */
00164 template
00165 <class type,                                                                                                                    //data type of the calculation
00166 type zero(void),                                                                                                                //gives the zero of this data type back
00167 bool lower(const type&, const type&)=defaultLower<type>,                                //test if one element of the type lower than the other
00168 bool higher(const type&, const type&)=defaultHigher<type>,                      //test if one element of the type higher than the other
00169 type doubleDiv(const type&, const double&)=defaultDoubleDiv<type>,      //divide a element of the type by a double value
00170 type doubleMul(const type&, const double&)=defaultDoubleMul<type>,      //mul. a element of the type by a double value
00171 type add(const type&, const type&)=defaultAdd<type>,                                    //add two elements of type
00172 type sub(const type&, const type&)=defaultSub<type>,                                    //sub two elements of type
00173 type mul(const type&, const type&)=defaultMul<type>,                                    //mul two elements of type
00174 type div(const type&, const type&)=defaultDiv<type> >                           //div two elements of type
00175 class TemplateValueAnalysation {
00176 public:
00177         /**
00178          * constructor
00179          * Needs a set of values for which the statistical values will calculate.
00180          * @param values (vector<type>& the set)
00181          */
00182         TemplateValueAnalysation(std::vector<type>& values) : m_vector(values), m_list(), m_listCreated(false) {}
00183 
00184         /**
00185          * default destructor
00186          */
00187         ~TemplateValueAnalysation() {}
00188 
00189         /**
00190          * this function calculate the average of the giving set
00191          *
00192          * It used zero, add and doubleDiv to calculate the average.
00193          * @return the average
00194          */
00195         type getAvg() {
00196                 type avg=zero();                                                                                                                                                //by begin the average is zero
00197                 __gnu_cxx::__normal_iterator<type*,std::vector<type,std::allocator<type> > > iter;
00198 
00199                 for(iter = m_vector.begin(); iter != m_vector.end(); iter++) {
00200                         avg = add(avg,(*iter));                                                                                                                         //for all elements in the set add it to the average.
00201                                                                                                                                                                                                 //So we become the sum. of all elements in the set.
00202                 }
00203 
00204                 if(m_vector.size()!=0)
00205                         avg = doubleDiv(avg,m_vector.size());                                                                                           //now devide the sum by the count of elements in the set.
00206 
00207                 return avg;                                                                                                                                                             //return the result
00208         }
00209 
00210         /**
00211          * this function search the min. value in the set
00212          *
00213          * For this it use lower
00214          * @return the minimum
00215          */
00216         type getMin() {
00217                 type min = m_vector[0];                 //the lowest element is at begin the first element
00218                 __gnu_cxx::__normal_iterator<type*,std::vector<type,std::allocator<type> > > iter = m_vector.begin();
00219 
00220                 for(iter++; iter != m_vector.end(); iter++) {
00221                         if(lower((*iter),min))          //if a element lower than min, so reset the min to the lower value.
00222                                 min=(*iter);
00223                 }
00224 
00225                 return min;                                             //return the lowest element
00226         }
00227 
00228         /**
00229          * this function search the max. value in the set
00230          *
00231          * For this it use lower
00232          * @return the minimum
00233          */
00234         type getMax() {
00235                 type max = m_vector[0];                 //the highest element is at begin the first element
00236                 __gnu_cxx::__normal_iterator<type*,std::vector<type,std::allocator<type> > > iter = m_vector.begin();
00237 
00238                 for(iter++; iter != m_vector.end(); iter++) {
00239                         if(lower(max,(*iter)))          //if a element higher than max, so reset the max to the higher value.
00240                                 max=(*iter);
00241                 }
00242 
00243                 return max;                                             //return the lowest element
00244         }
00245 
00246         /**
00247          * this function calculate the range of all values. For this he search the mibn and max and calculate from this values.
00248          *
00249          * use sub
00250          * @return the range of the values in the set
00251          */
00252         type getRange() {
00253                 type dMax = getMax();                   //become max
00254                 type dMin = getMin();                   //become min
00255 
00256                 return sub(dMax,dMin);                  //range=max-min
00257         }
00258 
00259         /**
00260          * this function search the median of the giving set of values.
00261          *
00262          * use add and doubleMul
00263          * @return the median
00264          */
00265         type getMedian() {
00266                 type median;
00267                 int x;
00268                 int num = m_vector.size()/2;
00269                 std::_List_iterator<TYPE_SAVE> iter;
00270 
00271                 if(!m_listCreated)
00272                         sort();                                                         //sort the set. to define the middle
00273 
00274                 iter = m_list.begin();                                  //go to the middle
00275                 for(x=0;x<num;x++) iter++;
00276 
00277                 if(m_vector.size() % 2 == 0) {                  //if the real middle between two values add this values and calculate the arithmetical middle.
00278                         median = (*iter->pointer);
00279                         iter--;
00280                         median = add(median,(*iter->pointer));
00281                         median = doubleMul(median,0.5);
00282                 }
00283 
00284                 else {
00285                         median = (*iter->pointer);                      //else gives the middle back
00286                 }
00287 
00288                 return median;
00289         }
00290 
00291         /**
00292          * this function calculate the under quartil
00293          *
00294          * use add and doubleMul
00295          * @return the under quartil
00296          */
00297         type getQuartil1() {
00298                 type q;
00299                 int x;
00300                 int num = m_vector.size()/4;
00301                 std::_List_iterator<TYPE_SAVE> iter;
00302 
00303                 if(!m_listCreated)
00304                         sort();                                                         //sort the set.
00305 
00306                 iter = m_list.begin();                                  //go to the under quartil
00307                 for(x=0;x<num;x++) iter++;
00308 
00309                 if(m_vector.size() % 4 == 0) {                  //if the real under quartil between two values add this values and calculate the arithmetical middle.
00310                         q = (*iter->pointer);
00311                         iter--;
00312                         q = add(q,(*iter->pointer));
00313                         q = doubleMul(q,0.5);
00314                 }
00315                 else {                                                                  //else return the quartil
00316                         q = (*iter->pointer);
00317                 }
00318 
00319                 return q;
00320         }
00321 
00322         /**
00323          * this function calculate the upper quartil.
00324          *
00325          * use add and doubleMul
00326          * @return the upper quartil
00327          */
00328         type getQuartil3() {
00329                 type q;
00330                 int x;
00331                 int num = m_vector.size()*3/4;
00332                 std::_List_iterator<TYPE_SAVE> iter;
00333 
00334                 if(!m_listCreated)
00335                         sort();                                                         //sort the set.
00336 
00337                 iter = m_list.begin();
00338                 for(x=0;x<num;x++) iter++;                              //go to the upper quartil
00339 
00340                 if(m_vector.size() % 4 == 0) {                  //if the real upper quartil between two values add this values and calculate the arithmetical middle.
00341                         q = (*iter->pointer);
00342                         iter--;
00343                         q = add(q,(*iter->pointer));
00344                         q = doubleMul(q,0.5);
00345                 }
00346                 else {                                                                  //else return the quartil
00347                         q = (*iter->pointer);
00348                 }
00349 
00350                 return q;
00351         }
00352 
00353         /**
00354          * this function calculate the range between the upper and under quartil. This range is called inter-quartil-range.
00355          *
00356          * use sub
00357          * @return the IQR
00358          */
00359         type getIQR() {
00360                 type q1 = getQuartil1();                        //calculate the under quartil
00361                 type q3 = getQuartil3();                        //calculate the upper quartil
00362 
00363                 return sub(q3,q1);                                      //IQR = Q3 - Q1
00364         }
00365 
00366         /**
00367          * this function calculate the whisker distance
00368          *
00369          * use doubleMul
00370          * @param factor (double) the factor for this distance
00371          * @return the result
00372          */
00373         type getWhisker(double factor) {
00374                 type dIqr = getIQR();                   //calculate the IQR
00375 
00376                 return doubleMul(dIqr,factor);  //WHISKER distance is factor*IQR
00377         }
00378 
00379         /**
00380          * this function search the lowest value in the set which is from under quartil inside the whisker distance
00381          *
00382          * use sub, lower and zero
00383          * @param factor (double) this factor is for calculating the whisker distance.
00384          * @return the lowest value inside
00385          */
00386         type getWhisker1(double factor) {
00387                 type dW = getWhisker(factor);                           //calculate the whisker distance
00388                 type dQ1 = getQuartil1();                                       //calculate the under quartil
00389                                                                                                         //TODO for optimization: getWhisker use getIQR and this calculate Q1 so it will be calculate two times!!!
00390                 type dBorder = sub(dQ1,dW);                                     //where is the border for the lowest value
00391                 std::_List_iterator<TYPE_SAVE> iter = m_list.begin();
00392 
00393                 while(lower((*iter->pointer),dBorder) && iter!=m_list.end()) {          //search
00394                         iter++;
00395                         if(iter==m_list.end())
00396                                 break;
00397                 }
00398 
00399                 if(iter==m_list.end())          // ERROR
00400                         return zero();
00401 
00402                 return (*iter->pointer);
00403         }
00404 
00405         /**
00406          * this function search the highest value in the set which is from the upper quartil inside the whisker distance
00407          *
00408          * use add and lower
00409          * @param factor (double) this factor is for calculating the whisker distance.
00410          * @return the highest value inside
00411          */
00412         type getWhisker3(double factor) {
00413                 type dW = getWhisker(factor);                           //calculate the whisker distance
00414                 type dQ3 = getQuartil3();                                       //calculate the upper quartil
00415                                                                                                         //TODO for optimization: getWhisker use getIQR and this calculate Q3 so it will be calculate two times!!!
00416                 type dBorder = add(dQ3,dW);                                     //where is the border for the lowest value
00417                 std::_List_iterator<TYPE_SAVE> iter = m_list.begin();
00418 
00419                 while(lower((*iter->pointer),dBorder) && iter!=m_list.end()) {          //search
00420                         iter++;
00421                         if(iter==m_list.end())
00422                                 break;
00423                 }
00424 
00425                 if(iter!=m_list.begin())
00426                         iter--;
00427 
00428                 return (*iter->pointer);
00429         }
00430 
00431         /**
00432          * this function give you the number of elements in the giving set, which aren't in the whisker distance
00433          *
00434          * use lower and higher
00435          * @param factor (double) this factor is for calculating the whisker distance
00436          * @return (int) the number of extreme values in the set
00437          */
00438         unsigned int getNumExtrems(double factor) {
00439                 unsigned int result = 0;
00440                 type dW1 = getWhisker1(factor);                                                         //find W1
00441                 type dW3 = getWhisker3(factor);                                                         //find W3
00442                 std::_List_iterator<TYPE_SAVE> iter = m_list.begin();
00443 
00444                 while(lower((*iter->pointer),dW1) && iter!=m_list.end()) {      //count all elements which are lower than W1
00445                         iter++;
00446                         if(iter==m_list.end())
00447                                 break;
00448                         result++;
00449                 }
00450 
00451                 while(!higher((*iter->pointer),dW3) && iter!=m_list.end()) {    //go from W1 to W3
00452                         iter++;
00453                         if(iter==m_list.end())
00454                                 break;
00455                 }
00456 
00457                 while(iter!=m_list.end()) {                                                                     //count all element which are higher than W3
00458                         iter++;
00459                         result++;
00460                 }
00461 
00462                 return result;
00463         }
00464 
00465         /**
00466          * this function gives one extreme value back
00467          *
00468          * use lower, higher and zero
00469          * @param factor (double) the factor for the whisker distance
00470          * @param i (unsigned int) the index of the searched extreme value
00471          * @return the founded extreme value
00472          */
00473         type getExtrem(double factor, unsigned int i) {
00474                 type dW1 = getWhisker1(factor);                                                 //find W1
00475                 type dW3 = getWhisker3(factor);                                                 //find W3
00476                 std::_List_iterator<TYPE_SAVE> iter = m_list.begin();
00477 
00478                 while(lower((*iter->pointer),dW1) && iter!=m_list.end()) {                      //search in lower area
00479                         i--;
00480 
00481                         if(i==0)
00482                                 return (*iter->pointer);
00483 
00484                         iter++;
00485                         if(iter==m_list.end())
00486                                 break;
00487                 }
00488 
00489                 while(!higher((*iter->pointer),dW3) && iter!=m_list.end()) {            //go from W1 to W3
00490                         iter++;
00491                         if(iter==m_list.end())
00492                                 break;
00493                 }
00494 
00495                 while(iter!=m_list.end()) {                                                                                     //search in upper area
00496                         i--;
00497 
00498                         if(i==0)
00499                                 return (*iter->pointer);
00500 
00501                         iter++;
00502                 }
00503 
00504                 return zero();          //not found                                                                             //if not found return zero
00505         }
00506 
00507         /**
00508          * this function search the value which is next to zero.
00509          *
00510          * use zero, sub and lower
00511          * @return the best value
00512          */
00513         type getBest(void) {
00514                 type z = zero();                                                                                        //test value is zero
00515                 type* l;
00516                 type* h;
00517 
00518                 if(!m_listCreated)
00519                         sort();                                                                                                 //sort the list
00520 
00521                 std::_List_iterator<TYPE_SAVE> iter = m_list.begin();
00522 
00523                 while(lower((*iter->pointer),z) && iter!=m_list.end()) {        //search the element which is as first higher than zero
00524                         iter++;
00525                         if(iter==m_list.end())
00526                                 break;
00527                 }
00528 
00529                 if(iter!=m_list.end())
00530                         //return (*iter->pointer);
00531                         h = iter->pointer;
00532 
00533                 else {
00534                         iter--;
00535                         //return (*iter->pointer);
00536                         h = iter->pointer;
00537                 }
00538 
00539                 while(!lower((*iter->pointer),z) && iter!= m_list.begin()) {    //search the element which is as first lower than zero
00540                         iter--;
00541                         if(iter==m_list.begin())
00542                                 break;
00543                 }
00544 
00545                 l = iter->pointer;
00546 
00547                 if(lower(sub(*h,z),sub(z,*l)))          //test which is next to zero
00548                         return *h;
00549                 else
00550                         return *l;
00551         }
00552 
00553 protected:
00554 
00555         /**
00556          * help structur for sorting the set.
00557          * define the lower than operator
00558          */
00559         struct TYPE_SAVE {
00560                 TYPE_SAVE(type& a) : pointer(&a) {}
00561 
00562                 type* pointer;
00563 
00564                 bool operator<(const TYPE_SAVE& other) {
00565                         return lower((*pointer),(*other.pointer));
00566                 }
00567         };
00568 
00569         /**
00570          * this vector save the giving set.
00571          */
00572         std::vector<type>& m_vector;
00573 
00574         /**
00575          * this list saves the sorted set
00576          */
00577         std::list<TYPE_SAVE> m_list;
00578 
00579         /**
00580          * this variable remember if the sorted list is created
00581          */
00582         bool m_listCreated;
00583 
00584         /**
00585          * this function create the sorted list
00586          */
00587         void sort(void) {
00588                 __gnu_cxx::__normal_iterator<type*,std::vector<type,std::allocator<type> > > iter;
00589 
00590                 for(iter = m_vector.begin(); iter != m_vector.end(); iter++) {                  //fill the sorted list with elements of the help structur
00591                         m_list.push_back(TYPE_SAVE((*iter)));
00592                 }
00593 
00594                 m_list.sort();                          //sort the list
00595                 m_listCreated = true;           //remember that it is created.
00596         }
00597 };
00598 
00599 #endif /* TEMPLATEVALUEANALYSATION_H_ */

Generated on Fri Oct 30 16:29:01 2009 for Robot Simulator of the Robotics Group for Self-Organization of Control by  doxygen 1.4.7