00001 #pragma once
00002 #ifndef OPENGM_SINGLESITEFUNCTION_HXX
00003 #define OPENGM_SINGLESITEFUNCTION_HXX
00004
00005 #include <vector>
00006 #include <algorithm>
00007
00008 #include "opengm/opengm.hxx"
00009 #include "opengm/functions/function_registration.hxx"
00010 #include "opengm/functions/function_properties_base.hxx"
00011
00012 namespace opengm {
00013
00015
00016 template<class T, size_t SIZE>
00017 class StackStorage {
00018 public:
00019 StackStorage(){}
00020 ~StackStorage(){}
00021 template<class ITERATOR>
00022 const T & operator()(ITERATOR iter) const {
00023 OPENGM_ASSERT(*iter<SIZE);
00024 return this->dataPointer_[*iter];
00025 }
00026 template<class ITERATOR>
00027 T & operator()(ITERATOR iter) {
00028 OPENGM_ASSERT(*iter<SIZE);
00029 return this->dataPointer_[*iter];
00030 }
00031 T & operator[](const size_t index) {
00032 OPENGM_ASSERT(index<SIZE);
00033 return this->dataPointer_[index];
00034 }
00035 const T & operator[](const size_t index) const {
00036 OPENGM_ASSERT(index<SIZE);
00037 return this->dataPointer_[index];
00038 }
00039
00040 private:
00041 T dataPointer_[SIZE];
00042 };
00043
00044 template<class T, size_t SIZE>
00045 class HeapStorage {
00046 public:
00047 HeapStorage() {
00048 dataPointer_ = new T[SIZE];
00049 }
00050 ~HeapStorage(){
00051 delete[] dataPointer_;
00052 }
00053 T& operator[](const size_t index) {
00054 OPENGM_ASSERT(index<SIZE);
00055 return this->dataPointer_[index];
00056 }
00057 const T& operator[](const size_t index) const {
00058 OPENGM_ASSERT(index<SIZE);
00059 return this->dataPointer_[index];
00060 }
00061 template<class ITERATOR>
00062 const T& operator()(ITERATOR iter) const {
00063 OPENGM_ASSERT(*iter<SIZE);
00064 return this->dataPointer_[*iter];
00065 }
00066 template<class ITERATOR>
00067 T& operator()(ITERATOR iter) {
00068 OPENGM_ASSERT(*iter<SIZE);
00069 return this->dataPointer_[*iter];
00070 }
00071
00072 private:
00073 T* dataPointer_;
00074 };
00075
00077
00081 template<class T, size_t SIZE, template<typename, size_t> class STORAGE>
00082 class StaticSingleSiteFunction
00083 : STORAGE<T, SIZE>,
00084 public FunctionBase<StaticSingleSiteFunction<T, SIZE, STORAGE>, T, size_t, size_t>
00085 {
00086 public:
00087 typedef T ValueType;
00088 typedef T value_type;
00089
00090 StaticSingleSiteFunction():STORAGE<T, SIZE>() {}
00091 StaticSingleSiteFunction(const StaticSingleSiteFunction& other)
00092 : STORAGE<T, SIZE>()
00093 {
00094 for(size_t i=0;i<SIZE;++i){
00095 (*this).operator [](i)=other[i];
00096 }
00097 }
00098
00099 StaticSingleSiteFunction& operator=(const StaticSingleSiteFunction & other)
00100 {
00101 if(this != &other) {
00102 for(size_t i=0;i<SIZE;++i) {
00103 (*this).operator [](i)=other[i];
00104 }
00105 }
00106 return *this;
00107 }
00108
00109 template<class ITERATOR> const T& operator()(ITERATOR iter) const
00110 {
00111 OPENGM_ASSERT(*iter < SIZE);
00112 return (static_cast<const STORAGE<T, SIZE>&>(*this)).operator()(iter);
00113 }
00114
00115 template<class ITERATOR> T& operator()(ITERATOR iter)
00116 {
00117 OPENGM_ASSERT(*iter<SIZE);
00118 return (static_cast<STORAGE<T, SIZE>&>(*this)).operator()(iter);
00119 }
00120
00121 size_t size() const
00122 { return SIZE; }
00123
00124 size_t dimension() const
00125 { return 1; }
00126
00127 size_t shape(const size_t index) const
00128 {
00129 OPENGM_ASSERT(index == 0);
00130 return SIZE;
00131 }
00132 };
00133
00137 template<class T>
00138 class DynamicSingleSiteFunction {
00139 public:
00140 typedef T ValueType;
00141 typedef T value_type;
00142
00143 DynamicSingleSiteFunction(const size_t size = 0)
00144 : size_(size)
00145 {
00146 if(size_ != 0){
00147 dataPointer_ = new T[size];
00148 }
00149 }
00150
00151 DynamicSingleSiteFunction(const size_t size, ValueType value)
00152 : size_(size)
00153 {
00154 if(size_ != 0) {
00155 dataPointer_ = new T[size];
00156 std::fill(dataPointer_, dataPointer_+size_, value);
00157 }
00158 }
00159
00160 ~DynamicSingleSiteFunction()
00161 {
00162 if(size_ != 0) {
00163 delete[] dataPointer_;
00164 }
00165 }
00166
00167 DynamicSingleSiteFunction(const DynamicSingleSiteFunction & other)
00168 {
00169 if(other.size_ != 0) {
00170 dataPointer_ = new T[other.size_];
00171 size_ = other.size_;
00172 std::copy(other.dataPointer_, other.dataPointer_+size_, dataPointer_);
00173 }
00174 else {
00175 size_=0;
00176 }
00177 }
00178
00179 DynamicSingleSiteFunction& operator=(const DynamicSingleSiteFunction& other)
00180 {
00181 if(this != &other) {
00182 if(other.size_ > size_) {
00183 delete[] dataPointer_;
00184 dataPointer_ = new T[other.size_];
00185 size_ = other.size_;
00186 std::copy(other.dataPointer_, other.dataPointer_ + size_, dataPointer_);
00187 }
00188 else if(other.size_ < size_) {
00189 delete[] dataPointer_;
00190 if(other.size_!= 0) {
00191 dataPointer_= new T[other.size_];
00192 size_ = other.size_;
00193 std::copy(other.dataPointer_, other.dataPointer_+size_, dataPointer_);
00194 }
00195 else {
00196 size_ = 0;
00197 }
00198 }
00199 if(other.size_ == size_) {
00200 std::copy(other.dataPointer_, other.dataPointer_+size_, dataPointer_);
00201 }
00202 }
00203 return *this;
00204 }
00205
00206 void assign(const size_t size)
00207 {
00208 if(size_ != size){
00209 delete[] dataPointer_;
00210 if(size != 0){
00211 dataPointer_ = new T[size];
00212 size_=size;
00213 }
00214 else {
00215 size_ = 0;
00216 }
00217 }
00218 }
00219
00220 void assign(const size_t size, const T value)
00221 {
00222 if(size_ != size){
00223 delete[] dataPointer_;
00224 if(size != 0) {
00225 dataPointer_ = new T[size];
00226 size_ = size;
00227 std::fill(dataPointer_, dataPointer_+size_, value);
00228 }
00229 else {
00230 size_=0;
00231 }
00232 }
00233 else {
00234 std::fill(dataPointer_, dataPointer_+size_, value);
00235 }
00236 }
00237
00238 size_t size() const
00239 { return size_; }
00240
00241 size_t dimension() const
00242 { return 1; }
00243
00244 size_t shape(const size_t index) const
00245 {
00246 OPENGM_ASSERT(index==0);
00247 return size_;
00248 }
00249
00250 T& operator[](const size_t index)
00251 {
00252 OPENGM_ASSERT(index < size_);
00253 return dataPointer_[index];
00254 }
00255
00256 const T & operator[](const size_t index) const
00257 {
00258 OPENGM_ASSERT(index < size_);
00259 return dataPointer_[index];
00260 }
00261
00262 template<class ITERATOR>
00263 const T& operator()(ITERATOR iter) const
00264 {
00265 OPENGM_ASSERT(*iter < size_);
00266 return dataPointer_[*iter];
00267 }
00268
00269 template<class ITERATOR>
00270 T& operator()(ITERATOR iter)
00271 {
00272 OPENGM_ASSERT(*iter < size_);
00273 return dataPointer_[*iter];
00274 }
00275
00276 private:
00277 T* dataPointer_;
00278 size_t size_;
00279 };
00280
00283 template<class T, size_t SIZE, template < typename , size_t > class STORAGE>
00284 struct FunctionRegistration< StaticSingleSiteFunction<T, SIZE, STORAGE> > {
00285 enum ID { Id = opengm::FUNCTION_TYPE_ID_OFFSET + 9 };
00286 };
00287
00289 template<class T>
00290 struct FunctionRegistration< DynamicSingleSiteFunction<T> > {
00291 enum ID { Id = opengm::FUNCTION_TYPE_ID_OFFSET + 10 };
00292 };
00293
00295 template<class T, size_t SIZE, template < typename , size_t > class STORAGE>
00296 class FunctionSerialization< StaticSingleSiteFunction<T, SIZE, STORAGE> > {
00297 public:
00298 typedef typename StaticSingleSiteFunction<T, SIZE, STORAGE> ::ValueType ValueType;
00299
00300 static size_t indexSequenceSize(const StaticSingleSiteFunction<T, SIZE, STORAGE> & f){
00301 return 0;
00302 }
00303
00304 static size_t valueSequenceSize(const StaticSingleSiteFunction<T, SIZE, STORAGE> & f){
00305 return SIZE;
00306 }
00307
00308 template<class INDEX_OUTPUT_ITERATOR, class VALUE_OUTPUT_ITERATOR >
00309 static void serialize(const StaticSingleSiteFunction<T, SIZE, STORAGE> & f, INDEX_OUTPUT_ITERATOR ii, VALUE_OUTPUT_ITERATOR vi){
00310 for(size_t i=0;i<SIZE;++i){
00311 size_t c[]={i};
00312 *vi=f(c);
00313 ++vi;
00314 }
00315 }
00316
00317 template<class INDEX_INPUT_ITERATOR , class VALUE_INPUT_ITERATOR>
00318 static void deserialize( INDEX_INPUT_ITERATOR ii, VALUE_INPUT_ITERATOR vi, StaticSingleSiteFunction<T, SIZE, STORAGE> & f){
00319 for(size_t i=0;i<SIZE;++i){
00320 size_t c[]={i};
00321 f(c)=*vi;
00322 ++vi;
00323 }
00324 }
00325 };
00326
00328 template<class T>
00329 class FunctionSerialization< DynamicSingleSiteFunction<T> > {
00330 public:
00331 typedef typename DynamicSingleSiteFunction<T>::ValueType ValueType;
00332
00333 static size_t indexSequenceSize(const DynamicSingleSiteFunction<T> & f){
00334 return 1;
00335 }
00336
00337 static size_t valueSequenceSize(const DynamicSingleSiteFunction<T> & f){
00338 return f.size();
00339 }
00340
00341 template<class INDEX_OUTPUT_ITERATOR, class VALUE_OUTPUT_ITERATOR >
00342 static void serialize(const DynamicSingleSiteFunction<T> & f, INDEX_OUTPUT_ITERATOR ii, VALUE_OUTPUT_ITERATOR vi){
00343 for(size_t i=0;i<f.size();++i){
00344 size_t c[]={i};
00345 *vi=f(c);
00346 ++vi;
00347 }
00348 }
00349
00350 template<class INDEX_INPUT_ITERATOR , class VALUE_INPUT_ITERATOR>
00351 static void deserialize( INDEX_INPUT_ITERATOR ii, VALUE_INPUT_ITERATOR vi, DynamicSingleSiteFunction<T> & f){
00352 const size_t size=*ii;
00353 f.assign(size);
00354 for(size_t i=0;i<size;++i){
00355 size_t c[]={i};
00356 f(c)=*vi;
00357 ++vi;
00358 }
00359 }
00360 };
00362
00363 }
00364
00365 #endif // #ifndef OPENGM_SINGLESITEFUNCTION_HXX