Robot Simulator of the Robotics Group for Self-Organization of Control: templatevalueanalysation.h Source File

- Main Page
- Namespaces
- Classes
- Files
- Directories
- Related Pages
- Examples

- Search for |

- File List
- File Members

# 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_ */