Use DiscreteValues everywhere

release/4.3a0
Frank Dellaert 2021-12-13 13:46:53 -05:00
parent c63c1167ba
commit e89a294376
35 changed files with 125 additions and 136 deletions

View File

@ -80,7 +80,7 @@ namespace gtsam {
/// @{
/// Value is just look up in AlgebraicDecisonTree
double operator()(const Values& values) const override {
double operator()(const DiscreteValues& values) const override {
return Potentials::operator()(values);
}

View File

@ -45,7 +45,7 @@ namespace gtsam {
}
/* ************************************************************************* */
double DiscreteBayesNet::evaluate(const DiscreteConditional::Values & values) const {
double DiscreteBayesNet::evaluate(const DiscreteValues & values) const {
// evaluate all conditionals and multiply
double result = 1.0;
for(DiscreteConditional::shared_ptr conditional: *this)
@ -54,18 +54,18 @@ namespace gtsam {
}
/* ************************************************************************* */
DiscreteFactor::Values DiscreteBayesNet::optimize() const {
DiscreteValues DiscreteBayesNet::optimize() const {
// solve each node in turn in topological sort order (parents first)
DiscreteFactor::Values result;
DiscreteValues result;
for (auto conditional: boost::adaptors::reverse(*this))
conditional->solveInPlace(&result);
return result;
}
/* ************************************************************************* */
DiscreteFactor::Values DiscreteBayesNet::sample() const {
DiscreteValues DiscreteBayesNet::sample() const {
// sample each node in turn in topological sort order (parents first)
DiscreteFactor::Values result;
DiscreteValues result;
for (auto conditional: boost::adaptors::reverse(*this))
conditional->sampleInPlace(&result);
return result;

View File

@ -77,16 +77,16 @@ namespace gtsam {
// /** Add a DiscreteCondtional in front, when listing parents first*/
// GTSAM_EXPORT void add_front(const Signature& s);
//** evaluate for given Values */
double evaluate(const DiscreteConditional::Values & values) const;
//** evaluate for given DiscreteValues */
double evaluate(const DiscreteValues & values) const;
/**
* Solve the DiscreteBayesNet by back-substitution
*/
DiscreteFactor::Values optimize() const;
DiscreteValues optimize() const;
/** Do ancestral sampling */
DiscreteFactor::Values sample() const;
DiscreteValues sample() const;
///@}

View File

@ -31,7 +31,7 @@ namespace gtsam {
/* ************************************************************************* */
double DiscreteBayesTreeClique::evaluate(
const DiscreteConditional::Values& values) const {
const DiscreteValues& values) const {
// evaluate all conditionals and multiply
double result = (*conditional_)(values);
for (const auto& child : children) {
@ -47,7 +47,7 @@ namespace gtsam {
/* ************************************************************************* */
double DiscreteBayesTree::evaluate(
const DiscreteConditional::Values& values) const {
const DiscreteValues& values) const {
double result = 1.0;
for (const auto& root : roots_) {
result *= root->evaluate(values);

View File

@ -57,8 +57,8 @@ class GTSAM_EXPORT DiscreteBayesTreeClique
conditional_->printSignature(s, formatter);
}
//** evaluate conditional probability of subtree for given Values */
double evaluate(const DiscreteConditional::Values& values) const;
//** evaluate conditional probability of subtree for given DiscreteValues */
double evaluate(const DiscreteValues& values) const;
};
/* ************************************************************************* */
@ -78,8 +78,8 @@ class GTSAM_EXPORT DiscreteBayesTree
/** Check equality */
bool equals(const This& other, double tol = 1e-9) const;
//** evaluate probability for given Values */
double evaluate(const DiscreteConditional::Values& values) const;
//** evaluate probability for given DiscreteValues */
double evaluate(const DiscreteValues& values) const;
};
} // namespace gtsam

View File

@ -97,7 +97,7 @@ bool DiscreteConditional::equals(const DiscreteFactor& other,
}
/* ******************************************************************************** */
Potentials::ADT DiscreteConditional::choose(const Values& parentsValues) const {
Potentials::ADT DiscreteConditional::choose(const DiscreteValues& parentsValues) const {
ADT pFS(*this);
Key j; size_t value;
for(Key key: parents()) {
@ -117,12 +117,12 @@ Potentials::ADT DiscreteConditional::choose(const Values& parentsValues) const {
}
/* ******************************************************************************** */
void DiscreteConditional::solveInPlace(Values* values) const {
void DiscreteConditional::solveInPlace(DiscreteValues* values) const {
// TODO: Abhijit asks: is this really the fastest way? He thinks it is.
ADT pFS = choose(*values); // P(F|S=parentsValues)
// Initialize
Values mpe;
DiscreteValues mpe;
double maxP = 0;
DiscreteKeys keys;
@ -131,10 +131,10 @@ void DiscreteConditional::solveInPlace(Values* values) const {
keys & dk;
}
// Get all Possible Configurations
vector<Values> allPosbValues = cartesianProduct(keys);
vector<DiscreteValues> allPosbValues = cartesianProduct(keys);
// Find the MPE
for(Values& frontalVals: allPosbValues) {
for(DiscreteValues& frontalVals: allPosbValues) {
double pValueS = pFS(frontalVals); // P(F=value|S=parentsValues)
// Update MPE solution if better
if (pValueS > maxP) {
@ -150,7 +150,7 @@ void DiscreteConditional::solveInPlace(Values* values) const {
}
/* ******************************************************************************** */
void DiscreteConditional::sampleInPlace(Values* values) const {
void DiscreteConditional::sampleInPlace(DiscreteValues* values) const {
assert(nrFrontals() == 1);
Key j = (firstFrontalKey());
size_t sampled = sample(*values); // Sample variable given parents
@ -158,7 +158,7 @@ void DiscreteConditional::sampleInPlace(Values* values) const {
}
/* ******************************************************************************** */
size_t DiscreteConditional::solve(const Values& parentsValues) const {
size_t DiscreteConditional::solve(const DiscreteValues& parentsValues) const {
// TODO: is this really the fastest way? I think it is.
ADT pFS = choose(parentsValues); // P(F|S=parentsValues)
@ -166,7 +166,7 @@ size_t DiscreteConditional::solve(const Values& parentsValues) const {
// Then, find the max over all remaining
// TODO, only works for one key now, seems horribly slow this way
size_t mpe = 0;
Values frontals;
DiscreteValues frontals;
double maxP = 0;
assert(nrFrontals() == 1);
Key j = (firstFrontalKey());
@ -183,7 +183,7 @@ size_t DiscreteConditional::solve(const Values& parentsValues) const {
}
/* ******************************************************************************** */
size_t DiscreteConditional::sample(const Values& parentsValues) const {
size_t DiscreteConditional::sample(const DiscreteValues& parentsValues) const {
static mt19937 rng(2); // random number generator
// Get the correct conditional density
@ -194,7 +194,7 @@ size_t DiscreteConditional::sample(const Values& parentsValues) const {
Key key = firstFrontalKey();
size_t nj = cardinality(key);
vector<double> p(nj);
Values frontals;
DiscreteValues frontals;
for (size_t value = 0; value < nj; value++) {
frontals[key] = value;
p[value] = pFS(frontals); // P(F=value|S=parentsValues)

View File

@ -42,9 +42,7 @@ public:
typedef DecisionTreeFactor BaseFactor; ///< Typedef to our factor base class
typedef Conditional<BaseFactor, This> BaseConditional; ///< Typedef to our conditional base class
/** A map from keys to values..
* TODO: Again, do we need this??? */
typedef Assignment<Key> Values;
using Values = DiscreteValues; ///< backwards compatibility
/// @name Standard Constructors
/// @{
@ -101,7 +99,7 @@ public:
}
/// Evaluate, just look up in AlgebraicDecisonTree
double operator()(const Values& values) const override {
double operator()(const DiscreteValues& values) const override {
return Potentials::operator()(values);
}
@ -111,31 +109,31 @@ public:
}
/** Restrict to given parent values, returns AlgebraicDecisionDiagram */
ADT choose(const Assignment<Key>& parentsValues) const;
ADT choose(const DiscreteValues& parentsValues) const;
/**
* solve a conditional
* @param parentsValues Known values of the parents
* @return MPE value of the child (1 frontal variable).
*/
size_t solve(const Values& parentsValues) const;
size_t solve(const DiscreteValues& parentsValues) const;
/**
* sample
* @param parentsValues Known values of the parents
* @return sample from conditional
*/
size_t sample(const Values& parentsValues) const;
size_t sample(const DiscreteValues& parentsValues) const;
/// @}
/// @name Advanced Interface
/// @{
/// solve a conditional, in place
void solveInPlace(Values* parentsValues) const;
void solveInPlace(DiscreteValues* parentsValues) const;
/// sample in place, stores result in partial solution
void sampleInPlace(Values* parentsValues) const;
void sampleInPlace(DiscreteValues* parentsValues) const;
/// @}

View File

@ -18,7 +18,7 @@
#pragma once
#include <gtsam/discrete/Assignment.h>
#include <gtsam/discrete/DiscreteValues.h>
#include <gtsam/inference/Factor.h>
#include <gtsam/base/Testable.h>
@ -40,17 +40,7 @@ public:
typedef boost::shared_ptr<DiscreteFactor> shared_ptr; ///< shared_ptr to this class
typedef Factor Base; ///< Our base class
/** A map from keys to values
* TODO: Do we need this? Should we just use gtsam::Values?
* We just need another special DiscreteValue to represent labels,
* However, all other Lie's operators are undefined in this class.
* The good thing is we can have a Hybrid graph of discrete/continuous variables
* together..
* Another good thing is we don't need to have the special DiscreteKey which stores
* cardinality of a Discrete variable. It should be handled naturally in
* the new class DiscreteValue, as the varible's type (domain)
*/
typedef Assignment<Key> Values;
using Values = DiscreteValues; ///< backwards compatibility
public:
@ -91,7 +81,7 @@ public:
/// @{
/// Find value for given assignment of values to variables
virtual double operator()(const Values&) const = 0;
virtual double operator()(const DiscreteValues&) const = 0;
/// Multiply in a DecisionTreeFactor and return the result as DecisionTreeFactor
virtual DecisionTreeFactor operator*(const DecisionTreeFactor&) const = 0;
@ -104,6 +94,6 @@ public:
// traits
template<> struct traits<DiscreteFactor> : public Testable<DiscreteFactor> {};
template<> struct traits<DiscreteFactor::Values> : public Testable<DiscreteFactor::Values> {};
template<> struct traits<DiscreteValues> : public Testable<DiscreteValues> {};
}// namespace gtsam

View File

@ -56,7 +56,7 @@ namespace gtsam {
/* ************************************************************************* */
double DiscreteFactorGraph::operator()(
const DiscreteFactor::Values &values) const {
const DiscreteValues &values) const {
double product = 1.0;
for( const sharedFactor& factor: factors_ )
product *= (*factor)(values);
@ -94,7 +94,7 @@ namespace gtsam {
// }
/* ************************************************************************* */
DiscreteFactorGraph::Values DiscreteFactorGraph::optimize() const
DiscreteValues DiscreteFactorGraph::optimize() const
{
gttic(DiscreteFactorGraph_optimize);
return BaseEliminateable::eliminateSequential()->optimize();

View File

@ -71,9 +71,10 @@ public:
typedef EliminateableFactorGraph<This> BaseEliminateable; ///< Typedef to base elimination class
typedef boost::shared_ptr<This> shared_ptr; ///< shared_ptr to this class
using Values = DiscreteValues; ///< backwards compatibility
/** A map from keys to values */
typedef KeyVector Indices;
typedef Assignment<Key> Values;
/** Default constructor */
DiscreteFactorGraph() {}
@ -130,7 +131,7 @@ public:
DecisionTreeFactor product() const;
/** Evaluates the factor graph given values, returns the joint probability of the factor graph given specific instantiation of values*/
double operator()(const DiscreteFactor::Values & values) const;
double operator()(const DiscreteValues & values) const;
/// print
void print(
@ -141,7 +142,7 @@ public:
* the dense elimination function specified in \c function,
* followed by back-substitution resulting from elimination. Is equivalent
* to calling graph.eliminateSequential()->optimize(). */
Values optimize() const;
DiscreteValues optimize() const;
// /** Permute the variables in the factors */

View File

@ -64,7 +64,7 @@ namespace gtsam {
//Create result
Vector vResult(key.second);
for (size_t state = 0; state < key.second ; ++ state) {
DiscreteFactor::Values values;
DiscreteValues values;
values[key.first] = state;
vResult(state) = (*marginalFactor)(values);
}

View File

@ -18,6 +18,7 @@
#include <gtsam/base/Testable.h>
#include <gtsam/discrete/DiscreteKey.h> // make sure we have traits
#include <gtsam/discrete/DiscreteValues.h>
// headers first to make sure no missing headers
//#define DT_NO_PRUNING
#include <gtsam/discrete/AlgebraicDecisionTree.h>
@ -445,7 +446,7 @@ TEST(ADT, equality_parser)
TEST(ADT, constructor)
{
DiscreteKey v0(0,2), v1(1,3);
Assignment<Key> x00, x01, x02, x10, x11, x12;
DiscreteValues x00, x01, x02, x10, x11, x12;
x00[0] = 0, x00[1] = 0;
x01[0] = 0, x01[1] = 1;
x02[0] = 0, x02[1] = 2;
@ -475,7 +476,7 @@ TEST(ADT, constructor)
for(double& t: table)
t = x++;
ADT f3(z0 & z1 & z2 & z3, table);
Assignment<Key> assignment;
DiscreteValues assignment;
assignment[0] = 0;
assignment[1] = 0;
assignment[2] = 0;
@ -501,7 +502,7 @@ TEST(ADT, conversion)
// f2.print("f2");
dot(fIndexKey, "conversion-f2");
Assignment<Key> x00, x01, x02, x10, x11, x12;
DiscreteValues x00, x01, x02, x10, x11, x12;
x00[5] = 0, x00[2] = 0;
x01[5] = 0, x01[2] = 1;
x10[5] = 1, x10[2] = 0;
@ -577,7 +578,7 @@ TEST(ADT, zero)
ADT notb(B, 1, 0);
ADT anotb = a * notb;
// GTSAM_PRINT(anotb);
Assignment<Key> x00, x01, x10, x11;
DiscreteValues x00, x01, x10, x11;
x00[0] = 0, x00[1] = 0;
x01[0] = 0, x01[1] = 1;
x10[0] = 1, x10[1] = 0;

View File

@ -43,7 +43,7 @@ TEST( DecisionTreeFactor, constructors)
// f2.print("f2:");
// f3.print("f3:");
DecisionTreeFactor::Values values;
DiscreteValues values;
values[0] = 1; // x
values[1] = 2; // y
values[2] = 1; // z

View File

@ -105,7 +105,7 @@ TEST(DiscreteBayesNet, Asia) {
// solve
auto actualMPE = chordal->optimize();
DiscreteFactor::Values expectedMPE;
DiscreteValues expectedMPE;
insert(expectedMPE)(Asia.first, 0)(Dyspnea.first, 0)(XRay.first, 0)(
Tuberculosis.first, 0)(Smoking.first, 0)(Either.first, 0)(
LungCancer.first, 0)(Bronchitis.first, 0);
@ -118,14 +118,14 @@ TEST(DiscreteBayesNet, Asia) {
// solve again, now with evidence
DiscreteBayesNet::shared_ptr chordal2 = fg.eliminateSequential(ordering);
auto actualMPE2 = chordal2->optimize();
DiscreteFactor::Values expectedMPE2;
DiscreteValues expectedMPE2;
insert(expectedMPE2)(Asia.first, 1)(Dyspnea.first, 1)(XRay.first, 0)(
Tuberculosis.first, 0)(Smoking.first, 1)(Either.first, 0)(
LungCancer.first, 0)(Bronchitis.first, 1);
EXPECT(assert_equal(expectedMPE2, actualMPE2));
// now sample from it
DiscreteFactor::Values expectedSample;
DiscreteValues expectedSample;
SETDEBUG("DiscreteConditional::sample", false);
insert(expectedSample)(Asia.first, 1)(Dyspnea.first, 1)(XRay.first, 1)(
Tuberculosis.first, 0)(Smoking.first, 1)(Either.first, 1)(

View File

@ -89,24 +89,24 @@ TEST_UNSAFE(DiscreteBayesTree, ThinTree) {
auto R = bayesTree->roots().front();
// Check whether BN and BT give the same answer on all configurations
vector<DiscreteFactor::Values> allPosbValues = cartesianProduct(
vector<DiscreteValues> allPosbValues = cartesianProduct(
key[0] & key[1] & key[2] & key[3] & key[4] & key[5] & key[6] & key[7] &
key[8] & key[9] & key[10] & key[11] & key[12] & key[13] & key[14]);
for (size_t i = 0; i < allPosbValues.size(); ++i) {
DiscreteFactor::Values x = allPosbValues[i];
DiscreteValues x = allPosbValues[i];
double expected = bayesNet.evaluate(x);
double actual = bayesTree->evaluate(x);
DOUBLES_EQUAL(expected, actual, 1e-9);
}
// Calculate all some marginals for Values==all1
// Calculate all some marginals for DiscreteValues==all1
Vector marginals = Vector::Zero(15);
double joint_12_14 = 0, joint_9_12_14 = 0, joint_8_12_14 = 0, joint_8_12 = 0,
joint82 = 0, joint12 = 0, joint24 = 0, joint45 = 0, joint46 = 0,
joint_4_11 = 0, joint_11_13 = 0, joint_11_13_14 = 0,
joint_11_12_13_14 = 0, joint_9_11_12_13 = 0, joint_8_11_12_13 = 0;
for (size_t i = 0; i < allPosbValues.size(); ++i) {
DiscreteFactor::Values x = allPosbValues[i];
DiscreteValues x = allPosbValues[i];
double px = bayesTree->evaluate(x);
for (size_t i = 0; i < 15; i++)
if (x[i]) marginals[i] += px;
@ -138,7 +138,7 @@ TEST_UNSAFE(DiscreteBayesTree, ThinTree) {
}
}
}
DiscreteFactor::Values all1 = allPosbValues.back();
DiscreteValues all1 = allPosbValues.back();
// check separator marginal P(S0)
auto clique = (*bayesTree)[0];

View File

@ -81,8 +81,8 @@ TEST_UNSAFE( DiscreteFactorGraph, DiscreteFactorGraphEvaluationTest) {
graph.add(P2, "0.9 0.6");
graph.add(P1 & P2, "4 1 10 4");
// Instantiate Values
DiscreteFactor::Values values;
// Instantiate DiscreteValues
DiscreteValues values;
values[0] = 1;
values[1] = 1;
@ -167,7 +167,7 @@ TEST( DiscreteFactorGraph, test)
// EXPECT(assert_equal(expected, *actual2));
// Test optimization
DiscreteFactor::Values expectedValues;
DiscreteValues expectedValues;
insert(expectedValues)(0, 0)(1, 0)(2, 0);
auto actualValues = graph.optimize();
EXPECT(assert_equal(expectedValues, actualValues));
@ -188,7 +188,7 @@ TEST( DiscreteFactorGraph, testMPE)
auto actualMPE = graph.optimize();
DiscreteFactor::Values expectedMPE;
DiscreteValues expectedMPE;
insert(expectedMPE)(0, 0)(1, 1)(2, 1);
EXPECT(assert_equal(expectedMPE, actualMPE));
}
@ -211,7 +211,7 @@ TEST( DiscreteFactorGraph, testMPE_Darwiche09book_p244)
// graph.product().potentials().dot("Darwiche-product");
// DiscreteSequentialSolver(graph).eliminate()->print();
DiscreteFactor::Values expectedMPE;
DiscreteValues expectedMPE;
insert(expectedMPE)(4, 0)(2, 0)(3, 1)(0, 1)(1, 1);
// Use the solver machinery.

View File

@ -47,7 +47,7 @@ TEST_UNSAFE( DiscreteMarginals, UGM_small ) {
DiscreteMarginals marginals(graph);
DiscreteFactor::shared_ptr actualC = marginals(Cathy.first);
DiscreteFactor::Values values;
DiscreteValues values;
values[Cathy.first] = 0;
EXPECT_DOUBLES_EQUAL( 0.359631, (*actualC)(values), 1e-6);
@ -94,7 +94,7 @@ TEST_UNSAFE( DiscreteMarginals, UGM_chain ) {
DiscreteMarginals marginals(graph);
DiscreteFactor::shared_ptr actualC = marginals(key[2].first);
DiscreteFactor::Values values;
DiscreteValues values;
values[key[2].first] = 0;
EXPECT_DOUBLES_EQUAL( 0.03426, (*actualC)(values), 1e-4);
@ -164,11 +164,11 @@ TEST_UNSAFE(DiscreteMarginals, truss2) {
graph.add(key[2] & key[3] & key[4], "1 2 3 4 5 6 7 8");
// Calculate the marginals by brute force
vector<DiscreteFactor::Values> allPosbValues =
vector<DiscreteValues> allPosbValues =
cartesianProduct(key[0] & key[1] & key[2] & key[3] & key[4]);
Vector T = Z_5x1, F = Z_5x1;
for (size_t i = 0; i < allPosbValues.size(); ++i) {
DiscreteFactor::Values x = allPosbValues[i];
DiscreteValues x = allPosbValues[i];
double px = graph(x);
for (size_t j = 0; j < 5; j++)
if (x[j])

View File

@ -26,7 +26,7 @@ void AllDiff::print(const std::string& s, const KeyFormatter& formatter) const {
}
/* ************************************************************************* */
double AllDiff::operator()(const Values& values) const {
double AllDiff::operator()(const DiscreteValues& values) const {
std::set<size_t> taken; // record values taken by keys
for (Key dkey : keys_) {
size_t value = values.at(dkey); // get the value for that key
@ -88,7 +88,7 @@ bool AllDiff::ensureArcConsistency(Key j, Domains* domains) const {
}
/* ************************************************************************* */
Constraint::shared_ptr AllDiff::partiallyApply(const Values& values) const {
Constraint::shared_ptr AllDiff::partiallyApply(const DiscreteValues& values) const {
DiscreteKeys newKeys;
// loop over keys and add them only if they do not appear in values
for (Key k : keys_)
@ -101,7 +101,7 @@ Constraint::shared_ptr AllDiff::partiallyApply(const Values& values) const {
/* ************************************************************************* */
Constraint::shared_ptr AllDiff::partiallyApply(
const Domains& domains) const {
DiscreteFactor::Values known;
DiscreteValues known;
for (Key k : keys_) {
const Domain& Dk = domains.at(k);
if (Dk.isSingleton()) known[k] = Dk.firstValue();

View File

@ -45,7 +45,7 @@ class GTSAM_UNSTABLE_EXPORT AllDiff : public Constraint {
}
/// Calculate value = expensive !
double operator()(const Values& values) const override;
double operator()(const DiscreteValues& values) const override;
/// Convert into a decisiontree, can be *very* expensive !
DecisionTreeFactor toDecisionTreeFactor() const override;
@ -62,7 +62,7 @@ class GTSAM_UNSTABLE_EXPORT AllDiff : public Constraint {
bool ensureArcConsistency(Key j, Domains* domains) const override;
/// Partially apply known values
Constraint::shared_ptr partiallyApply(const Values&) const override;
Constraint::shared_ptr partiallyApply(const DiscreteValues&) const override;
/// Partially apply known values, domain version
Constraint::shared_ptr partiallyApply(

View File

@ -47,7 +47,7 @@ class BinaryAllDiff : public Constraint {
}
/// Calculate value
double operator()(const Values& values) const override {
double operator()(const DiscreteValues& values) const override {
return (double)(values.at(keys_[0]) != values.at(keys_[1]));
}
@ -82,7 +82,7 @@ class BinaryAllDiff : public Constraint {
}
/// Partially apply known values
Constraint::shared_ptr partiallyApply(const Values&) const override {
Constraint::shared_ptr partiallyApply(const DiscreteValues&) const override {
throw std::runtime_error("BinaryAllDiff::partiallyApply not implemented");
}

View File

@ -14,13 +14,13 @@ using namespace std;
namespace gtsam {
/// Find the best total assignment - can be expensive
CSP::Values CSP::optimalAssignment() const {
DiscreteValues CSP::optimalAssignment() const {
DiscreteBayesNet::shared_ptr chordal = this->eliminateSequential();
return chordal->optimize();
}
/// Find the best total assignment - can be expensive
CSP::Values CSP::optimalAssignment(const Ordering& ordering) const {
DiscreteValues CSP::optimalAssignment(const Ordering& ordering) const {
DiscreteBayesNet::shared_ptr chordal = this->eliminateSequential(ordering);
return chordal->optimize();
}

View File

@ -20,10 +20,8 @@ namespace gtsam {
*/
class GTSAM_UNSTABLE_EXPORT CSP : public DiscreteFactorGraph {
public:
/** A map from keys to values */
typedef Assignment<Key> Values;
using Values = DiscreteValues; ///< backwards compatibility
public:
/// Add a unary constraint, allowing only a single value
void addSingleValue(const DiscreteKey& dkey, size_t value) {
emplace_shared<SingleValue>(dkey, value);
@ -46,10 +44,10 @@ class GTSAM_UNSTABLE_EXPORT CSP : public DiscreteFactorGraph {
// }
/// Find the best total assignment - can be expensive.
Values optimalAssignment() const;
DiscreteValues optimalAssignment() const;
/// Find the best total assignment, with given ordering - can be expensive.
Values optimalAssignment(const Ordering& ordering) const;
DiscreteValues optimalAssignment(const Ordering& ordering) const;
// /*
// * Perform loopy belief propagation

View File

@ -18,6 +18,7 @@
#pragma once
#include <gtsam/discrete/DiscreteFactor.h>
#include <gtsam/discrete/DiscreteValues.h>
#include <gtsam_unstable/dllexport.h>
#include <boost/assign.hpp>
@ -75,7 +76,7 @@ class GTSAM_EXPORT Constraint : public DiscreteFactor {
virtual bool ensureArcConsistency(Key j, Domains* domains) const = 0;
/// Partially apply known values
virtual shared_ptr partiallyApply(const Values&) const = 0;
virtual shared_ptr partiallyApply(const DiscreteValues&) const = 0;
/// Partially apply known values, domain version
virtual shared_ptr partiallyApply(const Domains&) const = 0;

View File

@ -31,7 +31,7 @@ string Domain::base1Str() const {
}
/* ************************************************************************* */
double Domain::operator()(const Values& values) const {
double Domain::operator()(const DiscreteValues& values) const {
return contains(values.at(key()));
}
@ -79,8 +79,8 @@ boost::optional<Domain> Domain::checkAllDiff(const KeyVector keys,
}
/* ************************************************************************* */
Constraint::shared_ptr Domain::partiallyApply(const Values& values) const {
Values::const_iterator it = values.find(key());
Constraint::shared_ptr Domain::partiallyApply(const DiscreteValues& values) const {
DiscreteValues::const_iterator it = values.find(key());
if (it != values.end() && !contains(it->second))
throw runtime_error("Domain::partiallyApply: unsatisfiable");
return boost::make_shared<Domain>(*this);

View File

@ -76,7 +76,7 @@ class GTSAM_UNSTABLE_EXPORT Domain : public Constraint {
bool contains(size_t value) const { return values_.count(value) > 0; }
/// Calculate value
double operator()(const Values& values) const override;
double operator()(const DiscreteValues& values) const override;
/// Convert into a decisiontree
DecisionTreeFactor toDecisionTreeFactor() const override;
@ -104,7 +104,7 @@ class GTSAM_UNSTABLE_EXPORT Domain : public Constraint {
const Domains& domains) const;
/// Partially apply known values
Constraint::shared_ptr partiallyApply(const Values& values) const override;
Constraint::shared_ptr partiallyApply(const DiscreteValues& values) const override;
/// Partially apply known values, domain version
Constraint::shared_ptr partiallyApply(const Domains& domains) const override;

View File

@ -202,7 +202,7 @@ void Scheduler::print(const string& s, const KeyFormatter& formatter) const {
} // print
/** Print readable form of assignment */
void Scheduler::printAssignment(const Values& assignment) const {
void Scheduler::printAssignment(const DiscreteValues& assignment) const {
// Not intended to be general! Assumes very particular ordering !
cout << endl;
for (size_t s = 0; s < nrStudents(); s++) {
@ -220,8 +220,8 @@ void Scheduler::printAssignment(const Values& assignment) const {
}
/** Special print for single-student case */
void Scheduler::printSpecial(const Values& assignment) const {
Values::const_iterator it = assignment.begin();
void Scheduler::printSpecial(const DiscreteValues& assignment) const {
DiscreteValues::const_iterator it = assignment.begin();
for (size_t area = 0; area < 3; area++, it++) {
size_t f = it->second;
cout << setw(12) << studentArea(0, area) << ": " << facultyName_[f] << endl;
@ -230,7 +230,7 @@ void Scheduler::printSpecial(const Values& assignment) const {
}
/** Accumulate faculty stats */
void Scheduler::accumulateStats(const Values& assignment,
void Scheduler::accumulateStats(const DiscreteValues& assignment,
vector<size_t>& stats) const {
for (size_t s = 0; s < nrStudents(); s++) {
Key base = 3 * s;
@ -256,7 +256,7 @@ DiscreteBayesNet::shared_ptr Scheduler::eliminate() const {
}
/** Find the best total assignment - can be expensive */
Scheduler::Values Scheduler::optimalAssignment() const {
DiscreteValues Scheduler::optimalAssignment() const {
DiscreteBayesNet::shared_ptr chordal = eliminate();
if (ISDEBUG("Scheduler::optimalAssignment")) {
@ -267,21 +267,21 @@ Scheduler::Values Scheduler::optimalAssignment() const {
}
gttic(my_optimize);
Values mpe = chordal->optimize();
DiscreteValues mpe = chordal->optimize();
gttoc(my_optimize);
return mpe;
}
/** find the assignment of students to slots with most possible committees */
Scheduler::Values Scheduler::bestSchedule() const {
Values best;
DiscreteValues Scheduler::bestSchedule() const {
DiscreteValues best;
throw runtime_error("bestSchedule not implemented");
return best;
}
/** find the corresponding most desirable committee assignment */
Scheduler::Values Scheduler::bestAssignment(const Values& bestSchedule) const {
Values best;
DiscreteValues Scheduler::bestAssignment(const DiscreteValues& bestSchedule) const {
DiscreteValues best;
throw runtime_error("bestAssignment not implemented");
return best;
}

View File

@ -134,26 +134,26 @@ class GTSAM_UNSTABLE_EXPORT Scheduler : public CSP {
const KeyFormatter& formatter = DefaultKeyFormatter) const override;
/** Print readable form of assignment */
void printAssignment(const Values& assignment) const;
void printAssignment(const DiscreteValues& assignment) const;
/** Special print for single-student case */
void printSpecial(const Values& assignment) const;
void printSpecial(const DiscreteValues& assignment) const;
/** Accumulate faculty stats */
void accumulateStats(const Values& assignment,
void accumulateStats(const DiscreteValues& assignment,
std::vector<size_t>& stats) const;
/** Eliminate, return a Bayes net */
DiscreteBayesNet::shared_ptr eliminate() const;
/** Find the best total assignment - can be expensive */
Values optimalAssignment() const;
DiscreteValues optimalAssignment() const;
/** find the assignment of students to slots with most possible committees */
Values bestSchedule() const;
DiscreteValues bestSchedule() const;
/** find the corresponding most desirable committee assignment */
Values bestAssignment(const Values& bestSchedule) const;
DiscreteValues bestAssignment(const DiscreteValues& bestSchedule) const;
}; // Scheduler

View File

@ -23,7 +23,7 @@ void SingleValue::print(const string& s, const KeyFormatter& formatter) const {
}
/* ************************************************************************* */
double SingleValue::operator()(const Values& values) const {
double SingleValue::operator()(const DiscreteValues& values) const {
return (double)(values.at(keys_[0]) == value_);
}
@ -57,8 +57,8 @@ bool SingleValue::ensureArcConsistency(Key j, Domains* domains) const {
}
/* ************************************************************************* */
Constraint::shared_ptr SingleValue::partiallyApply(const Values& values) const {
Values::const_iterator it = values.find(keys_[0]);
Constraint::shared_ptr SingleValue::partiallyApply(const DiscreteValues& values) const {
DiscreteValues::const_iterator it = values.find(keys_[0]);
if (it != values.end() && it->second != value_)
throw runtime_error("SingleValue::partiallyApply: unsatisfiable");
return boost::make_shared<SingleValue>(keys_[0], cardinality_, value_);

View File

@ -50,7 +50,7 @@ class GTSAM_UNSTABLE_EXPORT SingleValue : public Constraint {
}
/// Calculate value
double operator()(const Values& values) const override;
double operator()(const DiscreteValues& values) const override;
/// Convert into a decisiontree
DecisionTreeFactor toDecisionTreeFactor() const override;
@ -67,7 +67,7 @@ class GTSAM_UNSTABLE_EXPORT SingleValue : public Constraint {
bool ensureArcConsistency(Key j, Domains* domains) const override;
/// Partially apply known values
Constraint::shared_ptr partiallyApply(const Values& values) const override;
Constraint::shared_ptr partiallyApply(const DiscreteValues& values) const override;
/// Partially apply known values, domain version
Constraint::shared_ptr partiallyApply(

View File

@ -165,7 +165,7 @@ void solveStaged(size_t addMutex = 2) {
root->print(""/*scheduler.studentName(s)*/);
// solve root node only
Scheduler::Values values;
DiscreteValues values;
size_t bestSlot = root->solve(values);
// get corresponding count
@ -225,7 +225,7 @@ void sampleSolutions() {
// now, sample schedules
for (size_t n = 0; n < 500; n++) {
vector<size_t> stats(19, 0);
vector<Scheduler::Values> samples;
vector<DiscreteValues> samples;
for (size_t i = 0; i < 7; i++) {
samples.push_back(samplers[i]->sample());
schedulers[i].accumulateStats(samples[i], stats);
@ -319,7 +319,7 @@ void accomodateStudent() {
// GTSAM_PRINT(*chordal);
// solve root node only
Scheduler::Values values;
DiscreteValues values;
size_t bestSlot = root->solve(values);
// get corresponding count

View File

@ -190,7 +190,7 @@ void solveStaged(size_t addMutex = 2) {
root->print(""/*scheduler.studentName(s)*/);
// solve root node only
Scheduler::Values values;
DiscreteValues values;
size_t bestSlot = root->solve(values);
// get corresponding count
@ -234,7 +234,7 @@ void sampleSolutions() {
// now, sample schedules
for (size_t n = 0; n < 500; n++) {
vector<size_t> stats(19, 0);
vector<Scheduler::Values> samples;
vector<DiscreteValues> samples;
for (size_t i = 0; i < NRSTUDENTS; i++) {
samples.push_back(samplers[i]->sample());
schedulers[i].accumulateStats(samples[i], stats);

View File

@ -212,7 +212,7 @@ void solveStaged(size_t addMutex = 2) {
root->print(""/*scheduler.studentName(s)*/);
// solve root node only
Scheduler::Values values;
DiscreteValues values;
size_t bestSlot = root->solve(values);
// get corresponding count
@ -259,7 +259,7 @@ void sampleSolutions() {
// now, sample schedules
for (size_t n = 0; n < 10000; n++) {
vector<size_t> stats(nrFaculty, 0);
vector<Scheduler::Values> samples;
vector<DiscreteValues> samples;
for (size_t i = 0; i < NRSTUDENTS; i++) {
samples.push_back(samplers[i]->sample());
schedulers[i].accumulateStats(samples[i], stats);

View File

@ -112,14 +112,14 @@ TEST(CSP, allInOne) {
csp.addAllDiff(UT, AZ);
// Check an invalid combination, with ID==UT==AZ all same color
DiscreteFactor::Values invalid;
DiscreteValues invalid;
invalid[ID.first] = 0;
invalid[UT.first] = 0;
invalid[AZ.first] = 0;
EXPECT_DOUBLES_EQUAL(0, csp(invalid), 1e-9);
// Check a valid combination
DiscreteFactor::Values valid;
DiscreteValues valid;
valid[ID.first] = 0;
valid[UT.first] = 1;
valid[AZ.first] = 0;
@ -133,7 +133,7 @@ TEST(CSP, allInOne) {
// Solve
auto mpe = csp.optimalAssignment();
CSP::Values expected;
DiscreteValues expected;
insert(expected)(ID.first, 1)(UT.first, 0)(AZ.first, 1);
EXPECT(assert_equal(expected, mpe));
EXPECT_DOUBLES_EQUAL(1, csp(mpe), 1e-9);
@ -179,7 +179,7 @@ TEST(CSP, WesternUS) {
// Solve using that ordering:
auto mpe = csp.optimalAssignment(ordering);
// GTSAM_PRINT(mpe);
CSP::Values expected;
DiscreteValues expected;
insert(expected)(WA.first, 1)(CA.first, 1)(NV.first, 3)(OR.first, 0)(
MT.first, 1)(WY.first, 0)(NM.first, 3)(CO.first, 2)(ID.first, 2)(
UT.first, 1)(AZ.first, 0);
@ -213,14 +213,14 @@ TEST(CSP, ArcConsistency) {
// GTSAM_PRINT(csp);
// Check an invalid combination, with ID==UT==AZ all same color
DiscreteFactor::Values invalid;
DiscreteValues invalid;
invalid[ID.first] = 0;
invalid[UT.first] = 1;
invalid[AZ.first] = 0;
EXPECT_DOUBLES_EQUAL(0, csp(invalid), 1e-9);
// Check a valid combination
DiscreteFactor::Values valid;
DiscreteValues valid;
valid[ID.first] = 0;
valid[UT.first] = 1;
valid[AZ.first] = 2;
@ -228,7 +228,7 @@ TEST(CSP, ArcConsistency) {
// Solve
auto mpe = csp.optimalAssignment();
CSP::Values expected;
DiscreteValues expected;
insert(expected)(ID.first, 1)(UT.first, 0)(AZ.first, 2);
EXPECT(assert_equal(expected, mpe));
EXPECT_DOUBLES_EQUAL(1, csp(mpe), 1e-9);
@ -250,7 +250,7 @@ TEST(CSP, ArcConsistency) {
LONGS_EQUAL(2, domains.at(2).nrValues());
// Parial application, version 1
DiscreteFactor::Values known;
DiscreteValues known;
known[AZ.first] = 2;
DiscreteFactor::shared_ptr reduced1 = alldiff.partiallyApply(known);
DecisionTreeFactor f3(ID & UT, "0 1 1 1 0 1 1 1 0");

View File

@ -126,7 +126,7 @@ class LoopyBelief {
// normalize belief
double sum = 0.0;
for (size_t v = 0; v < allDiscreteKeys.at(key).second; ++v) {
DiscreteFactor::Values val;
DiscreteValues val;
val[key] = v;
sum += (*beliefAtKey)(val);
}

View File

@ -88,7 +88,7 @@ class Sudoku : public CSP {
}
/// Print readable form of assignment
void printAssignment(const DiscreteFactor::Values& assignment) const {
void printAssignment(const DiscreteValues& assignment) const {
for (size_t i = 0; i < n_; i++) {
for (size_t j = 0; j < n_; j++) {
Key k = key(i, j);
@ -127,7 +127,7 @@ TEST(Sudoku, small) {
// optimize and check
auto solution = csp.optimalAssignment();
CSP::Values expected;
DiscreteValues expected;
insert(expected)(csp.key(0, 0), 0)(csp.key(0, 1), 1)(csp.key(0, 2), 2)(
csp.key(0, 3), 3)(csp.key(1, 0), 2)(csp.key(1, 1), 3)(csp.key(1, 2), 0)(
csp.key(1, 3), 1)(csp.key(2, 0), 3)(csp.key(2, 1), 2)(csp.key(2, 2), 1)(