Move EvaluationCallback from Solver::Options to Problem::Options.

Adding it to Solver::Options was a mistake, as it prevents it from
being used in covariance estimation. Also updated associated docs.

https://github.com/ceres-solver/ceres-solver/issues/380
https://github.com/ceres-solver/ceres-solver/issues/401
https://github.com/ceres-solver/ceres-solver/issues/484

Change-Id: I63809a47a58e84c04a58bf8e59ace92f45fc2873
diff --git a/docs/source/nnls_modeling.rst b/docs/source/nnls_modeling.rst
index c35fac8..7a86640 100644
--- a/docs/source/nnls_modeling.rst
+++ b/docs/source/nnls_modeling.rst
@@ -1536,6 +1536,116 @@
    delete on each ``cost_function`` or ``loss_function`` pointer only
    once, regardless of how many residual blocks refer to them.
 
+.. class:: Problem::Options
+
+   Options struct that is used to control :class:`Problem::`.
+
+.. member:: Ownership Problem::Options::cost_function_ownership
+
+   Default: ``TAKE_OWNERSHIP``
+
+   This option controls whether the Problem object owns the cost
+   functions.
+
+   If set to TAKE_OWNERSHIP, then the problem object will delete the
+   cost functions on destruction. The destructor is careful to delete
+   the pointers only once, since sharing cost functions is allowed.
+
+.. member:: Ownership Problem::Options::loss_function_ownership
+
+   Default: ``TAKE_OWNERSHIP``
+
+   This option controls whether the Problem object owns the loss
+   functions.
+
+   If set to TAKE_OWNERSHIP, then the problem object will delete the
+   loss functions on destruction. The destructor is careful to delete
+   the pointers only once, since sharing loss functions is allowed.
+
+.. member:: Ownership Problem::Options::local_parameterization_ownership
+
+   Default: ``TAKE_OWNERSHIP``
+
+   This option controls whether the Problem object owns the local
+   parameterizations.
+
+   If set to TAKE_OWNERSHIP, then the problem object will delete the
+   local parameterizations on destruction. The destructor is careful
+   to delete the pointers only once, since sharing local
+   parameterizations is allowed.
+
+.. member:: bool Problem::Options::enable_fast_removal
+
+    Default: ``false``
+
+    If true, trades memory for faster
+    :member:`Problem::RemoveResidualBlock` and
+    :member:`Problem::RemoveParameterBlock` operations.
+
+    By default, :member:`Problem::RemoveParameterBlock` and
+    :member:`Problem::RemoveResidualBlock` take time proportional to
+    the size of the entire problem.  If you only ever remove
+    parameters or residuals from the problem occasionally, this might
+    be acceptable.  However, if you have memory to spare, enable this
+    option to make :member:`Problem::RemoveParameterBlock` take time
+    proportional to the number of residual blocks that depend on it,
+    and :member:`Problem::RemoveResidualBlock` take (on average)
+    constant time.
+
+    The increase in memory usage is twofold: an additional hash set
+    per parameter block containing all the residuals that depend on
+    the parameter block; and a hash set in the problem containing all
+    residuals.
+
+.. member:: bool Problem::Options::disable_all_safety_checks
+
+    Default: `false`
+
+    By default, Ceres performs a variety of safety checks when
+    constructing the problem. There is a small but measurable
+    performance penalty to these checks, typically around 5% of
+    construction time. If you are sure your problem construction is
+    correct, and 5% of the problem construction time is truly an
+    overhead you want to avoid, then you can set
+    disable_all_safety_checks to true.
+
+    **WARNING** Do not set this to true, unless you are absolutely
+    sure of what you are doing.
+
+.. member:: Context* Problem::Options::context
+
+    Default: `nullptr`
+
+    A Ceres global context to use for solving this problem. This may
+    help to reduce computation time as Ceres can reuse expensive
+    objects to create.  The context object can be `nullptr`, in which
+    case Ceres may create one.
+
+    Ceres does NOT take ownership of the pointer.
+
+.. member:: EvaluationCallback* Problem::Options::evaluation_callback
+
+    Default: `nullptr`
+
+    Using this callback interface, Ceres can notify you when it is
+    about to evaluate the residuals or Jacobians. With the callback,
+    you can share computation between residual blocks by doing the
+    shared computation in
+    :member:`EvaluationCallback::PrepareForEvaluation` before Ceres
+    calls :member:`CostFunction::Evaluate`. It also enables caching
+    results between a pure residual evaluation and a residual &
+    Jacobian evaluation.
+
+    Problem does NOT take ownership of the callback.
+
+    .. NOTE::
+
+       Evaluation callbacks are incompatible with inner iterations. So
+       calling Solve with
+       :member:`Solver::Options::use_inner_iterations` set to `true`
+       on a :class:`Problem` with a non-null evaluation callback is an
+       error.
+
 .. function:: ResidualBlockId Problem::AddResidualBlock(CostFunction* cost_function, LossFunction* loss_function, const vector<double*> parameter_blocks)
 .. function:: ResidualBlockId Problem::AddResidualBlock(CostFunction* cost_function, LossFunction* loss_function, double *x0, double *x1, ...)
 
@@ -1745,15 +1855,15 @@
    blocks for a parameter block will incur a scan of the entire
    :class:`Problem` object.
 
-.. function:: const CostFunction* GetCostFunctionForResidualBlock(const ResidualBlockId residual_block) const
+.. function:: const CostFunction* Problem::GetCostFunctionForResidualBlock(const ResidualBlockId residual_block) const
 
    Get the :class:`CostFunction` for the given residual block.
 
-.. function:: const LossFunction* GetLossFunctionForResidualBlock(const ResidualBlockId residual_block) const
+.. function:: const LossFunction* Problem::GetLossFunctionForResidualBlock(const ResidualBlockId residual_block) const
 
    Get the :class:`LossFunction` for the given residual block.
 
-.. function::  bool EvaluateResidualBlock(ResidualBlockId residual_block_id, bool apply_loss_function, double* cost,double* residuals, double** jacobians) const;
+.. function::  bool EvaluateResidualBlock(ResidualBlockId residual_block_id, bool apply_loss_function, double* cost,double* residuals, double** jacobians) const
 
    Evaluates the residual block, storing the scalar cost in ``cost``, the
    residual components in ``residuals``, and the jacobians between the
@@ -1783,8 +1893,21 @@
 
    .. NOTE::
 
-      TODO(sameeragarwal): Clarify interaction with IterationCallback
-      once that cleanup is done.
+      If an :class:`EvaluationCallback` is associated with the problem
+      then it is the user's responsibility to call
+      :func:`EvaluationCalback::PrepareForEvaluation` it before
+      calling this method.
+
+      This is because, if the user calls this method multiple times,
+      we cannot tell if the underlying parameter blocks have changed
+      between calls or not. So if ``EvaluateResidualBlock`` was
+      responsible for calling the
+      :func:`EvaluationCalback::PrepareForEvaluation`, it will have to
+      do it everytime it is called. Which makes the common case where
+      the parameter blocks do not change, inefficient. So we leave it
+      to the user to call the
+      :func:`EvaluationCalback::PrepareForEvaluation` as needed.
+
 
 .. function:: bool Problem::Evaluate(const Problem::EvaluateOptions& options, double* cost, vector<double>* residuals, vector<double>* gradient, CRSMatrix* jacobian)
 
@@ -1832,6 +1955,12 @@
       :class:`IterationCallback` at the end of an iteration during a
       solve.
 
+   .. NOTE::
+
+      If an EvaluationCallback is associated with the problem, then
+      its PrepareForEvaluation method will be called everytime this
+      method is called with ``new_point = true``.
+
 .. class:: Problem::EvaluateOptions
 
    Options struct that is used to control :func:`Problem::Evaluate`.
@@ -1873,7 +2002,64 @@
 
    Number of threads to use. (Requires OpenMP).
 
-..
+
+:class:`EvaluationCallback`
+===========================
+
+.. class:: EvaluationCallback
+
+   Interface for receiving callbacks before Ceres evaluates residuals or
+   Jacobians:
+
+   .. code-block:: c++
+
+      class EvaluationCallback {
+       public:
+        virtual ~EvaluationCallback() {}
+        virtual void PrepareForEvaluation()(bool evaluate_jacobians
+                                            bool new_evaluation_point) = 0;
+      };
+
+   Ceres will call ``PrepareForEvaluation()`` every time, and once
+   before it computes the residuals and/or the Jacobians.
+
+   User parameters (the double* values provided by the us)
+   are fixed until the next call to ``PrepareForEvaluation()``. If
+   ``new_evaluation_point == true``, then this is a new point that is
+   different from the last evaluated point. Otherwise, it is the same
+   point that was evaluated previously (either Jacobian or residual)
+   and the user can use cached results from previous evaluations. If
+   ``evaluate_jacobians`` is true, then Ceres will request Jacobians
+   in the upcoming cost evaluation.
+
+   Using this callback interface, Ceres can notify you when it is about
+   to evaluate the residuals or Jacobians. With the callback, you can
+   share computation between residual blocks by doing the shared
+   computation in PrepareForEvaluation() before Ceres calls
+   CostFunction::Evaluate() on all the residuals. It also enables
+   caching results between a pure residual evaluation and a residual &
+   Jacobian evaluation, via the new_evaluation_point argument.
+
+   One use case for this callback is if the cost function compute is
+   moved to the GPU. In that case, the prepare call does the actual cost
+   function evaluation, and subsequent calls from Ceres to the actual
+   cost functions merely copy the results from the GPU onto the
+   corresponding blocks for Ceres to plug into the solver.
+
+   **Note**: Ceres provides no mechanism to share data other than the
+   notification from the callback. Users must provide access to
+   pre-computed shared data to their cost functions behind the scenes;
+   this all happens without Ceres knowing. One approach is to put a
+   pointer to the shared data in each cost function (recommended) or to
+   use a global shared variable (discouraged; bug-prone).  As far as
+   Ceres is concerned, it is evaluating cost functions like any other;
+   it just so happens that behind the scenes the cost functions reuse
+   pre-computed data to execute faster.
+
+   See ``evaluation_callback_test.cc`` for code that explicitly verifies
+   the preconditions between ``PrepareForEvaluation()`` and
+   ``CostFunction::Evaluate()``.
+
 ``rotation.h``
 ==============
 
diff --git a/docs/source/nnls_solving.rst b/docs/source/nnls_solving.rst
index fde62b9..3a2ac01 100644
--- a/docs/source/nnls_solving.rst
+++ b/docs/source/nnls_solving.rst
@@ -1413,6 +1413,10 @@
    on each Newton/Trust region step using a coordinate descent
    algorithm.  For more details, see :ref:`section-inner-iterations`.
 
+   **Note** Inner iterations cannot be used with :class:`Problem`
+   objects that have an :class:`EvaluationCallback` associated with
+   them.
+
 .. member:: double Solver::Options::inner_iteration_tolerance
 
    Default: ``1e-3``
@@ -1603,63 +1607,40 @@
    which break this finite difference heuristic, but they do not come
    up often in practice.
 
-.. member:: vector<IterationCallback> Solver::Options::callbacks
-
-   Callbacks that are executed at the end of each iteration of the
-   :class:`Minimizer`. They are executed in the order that they are
-   specified in this vector. By default, parameter blocks are updated
-   only at the end of the optimization, i.e., when the
-   :class:`Minimizer` terminates. This behavior is controlled by
-   :member:`Solver::Options::update_state_every_iteration`. If the user
-   wishes to have access to the updated parameter blocks when his/her
-   callbacks are executed, then set
-   :member:`Solver::Options::update_state_every_iteration` to true.
-
-   The solver does NOT take ownership of these pointers.
-
 .. member:: bool Solver::Options::update_state_every_iteration
 
    Default: ``false``
 
-   If true, the user's parameter blocks are updated at the end of
-   every Minimizer iteration, otherwise they are updated when the
-   Minimizer terminates. This is useful if, for example, the user
-   wishes to visualize the state of the optimization every iteration
-   (in combination with an IterationCallback).
+   If ``update_state_every_iteration`` is ``true``, then Ceres Solver
+   will guarantee that at the end of every iteration and before any
+   user :class:`IterationCallback` is called, the parameter blocks are
+   updated to the current best solution found by the solver. Thus the
+   IterationCallback can inspect the values of the parameter blocks
+   for purposes of computation, visualization or termination.
 
-   **Note**: If :member:`Solver::Options::evaluation_callback` is set,
-   then the behaviour of this flag is slightly different in each case:
+   If ``update_state_every_iteration`` is ``false`` then there is no
+   such guarantee, and user provided :class:`IterationCallback` s should
+   not expect to look at the parameter blocks and interpret their
+   values.
 
-   1. If :member:`Solver::Options::update_state_every_iteration` is
-      false, then the user's state is changed at every residual and/or
-      jacobian evaluation. Any user provided IterationCallbacks should
-      **not** inspect and depend on the user visible state while the
-      solver is running, since they it have undefined contents.
+.. member:: vector<IterationCallback> Solver::Options::callbacks
 
-   2. If :member:`Solver::Options::update_state_every_iteration` is
-      false, then the user's state is changed at every residual and/or
-      jacobian evaluation, BUT the solver will ensure that before the
-      user provided `IterationCallbacks` are called, the user visible
-      state will be updated to the current best point found by the
-      solver.
+   Callbacks that are executed at the end of each iteration of the
+   :class:`Minimizer`. They are executed in the order that they are
+   specified in this vector.
 
-.. member:: bool Solver::Options::evaluation_callback
+   By default, parameter blocks are updated only at the end of the
+   optimization, i.e., when the :class:`Minimizer` terminates. This
+   means that by default, if an :class:`IterationCallback` inspects
+   the parameter blocks, they will not see them changing in the course
+   of the optimization.
 
-   Default: ``NULL``
+   To tell Ceres to update the parameter blocks at the end of each
+   iteration and before calling the user's callback, set
+   :member:`Solver::Options::update_state_every_iteration` to
+   ``true``.
 
-   If non-``NULL``, gets notified when Ceres is about to evaluate the
-   residuals and/or Jacobians. This enables sharing computation between
-   residuals, which in some cases is important for efficient cost
-   evaluation. See :class:`EvaluationCallback` for details.
-
-   **Note**: Evaluation callbacks are incompatible with inner
-   iterations.
-
-   **Warning**: This interacts with
-   :member:`Solver::Options::update_state_every_iteration`. See the
-   documentation for that option for more details.
-
-   The solver does `not`  take ownership of the pointer.
+   The solver does NOT take ownership of these pointers.
 
 :class:`ParameterBlockOrdering`
 ===============================
@@ -1720,62 +1701,6 @@
 
    Number of groups with one or more elements.
 
-:class:`EvaluationCallback`
-===========================
-
-.. class:: EvaluationCallback
-
-   Interface for receiving callbacks before Ceres evaluates residuals or
-   Jacobians:
-
-   .. code-block:: c++
-
-      class EvaluationCallback {
-       public:
-        virtual ~EvaluationCallback() {}
-        virtual void PrepareForEvaluation()(bool evaluate_jacobians
-                                            bool new_evaluation_point) = 0;
-      };
-
-   ``PrepareForEvaluation()`` is called before Ceres requests residuals
-   or jacobians for a given setting of the parameters. User parameters
-   (the double* values provided to the cost functions) are fixed until
-   the next call to ``PrepareForEvaluation()``. If
-   ``new_evaluation_point == true``, then this is a new point that is
-   different from the last evaluated point. Otherwise, it is the same
-   point that was evaluated previously (either jacobian or residual) and
-   the user can use cached results from previous evaluations. If
-   ``evaluate_jacobians`` is true, then Ceres will request jacobians in
-   the upcoming cost evaluation.
-
-   Using this callback interface, Ceres can notify you when it is about
-   to evaluate the residuals or jacobians. With the callback, you can
-   share computation between residual blocks by doing the shared
-   computation in PrepareForEvaluation() before Ceres calls
-   CostFunction::Evaluate() on all the residuals. It also enables
-   caching results between a pure residual evaluation and a residual &
-   jacobian evaluation, via the new_evaluation_point argument.
-
-   One use case for this callback is if the cost function compute is
-   moved to the GPU. In that case, the prepare call does the actual cost
-   function evaluation, and subsequent calls from Ceres to the actual
-   cost functions merely copy the results from the GPU onto the
-   corresponding blocks for Ceres to plug into the solver.
-
-   **Note**: Ceres provides no mechanism to share data other than the
-   notification from the callback. Users must provide access to
-   pre-computed shared data to their cost functions behind the scenes;
-   this all happens without Ceres knowing. One approach is to put a
-   pointer to the shared data in each cost function (recommended) or to
-   use a global shared variable (discouraged; bug-prone).  As far as
-   Ceres is concerned, it is evaluating cost functions like any other;
-   it just so happens that behind the scenes the cost functions reuse
-   pre-computed data to execute faster.
-
-   See ``evaluation_callback_test.cc`` for code that explicitly verifies
-   the preconditions between ``PrepareForEvaluation()`` and
-   ``CostFunction::Evaluate()``.
-
 :class:`IterationCallback`
 ==========================
 
diff --git a/include/ceres/ceres.h b/include/ceres/ceres.h
index 6e077cc..88875a0 100644
--- a/include/ceres/ceres.h
+++ b/include/ceres/ceres.h
@@ -46,6 +46,7 @@
 #include "ceres/dynamic_cost_function.h"
 #include "ceres/dynamic_cost_function_to_functor.h"
 #include "ceres/dynamic_numeric_diff_cost_function.h"
+#include "ceres/evaluation_callback.h"
 #include "ceres/gradient_checker.h"
 #include "ceres/gradient_problem.h"
 #include "ceres/gradient_problem_solver.h"
diff --git a/include/ceres/evaluation_callback.h b/include/ceres/evaluation_callback.h
index a0a8601..24122a8 100644
--- a/include/ceres/evaluation_callback.h
+++ b/include/ceres/evaluation_callback.h
@@ -35,28 +35,31 @@
 
 namespace ceres {
 
-// Using this callback interface, Ceres can notify you when it is about to
-// evaluate the residuals or jacobians. With the callback, you can share
-// computation between residual blocks by doing the shared computation in
-// PrepareForEvaluation() before Ceres calls CostFunction::Evaluate() on all
-// the residuals. It also enables caching results between a pure residual
-// evaluation and a residual & jacobian evaluation, via the
-// new_evaluation_point argument.
+// Using this callback interface, Ceres can notify you when it is
+// about to evaluate the residuals or jacobians. With the callback,
+// you can share computation between residual blocks by doing the
+// shared computation in PrepareForEvaluation() before Ceres calls
+// CostFunction::Evaluate(). It also enables caching results between a
+// pure residual evaluation and a residual & jacobian evaluation, via
+// the new_evaluation_point argument.
 //
-// One use case for this callback is if the cost function compute is moved to
-// the GPU. In that case, the prepare call does the actual cost function
-// evaluation, and subsequent calls from Ceres to the actual cost functions
-// merely copy the results from the GPU onto the corresponding blocks for Ceres
-// to plug into the solver.
+// One use case for this callback is if the cost function compute is
+// moved to the GPU. In that case, the prepare call does the actual
+// cost function evaluation, and subsequent calls from Ceres to the
+// actual cost functions merely copy the results from the GPU onto the
+// corresponding blocks for Ceres to plug into the solver.
 //
-// NOTE: Ceres provides no mechanism to share data other than the notification
-// from the callback. Users must provide access to pre-computed shared data to
-// their cost functions behind the scenes; this all happens without Ceres
-// knowing. One approach is to put a pointer to the shared data in each cost
-// function (recommended) or to use a global shared variable (discouraged;
-// bug-prone).  As far as Ceres is concerned, it is evaluating cost functions
-// like any other; it just so happens that behind the scenes the cost functions
-// reuse pre-computed data to execute faster.
+// NOTE: Ceres provides no mechanism to share data other than the
+// notification from the callback. Users must provide access to
+// pre-computed shared data to their cost functions behind the scenes;
+// this all happens without Ceres knowing.
+//
+// One approach is to put a pointer to the shared data in each cost
+// function (recommended) or to use a global shared variable
+// (discouraged; bug-prone).  As far as Ceres is concerned, it is
+// evaluating cost functions like any other; it just so happens that
+// behind the scenes the cost functions reuse pre-computed data to
+// execute faster.
 class CERES_EXPORT EvaluationCallback {
  public:
   virtual ~EvaluationCallback() {}
diff --git a/include/ceres/problem.h b/include/ceres/problem.h
index 366d6ac..1b57eec 100644
--- a/include/ceres/problem.h
+++ b/include/ceres/problem.h
@@ -50,6 +50,7 @@
 namespace ceres {
 
 class CostFunction;
+class EvaluationCallback;
 class LossFunction;
 class LocalParameterization;
 class Solver;
@@ -165,6 +166,23 @@
     //
     // Ceres does NOT take ownership of the pointer.
     Context* context = nullptr;
+
+    // Using this callback interface, Ceres can notify you when it is
+    // about to evaluate the residuals or jacobians. With the
+    // callback, you can share computation between residual blocks by
+    // doing the shared computation in
+    // EvaluationCallback::PrepareForEvaluation() before Ceres calls
+    // CostFunction::Evaluate(). It also enables caching results
+    // between a pure residual evaluation and a residual & jacobian
+    // evaluation.
+    //
+    // Problem DOES NOT take ownership of the callback.
+    //
+    // NOTE: Evaluation callbacks are incompatible with inner
+    // iterations. So calling Solve with
+    // Solver::Options::use_inner_iterations = true on a Problem with
+    // a non-null evaluation callback is an error.
+    EvaluationCallback* evaluation_callback = nullptr;
   };
 
   // The default constructor is equivalent to the
@@ -448,6 +466,10 @@
   // Note 3: This function cannot be called while the problem is being
   // solved, for example it cannot be called from an IterationCallback
   // at the end of an iteration during a solve.
+  //
+  // Note 4: If an EvaluationCallback is associated with the problem,
+  // then its PrepareForEvaluation method will be called everytime
+  // this method is called with new_point = true.
   bool Evaluate(const EvaluateOptions& options,
                 double* cost,
                 std::vector<double>* residuals,
@@ -480,8 +502,17 @@
   // apply_loss_function as the name implies allows the user to switch
   // the application of the loss function on and off.
   //
-  // TODO(sameeragarwal): Clarify interaction with IterationCallback
-  // once that cleanup is done.
+  // WARNING: If an EvaluationCallback is associated with the problem
+  // then it is the user's responsibility to call it before calling
+  // this method.
+  //
+  // This is because, if the user calls this method multiple times, we
+  // cannot tell if the underlying parameter blocks have changed
+  // between calls or not. So if EvaluateResidualBlock was responsible
+  // for calling the EvaluationCallback, it will have to do it
+  // everytime it is called. Which makes the common case where the
+  // parameter blocks do not change, inefficient. So we leave it to
+  // the user to call the EvaluationCallback as needed.
   bool EvaluateResidualBlock(ResidualBlockId residual_block_id,
                              bool apply_loss_function,
                              double* cost,
diff --git a/include/ceres/solver.h b/include/ceres/solver.h
index 10c2683..1e479ae 100644
--- a/include/ceres/solver.h
+++ b/include/ceres/solver.h
@@ -36,7 +36,6 @@
 #include <string>
 #include <vector>
 #include "ceres/crs_matrix.h"
-#include "ceres/evaluation_callback.h"
 #include "ceres/internal/disable_warnings.h"
 #include "ceres/internal/port.h"
 #include "ceres/iteration_callback.h"
@@ -697,26 +696,18 @@
     // optimistic. This number should be exposed for users to change.
     double gradient_check_numeric_derivative_relative_step_size = 1e-6;
 
-    // If true, the user's parameter blocks are updated at the end of
-    // every Minimizer iteration, otherwise they are updated when the
-    // Minimizer terminates. This is useful if, for example, the user
-    // wishes to visualize the state of the optimization every iteration
-    // (in combination with an IterationCallback).
-    //
-    // NOTE: If an evaluation_callback is provided, then the behaviour
-    // of this flag is slightly different in each case:
-    //
-    // (1) If update_state_every_iteration = false, then the user's
-    // state is changed at every residual and/or jacobian evaluation.
-    // Any user provided IterationCallbacks should NOT inspect and
-    // depend on the user visible state while the solver is running,
-    // since there will be undefined contents.
-    //
-    // (2) If update_state_every_iteration is true, then the user's
-    // state is changed at every residual and/or jacobian evaluation,
-    // BUT the solver will ensure that before the user provided
-    // IterationCallbacks are called, the user visible state will be
-    // updated to the current best point found by the solver.
+    // If update_state_every_iteration is true, then Ceres Solver will
+    // guarantee that at the end of every iteration and before any
+    // user provided IterationCallback is called, the parameter blocks
+    // are updated to the current best solution found by the
+    // solver. Thus the IterationCallback can inspect the values of
+    // the parameter blocks for purposes of computation, visualization
+    // or termination.
+
+    // If update_state_every_iteration is false then there is no such
+    // guarantee, and user provided IterationCallbacks should not
+    // expect to look at the parameter blocks and interpret their
+    // values.
     bool update_state_every_iteration = false;
 
     // Callbacks that are executed at the end of each iteration of the
@@ -735,19 +726,6 @@
     //
     // The solver does NOT take ownership of these pointers.
     std::vector<IterationCallback*> callbacks;
-
-    // If non-NULL, gets notified when Ceres is about to evaluate the
-    // residuals and/or Jacobians. This enables sharing computation
-    // between residuals, which in some cases is important for efficient
-    // cost evaluation. See evaluation_callback.h for details.
-    //
-    // NOTE: Evaluation callbacks are incompatible with inner iterations.
-    //
-    // WARNING: This interacts with update_state_every_iteration. See
-    // the documentation for that option for more details.
-    //
-    // The solver does NOT take ownership of the pointer.
-    EvaluationCallback* evaluation_callback = nullptr;
   };
 
   struct CERES_EXPORT Summary {
diff --git a/internal/ceres/evaluation_callback_test.cc b/internal/ceres/evaluation_callback_test.cc
index 9ca500f..dff0943 100644
--- a/internal/ceres/evaluation_callback_test.cc
+++ b/internal/ceres/evaluation_callback_test.cc
@@ -35,6 +35,7 @@
 #include <vector>
 
 #include "gtest/gtest.h"
+#include "ceres/evaluation_callback.h"
 #include "ceres/sized_cost_function.h"
 #include "ceres/problem.h"
 #include "ceres/problem_impl.h"
@@ -193,6 +194,7 @@
 
   WigglyBowlCostFunctionAndEvaluationCallback cost_function(parameters);
   Problem::Options problem_options;
+  problem_options.evaluation_callback = &cost_function;
   problem_options.cost_function_ownership = DO_NOT_TAKE_OWNERSHIP;
   Problem problem(problem_options);
   problem.AddResidualBlock(&cost_function, NULL, parameters);
@@ -200,7 +202,6 @@
   Solver::Options options;
   options.linear_solver_type = DENSE_QR;
   options.max_num_iterations = 300;  // Cost function is hard.
-  options.evaluation_callback = &cost_function;
 
   // Run the solve. Checking is done inside the cost function / callback.
   Solver::Summary summary;
@@ -240,6 +241,7 @@
 
   WigglyBowlCostFunctionAndEvaluationCallback cost_function(parameters);
   Problem::Options problem_options;
+  problem_options.evaluation_callback = &cost_function;
   problem_options.cost_function_ownership = DO_NOT_TAKE_OWNERSHIP;
   Problem problem(problem_options);
   problem.AddResidualBlock(&cost_function, NULL, parameters);
@@ -248,7 +250,7 @@
   options.linear_solver_type = DENSE_QR;
   options.max_num_iterations = 300;  // Cost function is hard.
   options.minimizer_type = ceres::LINE_SEARCH;
-  options.evaluation_callback = &cost_function;
+
   options.line_search_type = line_search;
   options.line_search_direction_type = line_search_direction;
   options.line_search_interpolation_type = line_search_interpolation;
diff --git a/internal/ceres/line_search_preprocessor.cc b/internal/ceres/line_search_preprocessor.cc
index 17226ad..5a21809 100644
--- a/internal/ceres/line_search_preprocessor.cc
+++ b/internal/ceres/line_search_preprocessor.cc
@@ -60,7 +60,8 @@
   pp->evaluator_options.num_eliminate_blocks = 0;
   pp->evaluator_options.num_threads = pp->options.num_threads;
   pp->evaluator_options.context = pp->problem->context();
-  pp->evaluator_options.evaluation_callback = pp->options.evaluation_callback;
+  pp->evaluator_options.evaluation_callback =
+      pp->reduced_program->mutable_evaluation_callback();
   pp->evaluator.reset(Evaluator::Create(pp->evaluator_options,
                                         pp->reduced_program.get(),
                                         &pp->error));
diff --git a/internal/ceres/problem_impl.cc b/internal/ceres/problem_impl.cc
index 523d5bd..63dad12 100644
--- a/internal/ceres/problem_impl.cc
+++ b/internal/ceres/problem_impl.cc
@@ -47,6 +47,7 @@
 #include "ceres/context_impl.h"
 #include "ceres/cost_function.h"
 #include "ceres/crs_matrix.h"
+#include "ceres/evaluation_callback.h"
 #include "ceres/evaluator.h"
 #include "ceres/internal/fixed_array.h"
 #include "ceres/internal/port.h"
@@ -244,6 +245,7 @@
 
 ProblemImpl::ProblemImpl(const Problem::Options& options)
     : options_(options), program_(new internal::Program) {
+  program_->evaluation_callback_ = options.evaluation_callback;
   InitializeContext(options_.context, &context_impl_, &context_impl_owned_);
 }
 
@@ -688,7 +690,8 @@
   // The main thread also does work so we only need to launch num_threads - 1.
   context_impl_->EnsureMinimumThreads(evaluator_options.num_threads - 1);
   evaluator_options.context = context_impl_;
-
+  evaluator_options.evaluation_callback =
+      program_->mutable_evaluation_callback();
   std::unique_ptr<Evaluator> evaluator(
       new ProgramEvaluator<ScratchEvaluatePreparer,
                            CompressedRowJacobianWriter>(evaluator_options,
diff --git a/internal/ceres/problem_impl.h b/internal/ceres/problem_impl.h
index 106992d..f366b7d 100644
--- a/internal/ceres/problem_impl.h
+++ b/internal/ceres/problem_impl.h
@@ -53,6 +53,7 @@
 namespace ceres {
 
 class CostFunction;
+class EvaluationCallback;
 class LossFunction;
 class LocalParameterization;
 struct CRSMatrix;
diff --git a/internal/ceres/program.cc b/internal/ceres/program.cc
index f1cd1bb..fa3fbf1 100644
--- a/internal/ceres/program.cc
+++ b/internal/ceres/program.cc
@@ -62,7 +62,8 @@
 
 Program::Program(const Program& program)
     : parameter_blocks_(program.parameter_blocks_),
-      residual_blocks_(program.residual_blocks_) {
+      residual_blocks_(program.residual_blocks_),
+      evaluation_callback_(program.evaluation_callback_){
 }
 
 const vector<ParameterBlock*>& Program::parameter_blocks() const {
@@ -81,6 +82,10 @@
   return &residual_blocks_;
 }
 
+EvaluationCallback* Program::mutable_evaluation_callback() {
+  return evaluation_callback_;
+}
+
 bool Program::StateVectorToParameterBlocks(const double *state) {
   for (int i = 0; i < parameter_blocks_.size(); ++i) {
     if (!parameter_blocks_[i]->IsConstant() &&
diff --git a/internal/ceres/program.h b/internal/ceres/program.h
index 38c958f..297be65 100644
--- a/internal/ceres/program.h
+++ b/internal/ceres/program.h
@@ -37,6 +37,9 @@
 #include "ceres/internal/port.h"
 
 namespace ceres {
+
+class EvaluationCallback;
+
 namespace internal {
 
 class ParameterBlock;
@@ -64,6 +67,7 @@
   const std::vector<ResidualBlock*>& residual_blocks() const;
   std::vector<ParameterBlock*>* mutable_parameter_blocks();
   std::vector<ResidualBlock*>* mutable_residual_blocks();
+  EvaluationCallback* mutable_evaluation_callback();
 
   // Serialize to/from the program and update states.
   //
@@ -182,6 +186,7 @@
   // The Program does not own the ParameterBlock or ResidualBlock objects.
   std::vector<ParameterBlock*> parameter_blocks_;
   std::vector<ResidualBlock*> residual_blocks_;
+  EvaluationCallback* evaluation_callback_ = nullptr;
 
   friend class ProblemImpl;
 };
diff --git a/internal/ceres/solver.cc b/internal/ceres/solver.cc
index 14e50f3..84a5e5a 100644
--- a/internal/ceres/solver.cc
+++ b/internal/ceres/solver.cc
@@ -128,14 +128,6 @@
     OPTION_GE(inner_iteration_tolerance, 0.0);
   }
 
-  if (options.use_inner_iterations &&
-      options.evaluation_callback != NULL) {
-    *error =  "Inner iterations (use_inner_iterations = true) can't be "
-        "combined with an evaluation callback "
-        "(options.evaluation_callback != NULL).";
-    return false;
-  }
-
   if (options.use_nonmonotonic_steps) {
     OPTION_GT(max_consecutive_nonmonotonic_steps, 0);
   }
diff --git a/internal/ceres/solver_test.cc b/internal/ceres/solver_test.cc
index 6fb5f74..02494de 100644
--- a/internal/ceres/solver_test.cc
+++ b/internal/ceres/solver_test.cc
@@ -94,15 +94,13 @@
   }
 };
 
-TEST(Solver, UpdateStateEveryIterationOption) {
+TEST(Solver, UpdateStateEveryIterationOptionNoEvaluationCallback) {
   double x = 50.0;
   const double original_x = x;
 
-  std::unique_ptr<CostFunction> cost_function(QuadraticCostFunctor::Create());
   Problem::Options problem_options;
-  problem_options.cost_function_ownership = DO_NOT_TAKE_OWNERSHIP;
   Problem problem(problem_options);
-  problem.AddResidualBlock(cost_function.get(), NULL, &x);
+  problem.AddResidualBlock(QuadraticCostFunctor::Create(), nullptr, &x);
 
   Solver::Options options;
   options.linear_solver_type = DENSE_QR;
@@ -114,14 +112,7 @@
 
   int num_iterations;
 
-  // There are four cases that need to be checked:
-  //
-  //   (update_state_every_iteration = true|false) X
-  //   (evaluation_callback = NULL|provided)
-  //
-  // These need to get checked since there is some interaction between them.
-
-  // First: update_state_every_iteration=false, evaluation_callback=NULL.
+  // First: update_state_every_iteration=false, evaluation_callback=nullptr.
   Solve(options, &problem, &summary);
   num_iterations = summary.num_successful_steps +
                    summary.num_unsuccessful_steps;
@@ -130,7 +121,7 @@
     EXPECT_EQ(50.0, callback.x_values[i]);
   }
 
-  // Second: update_state_every_iteration=true, evaluation_callback=NULL.
+  // Second: update_state_every_iteration=true, evaluation_callback=nullptr.
   x = 50.0;
   options.update_state_every_iteration = true;
   callback.x_values.clear();
@@ -140,34 +131,75 @@
   EXPECT_GT(num_iterations, 1);
   EXPECT_EQ(original_x, callback.x_values[0]);
   EXPECT_NE(original_x, callback.x_values[1]);
-
-  NoOpEvaluationCallback evaluation_callback;
-
-  // Third: update_state_every_iteration=true, evaluation_callback=!NULL.
-  x = 50.0;
-  options.update_state_every_iteration = true;
-  options.evaluation_callback = &evaluation_callback;
-  callback.x_values.clear();
-  Solve(options, &problem, &summary);
-  num_iterations = summary.num_successful_steps +
-                   summary.num_unsuccessful_steps;
-  EXPECT_GT(num_iterations, 1);
-  EXPECT_EQ(original_x, callback.x_values[0]);
-  EXPECT_NE(original_x, callback.x_values[1]);
-
-  // Fourth: update_state_every_iteration=false, evaluation_callback=!NULL.
-  x = 50.0;
-  options.update_state_every_iteration = false;
-  options.evaluation_callback = &evaluation_callback;
-  callback.x_values.clear();
-  Solve(options, &problem, &summary);
-  num_iterations = summary.num_successful_steps +
-                   summary.num_unsuccessful_steps;
-  EXPECT_GT(num_iterations, 1);
-  EXPECT_EQ(original_x, callback.x_values[0]);
-  EXPECT_NE(original_x, callback.x_values[1]);
 }
 
+TEST(Solver, UpdateStateEveryIterationOptionWithEvaluationCallback) {
+  double x = 50.0;
+  const double original_x = x;
+
+  Problem::Options problem_options;
+  NoOpEvaluationCallback evaluation_callback;
+  problem_options.evaluation_callback = &evaluation_callback;
+
+  Problem problem(problem_options);
+  problem.AddResidualBlock(QuadraticCostFunctor::Create(), nullptr, &x);
+
+  Solver::Options options;
+  options.linear_solver_type = DENSE_QR;
+  RememberingCallback callback(&x);
+  options.callbacks.push_back(&callback);
+
+  Solver::Summary summary;
+
+  int num_iterations;
+
+  // First: update_state_every_iteration=true, evaluation_callback=!nullptr.
+  x = 50.0;
+  options.update_state_every_iteration = true;
+  callback.x_values.clear();
+  Solve(options, &problem, &summary);
+  num_iterations = summary.num_successful_steps +
+                   summary.num_unsuccessful_steps;
+  EXPECT_GT(num_iterations, 1);
+  EXPECT_EQ(original_x, callback.x_values[0]);
+  EXPECT_NE(original_x, callback.x_values[1]);
+
+  // Second: update_state_every_iteration=false, evaluation_callback=!nullptr.
+  x = 50.0;
+  options.update_state_every_iteration = false;
+  callback.x_values.clear();
+  Solve(options, &problem, &summary);
+  num_iterations = summary.num_successful_steps +
+                   summary.num_unsuccessful_steps;
+  EXPECT_GT(num_iterations, 1);
+  EXPECT_EQ(original_x, callback.x_values[0]);
+  EXPECT_NE(original_x, callback.x_values[1]);
+}
+
+TEST(Solver, CantMixEvaluationCallbackWithInnerIterations) {
+  double x = 50.0;
+  double y = 60.0;
+
+  Problem::Options problem_options;
+  NoOpEvaluationCallback evaluation_callback;
+  problem_options.evaluation_callback = &evaluation_callback;
+
+  Problem problem(problem_options);
+  problem.AddResidualBlock(QuadraticCostFunctor::Create(), nullptr, &x);
+  problem.AddResidualBlock(QuadraticCostFunctor::Create(), nullptr, &y);
+
+  Solver::Options options;
+  options.use_inner_iterations = true;
+  Solver::Summary summary;
+  Solve(options, &problem, &summary);
+  EXPECT_EQ(summary.termination_type, FAILURE);
+
+  options.use_inner_iterations = false;
+  Solve(options, &problem, &summary);
+  EXPECT_EQ(summary.termination_type, CONVERGENCE);
+}
+
+
 // The parameters must be in separate blocks so that they can be individually
 // set constant or not.
 struct Quadratic4DCostFunction {
@@ -197,7 +229,7 @@
                         double* residuals,
                         double** jacobians) const {
     residuals[0] = parameters[0][0];
-    if (jacobians != NULL && jacobians[0] != NULL) {
+    if (jacobians != nullptr && jacobians[0] != nullptr) {
       jacobians[0][0] = 1.0;
     }
     return true;
@@ -259,7 +291,7 @@
 TEST(Solver, TrustRegionProblemIsConstant) {
   Problem problem;
   double x = 1;
-  problem.AddResidualBlock(new UnaryIdentityCostFunction, NULL, &x);
+  problem.AddResidualBlock(new UnaryIdentityCostFunction, nullptr, &x);
   problem.SetParameterBlockConstant(&x);
   Solver::Options options;
   options.minimizer_type = TRUST_REGION;
@@ -273,7 +305,7 @@
 TEST(Solver, LineSearchProblemIsConstant) {
   Problem problem;
   double x = 1;
-  problem.AddResidualBlock(new UnaryIdentityCostFunction, NULL, &x);
+  problem.AddResidualBlock(new UnaryIdentityCostFunction, nullptr, &x);
   problem.SetParameterBlockConstant(&x);
   Solver::Options options;
   options.minimizer_type = LINE_SEARCH;
@@ -438,30 +470,6 @@
   EXPECT_TRUE(options.IsValid(&message));
 }
 
-TEST(Solver, CantMixEvaluationCallbackWithInnerIterations) {
-  Solver::Options options;
-  NoOpEvaluationCallback evaluation_callback;
-  string message;
-
-  // Can't combine them.
-  options.use_inner_iterations = true;
-  options.evaluation_callback = &evaluation_callback;
-  EXPECT_FALSE(options.IsValid(&message));
-
-  // Either or none is OK.
-  options.use_inner_iterations = false;
-  options.evaluation_callback = &evaluation_callback;
-  EXPECT_TRUE(options.IsValid(&message));
-
-  options.use_inner_iterations = true;
-  options.evaluation_callback = NULL;
-  EXPECT_TRUE(options.IsValid(&message));
-
-  options.use_inner_iterations = false;
-  options.evaluation_callback = NULL;
-  EXPECT_TRUE(options.IsValid(&message));
-}
-
 template <int kNumResiduals, int... Ns>
 class DummyCostFunction : public SizedCostFunction<kNumResiduals, Ns...> {
  public:
@@ -479,7 +487,7 @@
 TEST(Solver, FixedCostForConstantProblem) {
   double x = 1.0;
   Problem problem;
-  problem.AddResidualBlock(new DummyCostFunction<2, 1>(), NULL, &x);
+  problem.AddResidualBlock(new DummyCostFunction<2, 1>(), nullptr, &x);
   problem.SetParameterBlockConstant(&x);
   const double expected_cost = 41.0 / 2.0;  // 1/2 * ((4 + 0)^2 + (4 + 1)^2)
   Solver::Options options;
diff --git a/internal/ceres/trust_region_preprocessor.cc b/internal/ceres/trust_region_preprocessor.cc
index aa7f095..dbeb3e5 100644
--- a/internal/ceres/trust_region_preprocessor.cc
+++ b/internal/ceres/trust_region_preprocessor.cc
@@ -256,7 +256,8 @@
   pp->evaluator_options.num_threads = options.num_threads;
   pp->evaluator_options.dynamic_sparsity = options.dynamic_sparsity;
   pp->evaluator_options.context = pp->problem->context();
-  pp->evaluator_options.evaluation_callback = options.evaluation_callback;
+  pp->evaluator_options.evaluation_callback =
+      pp->reduced_program->mutable_evaluation_callback();
   pp->evaluator.reset(Evaluator::Create(pp->evaluator_options,
                                         pp->reduced_program.get(),
                                         &pp->error));
@@ -273,6 +274,11 @@
     return true;
   }
 
+  if (pp->reduced_program->mutable_evaluation_callback()) {
+    pp->error = "Inner iterations cannot be used with EvaluationCallbacks";
+    return false;
+  }
+
   // With just one parameter block, the outer iteration of the trust
   // region method and inner iterations are doing exactly the same
   // thing, and thus inner iterations are not needed.