00001 #pragma once
00002 #ifndef OPENGM_SYNTHETIC_MODEL_GENERATOR2_HXX
00003 #define OPENGM_SYNTHETIC_MODEL_GENERATOR2_HXX
00004
00006
00007 #include <cstdlib>
00008 #include <vector>
00009 #include <cstdlib>
00010 #include <set>
00011 #include <functional>
00012
00013 #include <opengm/graphicalmodel/graphicalmodel.hxx>
00014
00015 namespace opengm {
00016
00017 template<class GM>
00018 class SyntheticModelGenerator2
00019 {
00020 public:
00021 typedef GM GraphicalModelType;
00022 typedef typename GM::ValueType ValueType;
00023 typedef typename GM::IndexType IndexType;
00024 typedef typename GM::LabelType LabelType;
00025 typedef opengm::ExplicitFunction<ValueType,IndexType,LabelType> ExplicitFunctionType;
00026
00027
00028 typedef typename GM::FunctionIdentifier FunctionIdentifier;
00029 typedef typename GM::OperatorType OperatorType;
00030
00031 enum FunctionTypes
00032 {
00033 EMPTY, CONSTF, URANDOM, IRANDOM, GPOTTS, RGPOTTS, L1
00034 };
00035
00036 class Parameter
00037 {
00038 public:
00039 std::vector<FunctionTypes> functionTypes_;
00040 std::vector<std::vector<ValueType> > functionParameters_;
00041 std::vector<bool> sharedFunctions_;
00042 bool randomNumberOfStates_;
00043
00044 Parameter()
00045 {
00046 functionTypes_.resize(2, URANDOM);
00047 functionParameters_.resize(2);
00048 functionParameters_[0].resize(2);
00049 functionParameters_[0][0] = 0;
00050 functionParameters_[0][1] = 1;
00051 functionParameters_[1].resize(2);
00052 functionParameters_[1][0] = 0;
00053 functionParameters_[1][1] = 1;
00054 sharedFunctions_.resize(2, true);
00055 randomNumberOfStates_ = false;
00056 }
00057
00058 bool isConsistent() const
00059 {
00060 return functionTypes_.size() == functionParameters_.size() &&
00061 functionParameters_.size() == sharedFunctions_.size();
00062 }
00063 };
00064
00065 SyntheticModelGenerator2();
00066 GM buildGrid(const size_t, const size_t, const size_t, const size_t, const Parameter&) const;
00067 GM buildFull(const size_t, const size_t, const size_t, const Parameter&) const;
00068 GM buildStar(const size_t, const size_t, const size_t, const Parameter&) const;
00069
00070 private:
00071 void addUnaries(GM&, const FunctionTypes, const std::vector<ValueType>&, const bool) const;
00072 template<class ITERATOR>
00073 FunctionIdentifier addFunction(GM&, const FunctionTypes, const std::vector<ValueType>&, ITERATOR, ITERATOR) const;
00074 GraphicalModelType getGM(size_t,size_t,bool) const;
00075 };
00076
00077 template<class GM>
00078 SyntheticModelGenerator2<GM>::SyntheticModelGenerator2()
00079 {}
00080
00081 template<class GM>
00082 GM SyntheticModelGenerator2<GM>::getGM(size_t numVar, size_t numStates, bool randomNumberOfStates) const
00083 {
00084 std::vector<typename GM::LabelType> numberOfLabels(numVar,numStates);
00085 return GM( opengm::DiscreteSpace<typename GM::IndexType,typename GM::LabelType>(numberOfLabels.begin(), numberOfLabels.end()));
00086 }
00087
00088 template<class GM>
00089 void SyntheticModelGenerator2<GM>::addUnaries
00090 (
00091 GM& gm,
00092 const FunctionTypes functionType,
00093 const std::vector<ValueType>& functionParameter,
00094 const bool sharedFunction
00095 ) const
00096 {
00097 typename GM::LabelType shape[1];
00098 typename GM::IndexType var[] = {0};
00099 FunctionIdentifier funcId;
00100 switch (functionType) {
00101 case URANDOM:
00102 OPENGM_ASSERT(functionParameter.size() == 2);
00103 OPENGM_ASSERT(functionParameter[0] <= functionParameter[1]);
00104 for(size_t i = 0; i < gm.numberOfVariables(); ++i) {
00105 shape[0] = gm.numberOfLabels(i);
00106 var[0] = i;
00107 if(!sharedFunction|| i == 0) {
00108 ExplicitFunctionType function(shape, shape + 1);
00109 for(size_t ni = 0; ni < shape[0]; ++ni) {
00110 function(ni) = functionParameter[0] + (functionParameter[1] - functionParameter[0]) * (rand() % 1000000) * 0.000001;
00111 }
00112 funcId = gm.addFunction(function);
00113 }
00114 gm.addFactor(funcId, var, var + 1);
00115 }
00116 break;
00117 case IRANDOM:
00118 OPENGM_ASSERT(functionParameter.size() == 2);
00119 OPENGM_ASSERT(functionParameter[0] <= functionParameter[1]);
00120 for(size_t i = 0; i < gm.numberOfVariables(); ++i) {
00121 shape[0] = gm.numberOfLabels(i);
00122 var[0] = i;
00123 if(!sharedFunction || i == 0) {
00124 ExplicitFunctionType function(shape, shape + 1);
00125 for(size_t ni = 0; ni < shape[0]; ++ni) {
00126 function(ni) = functionParameter[0] + rand() % (size_t) (functionParameter[1] - functionParameter[0]);
00127 }
00128 funcId = gm.addFunction(function);
00129 }
00130 gm.addFactor(funcId, var, var + 1);
00131 }
00132 break;
00133 case EMPTY:
00134
00135 break;
00136 case CONSTF:
00137 OPENGM_ASSERT(functionParameter.size() == 1);
00138 for(typename GM::IndexType i = 0; i < gm.numberOfVariables(); ++i) {
00139 shape[0] = gm.numberOfLabels(i);
00140 var[0] = i;
00141 if(!sharedFunction || i == 0) {
00142 ExplicitFunctionType function(shape, shape + 1);
00143 for(typename GM::LabelType ni = 0; ni < shape[0]; ++ni) {
00144 function(ni) = functionParameter[0];
00145 }
00146 funcId = gm.addFunction(function);
00147 }
00148 gm.addFactor(funcId, var, var + 1);
00149 }
00150 break;
00151 default:
00152 throw RuntimeError("Unknown function type for unary factors.");
00153 }
00154 }
00155
00156 template<class GM>
00157 template<class ITERATOR>
00158 typename GM::FunctionIdentifier SyntheticModelGenerator2<GM>::addFunction
00159 (
00160 GM& gm,
00161 const FunctionTypes functionType,
00162 const std::vector<ValueType>& functionParameter,
00163 ITERATOR shapeBegin, ITERATOR shapeEnd
00164 ) const
00165 {
00166 switch (functionType) {
00167 case URANDOM:
00168 {
00169 OPENGM_ASSERT(functionParameter.size() == 2);
00170 OPENGM_ASSERT(functionParameter[0] <= functionParameter[1]);
00171 ExplicitFunctionType function(shapeBegin, shapeEnd);
00172 for(typename GM::LabelType ni = 0; ni < shapeBegin[0]; ++ni) {
00173 for(typename GM::LabelType nj = 0; nj < shapeBegin[1]; ++nj) {
00174 function(ni, nj) = functionParameter[0] + (functionParameter[1] - functionParameter[0]) * (rand() % 1000000) * 0.000001;
00175 }
00176 }
00177 return gm.addFunction(function);
00178 }
00179 case IRANDOM:
00180 {
00181 OPENGM_ASSERT(functionParameter.size() == 2);
00182 OPENGM_ASSERT(functionParameter[0] <= functionParameter[1]);
00183 ExplicitFunctionType function(shapeBegin, shapeEnd);
00184 for(typename GM::LabelType ni = 0; ni < shapeBegin[0]; ++ni) {
00185 for(typename GM::LabelType nj = 0; nj < shapeBegin[1]; ++nj) {
00186 function(ni, nj) = functionParameter[0] + rand() % (size_t) (functionParameter[0] - functionParameter[1]);
00187 }
00188 }
00189 return gm.addFunction(function);
00190 }
00191 case GPOTTS:
00192 {
00193 OPENGM_ASSERT(functionParameter.size() == 1);
00194 ExplicitFunctionType function(shapeBegin, shapeEnd, functionParameter[0]);
00195 for(typename GM::LabelType ni = 0; ni < shapeBegin[0]; ++ni) {
00196 for(typename GM::LabelType nj = 0; nj < shapeBegin[1]; ++nj) {
00197 if(ni == nj)
00198 function(ni, nj) = 0;
00199 }
00200 }
00201 return gm.addFunction(function);
00202 }
00203 case L1:
00204 {
00205 OPENGM_ASSERT(functionParameter.size() == 1);
00206 ExplicitFunctionType function(shapeBegin, shapeEnd, functionParameter[0]);
00207 for(typename GM::LabelType ni = 0; ni < shapeBegin[0]; ++ni) {
00208 for(typename GM::LabelType nj = 0; nj < shapeBegin[1]; ++nj) {
00209 function(ni, nj) = 0.1*fabs(1.0*ni-1.0*nj);
00210 }
00211 }
00212 return gm.addFunction(function);
00213 }
00214 case RGPOTTS:
00215 {
00216 OPENGM_ASSERT(functionParameter.size() == 2);
00217 OPENGM_ASSERT(functionParameter[0] <= functionParameter[1]);
00218 ValueType v = functionParameter[0] + (functionParameter[1] - functionParameter[0]) * (rand() % 1000000) * 0.000001;
00219 ExplicitFunctionType function(shapeBegin, shapeEnd, v);
00220 for(typename GM::LabelType ni = 0; ni < shapeBegin[0]; ++ni) {
00221 for(typename GM::LabelType nj = 0; nj < shapeBegin[1]; ++nj) {
00222 if(ni == nj)
00223 function(ni, nj) = 0;
00224 }
00225 }
00226 return gm.addFunction(function);
00227 }
00228 case CONSTF:
00229 {
00230 OPENGM_ASSERT(functionParameter.size() == 1);
00231 ExplicitFunctionType function(shapeBegin, shapeEnd, functionParameter[0]);
00232 return gm.addFunction(function);
00233 }
00234 default:
00235 throw RuntimeError("Unknown function type for unary factors.");
00236 }
00237 }
00238
00239 template<class GM>
00240 GM SyntheticModelGenerator2<GM>::buildGrid
00241 (
00242 const size_t id,
00243 const size_t height, const size_t width,
00244 const size_t numStates,
00245 const Parameter& parameter
00246 ) const
00247 {
00248 srand(id);
00249 OPENGM_ASSERT(parameter.isConsistent());
00250 OPENGM_ASSERT(parameter.functionTypes_.size() == 2);
00251 GraphicalModelType gm = getGM(height*width,numStates,parameter.randomNumberOfStates_);
00252
00253 addUnaries(gm, parameter.functionTypes_[0], parameter.functionParameters_[0], parameter.sharedFunctions_[0] && !parameter.randomNumberOfStates_);
00254
00255 typename GM::LabelType shape[2];
00256 typename GM::IndexType var[2];
00257 bool newFunction = true;
00258 FunctionIdentifier funcId;
00259 for(size_t i = 0; i < height; ++i) {
00260 for(size_t j = 0; j < width; ++j) {
00261 size_t v = i + height * j;
00262 if(i + 1 < height) {
00263 var[0] = v;
00264 var[1] = i + 1 + height * j;
00265 shape[0] = gm.numberOfLabels(var[0]);
00266 shape[1] = gm.numberOfLabels(var[1]);
00267 if(newFunction) {
00268 funcId = addFunction(gm, parameter.functionTypes_[1], parameter.functionParameters_[1], shape, shape + 2);
00269 }
00270 newFunction = !parameter.sharedFunctions_[1] || parameter.randomNumberOfStates_;
00271 gm.addFactor(funcId, var, var + 2);
00272 }
00273 if(j + 1 < width) {
00274 var[0] = v;
00275 var[1] = i + height * (j + 1);
00276 shape[0] = gm.numberOfLabels(var[0]);
00277 shape[1] = gm.numberOfLabels(var[1]);
00278 if(newFunction) {
00279 funcId = addFunction(gm, parameter.functionTypes_[1], parameter.functionParameters_[1], shape, shape + 2);
00280 }
00281 newFunction = !parameter.sharedFunctions_[1] || parameter.randomNumberOfStates_;
00282 gm.addFactor(funcId, var, var + 2);
00283 }
00284 }
00285 }
00286 return gm;
00287 }
00288
00289 template<class GM>
00290 GM SyntheticModelGenerator2<GM>::buildFull
00291 (
00292 const size_t id,
00293 const size_t numVars,
00294 const size_t numStates,
00295 const Parameter& parameter
00296 ) const
00297 {
00298 srand(id);
00299 OPENGM_ASSERT(parameter.isConsistent());
00300 OPENGM_ASSERT(parameter.functionTypes_.size() == 2);
00301 GraphicalModelType gm = getGM(numVars,numStates,parameter.randomNumberOfStates_);
00302
00303 addUnaries(gm, parameter.functionTypes_[0], parameter.functionParameters_[0], parameter.sharedFunctions_[0]&& !parameter.randomNumberOfStates_);
00304
00305 typename GM::LabelType shape[2];
00306 typename GM::IndexType var[2];
00307 bool newFunction = true;
00308 FunctionIdentifier funcId;
00309 for(typename GM::IndexType i = 0; i < numVars; ++i) {
00310 for(typename GM::IndexType j = i + 1; j < numVars; ++j) {
00311 var[0] = i;
00312 var[1] = j;
00313 shape[0] = gm.numberOfLabels(var[0]);
00314 shape[1] = gm.numberOfLabels(var[1]);
00315 if(newFunction) {
00316 funcId = addFunction(gm, parameter.functionTypes_[1], parameter.functionParameters_[1], shape, shape + 2);
00317 }
00318 newFunction = !parameter.sharedFunctions_[1] || parameter.randomNumberOfStates_;
00319 gm.addFactor(funcId, var, var + 2);
00320 }
00321 }
00322 return gm;
00323 }
00324
00325 template<class GM>
00326 GM SyntheticModelGenerator2<GM>::buildStar
00327 (
00328 const size_t id,
00329 const size_t numVars,
00330 const size_t numStates,
00331 const Parameter& parameter
00332 ) const
00333 {
00334 srand(id);
00335 OPENGM_ASSERT(parameter.isConsistent());
00336 OPENGM_ASSERT(parameter.functionTypes_.size() == 2);
00337 GraphicalModelType gm = getGM(numVars,numStates,parameter.randomNumberOfStates_);
00338
00339 addUnaries(gm, parameter.functionTypes_[0], parameter.functionParameters_[0], parameter.sharedFunctions_[0]&& !parameter.randomNumberOfStates_);
00340
00341 typename GM::LabelType shape[2];
00342 typename GM::IndexType var[2];
00343 bool newFunction = true;
00344 FunctionIdentifier funcId;
00345 const size_t root = (rand() % gm.numberOfVariables());
00346 for(size_t i = 0; i < root; ++i) {
00347 var[0] = i;
00348 var[1] = root;
00349 shape[0] = gm.numberOfLabels(var[0]);
00350 shape[1] = gm.numberOfLabels(var[1]);
00351 if(newFunction) {
00352 funcId = addFunction(gm, parameter.functionTypes_[1], parameter.functionParameters_[1], shape, shape + 2);
00353 }
00354 newFunction = !parameter.sharedFunctions_[1] || parameter.randomNumberOfStates_;
00355 gm.addFactor(funcId, var, var + 2);
00356 }
00357 for(size_t i = root + 1; i < gm.numberOfVariables(); ++i) {
00358 var[0] = root;
00359 var[1] = i;
00360 shape[0] = gm.numberOfLabels(var[0]);
00361 shape[1] = gm.numberOfLabels(var[1]);
00362 if(newFunction) {
00363 funcId = addFunction(gm, parameter.functionTypes_[1], parameter.functionParameters_[1], shape, shape + 2);
00364 }
00365 newFunction = !parameter.sharedFunctions_[1] || parameter.randomNumberOfStates_;
00366 gm.addFactor(funcId, var, var + 2);
00367 }
00368 return gm;
00369 }
00370
00371 }
00372
00374
00375 #endif // #ifndef OPENGM_SYNTHETIC_MODEL_GENERATOR2_HXX
00376