1/* ----------------------------------------------------------------------------
2
3 * GTSAM Copyright 2010, Georgia Tech Research Corporation,
4 * Atlanta, Georgia 30332-0415
5 * All Rights Reserved
6 * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
7
8 * See LICENSE for the license information
9
10 * -------------------------------------------------------------------------- */
11
12/**
13 * @file Constraint.h
14 * @date May 15, 2012
15 * @author Frank Dellaert
16 */
17
18#pragma once
19
20#include <gtsam/discrete/DiscreteFactor.h>
21#include <gtsam/discrete/DiscreteValues.h>
22#include <gtsam_unstable/dllexport.h>
23
24#include <map>
25
26namespace gtsam {
27
28class Domain;
29using Domains = std::map<Key, Domain>;
30
31/**
32 * Base class for constraint factors
33 * Derived classes include SingleValue, BinaryAllDiff, and AllDiff.
34 */
35class GTSAM_UNSTABLE_EXPORT Constraint : public DiscreteFactor {
36 public:
37 typedef std::shared_ptr<Constraint> shared_ptr;
38
39 protected:
40 /// Construct unary constraint factor.
41 Constraint(Key j) : DiscreteFactor(KeyVector{j}) {}
42
43 /// Construct binary constraint factor.
44 Constraint(Key j1, Key j2) : DiscreteFactor(KeyVector{j1, j2}) {}
45
46 /// Construct n-way constraint factor.
47 Constraint(const KeyVector& js) : DiscreteFactor(js) {}
48
49 /// construct from container
50 template <class KeyIterator>
51 Constraint(KeyIterator beginKey, KeyIterator endKey)
52 : DiscreteFactor(beginKey, endKey) {}
53
54 public:
55 /// @name Standard Constructors
56 /// @{
57
58 /// Default constructor for I/O
59 Constraint();
60
61 /// Virtual destructor
62 ~Constraint() override {}
63
64 /// @}
65 /// @name Standard Interface
66 /// @{
67
68 /*
69 * Ensure Arc-consistency by checking every possible value of domain j.
70 * @param j domain to be checked
71 * @param (in/out) domains all domains, but only domains->at(j) will be
72 * checked.
73 * @return true if domains->at(j) was changed, false otherwise.
74 */
75 virtual bool ensureArcConsistency(Key j, Domains* domains) const = 0;
76
77 /// Partially apply known values
78 virtual shared_ptr partiallyApply(const DiscreteValues&) const = 0;
79
80 /// Partially apply known values, domain version
81 virtual shared_ptr partiallyApply(const Domains&) const = 0;
82
83 /// Multiply factors, DiscreteFactor::shared_ptr edition
84 DiscreteFactor::shared_ptr multiply(
85 const DiscreteFactor::shared_ptr& df) const override {
86 return std::make_shared<DecisionTreeFactor>(
87 args: this->operator*(dtf: df->toDecisionTreeFactor()));
88 }
89
90 /// Multiply by a scalar
91 virtual DiscreteFactor::shared_ptr operator*(double s) const override {
92 return this->toDecisionTreeFactor() * s;
93 }
94
95 /// Multiply by a DecisionTreeFactor and return a DecisionTreeFactor
96 DecisionTreeFactor operator*(const DecisionTreeFactor& dtf) const override {
97 return this->toDecisionTreeFactor() * dtf;
98 }
99
100 /// divide by DiscreteFactor::shared_ptr f (safely)
101 DiscreteFactor::shared_ptr operator/(
102 const DiscreteFactor::shared_ptr& df) const override {
103 return this->toDecisionTreeFactor() / df;
104 }
105
106 /// Get the number of non-zero values contained in this factor.
107 uint64_t nrValues() const override { return 1; };
108
109 DiscreteFactor::shared_ptr sum(size_t nrFrontals) const override {
110 return toDecisionTreeFactor().sum(nrFrontals);
111 }
112
113 DiscreteFactor::shared_ptr sum(const Ordering& keys) const override {
114 return toDecisionTreeFactor().sum(keys);
115 }
116
117 /// Find the max value
118 double max() const override { return toDecisionTreeFactor().max(); }
119
120 DiscreteFactor::shared_ptr max(size_t nrFrontals) const override {
121 return toDecisionTreeFactor().max(nrFrontals);
122 }
123
124 DiscreteFactor::shared_ptr max(const Ordering& keys) const override {
125 return toDecisionTreeFactor().max(keys);
126 }
127
128 /// Compute error for each assignment and return as a tree
129 AlgebraicDecisionTree<Key> errorTree() const override {
130 throw std::runtime_error("Constraint::error not implemented");
131 }
132
133 /// Compute error for each assignment and return as a tree
134 DiscreteFactor::shared_ptr restrict(
135 const DiscreteValues& assignment) const override {
136 throw std::runtime_error("Constraint::restrict not implemented");
137 }
138
139 /// @}
140 /// @name Wrapper support
141 /// @{
142
143 /// Render as markdown table.
144 std::string markdown(const KeyFormatter& keyFormatter = DefaultKeyFormatter,
145 const Names& names = {}) const override {
146 return "`Constraint` on " + std::to_string(val: size()) + " variables\n";
147 }
148
149 /// Render as html table.
150 std::string html(const KeyFormatter& keyFormatter = DefaultKeyFormatter,
151 const Names& names = {}) const override {
152 return "<p>Constraint on " + std::to_string(val: size()) + " variables</p>";
153 }
154
155 /// @}
156};
157// DiscreteFactor
158
159} // namespace gtsam
160