2 #ifndef OPENGM_SYNTHETIC_MODEL_GENERATOR2_HXX
3 #define OPENGM_SYNTHETIC_MODEL_GENERATOR2_HXX
21 class SyntheticModelGenerator {
24 typedef GM GraphicalModelType;
25 typedef typename GM::ValueType ValueType;
26 typedef typename GM::IndexType IndexType;
29 typedef typename GM::FunctionIdentifier FunctionIdentifier;
36 typedef RandomUniform<double> URandomGenerator;
37 typedef RandomUniform<int> IRandomGenerator;
41 enum FunctionTypes {CONSTF, URANDOM, IRANDOM, POTTS, L1};
42 typedef std::pair<ValueType, ValueType> MinMax;
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_;
54 Parameter(
const LabelType maxNumberOfStatesIn = 2,
const bool randomNumberOfStatesIn =
false);
57 bool sanityCheck()
const;
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);
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);
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_() {
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());
90 inline typename SyntheticModelGenerator<GM>::GraphicalModelType SyntheticModelGenerator<GM>::buildGrid(
const size_t id,
const IndexType width,
const IndexType height,
const Parameter& parameter) {
93 URandomGenerator uniformRandomGenerator(0.0, 1.0,
id);
94 IRandomGenerator integerRandomGenerator(0, 1,
id);
98 GraphicalModelType gm = initGM(width * height, integerRandomGenerator, parameter);
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;
106 bool newFunction =
true;
108 for(
size_t i = 0; i < parameter.functionsType_.size(); ++i) {
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);
119 if(parameter.randomNumberOfStates_) {
120 shape.resize(parameter.functionsOrder_[i]);
122 shape.resize(parameter.functionsOrder_[i], parameter.maxNumberOfStates_);
126 variables.resize(parameter.functionsOrder_[i]);
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)) {
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);
137 variables[l] = variableOffset + l;
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()) {
144 functionId = position->second;
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;
162 gm.addFactor(functionId, variables.begin(), variables.end());
165 if((height >= parameter.functionsOrder_[i]) && (k < height - parameter.functionsOrder_[i] + 1) && (parameter.functionsOrder_[i] > 1)) {
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));
172 variables[l] = variableOffset + (l * width);
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()) {
179 functionId = position->second;
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;
197 gm.addFactor(functionId, variables.begin(), variables.end());
203 if(parameter.sharedFunctions_[i]) {
204 sharedFunctionMap.clear();
212 inline typename SyntheticModelGenerator<GM>::GraphicalModelType SyntheticModelGenerator<GM>::buildFull(
const size_t id,
const IndexType numberOfVariables,
const Parameter& parameter) {
217 inline typename SyntheticModelGenerator<GM>::GraphicalModelType SyntheticModelGenerator<GM>::buildStar(
const size_t id,
const IndexType numberOfVariables,
const Parameter& parameter) {
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);
228 integerRandomGenerator.setLow(1);
229 integerRandomGenerator.setHigh(parameter.maxNumberOfStates_ + 1);
232 for(
size_t i = 0; i < numberOfVariables; i++) {
233 numberOfLabels[i] = integerRandomGenerator();
238 std::vector<typename GM::LabelType> numberOfLabels(numberOfVariables, parameter.maxNumberOfStates_);
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) {
250 ConstantFunctionType constantFunction(shapeBegin, shapeEnd, functionParameter[0]);
251 return gm.addFunction(constantFunction);
253 ConstantFunctionType constantFunction(shapeBegin, shapeEnd, uniformRandomGenerator());
254 return gm.addFunction(constantFunction);
257 case Parameter::URANDOM: {
258 ExplicitFunctionType
function(shapeBegin, shapeEnd);
259 ShapeWalker<SHAPE_ITERATOR> shapeWalker(shapeBegin,
function.dimension());
260 if(functionParameter.size() > 0) {
262 for(IndexType i = 0; i <
function.size(); ++i) {
263 function(shapeWalker.coordinateTuple().begin()) = functionParameter[i];
267 for(IndexType i = 0; i <
function.size(); ++i) {
268 function(shapeWalker.coordinateTuple().begin()) = uniformRandomGenerator();
272 return gm.addFunction(
function);
274 case Parameter::IRANDOM: {
275 ExplicitFunctionType
function(shapeBegin, shapeEnd);
276 ShapeWalker<SHAPE_ITERATOR> shapeWalker(shapeBegin,
function.dimension());
277 if(functionParameter.size() > 0) {
279 for(IndexType i = 0; i <
function.size(); ++i) {
280 function(shapeWalker.coordinateTuple().begin()) = functionParameter[i];
284 for(IndexType i = 0; i <
function.size(); ++i) {
285 function(shapeWalker.coordinateTuple().begin()) = integerRandomGenerator();
289 return gm.addFunction(
function);
291 case Parameter::POTTS: {
293 if(functionParameter.size() > 0) {
295 PottsFunctionType
function(shapeBegin[0], shapeBegin[1], functionParameter[0], functionParameter[1]);
296 return gm.addFunction(
function);
298 PottsFunctionType
function(shapeBegin[0], shapeBegin[1], uniformRandomGenerator(), uniformRandomGenerator());
299 return gm.addFunction(
function);
302 case Parameter::L1: {
304 if(functionParameter.size() > 0) {
306 AbsoluteDifferenceFunctionType
function(shapeBegin[0], shapeBegin[1], functionParameter[0]);
307 return gm.addFunction(
function);
309 AbsoluteDifferenceFunctionType
function(shapeBegin[0], shapeBegin[1], uniformRandomGenerator());
310 return gm.addFunction(
function);
314 throw RuntimeError(
"Unknown function type.");
320 class SyntheticModelGenerator2
323 typedef GM GraphicalModelType;
324 typedef typename GM::ValueType ValueType;
325 typedef typename GM::IndexType IndexType;
326 typedef typename GM::LabelType
LabelType;
330 typedef typename GM::FunctionIdentifier FunctionIdentifier;
331 typedef typename GM::OperatorType OperatorType;
335 EMPTY, CONSTF, URANDOM, IRANDOM, GPOTTS, RGPOTTS, L1, RPOTTS
341 std::vector<FunctionTypes> functionTypes_;
342 std::vector<std::vector<ValueType> > functionParameters_;
343 std::vector<bool> sharedFunctions_;
344 bool randomNumberOfStates_;
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;
360 bool isConsistent()
const
362 return functionTypes_.size() == functionParameters_.size() &&
363 functionParameters_.size() == sharedFunctions_.size();
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;
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;
381 SyntheticModelGenerator2<GM>::SyntheticModelGenerator2()
385 GM SyntheticModelGenerator2<GM>::getGM(
size_t numVar,
size_t numStates,
bool randomNumberOfStates)
const
387 if(randomNumberOfStates) {
388 std::vector<typename GM::LabelType> numberOfLabels(numVar);
390 opengm::RandomUniform<size_t> randomIntegerNumberGenerator(1,numStates + 1);
391 for(
size_t i = 0; i < numVar; i++) {
392 numberOfLabels[i] = randomIntegerNumberGenerator();
396 std::vector<typename GM::LabelType> numberOfLabels(numVar,numStates);
402 void SyntheticModelGenerator2<GM>::addUnaries
405 const FunctionTypes functionType,
406 const std::vector<ValueType>& functionParameter,
407 const bool sharedFunction
410 typename GM::LabelType shape[1];
411 typename GM::IndexType var[] = {0};
412 FunctionIdentifier funcId;
413 switch (functionType) {
417 for(
size_t i = 0; i < gm.numberOfVariables(); ++i) {
418 shape[0] = gm.numberOfLabels(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;
425 funcId = gm.addFunction(
function);
427 gm.addFactor(funcId, var, var + 1);
433 for(
size_t i = 0; i < gm.numberOfVariables(); ++i) {
434 shape[0] = gm.numberOfLabels(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]);
441 funcId = gm.addFunction(
function);
443 gm.addFactor(funcId, var, var + 1);
451 for(
typename GM::IndexType i = 0; i < gm.numberOfVariables(); ++i) {
452 shape[0] = gm.numberOfLabels(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];
459 funcId = gm.addFunction(
function);
461 gm.addFactor(funcId, var, var + 1);
465 throw RuntimeError(
"Unknown function type for unary factors.");
470 template<
class ITERATOR>
471 typename GM::FunctionIdentifier SyntheticModelGenerator2<GM>::addFunction
474 const FunctionTypes functionType,
475 const std::vector<ValueType>& functionParameter,
476 ITERATOR shapeBegin, ITERATOR shapeEnd
479 switch (functionType) {
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;
490 return gm.addFunction(
function);
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]);
502 return gm.addFunction(
function);
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) {
511 function(ni, nj) = 0;
514 return gm.addFunction(
function);
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);
525 return gm.addFunction(
function);
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) {
536 function(ni, nj) = 0;
539 return gm.addFunction(
function);
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) {
549 function(ni, nj) = 0;
552 return gm.addFunction(
function);
557 ExplicitFunctionType
function(shapeBegin, shapeEnd, functionParameter[0]);
558 return gm.addFunction(
function);
561 throw RuntimeError(
"Unknown function type for unary factors.");
566 GM SyntheticModelGenerator2<GM>::buildGrid
569 const size_t height,
const size_t width,
570 const size_t numStates,
571 const Parameter& parameter
577 GraphicalModelType gm = getGM(height*width,numStates,parameter.randomNumberOfStates_);
579 addUnaries(gm, parameter.functionTypes_[0], parameter.functionParameters_[0], parameter.sharedFunctions_[0] && !parameter.randomNumberOfStates_);
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;
590 var[1] = i + 1 + height * j;
591 shape[0] = gm.numberOfLabels(var[0]);
592 shape[1] = gm.numberOfLabels(var[1]);
594 funcId = addFunction(gm, parameter.functionTypes_[1], parameter.functionParameters_[1], shape, shape + 2);
596 newFunction = !parameter.sharedFunctions_[1] || parameter.randomNumberOfStates_;
597 gm.addFactor(funcId, var, var + 2);
601 var[1] = i + height * (j + 1);
602 shape[0] = gm.numberOfLabels(var[0]);
603 shape[1] = gm.numberOfLabels(var[1]);
605 funcId = addFunction(gm, parameter.functionTypes_[1], parameter.functionParameters_[1], shape, shape + 2);
607 newFunction = !parameter.sharedFunctions_[1] || parameter.randomNumberOfStates_;
608 gm.addFactor(funcId, var, var + 2);
616 GM SyntheticModelGenerator2<GM>::buildHigherOrderGrid(
618 const size_t height,
const size_t width,
619 const size_t numStates,
const size_t order,
620 const Parameter& parameter)
const {
628 GraphicalModelType gm = getGM(height*width,numStates,parameter.randomNumberOfStates_);
631 addUnaries(gm, parameter.functionTypes_[0], parameter.functionParameters_[0], parameter.sharedFunctions_[0] && !parameter.randomNumberOfStates_);
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;
643 var[1] = i + 1 + height * j;
644 shape[0] = gm.numberOfLabels(var[0]);
645 shape[1] = gm.numberOfLabels(var[1]);
647 funcId = addFunction(gm, parameter.functionTypes_[1], parameter.functionParameters_[1], shape, shape + 2);
649 newFunction = !parameter.sharedFunctions_[1] || parameter.randomNumberOfStates_;
650 gm.addFactor(funcId, var, var + 2);
654 var[1] = i + height * (j + 1);
655 shape[0] = gm.numberOfLabels(var[0]);
656 shape[1] = gm.numberOfLabels(var[1]);
658 funcId = addFunction(gm, parameter.functionTypes_[1], parameter.functionParameters_[1], shape, shape + 2);
660 newFunction = !parameter.sharedFunctions_[1] || parameter.randomNumberOfStates_;
661 gm.addFactor(funcId, var, var + 2);
670 GM SyntheticModelGenerator2<GM>::buildFull
673 const size_t numVars,
674 const size_t numStates,
675 const Parameter& parameter
681 GraphicalModelType gm = getGM(numVars,numStates,parameter.randomNumberOfStates_);
683 addUnaries(gm, parameter.functionTypes_[0], parameter.functionParameters_[0], parameter.sharedFunctions_[0]&& !parameter.randomNumberOfStates_);
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) {
693 shape[0] = gm.numberOfLabels(var[0]);
694 shape[1] = gm.numberOfLabels(var[1]);
696 funcId = addFunction(gm, parameter.functionTypes_[1], parameter.functionParameters_[1], shape, shape + 2);
698 newFunction = !parameter.sharedFunctions_[1] || parameter.randomNumberOfStates_;
699 gm.addFactor(funcId, var, var + 2);
706 GM SyntheticModelGenerator2<GM>::buildStar
709 const size_t numVars,
710 const size_t numStates,
711 const Parameter& parameter
717 GraphicalModelType gm = getGM(numVars,numStates,parameter.randomNumberOfStates_);
719 addUnaries(gm, parameter.functionTypes_[0], parameter.functionParameters_[0], parameter.sharedFunctions_[0]&& !parameter.randomNumberOfStates_);
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) {
729 shape[0] = gm.numberOfLabels(var[0]);
730 shape[1] = gm.numberOfLabels(var[1]);
732 funcId = addFunction(gm, parameter.functionTypes_[1], parameter.functionParameters_[1], shape, shape + 2);
734 newFunction = !parameter.sharedFunctions_[1] || parameter.randomNumberOfStates_;
735 gm.addFactor(funcId, var, var + 2);
737 for(
size_t i = root + 1; i < gm.numberOfVariables(); ++i) {
740 shape[0] = gm.numberOfLabels(var[0]);
741 shape[1] = gm.numberOfLabels(var[1]);
743 funcId = addFunction(gm, parameter.functionTypes_[1], parameter.functionParameters_[1], shape, shape + 2);
745 newFunction = !parameter.sharedFunctions_[1] || parameter.randomNumberOfStates_;
746 gm.addFactor(funcId, var, var + 2);
755 #endif // #ifndef OPENGM_SYNTHETIC_MODEL_GENERATOR2_HXX
Discrete space in which variables can have differently many labels.
Absolute difference between two labels.
#define OPENGM_ASSERT(expression)
Potts function for two variables.