cleanup and better assertions
parent
0bbd279bbb
commit
b68530dcbb
|
@ -72,25 +72,45 @@ Ordering getOrdering(HybridGaussianFactorGraph& factors,
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(HybridEstimation, Full) {
|
TEST(HybridEstimation, Full) {
|
||||||
size_t K = 3;
|
size_t K = 6;
|
||||||
std::vector<double> measurements = {0, 1, 2};
|
std::vector<double> measurements = {0, 1, 2, 2, 2, 3};
|
||||||
// Ground truth discrete seq
|
// Ground truth discrete seq
|
||||||
std::vector<size_t> discrete_seq = {1, 1, 0};
|
std::vector<size_t> discrete_seq = {1, 1, 0, 0, 1};
|
||||||
// Switching example of robot moving in 1D
|
// Switching example of robot moving in 1D
|
||||||
// with given measurements and equal mode priors.
|
// with given measurements and equal mode priors.
|
||||||
Switching switching(K, 1.0, 0.1, measurements, "1/1 1/1");
|
Switching switching(K, 1.0, 0.1, measurements, "1/1 1/1");
|
||||||
HybridGaussianFactorGraph graph = switching.linearizedFactorGraph;
|
HybridGaussianFactorGraph graph = switching.linearizedFactorGraph;
|
||||||
|
|
||||||
Ordering hybridOrdering;
|
Ordering hybridOrdering;
|
||||||
hybridOrdering += X(0);
|
for (size_t k = 0; k < K; k++) {
|
||||||
hybridOrdering += X(1);
|
hybridOrdering += X(k);
|
||||||
hybridOrdering += X(2);
|
}
|
||||||
hybridOrdering += M(0);
|
for (size_t k = 0; k < K - 1; k++) {
|
||||||
hybridOrdering += M(1);
|
hybridOrdering += M(k);
|
||||||
|
}
|
||||||
|
|
||||||
HybridBayesNet::shared_ptr bayesNet =
|
HybridBayesNet::shared_ptr bayesNet =
|
||||||
graph.eliminateSequential(hybridOrdering);
|
graph.eliminateSequential(hybridOrdering);
|
||||||
|
|
||||||
EXPECT_LONGS_EQUAL(5, bayesNet->size());
|
bayesNet->print();
|
||||||
|
EXPECT_LONGS_EQUAL(2 * K - 1, bayesNet->size());
|
||||||
|
|
||||||
|
HybridValues delta = bayesNet->optimize();
|
||||||
|
|
||||||
|
Values initial = switching.linearizationPoint;
|
||||||
|
Values result = initial.retract(delta.continuous());
|
||||||
|
|
||||||
|
DiscreteValues expected_discrete;
|
||||||
|
for (size_t k = 0; k < K - 1; k++) {
|
||||||
|
expected_discrete[M(k)] = discrete_seq[k];
|
||||||
|
}
|
||||||
|
EXPECT(assert_equal(expected_discrete, delta.discrete()));
|
||||||
|
|
||||||
|
Values expected_continuous;
|
||||||
|
for (size_t k = 0; k < K; k++) {
|
||||||
|
expected_continuous.insert(X(k), measurements[k]);
|
||||||
|
}
|
||||||
|
EXPECT(assert_equal(expected_continuous, result));
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
@ -102,8 +122,8 @@ TEST(HybridEstimation, Incremental) {
|
||||||
// Ground truth discrete seq
|
// Ground truth discrete seq
|
||||||
std::vector<size_t> discrete_seq = {1, 1, 0, 0, 0, 1, 1, 1, 1, 0,
|
std::vector<size_t> discrete_seq = {1, 1, 0, 0, 0, 1, 1, 1, 1, 0,
|
||||||
1, 1, 1, 0, 0, 1, 1, 0, 0, 0};
|
1, 1, 1, 0, 0, 1, 1, 0, 0, 0};
|
||||||
// Switching example of robot moving in 1D with given measurements and equal
|
// Switching example of robot moving in 1D
|
||||||
// mode priors.
|
// with given measurements and equal mode priors.
|
||||||
Switching switching(K, 1.0, 0.1, measurements, "1/1 1/1");
|
Switching switching(K, 1.0, 0.1, measurements, "1/1 1/1");
|
||||||
HybridSmoother smoother;
|
HybridSmoother smoother;
|
||||||
HybridNonlinearFactorGraph graph;
|
HybridNonlinearFactorGraph graph;
|
||||||
|
@ -209,13 +229,16 @@ std::vector<size_t> getDiscreteSequence(size_t x) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Helper method to get the tree of unnormalized probabilities
|
* @brief Helper method to get the tree of
|
||||||
* as per the new elimination scheme.
|
* unnormalized probabilities as per the elimination scheme.
|
||||||
|
*
|
||||||
|
* Used as a helper to compute q(\mu | M, Z) which is used by
|
||||||
|
* both P(X | M, Z) and P(M | Z).
|
||||||
*
|
*
|
||||||
* @param graph The HybridGaussianFactorGraph to eliminate.
|
* @param graph The HybridGaussianFactorGraph to eliminate.
|
||||||
* @return AlgebraicDecisionTree<Key>
|
* @return AlgebraicDecisionTree<Key>
|
||||||
*/
|
*/
|
||||||
AlgebraicDecisionTree<Key> probPrimeTree(
|
AlgebraicDecisionTree<Key> getProbPrimeTree(
|
||||||
const HybridGaussianFactorGraph& graph) {
|
const HybridGaussianFactorGraph& graph) {
|
||||||
HybridBayesNet::shared_ptr bayesNet;
|
HybridBayesNet::shared_ptr bayesNet;
|
||||||
HybridGaussianFactorGraph::shared_ptr remainingGraph;
|
HybridGaussianFactorGraph::shared_ptr remainingGraph;
|
||||||
|
@ -239,20 +262,19 @@ AlgebraicDecisionTree<Key> probPrimeTree(
|
||||||
DecisionTree<Key, VectorValues::shared_ptr> delta_tree(discrete_keys,
|
DecisionTree<Key, VectorValues::shared_ptr> delta_tree(discrete_keys,
|
||||||
vector_values);
|
vector_values);
|
||||||
|
|
||||||
|
// Get the probPrime tree with the correct leaf probabilities
|
||||||
std::vector<double> probPrimes;
|
std::vector<double> probPrimes;
|
||||||
for (const DiscreteValues& assignment : assignments) {
|
for (const DiscreteValues& assignment : assignments) {
|
||||||
double error = 0.0;
|
|
||||||
VectorValues delta = *delta_tree(assignment);
|
VectorValues delta = *delta_tree(assignment);
|
||||||
for (auto factor : graph) {
|
|
||||||
if (factor->isHybrid()) {
|
|
||||||
auto f = boost::static_pointer_cast<GaussianMixtureFactor>(factor);
|
|
||||||
error += f->error(delta, assignment);
|
|
||||||
|
|
||||||
} else if (factor->isContinuous()) {
|
// If VectorValues is empty, it means this is a pruned branch.
|
||||||
auto f = boost::static_pointer_cast<HybridGaussianFactor>(factor);
|
// Set the probPrime to 0.0.
|
||||||
error += f->inner()->error(delta);
|
if (delta.size() == 0) {
|
||||||
}
|
probPrimes.push_back(0.0);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double error = graph.error(delta, assignment);
|
||||||
probPrimes.push_back(exp(-error));
|
probPrimes.push_back(exp(-error));
|
||||||
}
|
}
|
||||||
AlgebraicDecisionTree<Key> probPrimeTree(discrete_keys, probPrimes);
|
AlgebraicDecisionTree<Key> probPrimeTree(discrete_keys, probPrimes);
|
||||||
|
@ -261,7 +283,8 @@ AlgebraicDecisionTree<Key> probPrimeTree(
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
/**
|
/**
|
||||||
* Test for correctness of different branches of the P'(Continuous | Discrete).
|
* Test for correctness of different branches of the P'(Continuous |
|
||||||
|
Discrete).
|
||||||
* The values should match those of P'(Continuous) for each discrete mode.
|
* The values should match those of P'(Continuous) for each discrete mode.
|
||||||
*/
|
*/
|
||||||
TEST(HybridEstimation, Probability) {
|
TEST(HybridEstimation, Probability) {
|
||||||
|
@ -287,8 +310,8 @@ TEST(HybridEstimation, Probability) {
|
||||||
expected_prob_primes.push_back(prob_prime);
|
expected_prob_primes.push_back(prob_prime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switching example of robot moving in 1D with given measurements and equal
|
// Switching example of robot moving in 1D with
|
||||||
// mode priors.
|
// given measurements and equal mode priors.
|
||||||
Switching switching(K, between_sigma, measurement_sigma, measurements,
|
Switching switching(K, between_sigma, measurement_sigma, measurements,
|
||||||
"1/1 1/1");
|
"1/1 1/1");
|
||||||
auto graph = switching.linearizedFactorGraph;
|
auto graph = switching.linearizedFactorGraph;
|
||||||
|
@ -358,7 +381,7 @@ TEST(HybridEstimation, ProbabilityMultifrontal) {
|
||||||
Ordering ordering = getOrdering(graph, HybridGaussianFactorGraph());
|
Ordering ordering = getOrdering(graph, HybridGaussianFactorGraph());
|
||||||
|
|
||||||
// Get the tree of unnormalized probabilities for each mode sequence.
|
// Get the tree of unnormalized probabilities for each mode sequence.
|
||||||
AlgebraicDecisionTree<Key> expected_probPrimeTree = probPrimeTree(graph);
|
AlgebraicDecisionTree<Key> expected_probPrimeTree = getProbPrimeTree(graph);
|
||||||
|
|
||||||
// Eliminate continuous
|
// Eliminate continuous
|
||||||
Ordering continuous_ordering(graph.continuousKeys());
|
Ordering continuous_ordering(graph.continuousKeys());
|
||||||
|
@ -412,8 +435,8 @@ TEST(HybridEstimation, ProbabilityMultifrontal) {
|
||||||
discreteBayesTree->addClique(clique, discrete_clique);
|
discreteBayesTree->addClique(clique, discrete_clique);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Remove the clique from the children of the parents since it will get
|
// Remove the clique from the children of the parents since
|
||||||
// added again in addClique.
|
// it will get added again in addClique.
|
||||||
auto clique_it = std::find(clique->parent()->children.begin(),
|
auto clique_it = std::find(clique->parent()->children.begin(),
|
||||||
clique->parent()->children.end(), clique);
|
clique->parent()->children.end(), clique);
|
||||||
clique->parent()->children.erase(clique_it);
|
clique->parent()->children.erase(clique_it);
|
||||||
|
|
Loading…
Reference in New Issue