NonlinearConstraints now handle inactive constraints (when the state is already in the feasible region) by returning empty factors on linearization.
parent
cf6474c99b
commit
f3e825767b
|
@ -61,6 +61,13 @@ NonlinearConstraint1<Config>::linearize(const Config& config, const VectorConfig
|
||||||
// find the error
|
// find the error
|
||||||
Vector g = g_(config, key_);
|
Vector g = g_(config, key_);
|
||||||
|
|
||||||
|
// determine if this is an active constraint
|
||||||
|
if (zero(g)) {
|
||||||
|
GaussianFactor::shared_ptr factor(new GaussianFactor(Vector_(0)));
|
||||||
|
GaussianFactor::shared_ptr constraint(new GaussianFactor(Vector_(0)));
|
||||||
|
return std::make_pair(factor, constraint);
|
||||||
|
}
|
||||||
|
|
||||||
// construct the gradient
|
// construct the gradient
|
||||||
Matrix grad = gradG_(config, key_);
|
Matrix grad = gradG_(config, key_);
|
||||||
|
|
||||||
|
|
|
@ -177,6 +177,78 @@ TEST( NonlinearConstraint2, binary_scalar_equal ) {
|
||||||
CHECK(!c1.equals(c4));
|
CHECK(!c1.equals(c4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
// Inequality tests
|
||||||
|
/* ************************************************************************* */
|
||||||
|
namespace inequality_unary {
|
||||||
|
/** p = 1, gradG(x) = 2*x */
|
||||||
|
Matrix grad_g(const VectorConfig& config, const std::string& key) {
|
||||||
|
double x = config[key](0);
|
||||||
|
return Matrix_(1,1, 2*x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** p = 1, g(x) x^2 - 5 > 0 */
|
||||||
|
Vector g_func(const VectorConfig& config, const std::string& key) {
|
||||||
|
double x = config[key](0);
|
||||||
|
double g = x*x-5;
|
||||||
|
if (g > 0)
|
||||||
|
return Vector_(1, 0.0); // return exactly zero
|
||||||
|
else
|
||||||
|
return Vector_(1, g); // return the actual cost
|
||||||
|
}
|
||||||
|
} // \namespace test1
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
TEST( NonlinearConstraint1, unary_inequality ) {
|
||||||
|
size_t p = 1;
|
||||||
|
NonlinearConstraint1<VectorConfig> c1("x", *inequality_unary::grad_g,
|
||||||
|
*inequality_unary::g_func, p, "L_x1");
|
||||||
|
|
||||||
|
// get configurations to use for evaluation
|
||||||
|
VectorConfig config1, config2;
|
||||||
|
config1.insert("x", Vector_(1, 10.0)); // should have zero error
|
||||||
|
config2.insert("x", Vector_(1, 1.0)); // should have nonzero error
|
||||||
|
|
||||||
|
// check error
|
||||||
|
Vector actError1 = c1.error_vector(config1);
|
||||||
|
Vector actError2 = c1.error_vector(config2);
|
||||||
|
CHECK(actError1(0) == 0.0); // NOTE: using exact comparison here, as this value is forced
|
||||||
|
CHECK(assert_equal(actError2, Vector_(1, -4.0, 1e-9)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
TEST( NonlinearConstraint1, unary_inequality_linearize ) {
|
||||||
|
size_t p = 1;
|
||||||
|
NonlinearConstraint1<VectorConfig> c1("x", *inequality_unary::grad_g,
|
||||||
|
*inequality_unary::g_func, p, "L_x");
|
||||||
|
|
||||||
|
// get configurations to use for linearization
|
||||||
|
VectorConfig config1, config2;
|
||||||
|
config1.insert("x", Vector_(1, 10.0)); // should have zero error
|
||||||
|
config2.insert("x", Vector_(1, 1.0)); // should have nonzero error
|
||||||
|
|
||||||
|
// get a configuration of Lagrange multipliers
|
||||||
|
VectorConfig lagrangeConfig;
|
||||||
|
lagrangeConfig.insert("L_x", Vector_(1, 3.0));
|
||||||
|
|
||||||
|
// linearize for inactive constraint
|
||||||
|
GaussianFactor::shared_ptr actFactor1, actConstraint1;
|
||||||
|
boost::tie(actFactor1, actConstraint1) = c1.linearize(config1, lagrangeConfig);
|
||||||
|
|
||||||
|
// verify empty factors
|
||||||
|
CHECK(actFactor1->empty());
|
||||||
|
CHECK(actConstraint1->empty());
|
||||||
|
|
||||||
|
// linearize for active constraint
|
||||||
|
GaussianFactor::shared_ptr actFactor2, actConstraint2;
|
||||||
|
boost::tie(actFactor2, actConstraint2) = c1.linearize(config2, lagrangeConfig);
|
||||||
|
|
||||||
|
// verify
|
||||||
|
GaussianFactor expFactor("x", Matrix_(1,1, 6.0), "L_x", eye(1), zero(1), 1.0);
|
||||||
|
GaussianFactor expConstraint("x", Matrix_(1,1, 2.0), Vector_(1,-4.0), 0.0);
|
||||||
|
CHECK(assert_equal(*actFactor2, expFactor));
|
||||||
|
CHECK(assert_equal(*actConstraint2, expConstraint));
|
||||||
|
}
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
int main() { TestResult tr; return TestRegistry::runAllTests(tr); }
|
int main() { TestResult tr; return TestRegistry::runAllTests(tr); }
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
|
Loading…
Reference in New Issue