Improve infeasibility detection for constant and
variable parameter blocks.

1. Check if constant parameter blocks have infeasible values.
2. Check if variable parameter blocks have impossible bounds.

Change-Id: I0a58bc3eba42f0655fe90b58ea6ee21fae8c8f61
diff --git a/internal/ceres/solver_impl.cc b/internal/ceres/solver_impl.cc
index 070ed80..937ab78 100644
--- a/internal/ceres/solver_impl.cc
+++ b/internal/ceres/solver_impl.cc
@@ -345,39 +345,57 @@
   return false;
 }
 
-// Returns true, if the problem has any constant parameter blocks
-// which are not feasible. This means that Ceres cannot produce a
-// feasible solution to the problem.
-bool HasInfeasibleConstantParameterBlock(const ProblemImpl* problem,
-                                         string* message) {
+// Returns false, if the problem has any constant parameter blocks
+// which are not feasible, or any variable parameter blocks which have
+// a lower bound greater than or equal to the upper bound.
+bool ParameterBlocksAreFeasible(const ProblemImpl* problem, string* message) {
   CHECK_NOTNULL(message);
   const Program& program = problem->program();
   const vector<ParameterBlock*>& parameter_blocks = program.parameter_blocks();
   for (int i = 0; i < parameter_blocks.size(); ++i) {
-    if (!parameter_blocks[i]->IsConstant()) {
-      continue;
-    }
-
     const double* array = parameter_blocks[i]->user_state();
     const double* lower_bounds = parameter_blocks[i]->lower_bounds();
     const double* upper_bounds = parameter_blocks[i]->upper_bounds();
     const int size = parameter_blocks[i]->Size();
-    for (int j = 0; j < size; ++j) {
-      if (array[j] < lower_bounds[j] || array[j] > upper_bounds[j]) {
-        *message = StringPrintf(
-            "ParameterBlock: %p with size %d has at least one infeasible value."
-            "\nFirst infeasible value is at index: %d."
-            "\nLower bound: %e, value: %e, upper bound: %e"
-            "\nParameter block values: ",
-            array, size, j, lower_bounds[j], array[j], upper_bounds[j]);
-        AppendArrayToString(size, array, message);
-        return true;
+    if (parameter_blocks[i]->IsConstant()) {
+      // Constant parameter blocks must start in the feasible region
+      // to ultimately produce a feasible solution, since Ceres cannot
+      // change them.
+      for (int j = 0; j < size; ++j) {
+        if (array[j] < lower_bounds[j] || array[j] > upper_bounds[j]) {
+          *message = StringPrintf(
+              "ParameterBlock: %p with size %d has at least one infeasible value."
+              "\nFirst infeasible value is at index: %d."
+              "\nLower bound: %e, value: %e, upper bound: %e"
+              "\nParameter block values: ",
+              array, size, j, lower_bounds[j], array[j], upper_bounds[j]);
+          AppendArrayToString(size, array, message);
+          return false;
+        }
+      }
+    } else {
+      // Variable parameter blocks must have non-empty feasible
+      // regions, otherwise there is no way to produce a feasible
+      // solution.
+      for (int j = 0; j < size; ++j) {
+        if (lower_bounds[j] >= upper_bounds[j]) {
+          *message = StringPrintf(
+              "ParameterBlock: %p with size %d has at least one infeasible bound."
+              "\nFirst infeasible bound is at index: %d."
+              "\nLower bound: %e, upper bound: %e"
+              "\nParameter block values: ",
+              array, size, j, lower_bounds[j], upper_bounds[j]);
+          AppendArrayToString(size, array, message);
+          return false;
+        }
       }
     }
   }
-  return false;
+
+  return true;
 }
 
+
 }  // namespace
 
 void SolverImpl::TrustRegionMinimize(
@@ -594,7 +612,7 @@
     return;
   }
 
-  if (HasInfeasibleConstantParameterBlock(problem_impl, &summary->message)) {
+  if (!ParameterBlocksAreFeasible(problem_impl, &summary->message)) {
     LOG(ERROR) << "Terminating: " << summary->message;
     return;
   }