datastructures/sparsemarray/sparsemarray.hxx

Go to the documentation of this file.
00001 #pragma once
00002 #ifndef OPENGM_SPARSEMARRAY
00003 #define OPENGM_SPARSEMARRAY
00004 
00005 #include <algorithm>
00006 #include <iostream>
00007 #include <map>
00008 #include "opengm/functions/function_properties_base.hxx"
00009 
00010 
00011 namespace opengm {
00012 
00013 template<class T,class I,class L,class CONTAINER=std::map<I,T> >
00014 class SparseFunction   : public FunctionBase<SparseFunction<T, I, L,CONTAINER>, T, I, L> {
00015 public:
00016     typedef CONTAINER ContainerType;
00017     typedef typename ContainerType::key_type KeyType;
00018     typedef typename ContainerType::mapped_type MappedType;
00019     typedef std::pair<KeyType,MappedType> KeyValPairType;
00020     typedef T ValueType;
00021     typedef I IndexType;
00022     typedef L LabelType;
00023 
00024 
00025     typedef typename ContainerType::const_iterator ConstContainerIteratorType;
00026     typedef typename ContainerType::iterator ContainerIteratorType;
00027 
00028 
00029     SparseFunction():
00030       dimension_(0),
00031       defaultValue_(0),
00032       container_(),
00033       shape_(),
00034       strides_(){
00035     }
00036 
00037 
00038     //constructors
00039     template<class SHAPE_ITERATOR>
00040     SparseFunction(SHAPE_ITERATOR shapeBegin,SHAPE_ITERATOR shapeEnd ,const ValueType defaultValue):
00041     dimension_(std::distance(shapeBegin,shapeEnd)),
00042     defaultValue_(defaultValue),
00043     container_(){
00044         shape_.resize(dimension_);
00045         strides_.resize(dimension_);
00046         // compute strides
00047         LabelType strideVal=1;
00048         for(unsigned short  dim=0;dim<dimension_;++dim){
00049             shape_[dim]=*shapeBegin;
00050             strides_[dim]=strideVal;
00051             strideVal*=shape_[dim];
00052             ++shapeBegin;
00053         }
00054     }
00055 
00056     size_t size()const{
00057       size_t size =1;
00058       for(unsigned short  dim=0;dim<dimension_;++dim){
00059             size*=static_cast<size_t>(shape_[dim]);
00060       }
00061       return size;
00062     }
00063 
00064     const ContainerType & container()const{
00065         return container_;
00066     }
00067     ContainerType & container(){
00068         return container_;
00069     }
00070     const size_t dimension()const{
00071         return dimension_;
00072     }
00073     const LabelType shape(const IndexType i)const{
00074         return shape_[i];
00075     }
00076 
00077 
00078 
00079     template<class COORDINATE_ITERATOR>
00080     void keyToCoordinate(const KeyType key, COORDINATE_ITERATOR coordinate )const{
00081         typedef typename std::iterator_traits<COORDINATE_ITERATOR>::value_type CoordType;
00082         KeyType keyRest=key;
00083         if(dimension_!=1){
00084             for(unsigned short  d=0;d<dimension_;++d){
00085                 const unsigned short dim=(dimension_-1)-d;
00086                 const KeyType c=keyRest/static_cast<KeyType>( strides_[dim] );
00087                 keyRest=keyRest-c*static_cast<KeyType>( strides_[dim] );
00088                 coordinate[dim]=static_cast<CoordType>(c);
00089             }
00090         }
00091         else{
00092             *coordinate=static_cast<CoordType>(key);
00093         }
00094     }
00095 
00096 
00097     template<class COORDINATE_ITERATOR>
00098     KeyType coordinateToKey(COORDINATE_ITERATOR coordinate)const{
00099         KeyType key=static_cast<KeyType>(0);
00100         for(unsigned short  dim=0;dim<dimension_;++dim){
00101             key+=strides_[dim]*static_cast<KeyType>(*coordinate);
00102             ++coordinate;
00103         }
00104         return key;
00105     }
00106 
00107     template<class COORDINATE_ITERATOR,size_t DIM>
00108     KeyType coordinateToKeyWithDim(COORDINATE_ITERATOR coordinate )const{
00109         KeyType key=static_cast<KeyType>(0);
00110         for(unsigned short  dim=0;dim<DIM;++dim){
00111             key+=strides_[dim]*static_cast<KeyType>(coordinate[dim]);
00112         }
00113         return key;
00114     }
00115 
00116     template<class COORDINATE_ITERATOR>
00117     ValueType operator()(COORDINATE_ITERATOR coordinate)const{
00118         typedef COORDINATE_ITERATOR CoordType;
00119         KeyType key;//=coordinateToKey(coordinate);
00120 
00121         switch (dimension_)
00122         {
00123             case 1:
00124                 return valueFromKey(coordinateToKeyWithDim<CoordType,1>(coordinate));
00125             case 2:
00126                 return valueFromKey(coordinateToKeyWithDim<CoordType,2>(coordinate));
00127             case 3:
00128                 return valueFromKey(coordinateToKeyWithDim<CoordType,3>(coordinate));
00129             case 4:
00130                 return valueFromKey(coordinateToKeyWithDim<CoordType,4>(coordinate));
00131             case 5:
00132                 return valueFromKey(coordinateToKeyWithDim<CoordType,5>(coordinate));
00133             case 6:
00134                 return valueFromKey(coordinateToKeyWithDim<CoordType,6>(coordinate));
00135             case 7:
00136                 return valueFromKey(coordinateToKeyWithDim<CoordType,7>(coordinate));
00137             case 8:
00138                 return valueFromKey(coordinateToKeyWithDim<CoordType,8>(coordinate));
00139             case 9:
00140                 return valueFromKey(coordinateToKeyWithDim<CoordType,9>(coordinate));
00141             case 10:
00142                 return valueFromKey(coordinateToKeyWithDim<CoordType,10>(coordinate));
00143             case 11:
00144                 return valueFromKey(coordinateToKeyWithDim<CoordType,11>(coordinate));
00145             case 12:
00146                 return valueFromKey(coordinateToKeyWithDim<CoordType,12>(coordinate));
00147             case 13:
00148                 return valueFromKey(coordinateToKeyWithDim<CoordType,13>(coordinate));
00149             case 14:
00150                 return valueFromKey(coordinateToKeyWithDim<CoordType,14>(coordinate));
00151             case 15:
00152                 return valueFromKey(coordinateToKeyWithDim<CoordType,15>(coordinate));
00153             case 16:
00154                 return valueFromKey(coordinateToKeyWithDim<CoordType,16>(coordinate));
00155             default:
00156                 return valueFromKey(coordinateToKey(coordinate));
00157         }
00158     }
00159 
00160     ValueType defaultValue()const{
00161       return defaultValue_;
00162     }
00163 
00164     ValueType valueFromKey(const KeyType key)const{
00165         ConstContainerIteratorType iter=container_.find(key);
00166         if(iter!=container_.end()){
00167             return iter->second;
00168         }
00169         else{
00170             return defaultValue_;
00171         }
00172     }
00173 
00174     template<class COORDINATE_ITERATOR>
00175     void insert(COORDINATE_ITERATOR coordinate,const ValueType value){
00176         container_.insert(KeyValPairType(coordinateToKey(coordinate),value));
00177     }
00178 
00179 private:
00180     unsigned short dimension_;
00181     ValueType defaultValue_;        
00182     ContainerType container_;
00183     std::vector<LabelType> shape_;
00184     std::vector<size_t> strides_;
00185 
00186 };
00187 }
00188 
00189 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Mon Jun 17 16:31:06 2013 for OpenGM by  doxygen 1.6.3