Allow SubsetParameterization to accept an empty vector of constant parameters.

Thanks to Frédéric Devernay for reporting this and providing an initial fix.

Change-Id: Id86a2051ab7841ecafdcfb00f4634b353a7ef3b4
diff --git a/internal/ceres/local_parameterization.cc b/internal/ceres/local_parameterization.cc
index 97fdbed..62947f0 100644
--- a/internal/ceres/local_parameterization.cc
+++ b/internal/ceres/local_parameterization.cc
@@ -94,6 +94,10 @@
 SubsetParameterization::SubsetParameterization(
     int size, const vector<int>& constant_parameters)
     : local_size_(size - constant_parameters.size()), constancy_mask_(size, 0) {
+  if (constant_parameters.empty()) {
+    return;
+  }
+
   vector<int> constant = constant_parameters;
   std::sort(constant.begin(), constant.end());
   CHECK_GE(constant.front(), 0) << "Indices indicating constant parameter must "
diff --git a/internal/ceres/local_parameterization_test.cc b/internal/ceres/local_parameterization_test.cc
index 636cac2..ec8e660 100644
--- a/internal/ceres/local_parameterization_test.cc
+++ b/internal/ceres/local_parameterization_test.cc
@@ -75,6 +75,33 @@
   EXPECT_EQ((local_matrix - global_matrix).norm(), 0.0);
 }
 
+TEST(SubsetParameterization, EmptyConstantParameters) {
+  std::vector<int> constant_parameters;
+  SubsetParameterization parameterization(3, constant_parameters);
+  EXPECT_EQ(parameterization.GlobalSize(), 3);
+  EXPECT_EQ(parameterization.LocalSize(), 3);
+  double x[3] = {1, 2, 3};
+  double delta[3] = {4, 5, 6};
+  double x_plus_delta[3] = {-1, -2, -3};
+  parameterization.Plus(x, delta, x_plus_delta);
+  EXPECT_EQ(x_plus_delta[0], x[0] + delta[0]);
+  EXPECT_EQ(x_plus_delta[1], x[1] + delta[1]);
+  EXPECT_EQ(x_plus_delta[2], x[2] + delta[2]);
+
+  Matrix jacobian(3, 3);
+  Matrix expected_jacobian(3, 3);
+  expected_jacobian.setIdentity();
+  parameterization.ComputeJacobian(x, jacobian.data());
+  EXPECT_EQ(jacobian, expected_jacobian);
+
+  Matrix global_matrix(3, 5);
+  global_matrix.setRandom();
+  Matrix local_matrix(3, 5);
+  parameterization.MultiplyByJacobian(
+      x, 5, global_matrix.data(), local_matrix.data());
+  EXPECT_EQ(global_matrix, local_matrix);
+}
+
 TEST(SubsetParameterization, NegativeParameterIndexDeathTest) {
   std::vector<int> constant_parameters;
   constant_parameters.push_back(-1);