While much of Ceres Solver is devoted to solving non-linear least
squares problems, internally it contains a solver that can solve
general unconstrained optimization problems using just their objective
function value and gradients. The GradientProblem and
GradientProblemSolver objects give the user access to this solver.

So without much further ado, let us look at how one goes about using
them.

We begin by defining an instance of the FirstOrderFunction
interface. This is the object that is responsible for computing the
objective function value and the gradient (if required). This is the
analog of the CostFunction when defining non-linear least
squares problems in Ceres.