OpenGM  2.3.x
Discrete Graphical Model Library
lp_reparametrization.hxx
Go to the documentation of this file.
1 /*
2  * lp_reparametrization_storage.hxx
3  *
4  * Created on: Sep 16, 2013
5  * Author: bsavchyn
6  */
7 
8 #ifndef LP_REPARAMETRIZATION_STORAGE_HXX_
9 #define LP_REPARAMETRIZATION_STORAGE_HXX_
12 
13 
14 //#ifdef WITH_HDF5
15 //#include <opengm/inference/auxiliary/lp_reparametrization_hdf5.hxx>
16 //#endif
17 
18 
19 namespace opengm{
20 
21 #ifdef TRWS_DEBUG_OUTPUT
22 using OUT::operator <<;
23 #endif
24 
25 
26 template<class GM>
28 public:
29  typedef GM GraphicalModelType;
30  typedef typename GM::ValueType ValueType;
31  typedef typename GM::FactorType FactorType;
32  typedef typename GM::IndexType IndexType;
33  typedef typename GM::LabelType LabelType;
34 
35  //typedef std::valarray<ValueType> UnaryFactor;
36  typedef std::vector<ValueType> UnaryFactor;
37  typedef ValueType* uIterator;
38  typedef std::vector<UnaryFactor> VecUnaryFactors;
39  typedef std::map<IndexType,IndexType> VarIdMapType;
40  LPReparametrisationStorage(const GM& gm);
41 
42  const UnaryFactor& get(IndexType factorIndex,IndexType relativeVarIndex)const//const access
43  {
44  OPENGM_ASSERT(factorIndex < _gm.numberOfFactors());
45  OPENGM_ASSERT(relativeVarIndex < _dualVariables[factorIndex].size());
46  return _dualVariables[factorIndex][relativeVarIndex];
47  }
48  std::pair<uIterator,uIterator> getIterators(IndexType factorIndex,IndexType relativeVarIndex)
49  {
50  OPENGM_ASSERT(factorIndex < _gm.numberOfFactors());
51  OPENGM_ASSERT(relativeVarIndex < _dualVariables[factorIndex].size());
52  UnaryFactor& uf=_dualVariables[factorIndex][relativeVarIndex];
53  uIterator begin=&uf[0];
54  return std::make_pair(begin,begin+uf.size());
55  }
56 
57  template<class ITERATOR>
58  ValueType getFactorValue(IndexType findex,ITERATOR it)const
59  {
60  OPENGM_ASSERT(findex < _gm.numberOfFactors());
61  const typename GM::FactorType& factor=_gm[findex];
62 
63  ValueType res=0;//factor(it);
64  if (factor.numberOfVariables()>1)
65  {
66  res=factor(it);
67  for (IndexType varId=0;varId<factor.numberOfVariables();++varId)
68  {
69  OPENGM_ASSERT(varId < _dualVariables[findex].size());
70  OPENGM_ASSERT(*(it+varId) < _dualVariables[findex][varId].size());
71  res+=_dualVariables[findex][varId][*(it+varId)];
72  }
73  }else
74  {
75  res=getVariableValue(factor.variableIndex(0),*it);
76  }
77  return res;
78  }
79 
80  ValueType getVariableValue(IndexType varIndex,LabelType label)const
81  {
82  OPENGM_ASSERT(varIndex < _gm.numberOfVariables());
83  ValueType res=0.0;
84  for (IndexType i=0;i<_gm.numberOfFactors(varIndex);++i)
85  {
86  IndexType factorId=_gm.factorOfVariable(varIndex,i);
87  OPENGM_ASSERT(factorId < _gm.numberOfFactors());
88  if (_gm[factorId].numberOfVariables()==1)
89  {
90  res+=_gm[factorId](&label);
91  continue;
92  }
93 
94  OPENGM_ASSERT( factorId < _dualVariables.size() );
95  OPENGM_ASSERT(label < _dualVariables[factorId][localId(factorId,varIndex)].size());
96  res-=_dualVariables[factorId][localId(factorId,varIndex)][label];
97  }
98 
99  return res;
100  }
101 #ifdef TRWS_DEBUG_OUTPUT
102  void PrintTestData(std::ostream& fout)const;
103 #endif
104  IndexType localId(IndexType factorId,IndexType varIndex)const{
105  typename VarIdMapType::const_iterator it = _localIdMap[factorId].find(varIndex);
106  trws_base::exception_check(it!=_localIdMap[factorId].end(),"LPReparametrisationStorage:localId() - factor and variable are not connected!");
107  return it->second;};
108 
109  const GM& graphicalModel()const{return _gm;}
110 
111  template<class VECTOR>
112  void serialize(VECTOR* pserialization)const;
113  template<class VECTOR>
114  void deserialize(const VECTOR& serialization);
115 private:
116  LPReparametrisationStorage(const LPReparametrisationStorage&);//TODO: carefully implement, when needed
117  LPReparametrisationStorage& operator=(const LPReparametrisationStorage&);//TODO: carefully implement, when needed
118  const GM& _gm;
119  std::vector<VecUnaryFactors> _dualVariables;
120  std::vector<VarIdMapType> _localIdMap;
121 };
122 
123 template<class GM>
125 :_gm(gm),_localIdMap(gm.numberOfFactors())
126  {
127  _dualVariables.resize(_gm.numberOfFactors());
128  //for all factors with order > 1
129  for (IndexType findex=0;findex<_gm.numberOfFactors();++findex)
130  {
131  IndexType numVars=_gm[findex].numberOfVariables();
132  VarIdMapType& mapFindex=_localIdMap[findex];
133  if (numVars>=2)
134  {
135 
136  _dualVariables[findex].resize(numVars);
137  //std::valarray<IndexType> v(numVars);
138  std::vector<IndexType> v(numVars);
139  _gm[findex].variableIndices(&v[0]);
140  for (IndexType n=0;n<numVars;++n)
141  {
142  //_dualVariables[findex][n].assign(_gm.numberOfLabels(v[n]),0.0);//TODO. Do it like this
143  _dualVariables[findex][n].resize(_gm.numberOfLabels(v[n]));
144  mapFindex[v[n]]=n;
145  }
146  }
147  }
148 
149  }
150 
151 #ifdef TRWS_DEBUG_OUTPUT
152 template<class GM>
153 void LPReparametrisationStorage<GM>::PrintTestData(std::ostream& fout)const
154 {
155  fout << "_dualVariables.size()=" << _dualVariables.size()<<std::endl;
156  for (IndexType factorIndex=0;factorIndex<_dualVariables.size();++factorIndex )
157  {
158  fout <<"factorIndex="<<factorIndex<<": ---------------------------------"<<std::endl;
159  for (IndexType varId=0;varId<_dualVariables[factorIndex].size();++varId)
160  fout <<"varId="<<varId<<": "<< _dualVariables[factorIndex][varId]<<std::endl;
161  }
162 }
163 #endif
164 
165 template<class GM>
166 template<class VECTOR>
167 void LPReparametrisationStorage<GM>::serialize(VECTOR* pserialization)const
168 {
169 //computing total space needed:
170 size_t i=0;
171 for (IndexType factorId=0;factorId<_dualVariables.size();++factorId)
172  for (IndexType localId=0;localId<_dualVariables[factorId].size();++localId)
173  for (LabelType label=0;label<_dualVariables[factorId][localId].size();++label)
174  ++i;
175 
176  pserialization->resize(i);
177  //serializing....
178  i=0;
179  for (IndexType factorId=0;factorId<_dualVariables.size();++factorId)
180  for (IndexType localId=0;localId<_dualVariables[factorId].size();++localId)
181  for (LabelType label=0;label<_dualVariables[factorId][localId].size();++label)
182  (*pserialization)[i++]=_dualVariables[factorId][localId][label];
183 }
184 
185 template<class GM>
186 template<class VECTOR>
187 void LPReparametrisationStorage<GM>::deserialize(const VECTOR& serialization)
188 {
189  size_t i=0;
190  for (IndexType factorId=0;factorId<_gm.numberOfFactors();++factorId)
191  {
192  OPENGM_ASSERT(factorId<_dualVariables.size());
193  if (_gm[factorId].numberOfVariables()==1) continue;
194  for (IndexType localId=0;localId<_gm[factorId].numberOfVariables();++localId)
195  {
196  OPENGM_ASSERT(localId<_dualVariables[factorId].size());
197  for (LabelType label=0;label<_dualVariables[factorId][localId].size();++label)
198  {
199  OPENGM_ASSERT(label<_dualVariables[factorId][localId].size());
200  if (i>=serialization.size())
201  throw std::runtime_error("LPReparametrisationStorage<GM>::deserialize(): Size of serialization is less than required for the graphical model! Deserialization failed.");
202  _dualVariables[factorId][localId][label]=serialization[i++];
203  }
204  }
205  }
206  if (i!=serialization.size())
207  throw std::runtime_error("LPReparametrisationStorage<GM>::deserialize(): Size of serialization is greater than required for the graphical model! Deserialization failed.");
208 }
209 /*
210 #ifdef WITH_HDF5
211 
212 template<class GM>
213 void save(const LPReparametrisationStorage<GM>& repa,const std::string& filename,const std::string& modelname)
214 {
215  hid_t file = H5Fcreate(filename.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
216  OPENGM_ASSERT(file >= 0);
217  marray::Vector<typename GM::ValueType> marr;
218  repa.serialize(&marr);
219  marray::hdf5::save(file,modelname.c_str(),marr);
220  H5Fclose(file);
221 }
222 
223 template<class GM>
224 void load(LPReparametrisationStorage<GM>* prepa, const std::string& filename, const std::string& modelname)
225 {
226  hid_t file = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
227  OPENGM_ASSERT(file>=0);
228  marray::Vector<typename GM::ValueType> marr;
229  marray::hdf5::load(file,modelname.c_str(),marr);
230  prepa->deserialize(marr);
231  H5Fclose(file);
232 };
233 
234 #endif
235 */
236 
237 template<class GM, class REPASTORAGE>
238 class ReparametrizationView : public opengm::FunctionBase<ReparametrizationView<GM,REPASTORAGE>,
239 typename GM::ValueType,typename GM::IndexType, typename GM::LabelType>
240 {
241 public:
242  typedef typename GM::ValueType ValueType;
243  typedef ValueType value_type;
244  typedef typename GM::FactorType FactorType;
245  typedef typename GM::OperatorType OperatorType;
246  typedef typename GM::IndexType IndexType;
247  typedef typename GM::LabelType LabelType;
248 
249  typedef GM GraphicalModelType;
250  typedef REPASTORAGE ReparametrizationStorageType;
251 
252  ReparametrizationView(const FactorType & factor,const REPASTORAGE& repaStorage,IndexType factorId)
253  :_pfactor(&factor),_prepaStorage(&repaStorage),_factorId(factorId)
254  {};
255 
256  template<class Iterator>
257  ValueType operator()(Iterator begin)const
258  {
259  switch (_pfactor->numberOfVariables())
260  {
261  case 1: return _prepaStorage->getVariableValue(_pfactor->variableIndex(0),*begin);
262  default: return _prepaStorage->getFactorValue(_factorId,begin);
263  };
264  }
265 
266  LabelType shape(const IndexType& index)const{return _pfactor->numberOfLabels(index);};
267  IndexType dimension()const{return _pfactor->numberOfVariables();};
268  IndexType size()const{return _pfactor->size();};
269 
270 private:
271  const FactorType* _pfactor;
272  const REPASTORAGE* _prepaStorage;
273  IndexType _factorId;
274 };
275 
277 {
279 };
280 
281 template<class GM, class ACC>
283 {
284 public:
285  typedef GM GraphicalModelType;
286  typedef typename GraphicalModelType::ValueType ValueType;
287  typedef typename GraphicalModelType::IndexType IndexType;
288  typedef typename GraphicalModelType::LabelType LabelType;
289  typedef typename std::vector<bool> MaskType;
290  typedef typename std::vector<MaskType> ImmovableLabelingType;
295 
296  LPReparametrizer(const GM& gm):_gm(gm),_repastorage(_gm){};
297  virtual ~LPReparametrizer(){};
298  RepaStorageType& Reparametrization(){return _repastorage;};
299  //TODO: To implement
300  virtual void getArcConsistency(std::vector<bool>* pmask,std::vector<LabelType>* plabeling,IndexType modelorder=2);
301  virtual void reparametrize(const MaskType* pmask=0){};
302  void reparametrize(const ImmovableLabelingType& immovableLabeling){};
303  virtual void getReparametrizedModel(ReparametrizedGMType& gm)const;
304  const GM& graphicalModel()const{return _gm;}
305 private:
306  const GM& _gm;
307  RepaStorageType _repastorage;
308 };
309 
310 template<class GM, class ACC>
312 {
313  gm=ReparametrizedGMType(_gm.space());
314  //copying factors
315  for (typename GM::IndexType factorID=0;factorID<_gm.numberOfFactors();++factorID)
316  {
317  const typename GM::FactorType& f=_gm[factorID];
318  opengm::ReparametrizationView<GM,RepaStorageType> repaView(f,_repastorage,factorID);
319  typename ReparametrizedGMType::FunctionIdentifier fId=gm.addFunction(repaView);
320  gm.addFactor(fId,f.variableIndicesBegin(), f.variableIndicesEnd());
321  }
322 }
323 
324 template<class GM, class ACC>
325 void LPReparametrizer<GM,ACC>::getArcConsistency(std::vector<bool>* pmask,std::vector<LabelType>* plabeling,IndexType modelorder)
326 {
327  pmask->assign(_gm.numberOfVariables(),true);
328  ReparametrizedGMType repagm;
329  getReparametrizedModel(repagm);
330 
337  std::vector<ValueType> optimalValues(repagm.numberOfFactors());
338  std::vector< std::vector<LabelType> > optimalLabelings(repagm.numberOfFactors(),std::vector<LabelType>(modelorder));
339  //std::vector<LabelType> locallyOptimalLabels(repagm.numberOfVariables(),0);//in case there is no corresponding unary factor 0 is always one of optimal labels (all labels are optimal)
340  std::vector<LabelType>& locallyOptimalLabels=*plabeling;
341  locallyOptimalLabels.assign(repagm.numberOfVariables(),0);//in case there is no corresponding unary factor 0 is always one of optimal labels (all labels are optimal)
342 
343  std::vector<IndexType> unaryFactors; unaryFactors.reserve(repagm.numberOfFactors());
344  std::vector<ValueType> worstValue(repagm.numberOfFactors(),0);
345 
346 // std::cout << "First cycle:" <<std::endl;
347 
348  for (IndexType factorId=0;factorId<repagm.numberOfFactors();++factorId)
349  {
350  const typename ReparametrizedGMType::FactorType& factor=repagm[factorId];
351  optimalLabelings[factorId].resize(factor.numberOfVariables());
352  //accumulate.template<ACC>(factor,optimalValues[factorId],optimalLabelings[factorId]);
353  accumulate<ACC,typename ReparametrizedGMType::FactorType,ValueType,LabelType>(factor,optimalValues[factorId],optimalLabelings[factorId]);
354 
355 // std::cout << "factorId=" << factorId<< ", optimalValues=" << optimalValues[factorId] << ", optimalLabelings=" << optimalLabelings[factorId] <<std::endl;
356 
357  if (factor.numberOfVariables() == 1)
358  {
359  unaryFactors.push_back(factorId);
360  locallyOptimalLabels[factor.variableIndex(0)]=optimalLabelings[factorId][0];
361 // std::cout << "locallyOptimalLabels[" << factor.variableIndex(0)<<"]=" << locallyOptimalLabels[factor.variableIndex(0)] << std::endl;
362  }else
363  {
364  if (ACC::bop(0,1))
365  worstValue[factorId]=factor.max();
366  else
367  worstValue[factorId]=factor.min();
368  }
369 
370  }
371 
381  for (IndexType i=0;i<unaryFactors.size();++i)
382  {
383  IndexType var= repagm[unaryFactors[i]].variableIndex(0);
384  IndexType numOfFactors=repagm.numberOfFactors(var);
385 
386  for (IndexType f=0;f<numOfFactors;++f)
387  {
388  IndexType factorId=repagm.factorOfVariable(var,f);
389  const typename ReparametrizedGMType::FactorType& factor=repagm[factorId];
390 
391 // std::cout << "factorId=" <<factorId <<", optimalValues="<< optimalValues[factorId]<< std::endl;
392 
393  if (factor.numberOfVariables() <= 1) continue;
394 
395  IndexType localVarIndex= std::find(factor.variableIndicesBegin(),factor.variableIndicesEnd(),var) -factor.variableIndicesBegin();
396 
397  OPENGM_ASSERT((IndexType)localVarIndex != (IndexType)(factor.variableIndicesEnd()-factor.variableIndicesBegin()));
398 
399  if (optimalLabelings[factorId][localVarIndex]==locallyOptimalLabels[var]) continue;
400 
401  std::vector<LabelType> labeling(optimalLabelings[factorId].size());
402  //labeling[localVarIndex]=locallyOptimalLabels[var];
403 
404  for (IndexType v=0;v<factor.numberOfVariables();++v)
405  labeling[v]=locallyOptimalLabels[factor.variableIndex(v)];
406 
407 // std::cout <<"worstValue="<<worstValue[factorId] << ", localVarIndex=" <<localVarIndex <<", labeling="<< labeling<<std::endl;
408 
409  if (fabs(factor(labeling.begin())-optimalValues[factorId])
410  <factor.numberOfVariables()*fabs(worstValue[factorId])*std::numeric_limits<ValueType>::epsilon()) continue;
411 
413 // std::cout << "False:("<<std::endl;
414 
415  (*pmask)[var]=false; break;
416  }
417  }
418 
419 }
420 
421 }
422 
423 
424 #endif /* LP_REPARAMETRIZATION_STORAGE_HXX_ */
IndexType addFactor(const FunctionIdentifier &, ITERATOR, ITERATOR)
add a factor to the graphical model
The OpenGM namespace.
Definition: config.hxx:43
void exception_check(bool condition, const std::string &str)
Definition: utilities2.hxx:90
Fallback implementation of member functions of OpenGM functions.
ReparametrizationView(const FactorType &factor, const REPASTORAGE &repaStorage, IndexType factorId)
std::map< IndexType, IndexType > VarIdMapType
ValueType operator()(Iterator begin) const
std::pair< uIterator, uIterator > getIterators(IndexType factorIndex, IndexType relativeVarIndex)
Discrete space in which variables can have differently many labels.
const GM & graphicalModel() const
virtual void getReparametrizedModel(ReparametrizedGMType &gm) const
FunctionIdentifier addFunction(const FUNCTION_TYPE &)
add a function to the graphical model
ValueType getVariableValue(IndexType varIndex, LabelType label) const
IndexType factorOfVariable(const IndexType, const IndexType) const
return the k-th factor connected to the j-th variable
VariablesIteratorType variableIndicesBegin() const
#define OPENGM_ASSERT(expression)
Definition: opengm.hxx:77
std::vector< MaskType > ImmovableLabelingType
void deserialize(const VECTOR &serialization)
IndexType localId(IndexType factorId, IndexType varIndex) const
VariablesIteratorType variableIndicesEnd() const
LPReparametrizer_Parameter Parameter
LabelType shape(const IndexType &index) const
LPReparametrisationStorage< GM > RepaStorageType
opengm::GraphicalModel< ValueType, opengm::Adder, opengm::ReparametrizationView< GM, RepaStorageType >, opengm::DiscreteSpace< IndexType, LabelType > > ReparametrizedGMType
Abstraction (wrapper class) of factors, independent of the function used to implement the factor...
ValueType getFactorValue(IndexType findex, ITERATOR it) const
IndexType numberOfVariables() const
std::vector< UnaryFactor > VecUnaryFactors
GraphicalModelType::ValueType ValueType
GraphicalModelType::LabelType LabelType
virtual void getArcConsistency(std::vector< bool > *pmask, std::vector< LabelType > *plabeling, IndexType modelorder=2)
IndexType variableIndex(const IndexType) const
return the index of the j-th variable
void reparametrize(const ImmovableLabelingType &immovableLabeling)
RepaStorageType & Reparametrization()
GraphicalModelType::IndexType IndexType
IndexType numberOfVariables() const
void serialize(VECTOR *pserialization) const
IndexType numberOfFactors() const
virtual void reparametrize(const MaskType *pmask=0)