Search code examples
ceres-solver

Ceres Solver: how to define bounds/constraints?


Ceres solver states everywhere that it can

[...] solve robustified bounds constrained non-linear least squares problems

and that it supports upper and lower bounds constraints on the parameter blocks (for example in http://ceres-solver.org/modeling_faqs.html it states Ceres Solver only supports upper and lower bounds constraints on the parameter blocks), but somehow I can't find anywhere in the documentation how I can set these upper and lower bounds.

So, how do I set upper and lower bounds for parameter blocks in ceres solver?

Specifically, how do I do that in an AutoDiffCostFunction? If I use if statements to return a very big residual out of bounds, then that function isn't differentiable.

For example, this is the ceres Hello World:

struct CostFunctor {
   template <typename T>
   bool operator()(const T* const x, T* residual) const {
     residual[0] = 10.0 - x[0];
     return true;
   }
};

int main(int argc, char** argv) {
  google::InitGoogleLogging(argv[0]);

  // The variable to solve for with its initial value.
  double initial_x = 5.0;
  double x = initial_x;

  // Build the problem.
  Problem problem;

  // Set up the only cost function (also known as residual). This uses
  // auto-differentiation to obtain the derivative (jacobian).
  CostFunction* cost_function =
      new AutoDiffCostFunction<CostFunctor, 1, 1>(new CostFunctor);
  problem.AddResidualBlock(cost_function, nullptr, &x);

  // Run the solver!
  Solver::Options options;
  options.linear_solver_type = ceres::DENSE_QR;
  options.minimizer_progress_to_stdout = true;
  Solver::Summary summary;
  Solve(options, &problem, &summary);

  std::cout << summary.BriefReport() << "\n";
  std::cout << "x : " << initial_x
            << " -> " << x << "\n";
  return 0;
}

how would I impose in this example a lower bound of 2.0 and an upper bound of 20.0 to the parameter x?


Solution

  • You can use methods setParameterLowerBound and setParameterUpperBound as defined here: http://ceres-solver.org/nnls_modeling.html?highlight=setparameterlowerbound#_CPPv4N5ceres7Problem22SetParameterLowerBoundEPdid

    In your case, I guess something like this:

    problem.SetParameterLowerBound(&x, 0, lower_bound);
    problem.SetParameterUpperBound(&x, 0, upper_bound);