28 #ifndef OPENGM_UTILITIES_CANONICAL_FACTORS_HXX
29 #define OPENGM_UTILITIES_CANONICAL_FACTORS_HXX
43 namespace canonical_view {
66 namespace canonical_view_internal {
73 typedef typename GM::ValueType ValType;
74 typedef typename GM::IndexType IndType;
75 typedef typename GM::LabelType LabType;
76 typedef typename GM::FunctionTypeList OldTypeList;
80 typedef ConstantFunction<ValType, IndType, LabType> ConstFunType;
81 typedef AccumulatedViewFunction<GM> AccViewType;
82 typedef typename meta::TypeListGenerator<ConstFunType, AccViewType>::type NewTypeList;
85 typedef GraphicalModel<
86 typename GM::ValueType,
87 typename GM::OperatorType,
88 typename meta::MergeTypeListsWithoutDups<OldTypeList, NewTypeList>::type,
89 typename GM::SpaceType
95 template<
class GM, canonical_view::CloneOption CLONE>
99 struct CloneHelper<GM, canonical_view::
CloneNever> {
101 static const FUNC& handleInjected(
const FUNC &func) {
return func; }
104 static const FUNC& handleView(
const FUNC &func) {
return func; }
108 struct CloneHelper<GM, canonical_view::
CloneViews> {
110 static const FUNC& handleInjected(
const FUNC &func) {
return func; }
113 static typename GM::ExplFuncType handleView(
const FUNC &func)
115 typename GM::ExplFuncType result;
122 struct CloneHelper<GM, canonical_view::
CloneDeep> {
124 static typename GM::ExplFuncType handleInjected(
const FUNC &func)
126 typename GM::ExplFuncType result;
132 static typename GM::ExplFuncType handleView(
const FUNC &func)
134 typename GM::ExplFuncType result;
144 template<
class GM, canonical_view::CloneOption CLONE>
145 class FunctionInjectionFunctor {
147 FunctionInjectionFunctor(GM &gm)
152 template<
class FUNCTION>
153 void operator()(FUNCTION &func)
155 result_ = gm_->addFunction(CloneHelper<GM, CLONE>::handleInjected(func));
158 typename GM::FunctionIdentifier result()
const
165 typename GM::FunctionIdentifier result_;
171 template<
class WRAPPER,
class WRAPPED, canonical_view::CloneOption CLONE>
172 class FunctionInjector {
182 typename WRAPPER::FunctionIdentifier
185 const typename WRAPPED::FactorType &factor
188 typename WRAPPED::FunctionIdentifier id(factor.functionIndex(), factor.functionType());
190 typename MapType::const_iterator it = map_.find(
id);
191 if (it != map_.end())
194 FunctionInjectionFunctor<WRAPPER, CLONE> injector(*gm_);
195 factor.callFunctor(injector);
196 typename WRAPPER::FunctionIdentifier result = injector.result();
203 typename WRAPPED::FunctionIdentifier,
204 typename WRAPPER::FunctionIdentifier
226 template<
class GM, canonical_view::CloneOption CLONE = canonical_view::CloneNever>
229 typedef typename canonical_view_internal::Generator<GM>::type
Parent;
248 typedef std::vector<IndexType> Variables;
249 typedef std::vector<const typename GM::FactorType*> Factors;
250 typedef std::vector<Factors> UnaryFactors;
251 typedef std::map<Variables, Factors> FactorMap;
252 typedef std::map<FunctionIdentifier, typename GM::FunctionIdentifier> FunctionMap;
254 FunctionInjectorType injector(*
this);
255 UnaryFactors unaryFactors(gm.numberOfVariables());
256 FactorMap otherFactors;
262 for (IndexType i = 0; i < gm.numberOfFactors(); ++i) {
263 const typename GM::FactorType &f = gm[i];
264 if (f.numberOfVariables() == 1) {
265 unaryFactors[f.variableIndex(0)].push_back(&f);
267 std::vector<IndexType> vars(f.variableIndicesBegin(), f.variableIndicesEnd());
268 otherFactors[vars].push_back(&f);
274 for (IndexType i = 0; i < gm.numberOfVariables(); ++i) {
275 FunctionIdentifier fid;
276 IndexType vars[1] = { i };
279 switch (unaryFactors[i].size()) {
281 LabelType shape[1] = { gm.numberOfLabels(i) };
282 ConstFuncType func(shape, shape+1, 0);
283 fid = this->addFunction(func);
287 fid = injector.inject(*unaryFactors[i][0]);
291 ViewFuncType func(unaryFactors[i].begin(), unaryFactors[i].end());
292 fid = this->addFunction(CloneHelperType::handleView(func));
297 this->addFactor(fid, vars, vars+1);
301 for (
typename FactorMap::const_iterator it = otherFactors.begin(); it != otherFactors.end(); ++it) {
302 const Variables &vars= it ->first;
303 const Factors &factors = it->second;
304 FunctionIdentifier fid;
307 if (factors.size() == 1) {
309 fid = injector.inject(*factors[0]);
312 ViewFuncType func(it->second.begin(), it->second.end());
313 fid = this->addFunction(CloneHelperType::handleView(func));
316 this->addFactor(fid, vars.begin(), vars.end());
Parent::IndexType IndexType
ExplicitFunction< T, I, L > cloneAsExplicitFunction(const FUNC &function)
AccumulatedViewFunction< GM > ViewFuncType
canonical_view_internal::Generator< GM >::type Parent
CloneOption
Controls cloning behavior of a CanonicalView.
Parent::ValueType ValueType
#define OPENGM_ASSERT_OP(a, op, b)
runtime assertion
CanonicalView(const GM &gm)
ExplicitFunction< ValueType, IndexType, LabelType > ExplFuncType
ConstantFunction< ValueType, IndexType, LabelType > ConstFuncType
Parent::LabelType LabelType
canonical_view_internal::CloneHelper< MyType, CLONE > CloneHelperType
CanonicalView< GM, CLONE > MyType
Parent::FunctionIdentifier FunctionIdentifier
canonical_view_internal::FunctionInjector< MyType, GM, CLONE > FunctionInjectorType
Canonical view of an arbitrary GraphicalModel.