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
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
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;
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