00001 #pragma once
00002 #ifndef OPENGM_GRAPHICALMODEL_EXPLICIT_STORAGE_HXX
00003 #define OPENGM_GRAPHICALMODEL_EXPLICIT_STORAGE_HXX
00004
00005 #include <vector>
00006 #include <algorithm>
00007 #include <numeric>
00008 #include <map>
00009
00010 #include "opengm/graphicalmodel/graphicalmodel.hxx"
00011 #include "opengm/datastructures/marray/marray.hxx"
00012 #include "opengm/functions/explicit_function.hxx"
00013 #include "opengm/opengm.hxx"
00014 #include "opengm/utilities/indexing.hxx"
00015 #include "opengm/utilities/metaprogramming.hxx"
00016 #include "opengm/operations/minimizer.hxx"
00017 #include "opengm/graphicalmodel/space/discretespace.hxx"
00018
00019 namespace opengm{
00020
00021 template<
00022 class T,
00023 class OPERATOR,
00024 class FUNCTION_TYPE_LIST ,
00025 class SPACE ,
00026 bool EDITABLE
00027 >
00028 class GraphicalModel;
00029
00030
00031 template<unsigned int I,unsigned int D,bool END>
00032 class FunctionIteratation;
00033
00034
00063
00064 template<class GM>
00065 class ExplicitStorage {
00066
00067 template<unsigned int I,unsigned int D,bool END>
00068 friend class FunctionIteratation;
00069 typedef GM GraphicalModelType;
00070 typedef typename GraphicalModelType::LabelType LabelType;
00071 typedef typename GraphicalModelType::IndexType IndexType;
00072 typedef typename GraphicalModelType::ValueType ValueType;
00073 typedef typename GraphicalModelType::OperatorType OperatorType;
00074 typedef typename GraphicalModelType::FactorType FactorType;
00075 typedef typename GraphicalModelType::IndependentFactorType IndependentFactorType;
00076 typedef typename GraphicalModelType::FunctionIdentifier FunctionIdentifier;
00077
00078 public:
00079 ExplicitStorage(const GraphicalModelType & gm )
00080 :gm_(gm),
00081 functionSize_(GraphicalModelType::NrOfFunctionTypes),
00082 functionTypeStart_(GraphicalModelType::NrOfFunctionTypes,0){
00083
00084
00085 size_t numFTotal=0;
00086 for(size_t i=0;i<GraphicalModelType::NrOfFunctionTypes;++i){
00087 functionSize_[i]=gm_.numberOfFunctions(i);
00088 numFTotal+=functionSize_[i];
00089 }
00090
00091 functionIndexToStart_.resize(numFTotal);
00092 functionTypeStart_[0]=0;
00093 for(size_t i=1;i<GraphicalModelType::NrOfFunctionTypes;++i){
00094 for(size_t ii=0;ii<i;++ii){
00095 functionTypeStart_[i]+=functionSize_[ii];
00096 }
00097 }
00098
00099
00100 size_t storageSize=0;
00101 FunctionIteratation<0,GraphicalModelType::NrOfFunctionTypes,false>::size(*this,storageSize);
00102
00103
00104
00105 data_ = new ValueType[storageSize];
00106 dataSize_=storageSize;
00107
00108
00109 size_t currentOffset=0;
00110 FunctionIteratation<0,GraphicalModelType::NrOfFunctionTypes,false>::store(*this,currentOffset);
00111 OPENGM_ASSERT(currentOffset==storageSize);
00112 }
00113 ~ExplicitStorage(){
00114 delete[] data_;
00115 }
00116
00117 ValueType const * operator[](const FactorType & factor)const{
00118 const size_t scalarIndex=fidToIndex(factor.functionType(),factor.functionIndex());
00119 return data_+functionIndexToStart_[scalarIndex];
00120 }
00121
00122 private:
00123 size_t dataSize_;
00124 const GraphicalModelType & gm_;
00125 std::vector<size_t> functionSize_;
00126 std::vector<size_t> functionTypeStart_;
00127 std::vector<size_t> functionIndexToStart_;
00128 ValueType * data_;
00129
00130
00131 size_t fidToIndex(const size_t functionType,const size_t functionIndex)const{
00132 return functionTypeStart_[functionType]+functionIndex;
00133 }
00134
00135 ValueType const * getFunction(size_t functionType,size_t functionIndex){
00136
00137 }
00138
00139 };
00140
00152 template<class GM>
00153 class ConvertToExplicit{
00154 private:
00155 typedef typename GM::ValueType GmValueType;
00156 typedef typename GM::OperatorType GmOperatorTye;
00157 typedef typename GM::FunctionIdentifier GmFunctionIdentifier;
00158 public:
00159 typedef GraphicalModel<GmValueType,GmOperatorTye,ExplicitFunction<GmValueType>,DiscreteSpace< > ,false> ExplicitGraphicalModelType;
00160 private:
00161 typedef typename ExplicitGraphicalModelType::FunctionIdentifier FunctionIdentifier;
00162 public:
00163 static void convert(const GM & gm,ExplicitGraphicalModelType & explicitGm){
00164 DiscreteSpace< > space;
00165 space.reserve(gm.numberOfVariables());
00166 for(size_t v=0;v<gm.numberOfVariables();++v){
00167 space.addVariable(gm.numberOfLabels(v));
00168 }
00169 explicitGm.assign(space);
00170 std::map<GmFunctionIdentifier,FunctionIdentifier> fidMap;
00171
00172 FunctionIteratation<0,GM::NrOfFunctionTypes,false>::convert(gm,explicitGm,fidMap);
00173 for(size_t f=0;f<gm.numberOfFactors();++f){
00174 const typename GM::FactorType & factor=gm[f];
00175 FunctionIdentifier explicitFid=fidMap[GmFunctionIdentifier(factor.functionIndex(),factor.functionType())];
00176 explicitGm.addFactor(explicitFid,factor.variableIndicesBegin(),factor.variableIndicesEnd());
00177 }
00178 }
00179 };
00180
00181
00182
00183 template<unsigned int IX,unsigned int DX>
00184 class FunctionIteratation<IX,DX,false>{
00185 public:
00186 template<class STORAGE>
00187 static void size( STORAGE & storage ,size_t & neededStorage){
00188
00189 const size_t numF=storage.functionSize_[IX];
00190 for(size_t f=0;f<numF;++f){
00191 neededStorage+=storage.gm_. template functions<IX>()[f].size();
00192 }
00193 FunctionIteratation<IX+1,DX,IX+1==DX >::size(storage,neededStorage);
00194 }
00195
00196 template<class STORAGE>
00197 static void store( STORAGE & storage ,size_t & currentOffset){
00198
00199 typedef typename STORAGE::GraphicalModelType::FunctionTypeList FTypeList;
00200 typedef typename meta::TypeAtTypeList<FTypeList,IX>::type FunctionType;
00201 typedef typename FunctionType::FunctionShapeIteratorType FunctionShapeIteratorType;
00202 const size_t numF=storage.functionSize_[IX];
00203 for(size_t f=0;f<numF;++f){
00204 const FunctionType & function = storage.gm_. template functions<IX>()[f];
00205 const size_t functionSize=function.size();
00206
00207 const size_t fIndex=storage.fidToIndex(IX,f);
00208
00209 OPENGM_ASSERT(fIndex<storage.functionIndexToStart_.size());
00210
00211 storage.functionIndexToStart_[fIndex]=currentOffset;
00212
00213 ShapeWalker< FunctionShapeIteratorType > walker(function.functionShapeBegin(),function.dimension());
00214 for (size_t i = 0; i < functionSize; ++i) {
00215 OPENGM_ASSERT(currentOffset+i<storage.dataSize_);
00216 storage.data_[currentOffset+i]=function(walker.coordinateTuple().begin());
00217 ++walker;
00218 }
00219 currentOffset+=functionSize;
00220 }
00221 FunctionIteratation<IX+1,DX,IX+1==DX >::store(storage,currentOffset);
00222 }
00223
00224 template<class GM,class GM_EXPLICIT,class FID_MAP>
00225 static void convert(const GM & gm ,GM_EXPLICIT & gmExplicit , FID_MAP & fidMap){
00226
00227 typedef typename GM::FunctionTypeList FTypeList;
00228 typedef typename meta::TypeAtTypeList<FTypeList,IX>::type FunctionType;
00229 typedef typename FunctionType::FunctionShapeIteratorType FunctionShapeIteratorType;
00230 const size_t numF=gm. template functions<IX>().size();
00231
00232 for(size_t f=0;f<numF;++f){
00233 const FunctionType & function = gm. template functions<IX>()[f];
00234 const size_t functionSize=function.size();
00235
00236
00237 ExplicitFunction<typename GM_EXPLICIT::ValueType> explicitFunction(function.functionShapeBegin(),function.functionShapeEnd());
00238 ShapeWalker< FunctionShapeIteratorType > walker(function.functionShapeBegin(),function.dimension());
00239 for (size_t i = 0; i < functionSize; ++i) {
00240 explicitFunction(i)=function(walker.coordinateTuple().begin());
00241 ++walker;
00242 }
00243
00244 typename GM::FunctionIdentifier gmFid(f,IX);
00245 fidMap[gmFid]=gmExplicit.addFunction(explicitFunction);
00246 }
00247 FunctionIteratation<IX+1,DX,IX+1==DX >::convert(gm,gmExplicit,fidMap);
00248 }
00249
00250
00251 };
00252
00253
00254 template<unsigned int IX,unsigned int DX>
00255 class FunctionIteratation<IX,DX,true>{
00256 public:
00257 template<class STORAGE>
00258 static void size( STORAGE & storage ,size_t & neededStorage){
00259
00260 }
00261
00262 template<class STORAGE>
00263 static void store( STORAGE & storage ,size_t & currentOffset){
00264
00265 }
00266
00267 template<class GM,class GM_EXPLICIT,class FID_MAP>
00268 static void convert(const GM & gm ,GM_EXPLICIT & gmExplicit , FID_MAP & fidMap){
00269
00270 }
00271 };
00272
00273 }
00274
00275 #endif //OPENGM_GRAPHICALMODEL_EXPLICIT_STORAGE_HXX