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

# sparsearray.h

Go to the documentation of this file.

    00001 /***************************************************************************
    00002  *   Copyright (C) 2005-2011 LpzRobots development team                    *
    00003  *    Georg Martius  <georg dot martius at web dot de>                     *
    00004  *    Frank Guettler <guettler at informatik dot uni-leipzig dot de        *
    00005  *    Frank Hesse    <frank at nld dot ds dot mpg dot de>                  *
    00006  *    Ralf Der       <ralfder at mis dot mpg dot de>                       *
    00007  *                                                                         *
    00008  *   This program is free software; you can redistribute it and/or modify  *
    00009  *   it under the terms of the GNU General Public License as published by  *
    00010  *   the Free Software Foundation; either version 2 of the License, or     *
    00011  *   (at your option) any later version.                                   *
    00012  *                                                                         *
    00013  *   This program is distributed in the hope that it will be useful,       *
    00014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
    00015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
    00016  *   GNU General Public License for more details.                          *
    00017  *                                                                         *
    00018  *   You should have received a copy of the GNU General Public License     *
    00019  *   along with this program; if not, write to the                         *
    00020  *   Free Software Foundation, Inc.,                                       *
    00021  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
    00022  *                                                                         *
    00023  ***************************************************************************/
    00024 #ifndef __SPARSEARRAY_H_
    00025 #define __SPARSEARRAY_H_
    00026
    00027 #include <cstdlib>
    00028 #include "stl_map.h"
    00029
    00030 /**
    00031  * Array which uses an HashTable for elements stored in this array.
    00032  * Can be used as an base class of SparseMatrix.
    00033  * first (fast implemented) version.
    00034  */
    00035 namespace matrix
    00036 {
    00037
    00038   #define COMPARE_EPS 1e-12
    00039
    00040   // forward declaration
    00041   //template<typename I, typename D> class SparseArray;
    00042
    00043
    00044
    00045   template<typename I, typename D> class SparseArray
    00046   {
    00047   public:
    00048     class ArrayElement
    00049     {
    00050     public:
    00051       ArrayElement() : index(0), value(0), hashData(0), dummy(0) { }
    00052
    00053       inline void reallocate(HashMap<I, D* >* hashData)
    00054       {
    00055         this->hashData=hashData;
    00056         value=0;
    00057         dummy=0;
    00058       }
    00059
    00060       inline void set (const I index, D value, D* dummy)
    00061       {
    00062         this->index=index;
    00063         this->value=value;
    00064         this->dummy=dummy;
    00065       }
    00066
    00067       // TODO: could be tricky: two ArrayElements at the same time???
    00068       inline D operator+ (ArrayElement& el2)            { return value+el2.value; }
    00069       inline D operator+ (D el2)                        { return value+el2; }
    00070    /*   inline D operator++ ()                            { this=(value+1); return value; }*/
    00071       inline bool operator> (D el2)                     { return value>el2; }
    00072       // TODO: could be tricky: two ArrayElements at the same time???
    00073       inline bool operator> (ArrayElement& el2)         { return value>el2.value; }
    00074       inline D& operator= (D value)
    00075       {
    00076         if (dummy==0)
    00077         {
    00078           dummy = (D*) malloc(sizeof(D));
    00079           (*hashData)[index]=dummy;
    00080         }
    00081         *dummy = value;
    00082         return *dummy;
    00083       }
    00084       inline D& operator= (ArrayElement& el2)           { this=el2.value; }
    00085
    00086       inline operator D()                               { return value; }
    00087
    00088     protected:
    00089       I index;
    00090       D value;
    00091       HashMap<I, D* >* hashData;
    00092       D* dummy;
    00093     };
    00094
    00095     SparseArray(I arraySize) : arraySize(arraySize), hashData(0)
    00096     {
    00097       allocate();
    00098     }
    00099
    00100     virtual ~SparseArray() {
    00101       freeData();
    00102     }
    00103
    00104     virtual inline void reallocate(I arraySize)
    00105     {
    00106       this->arraySize=arraySize;
    00107       allocate();
    00108     }
    00109
    00110     virtual inline I size() { return this->arraySize; }
    00111
    00112     inline ArrayElement& operator[](const I index)
    00113     {
    00114       typename HashMap<I,D*>::const_iterator iterator = hashData->find(index);
    00115       if (iterator!= hashData->end())
    00116       {
    00117         D* dummy = (*iterator).second;
    00118         elementDummy.set(index, *dummy, dummy);
    00119       } else
    00120         elementDummy.set(index, 0, 0);
    00121       return elementDummy;
    00122     }
    00123
    00124     /** sets the data (row-wise).
    00125         @param _data if null then matrix elements are set to zero
    00126         otherwise the field MUST have the length should be getSize()*/
    00127 /*    virtual void inline set(const D* _data)
    00128     {
    00129       allocate();
    00130       for (I i=0;i<arraySize;i++)
    00131         if (_data[i]>COMPARE_EPS)
    00132           this[i]=_data[i];
    00133     }*/
    00134
    00135     virtual inline long getRealSize()
    00136     {
    00137       long sumSize = sizeof *this;
    00138       sumSize += sizeof *hashData;
    00139       sumSize += hashData->size() * (sizeof(D*)+sizeof(D));
    00140       return sumSize;
    00141     }
    00142
    00143
    00144   protected:
    00145     ArrayElement elementDummy;
    00146     /// set of all array values
    00147     I arraySize;
    00148     HashMap<I, D* >* hashData;
    00149
    00150     virtual void inline allocate()
    00151     {
    00152       if (hashData)
    00153         freeData();
    00154       hashData = new HashMap<I, D* >();
    00155       elementDummy.reallocate(hashData);
    00156     }
    00157
    00158     virtual void inline freeData()
    00159     {
    00160       // TODO: free all elements in hashData
    00161 //      for (HashMap<I,D*>::iterator iterator = hashData->begin();iterator!=hashData->end();iterator++)
    00162 //        free((*iterator).second);
    00163       if (hashData)
    00164       {
    00165         delete hashData;
    00166         hashData = 0;
    00167       }
    00168     }
    00169
    00170   private:
    00171     SparseArray() {}
    00172
    00173   };
    00174
    00175
    00176 } // namespace matrix
    00177
    00178 #endif /* __SPARSEARRAY_H_ */