OpenGM  2.3.x
Discrete Graphical Model Library
graphicalmodel/modelgenerators/syntheticmodelgenerator.hxx
Go to the documentation of this file.
1 #pragma once
2 #ifndef OPENGM_SYNTHETIC_MODEL_GENERATOR2_HXX
3 #define OPENGM_SYNTHETIC_MODEL_GENERATOR2_HXX
4 
6 
7 #include <vector>
8 #include <map>
9 
17 
18 namespace opengm {
19 
20  template<class GM>
21  class SyntheticModelGenerator {
22  public:
23  // typedefs
24  typedef GM GraphicalModelType;
25  typedef typename GM::ValueType ValueType;
26  typedef typename GM::IndexType IndexType;
27  typedef typename GM::LabelType LabelType;
28 
29  typedef typename GM::FunctionIdentifier FunctionIdentifier;
30 
34  typedef opengm::AbsoluteDifferenceFunction<ValueType, IndexType, LabelType> AbsoluteDifferenceFunctionType;
35 
36  typedef RandomUniform<double> URandomGenerator;
37  typedef RandomUniform<int> IRandomGenerator;
38 
39  struct Parameter {
40  // typedefs
41  enum FunctionTypes {CONSTF, URANDOM, IRANDOM, POTTS, L1};
42  typedef std::pair<ValueType, ValueType> MinMax;
43 
44  // member
45  LabelType maxNumberOfStates_;
46  bool randomNumberOfStates_;
47  std::vector<FunctionTypes> functionsType_;
48  std::vector<MinMax> functionsMinMax_;
49  std::vector<IndexType> functionsOrder_;
50  std::vector<bool> sharedFunctions_;
51  std::vector<std::vector<ValueType> > functionsParameter_;
52 
53  // constructor
54  Parameter(const LabelType maxNumberOfStatesIn = 2, const bool randomNumberOfStatesIn = false);
55 
56  // check parameter consistency
57  bool sanityCheck() const;
58  };
59 
60  // static public methods
61  static GraphicalModelType buildGrid(const size_t id, const IndexType width, const IndexType height, const Parameter& parameter);
62  static GraphicalModelType buildFull(const size_t id, const IndexType numberOfVariables, const Parameter& parameter);
63  static GraphicalModelType buildStar(const size_t id, const IndexType numberOfVariables, const Parameter& parameter);
64  protected:
65  // static protected methods
66  template<class IRANDOM_GENERATOR>
67  static GraphicalModelType initGM(const IndexType numberOfVariables, IRANDOM_GENERATOR& integerRandomGenerator, const Parameter& parameter);
68  template<class SHAPE_ITERATOR, class URANDOM_GENERATOR, class IRANDOM_GENERATOR>
69  static FunctionIdentifier addFunction(GraphicalModelType& gm, const typename Parameter::FunctionTypes functionType, const std::vector<ValueType>& functionsParameter, SHAPE_ITERATOR shapeBegin, SHAPE_ITERATOR shapeEnd, URANDOM_GENERATOR& uniformRandomGenerator, IRANDOM_GENERATOR& integerRandomGenerator);
70  };
71 
72  template <class GM>
73  inline SyntheticModelGenerator<GM>::Parameter::Parameter(
74  const LabelType maxNumberOfStatesIn, const bool randomNumberOfStatesIn)
75  : maxNumberOfStates_(maxNumberOfStatesIn),
76  randomNumberOfStates_(randomNumberOfStatesIn), functionsType_(),
77  functionsMinMax_(), functionsOrder_(), sharedFunctions_(),
78  functionsParameter_() {
79  }
80 
81  template <class GM>
82  inline bool SyntheticModelGenerator<GM>::Parameter::sanityCheck() const {
83  return (functionsType_.size() == functionsMinMax_.size()) &&
84  (functionsMinMax_.size() == functionsOrder_.size()) &&
85  (functionsOrder_.size() == sharedFunctions_.size()) &&
86  (sharedFunctions_.size() == functionsParameter_.size());
87  }
88 
89  template <class GM>
90  inline typename SyntheticModelGenerator<GM>::GraphicalModelType SyntheticModelGenerator<GM>::buildGrid(const size_t id, const IndexType width, const IndexType height, const Parameter& parameter) {
91  OPENGM_ASSERT(parameter.sanityCheck());
92 
93  URandomGenerator uniformRandomGenerator(0.0, 1.0, id);
94  IRandomGenerator integerRandomGenerator(0, 1, id);
95 
96  // init gm
97  // TODO: width * height might overflow hence add overflow test (not trivial)
98  GraphicalModelType gm = initGM(width * height, integerRandomGenerator, parameter);
99 
100  // build grid structure
101  std::vector<LabelType> shape(1, parameter.maxNumberOfStates_);
102  std::vector<IndexType> variables(1, 0);
103  FunctionIdentifier functionId;
104  std::map<std::vector<LabelType>, FunctionIdentifier> sharedFunctionMap;
105 
106  bool newFunction = true;
107 
108  for(size_t i = 0; i < parameter.functionsType_.size(); ++i) {
109  //OPENGM_ASSERT(parameter.functionsOrder_[i] <= width);
110  //OPENGM_ASSERT(parameter.functionsOrder_[i] <= height);
111 
112  // set new bounds for random generators
113  uniformRandomGenerator.setLow(parameter.functionsMinMax_[i].first);
114  uniformRandomGenerator.setHigh(parameter.functionsMinMax_[i].second);
115  integerRandomGenerator.setLow(parameter.functionsMinMax_[i].first);
116  integerRandomGenerator.setHigh(parameter.functionsMinMax_[i].second);
117 
118  // resize shape
119  if(parameter.randomNumberOfStates_) {
120  shape.resize(parameter.functionsOrder_[i]);
121  } else {
122  shape.resize(parameter.functionsOrder_[i], parameter.maxNumberOfStates_);
123  }
124 
125  // resize variables
126  variables.resize(parameter.functionsOrder_[i]);
127 
128  for(IndexType j = 0; j < width; ++j) {
129  for(IndexType k = 0; k < height; ++k) {
130  if((width >= parameter.functionsOrder_[i]) && (j < width - parameter.functionsOrder_[i] + 1)) {
131  // horizontal
132  IndexType variableOffset = j + (k * width);
133  for(IndexType l = 0; l < parameter.functionsOrder_[i]; ++l) {
134  if(parameter.randomNumberOfStates_) {
135  shape[l] = gm.numberOfLabels(variableOffset + l);
136  }
137  variables[l] = variableOffset + l;
138  }
139  if(parameter.sharedFunctions_[i]) {
140  const typename std::map<std::vector<LabelType>, FunctionIdentifier>::const_iterator position = sharedFunctionMap.find(shape);
141  if(position != sharedFunctionMap.end()) {
142  // use shared function
143  newFunction = false;
144  functionId = position->second;
145  } else {
146  // use new function
147  newFunction = true;
148  }
149  } else {
150  newFunction = true;
151  }
152 
153  if(newFunction) {
154  // add new function
155  functionId = addFunction(gm, parameter.functionsType_[i], parameter.functionsParameter_[i], shape.begin(), shape.end(), uniformRandomGenerator, integerRandomGenerator);
156  if(parameter.sharedFunctions_[i]) {
157  sharedFunctionMap[shape] = functionId;
158  }
159  }
160 
161  // add horizontal factor
162  gm.addFactor(functionId, variables.begin(), variables.end());
163  }
164 
165  if((height >= parameter.functionsOrder_[i]) && (k < height - parameter.functionsOrder_[i] + 1) && (parameter.functionsOrder_[i] > 1)) {
166  // vertical (only if parameter.functionsOrder_[i] > 1 otherwise unary factors would be added twice)
167  IndexType variableOffset = j + (k * width);
168  for(IndexType l = 0; l < parameter.functionsOrder_[i]; ++l) {
169  if(parameter.randomNumberOfStates_) {
170  shape[l] = gm.numberOfLabels(variableOffset + (l * width));
171  }
172  variables[l] = variableOffset + (l * width);
173  }
174  if(parameter.sharedFunctions_[i]) {
175  const typename std::map<std::vector<LabelType>, FunctionIdentifier>::const_iterator position = sharedFunctionMap.find(shape);
176  if(position != sharedFunctionMap.end()) {
177  // use shared function
178  newFunction = false;
179  functionId = position->second;
180  } else {
181  // use new function
182  newFunction = true;
183  }
184  } else {
185  newFunction = true;
186  }
187 
188  if(newFunction) {
189  // add new function
190  functionId = addFunction(gm, parameter.functionsType_[i], parameter.functionsParameter_[i], shape.begin(), shape.end(), uniformRandomGenerator, integerRandomGenerator);
191  if(parameter.sharedFunctions_[i]) {
192  sharedFunctionMap[shape] = functionId;
193  }
194  }
195 
196  // add vertical factor
197  gm.addFactor(functionId, variables.begin(), variables.end());
198  }
199  }
200  }
201 
202  // clear shared function map for next iteration
203  if(parameter.sharedFunctions_[i]) {
204  sharedFunctionMap.clear();
205  }
206  }
207 
208  return gm;
209  }
210 
211  template <class GM>
212  inline typename SyntheticModelGenerator<GM>::GraphicalModelType SyntheticModelGenerator<GM>::buildFull(const size_t id, const IndexType numberOfVariables, const Parameter& parameter) {
213 
214  }
215 
216  template <class GM>
217  inline typename SyntheticModelGenerator<GM>::GraphicalModelType SyntheticModelGenerator<GM>::buildStar(const size_t id, const IndexType numberOfVariables, const Parameter& parameter) {
218 
219  }
220 
221  template <class GM>
222  template<class IRANDOM_GENERATOR>
223  inline typename SyntheticModelGenerator<GM>::GraphicalModelType SyntheticModelGenerator<GM>::initGM(const IndexType numberOfVariables, IRANDOM_GENERATOR& integerRandomGenerator, const Parameter& parameter) {
224  if(parameter.randomNumberOfStates_) {
225  std::vector<typename GM::LabelType> numberOfLabels(numberOfVariables);
226  // generate random integer variables in the range [1, parameter.maxNumberOfStates_ + 1) = [1, parameter.maxNumberOfStates_]
227  // TODO check if parameter.maxNumberOfStates_ + 1 fits in value type of IRANDOM_GENERATOR
228  integerRandomGenerator.setLow(1);
229  integerRandomGenerator.setHigh(parameter.maxNumberOfStates_ + 1);
230 
231  // generate number of labels
232  for(size_t i = 0; i < numberOfVariables; i++) {
233  numberOfLabels[i] = integerRandomGenerator();
234  }
235 
236  return GM(opengm::DiscreteSpace<typename GM::IndexType,typename GM::LabelType>(numberOfLabels.begin(), numberOfLabels.end()));
237  } else {
238  std::vector<typename GM::LabelType> numberOfLabels(numberOfVariables, parameter.maxNumberOfStates_);
239  return GM(opengm::DiscreteSpace<typename GM::IndexType,typename GM::LabelType>(numberOfLabels.begin(), numberOfLabels.end()));
240  }
241  }
242 
243  template <class GM>
244  template<class SHAPE_ITERATOR, class URANDOM_GENERATOR, class IRANDOM_GENERATOR>
245  inline typename SyntheticModelGenerator<GM>::FunctionIdentifier SyntheticModelGenerator<GM>::addFunction(GraphicalModelType& gm, const typename Parameter::FunctionTypes functionType, const std::vector<ValueType>& functionParameter, SHAPE_ITERATOR shapeBegin, SHAPE_ITERATOR shapeEnd, URANDOM_GENERATOR& uniformRandomGenerator, IRANDOM_GENERATOR& integerRandomGenerator) {
246  switch (functionType) {
247  case Parameter::CONSTF: {
248  if(functionParameter.size() > 0) {
249  OPENGM_ASSERT(functionParameter.size() == 1);
250  ConstantFunctionType constantFunction(shapeBegin, shapeEnd, functionParameter[0]);
251  return gm.addFunction(constantFunction);
252  } else {
253  ConstantFunctionType constantFunction(shapeBegin, shapeEnd, uniformRandomGenerator());
254  return gm.addFunction(constantFunction);
255  }
256  }
257  case Parameter::URANDOM: {
258  ExplicitFunctionType function(shapeBegin, shapeEnd);
259  ShapeWalker<SHAPE_ITERATOR> shapeWalker(shapeBegin, function.dimension());
260  if(functionParameter.size() > 0) {
261  OPENGM_ASSERT(functionParameter.size() == function.size());
262  for(IndexType i = 0; i < function.size(); ++i) {
263  function(shapeWalker.coordinateTuple().begin()) = functionParameter[i];
264  ++shapeWalker;
265  }
266  } else {
267  for(IndexType i = 0; i < function.size(); ++i) {
268  function(shapeWalker.coordinateTuple().begin()) = uniformRandomGenerator();
269  ++shapeWalker;
270  }
271  }
272  return gm.addFunction(function);
273  }
274  case Parameter::IRANDOM: {
275  ExplicitFunctionType function(shapeBegin, shapeEnd);
276  ShapeWalker<SHAPE_ITERATOR> shapeWalker(shapeBegin, function.dimension());
277  if(functionParameter.size() > 0) {
278  OPENGM_ASSERT(functionParameter.size() == function.size());
279  for(IndexType i = 0; i < function.size(); ++i) {
280  function(shapeWalker.coordinateTuple().begin()) = functionParameter[i];
281  ++shapeWalker;
282  }
283  } else {
284  for(IndexType i = 0; i < function.size(); ++i) {
285  function(shapeWalker.coordinateTuple().begin()) = integerRandomGenerator();
286  ++shapeWalker;
287  }
288  }
289  return gm.addFunction(function);
290  }
291  case Parameter::POTTS: {
292  OPENGM_ASSERT(std::distance(shapeBegin, shapeEnd) == 2);
293  if(functionParameter.size() > 0) {
294  OPENGM_ASSERT(functionParameter.size() == 2);
295  PottsFunctionType function(shapeBegin[0], shapeBegin[1], functionParameter[0], functionParameter[1]);
296  return gm.addFunction(function);
297  } else {
298  PottsFunctionType function(shapeBegin[0], shapeBegin[1], uniformRandomGenerator(), uniformRandomGenerator());
299  return gm.addFunction(function);
300  }
301  }
302  case Parameter::L1: {
303  OPENGM_ASSERT(std::distance(shapeBegin, shapeEnd) == 2);
304  if(functionParameter.size() > 0) {
305  OPENGM_ASSERT(functionParameter.size() == 1);
306  AbsoluteDifferenceFunctionType function(shapeBegin[0], shapeBegin[1], functionParameter[0]);
307  return gm.addFunction(function);
308  } else {
309  AbsoluteDifferenceFunctionType function(shapeBegin[0], shapeBegin[1], uniformRandomGenerator());
310  return gm.addFunction(function);
311  }
312  }
313  default:
314  throw RuntimeError("Unknown function type.");
315  }
316  }
317 
318 
319  template<class GM>
320  class SyntheticModelGenerator2
321  {
322  public:
323  typedef GM GraphicalModelType;
324  typedef typename GM::ValueType ValueType;
325  typedef typename GM::IndexType IndexType;
326  typedef typename GM::LabelType LabelType;
327  typedef opengm::ExplicitFunction<ValueType,IndexType,LabelType> ExplicitFunctionType;
328  // typedef typename GM::SparseFunctionType SparseFunctionType;
329  // typedef typename GM::ImplicitFunctionType ImplicitFunctionType;
330  typedef typename GM::FunctionIdentifier FunctionIdentifier;
331  typedef typename GM::OperatorType OperatorType;
332 
333  enum FunctionTypes
334  {
335  EMPTY, CONSTF, URANDOM, IRANDOM, GPOTTS, RGPOTTS, L1, RPOTTS
336  }; // GRANDOM
337 
338  class Parameter
339  {
340  public:
341  std::vector<FunctionTypes> functionTypes_;
342  std::vector<std::vector<ValueType> > functionParameters_;
343  std::vector<bool> sharedFunctions_;
344  bool randomNumberOfStates_;
345 
346  Parameter()
347  {
348  functionTypes_.resize(2, URANDOM);
349  functionParameters_.resize(2);
350  functionParameters_[0].resize(2);
351  functionParameters_[0][0] = 0.1;
352  functionParameters_[0][1] = 1;
353  functionParameters_[1].resize(2);
354  functionParameters_[1][0] = 0.1;
355  functionParameters_[1][1] = 1;
356  sharedFunctions_.resize(2, true);
357  randomNumberOfStates_ = false;
358  }
359 
360  bool isConsistent() const
361  {
362  return functionTypes_.size() == functionParameters_.size() &&
363  functionParameters_.size() == sharedFunctions_.size();
364  }
365  };
366 
367  SyntheticModelGenerator2();
368  GM buildGrid(const size_t, const size_t, const size_t, const size_t, const Parameter&) const;
369  GM buildHigherOrderGrid(const size_t, const size_t, const size_t, const size_t, const size_t, const Parameter&) const;
370  GM buildFull(const size_t, const size_t, const size_t, const Parameter&) const;
371  GM buildStar(const size_t, const size_t, const size_t, const Parameter&) const;
372 
373  private:
374  void addUnaries(GM&, const FunctionTypes, const std::vector<ValueType>&, const bool) const;
375  template<class ITERATOR>
376  FunctionIdentifier addFunction(GM&, const FunctionTypes, const std::vector<ValueType>&, ITERATOR, ITERATOR) const;
377  GraphicalModelType getGM(size_t,size_t,bool) const;
378  };
379 
380  template<class GM>
381  SyntheticModelGenerator2<GM>::SyntheticModelGenerator2()
382  {}
383 
384  template<class GM>
385  GM SyntheticModelGenerator2<GM>::getGM(size_t numVar, size_t numStates, bool randomNumberOfStates) const
386  {
387  if(randomNumberOfStates) {
388  std::vector<typename GM::LabelType> numberOfLabels(numVar);
389  // generate random integer variables in the range [1, numStates + 1) = [1, numStates]
390  opengm::RandomUniform<size_t> randomIntegerNumberGenerator(1,numStates + 1);
391  for(size_t i = 0; i < numVar; i++) {
392  numberOfLabels[i] = randomIntegerNumberGenerator();
393  }
394  return GM( opengm::DiscreteSpace<typename GM::IndexType,typename GM::LabelType>(numberOfLabels.begin(), numberOfLabels.end()));
395  } else {
396  std::vector<typename GM::LabelType> numberOfLabels(numVar,numStates);
397  return GM( opengm::DiscreteSpace<typename GM::IndexType,typename GM::LabelType>(numberOfLabels.begin(), numberOfLabels.end()));
398  }
399  }
400 
401  template<class GM>
402  void SyntheticModelGenerator2<GM>::addUnaries
403  (
404  GM& gm,
405  const FunctionTypes functionType,
406  const std::vector<ValueType>& functionParameter,
407  const bool sharedFunction
408  ) const
409  {
410  typename GM::LabelType shape[1];
411  typename GM::IndexType var[] = {0};
412  FunctionIdentifier funcId;
413  switch (functionType) {
414  case URANDOM:
415  OPENGM_ASSERT(functionParameter.size() == 2);
416  OPENGM_ASSERT(functionParameter[0] <= functionParameter[1]);
417  for(size_t i = 0; i < gm.numberOfVariables(); ++i) {
418  shape[0] = gm.numberOfLabels(i);
419  var[0] = i;
420  if(!sharedFunction|| i == 0) {
421  ExplicitFunctionType function(shape, shape + 1);
422  for(size_t ni = 0; ni < shape[0]; ++ni) {
423  function(ni) = functionParameter[0] + (functionParameter[1] - functionParameter[0]) * (rand() % 1000000) * 0.000001;
424  }
425  funcId = gm.addFunction(function);
426  }
427  gm.addFactor(funcId, var, var + 1);
428  }
429  break;
430  case IRANDOM:
431  OPENGM_ASSERT(functionParameter.size() == 2);
432  OPENGM_ASSERT(functionParameter[0] <= functionParameter[1]);
433  for(size_t i = 0; i < gm.numberOfVariables(); ++i) {
434  shape[0] = gm.numberOfLabels(i);
435  var[0] = i;
436  if(!sharedFunction || i == 0) {
437  ExplicitFunctionType function(shape, shape + 1);
438  for(size_t ni = 0; ni < shape[0]; ++ni) {
439  function(ni) = functionParameter[0] + rand() % (size_t) (functionParameter[1] - functionParameter[0]);
440  }
441  funcId = gm.addFunction(function);
442  }
443  gm.addFactor(funcId, var, var + 1);
444  }
445  break;
446  case EMPTY:
447  // do nothing
448  break;
449  case CONSTF:
450  OPENGM_ASSERT(functionParameter.size() == 1);
451  for(typename GM::IndexType i = 0; i < gm.numberOfVariables(); ++i) {
452  shape[0] = gm.numberOfLabels(i);
453  var[0] = i;
454  if(!sharedFunction || i == 0) {
455  ExplicitFunctionType function(shape, shape + 1);
456  for(typename GM::LabelType ni = 0; ni < shape[0]; ++ni) {
457  function(ni) = functionParameter[0];
458  }
459  funcId = gm.addFunction(function);
460  }
461  gm.addFactor(funcId, var, var + 1);
462  }
463  break;
464  default:
465  throw RuntimeError("Unknown function type for unary factors.");
466  }
467  }
468 
469  template<class GM>
470  template<class ITERATOR>
471  typename GM::FunctionIdentifier SyntheticModelGenerator2<GM>::addFunction
472  (
473  GM& gm,
474  const FunctionTypes functionType,
475  const std::vector<ValueType>& functionParameter,
476  ITERATOR shapeBegin, ITERATOR shapeEnd
477  ) const
478  {
479  switch (functionType) {
480  case URANDOM:
481  {
482  OPENGM_ASSERT(functionParameter.size() == 2);
483  OPENGM_ASSERT(functionParameter[0] <= functionParameter[1]);
484  ExplicitFunctionType function(shapeBegin, shapeEnd);
485  for(typename GM::LabelType ni = 0; ni < shapeBegin[0]; ++ni) {
486  for(typename GM::LabelType nj = 0; nj < shapeBegin[1]; ++nj) {
487  function(ni, nj) = functionParameter[0] + (functionParameter[1] - functionParameter[0]) * (rand() % 1000000) * 0.000001;
488  }
489  }
490  return gm.addFunction(function);
491  }
492  case IRANDOM:
493  {
494  OPENGM_ASSERT(functionParameter.size() == 2);
495  OPENGM_ASSERT(functionParameter[0] <= functionParameter[1]);
496  ExplicitFunctionType function(shapeBegin, shapeEnd);
497  for(typename GM::LabelType ni = 0; ni < shapeBegin[0]; ++ni) {
498  for(typename GM::LabelType nj = 0; nj < shapeBegin[1]; ++nj) {
499  function(ni, nj) = functionParameter[0] + rand() % (size_t) (functionParameter[0] - functionParameter[1]);
500  }
501  }
502  return gm.addFunction(function);
503  }
504  case GPOTTS:
505  {
506  OPENGM_ASSERT(functionParameter.size() == 1);
507  ExplicitFunctionType function(shapeBegin, shapeEnd, functionParameter[0]);
508  for(typename GM::LabelType ni = 0; ni < shapeBegin[0]; ++ni) {
509  for(typename GM::LabelType nj = 0; nj < shapeBegin[1]; ++nj) {
510  if(ni == nj)
511  function(ni, nj) = 0;
512  }
513  }
514  return gm.addFunction(function);
515  }
516  case L1:
517  {
518  OPENGM_ASSERT(functionParameter.size() == 1);
519  ExplicitFunctionType function(shapeBegin, shapeEnd, functionParameter[0]);
520  for(typename GM::LabelType ni = 0; ni < shapeBegin[0]; ++ni) {
521  for(typename GM::LabelType nj = 0; nj < shapeBegin[1]; ++nj) {
522  function(ni, nj) = 0.1*fabs(1.0*ni-1.0*nj);
523  }
524  }
525  return gm.addFunction(function);
526  }
527  case RGPOTTS:
528  {
529  OPENGM_ASSERT(functionParameter.size() == 2);
530  OPENGM_ASSERT(functionParameter[0] <= functionParameter[1]);
531  ValueType v = functionParameter[0] + (functionParameter[1] - functionParameter[0]) * (rand() % 1000000) * 0.000001;
532  ExplicitFunctionType function(shapeBegin, shapeEnd, v);
533  for(typename GM::LabelType ni = 0; ni < shapeBegin[0]; ++ni) {
534  for(typename GM::LabelType nj = 0; nj < shapeBegin[1]; ++nj) {
535  if(ni == nj)
536  function(ni, nj) = 0;
537  }
538  }
539  return gm.addFunction(function);
540  }
541  case RPOTTS:
542  {
543  OPENGM_ASSERT(functionParameter.size() == 1);
544  ValueType v = functionParameter[0] * (1.0 - 2.0*(rand() % 1000) * 0.001);
545  ExplicitFunctionType function(shapeBegin, shapeEnd, v);
546  for(typename GM::LabelType ni = 0; ni < shapeBegin[0]; ++ni) {
547  for(typename GM::LabelType nj = 0; nj < shapeBegin[1]; ++nj) {
548  if(ni == nj)
549  function(ni, nj) = 0;
550  }
551  }
552  return gm.addFunction(function);
553  }
554  case CONSTF:
555  {
556  OPENGM_ASSERT(functionParameter.size() == 1);
557  ExplicitFunctionType function(shapeBegin, shapeEnd, functionParameter[0]);
558  return gm.addFunction(function);
559  }
560  default:
561  throw RuntimeError("Unknown function type for unary factors.");
562  }
563  }
564 
565  template<class GM>
566  GM SyntheticModelGenerator2<GM>::buildGrid
567  (
568  const size_t id,
569  const size_t height, const size_t width,
570  const size_t numStates,
571  const Parameter& parameter
572  ) const
573  {
574  srand(id);
575  OPENGM_ASSERT(parameter.isConsistent());
576  OPENGM_ASSERT(parameter.functionTypes_.size() == 2);
577  GraphicalModelType gm = getGM(height*width,numStates,parameter.randomNumberOfStates_);
578  // UNARY
579  addUnaries(gm, parameter.functionTypes_[0], parameter.functionParameters_[0], parameter.sharedFunctions_[0] && !parameter.randomNumberOfStates_);
580  // PAIRWISE
581  typename GM::LabelType shape[2];
582  typename GM::IndexType var[2];
583  bool newFunction = true;
584  FunctionIdentifier funcId;
585  for(size_t i = 0; i < height; ++i) {
586  for(size_t j = 0; j < width; ++j) {
587  size_t v = i + height * j;
588  if(i + 1 < height) {
589  var[0] = v;
590  var[1] = i + 1 + height * j;
591  shape[0] = gm.numberOfLabels(var[0]);
592  shape[1] = gm.numberOfLabels(var[1]);
593  if(newFunction) {
594  funcId = addFunction(gm, parameter.functionTypes_[1], parameter.functionParameters_[1], shape, shape + 2);
595  }
596  newFunction = !parameter.sharedFunctions_[1] || parameter.randomNumberOfStates_;
597  gm.addFactor(funcId, var, var + 2);
598  }
599  if(j + 1 < width) {
600  var[0] = v;
601  var[1] = i + height * (j + 1);
602  shape[0] = gm.numberOfLabels(var[0]);
603  shape[1] = gm.numberOfLabels(var[1]);
604  if(newFunction) {
605  funcId = addFunction(gm, parameter.functionTypes_[1], parameter.functionParameters_[1], shape, shape + 2);
606  }
607  newFunction = !parameter.sharedFunctions_[1] || parameter.randomNumberOfStates_;
608  gm.addFactor(funcId, var, var + 2);
609  }
610  }
611  }
612  return gm;
613  }
614 
615  template<class GM>
616  GM SyntheticModelGenerator2<GM>::buildHigherOrderGrid(
617  const size_t id,
618  const size_t height, const size_t width,
619  const size_t numStates, const size_t order,
620  const Parameter& parameter) const {
621  srand(id);
622  OPENGM_ASSERT(parameter.isConsistent());
623  OPENGM_ASSERT(parameter.functionTypes_.size() == 2);
624  OPENGM_ASSERT(order >= 2);
625  OPENGM_ASSERT(order <= height);
626  OPENGM_ASSERT(order <= width);
627 
628  GraphicalModelType gm = getGM(height*width,numStates,parameter.randomNumberOfStates_);
629 
630  // add unaries
631  addUnaries(gm, parameter.functionTypes_[0], parameter.functionParameters_[0], parameter.sharedFunctions_[0] && !parameter.randomNumberOfStates_);
632 
633  // add higher order factors
634  typename GM::LabelType shape[order];
635  typename GM::IndexType var[order];
636  bool newFunction = true;
637  FunctionIdentifier funcId;
638  for(size_t i = 0; i < height - order + 1; ++i) {
639  for(size_t j = 0; j < width - order + 1; ++j) {
640  size_t v = i + height * j;
641  if(i + 1 < height) {
642  var[0] = v;
643  var[1] = i + 1 + height * j;
644  shape[0] = gm.numberOfLabels(var[0]);
645  shape[1] = gm.numberOfLabels(var[1]);
646  if(newFunction) {
647  funcId = addFunction(gm, parameter.functionTypes_[1], parameter.functionParameters_[1], shape, shape + 2);
648  }
649  newFunction = !parameter.sharedFunctions_[1] || parameter.randomNumberOfStates_;
650  gm.addFactor(funcId, var, var + 2);
651  }
652  if(j + 1 < width) {
653  var[0] = v;
654  var[1] = i + height * (j + 1);
655  shape[0] = gm.numberOfLabels(var[0]);
656  shape[1] = gm.numberOfLabels(var[1]);
657  if(newFunction) {
658  funcId = addFunction(gm, parameter.functionTypes_[1], parameter.functionParameters_[1], shape, shape + 2);
659  }
660  newFunction = !parameter.sharedFunctions_[1] || parameter.randomNumberOfStates_;
661  gm.addFactor(funcId, var, var + 2);
662  }
663  }
664  }
665  return gm;
666 
667  }
668 
669  template<class GM>
670  GM SyntheticModelGenerator2<GM>::buildFull
671  (
672  const size_t id,
673  const size_t numVars,
674  const size_t numStates,
675  const Parameter& parameter
676  ) const
677  {
678  srand(id);
679  OPENGM_ASSERT(parameter.isConsistent());
680  OPENGM_ASSERT(parameter.functionTypes_.size() == 2);
681  GraphicalModelType gm = getGM(numVars,numStates,parameter.randomNumberOfStates_);
682  //UNARY
683  addUnaries(gm, parameter.functionTypes_[0], parameter.functionParameters_[0], parameter.sharedFunctions_[0]&& !parameter.randomNumberOfStates_);
684  //PAIRWISE
685  typename GM::LabelType shape[2];
686  typename GM::IndexType var[2];
687  bool newFunction = true;
688  FunctionIdentifier funcId;
689  for(typename GM::IndexType i = 0; i < numVars; ++i) {
690  for(typename GM::IndexType j = i + 1; j < numVars; ++j) {
691  var[0] = i;
692  var[1] = j;
693  shape[0] = gm.numberOfLabels(var[0]);
694  shape[1] = gm.numberOfLabels(var[1]);
695  if(newFunction) {
696  funcId = addFunction(gm, parameter.functionTypes_[1], parameter.functionParameters_[1], shape, shape + 2);
697  }
698  newFunction = !parameter.sharedFunctions_[1] || parameter.randomNumberOfStates_;
699  gm.addFactor(funcId, var, var + 2);
700  }
701  }
702  return gm;
703  }
704 
705  template<class GM>
706  GM SyntheticModelGenerator2<GM>::buildStar
707  (
708  const size_t id,
709  const size_t numVars,
710  const size_t numStates,
711  const Parameter& parameter
712  ) const
713  {
714  srand(id);
715  OPENGM_ASSERT(parameter.isConsistent());
716  OPENGM_ASSERT(parameter.functionTypes_.size() == 2);
717  GraphicalModelType gm = getGM(numVars,numStates,parameter.randomNumberOfStates_);
718  // UNARY
719  addUnaries(gm, parameter.functionTypes_[0], parameter.functionParameters_[0], parameter.sharedFunctions_[0]&& !parameter.randomNumberOfStates_);
720  // PAIRWISE
721  typename GM::LabelType shape[2];
722  typename GM::IndexType var[2];
723  bool newFunction = true;
724  FunctionIdentifier funcId;
725  const size_t root = (rand() % gm.numberOfVariables());
726  for(size_t i = 0; i < root; ++i) {
727  var[0] = i;
728  var[1] = root;
729  shape[0] = gm.numberOfLabels(var[0]);
730  shape[1] = gm.numberOfLabels(var[1]);
731  if(newFunction) {
732  funcId = addFunction(gm, parameter.functionTypes_[1], parameter.functionParameters_[1], shape, shape + 2);
733  }
734  newFunction = !parameter.sharedFunctions_[1] || parameter.randomNumberOfStates_;
735  gm.addFactor(funcId, var, var + 2);
736  }
737  for(size_t i = root + 1; i < gm.numberOfVariables(); ++i) {
738  var[0] = root;
739  var[1] = i;
740  shape[0] = gm.numberOfLabels(var[0]);
741  shape[1] = gm.numberOfLabels(var[1]);
742  if(newFunction) {
743  funcId = addFunction(gm, parameter.functionTypes_[1], parameter.functionParameters_[1], shape, shape + 2);
744  }
745  newFunction = !parameter.sharedFunctions_[1] || parameter.randomNumberOfStates_;
746  gm.addFactor(funcId, var, var + 2);
747  }
748  return gm;
749  }
750 
751 } // namespace opengm
752 
754 
755 #endif // #ifndef OPENGM_SYNTHETIC_MODEL_GENERATOR2_HXX
Constant function.
Definition: constant.hxx:19
The OpenGM namespace.
Definition: config.hxx:43
Discrete space in which variables can have differently many labels.
Absolute difference between two labels.
#define OPENGM_ASSERT(expression)
Definition: opengm.hxx:77
Potts function for two variables.
Definition: potts.hxx:19