Evaluate ResidualBlocks without LossFunction if needed.

1. Add the ability to evaluate the problem without loss function.
2. Remove static Evaluator::Evaluate
3. Refactor the common code from problem_test.cc and
   evaluator_test.cc into evaluator_test_utils.cc

Change-Id: I1aa841580afe91d288fbb65288b0ffdd1e43e827
diff --git a/include/ceres/problem.h b/include/ceres/problem.h
index bab3bfe..b1ccbab 100644
--- a/include/ceres/problem.h
+++ b/include/ceres/problem.h
@@ -331,7 +331,8 @@
   // Options struct to control Problem::Evaluate.
   struct EvaluateOptions {
     EvaluateOptions()
-        : num_threads(1) {
+        : apply_loss_function(true),
+          num_threads(1) {
     }
 
     // The set of parameter blocks for which evaluation should be
@@ -360,6 +361,15 @@
     // they were added to the problem. But, this may change if the
     // user removes any residual blocks from the problem.
     vector<ResidualBlockId> residual_blocks;
+
+    // Even though the residual blocks in the problem may contain loss
+    // functions, setting apply_loss_function to false will turn off
+    // the application of the loss function to the output of the cost
+    // function. This is of use for example if the user wishes to
+    // analyse the solution quality by studying the distribution of
+    // residuals before and after the solve.
+    bool apply_loss_function;
+
     int num_threads;
   };
 
diff --git a/internal/ceres/CMakeLists.txt b/internal/ceres/CMakeLists.txt
index 5440713..703a9e7 100644
--- a/internal/ceres/CMakeLists.txt
+++ b/internal/ceres/CMakeLists.txt
@@ -215,7 +215,11 @@
 
 IF (${BUILD_TESTING} AND ${GFLAGS})
   ADD_LIBRARY(gtest gmock_gtest_all.cc gmock_main.cc)
-  ADD_LIBRARY(test_util test_util.cc numeric_diff_test_utils.cc)
+  ADD_LIBRARY(test_util
+              evaluator_test_utils.cc
+              numeric_diff_test_utils.cc
+              test_util.cc)
+
   TARGET_LINK_LIBRARIES(gtest ${GFLAGS_LIB} ${GLOG_LIB})
 
   MACRO (CERES_TEST NAME)
diff --git a/internal/ceres/evaluator.cc b/internal/ceres/evaluator.cc
index a3ce6f0..31a4176 100644
--- a/internal/ceres/evaluator.cc
+++ b/internal/ceres/evaluator.cc
@@ -72,76 +72,5 @@
   }
 }
 
-bool Evaluator::Evaluate(Program* program,
-                         int num_threads,
-                         double* cost,
-                         vector<double>* residuals,
-                         vector<double>* gradient,
-                         CRSMatrix* output_jacobian) {
-  CHECK_GE(num_threads, 1)
-      << "This is a Ceres bug; please contact the developers!";
-  CHECK_NOTNULL(cost);
-
-  // Setup the Parameter indices and offsets before an evaluator can
-  // be constructed and used.
-  program->SetParameterOffsetsAndIndex();
-
-  Evaluator::Options evaluator_options;
-  evaluator_options.linear_solver_type = SPARSE_NORMAL_CHOLESKY;
-  evaluator_options.num_threads = num_threads;
-
-  string error;
-  scoped_ptr<Evaluator> evaluator(
-      Evaluator::Create(evaluator_options, program, &error));
-  if (evaluator.get() == NULL) {
-    LOG(ERROR) << "Unable to create an Evaluator object. "
-               << "Error: " << error
-               << "This is a Ceres bug; please contact the developers!";
-    return false;
-  }
-
-  if (residuals !=NULL) {
-    residuals->resize(evaluator->NumResiduals());
-  }
-
-  if (gradient != NULL) {
-    gradient->resize(evaluator->NumEffectiveParameters());
-  }
-
-  scoped_ptr<CompressedRowSparseMatrix> jacobian;
-  if (output_jacobian != NULL) {
-    jacobian.reset(
-        down_cast<CompressedRowSparseMatrix*>(evaluator->CreateJacobian()));
-  }
-
-  // Point the state pointers to the user state pointers. This is
-  // needed so that we can extract a parameter vector which is then
-  // passed to Evaluator::Evaluate.
-  program->SetParameterBlockStatePtrsToUserStatePtrs();
-
-  // Copy the value of the parameter blocks into a vector, since the
-  // Evaluate::Evaluate method needs its input as such. The previous
-  // call to SetParameterBlockStatePtrsToUserStatePtrs ensures that
-  // these values are the ones corresponding to the actual state of
-  // the parameter blocks, rather than the temporary state pointer
-  // used for evaluation.
-  Vector parameters(program->NumParameters());
-  program->ParameterBlocksToStateVector(parameters.data());
-
-  if (!evaluator->Evaluate(parameters.data(),
-                           cost,
-                           residuals != NULL ? &(*residuals)[0] : NULL,
-                           gradient != NULL ? &(*gradient)[0] : NULL,
-                           jacobian.get())) {
-    return false;
-  }
-
-  if (output_jacobian != NULL) {
-    jacobian->ToCRSMatrix(output_jacobian);
-  }
-
-  return true;
-}
-
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/evaluator.h b/internal/ceres/evaluator.h
index 14a8818..07cfa37 100644
--- a/internal/ceres/evaluator.h
+++ b/internal/ceres/evaluator.h
@@ -72,7 +72,6 @@
                            Program* program,
                            string* error);
 
-
   // This is used for computing the cost, residual and Jacobian for
   // returning to the user. For actually solving the optimization
   // problem, the optimization algorithm uses the ProgramEvaluator
@@ -116,6 +115,18 @@
   // Schur complement based methods.
   virtual SparseMatrix* CreateJacobian() const = 0;
 
+
+  // Options struct to control Evaluator::Evaluate;
+  struct EvaluateOptions {
+    EvaluateOptions()
+        : apply_loss_function(true) {
+    }
+
+    // If false, the loss function correction is not applied to the
+    // residual blocks.
+    bool apply_loss_function;
+  };
+
   // Evaluate the cost function for the given state. Returns the cost,
   // residuals, and jacobian in the corresponding arguments. Both residuals and
   // jacobian are optional; to avoid computing them, pass NULL.
@@ -125,12 +136,29 @@
   //
   // state is an array of size NumParameters(), cost is a pointer to a single
   // double, and residuals is an array of doubles of size NumResiduals().
-  virtual bool Evaluate(const double* state,
+  virtual bool Evaluate(const EvaluateOptions& evaluate_options,
+                        const double* state,
                         double* cost,
                         double* residuals,
                         double* gradient,
                         SparseMatrix* jacobian) = 0;
 
+  // Variant of Evaluator::Evaluate where the user wishes to use the
+  // default EvaluateOptions struct. This is mostly here as a
+  // convenience method.
+  virtual bool Evaluate(const double* state,
+                        double* cost,
+                        double* residuals,
+                        double* gradient,
+                        SparseMatrix* jacobian) {
+    return Evaluate(EvaluateOptions(),
+                    state,
+                    cost,
+                    residuals,
+                    gradient,
+                    jacobian);
+  }
+
   // Make a change delta (of size NumEffectiveParameters()) to state (of size
   // NumParameters()) and store the result in state_plus_delta.
   //
diff --git a/internal/ceres/evaluator_test.cc b/internal/ceres/evaluator_test.cc
index 9e9d31b..ea24504 100644
--- a/internal/ceres/evaluator_test.cc
+++ b/internal/ceres/evaluator_test.cc
@@ -36,6 +36,7 @@
 #include "ceres/casts.h"
 #include "ceres/cost_function.h"
 #include "ceres/crs_matrix.h"
+#include "ceres/evaluator_test_utils.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/internal/scoped_ptr.h"
 #include "ceres/local_parameterization.h"
@@ -90,65 +91,6 @@
   }
 };
 
-struct ExpectedEvaluation {
-  int num_rows;
-  int num_cols;
-  double cost;
-  const double residuals[50];
-  const double gradient[50];
-  const double jacobian[200];
-};
-
-void CompareEvaluations(int expected_num_rows,
-                        int expected_num_cols,
-                        double expected_cost,
-                        const double* expected_residuals,
-                        const double* expected_gradient,
-                        const double* expected_jacobian,
-                        const double actual_cost,
-                        const double* actual_residuals,
-                        const double* actual_gradient,
-                        const double* actual_jacobian) {
-  EXPECT_EQ(expected_cost, actual_cost);
-
-  if (expected_residuals != NULL) {
-    ConstVectorRef expected_residuals_vector(expected_residuals,
-                                             expected_num_rows);
-    ConstVectorRef actual_residuals_vector(actual_residuals,
-                                           expected_num_rows);
-    EXPECT_TRUE((actual_residuals_vector.array() ==
-                 expected_residuals_vector.array()).all())
-        << "Actual:\n" << actual_residuals_vector
-        << "\nExpected:\n" << expected_residuals_vector;
-  }
-
-  if (expected_gradient != NULL) {
-    ConstVectorRef expected_gradient_vector(expected_gradient,
-                                            expected_num_cols);
-    ConstVectorRef actual_gradient_vector(actual_gradient,
-                                            expected_num_cols);
-
-    EXPECT_TRUE((actual_gradient_vector.array() ==
-                 expected_gradient_vector.array()).all())
-        << "Actual:\n" << actual_gradient_vector.transpose()
-        << "\nExpected:\n" << expected_gradient_vector.transpose();
-  }
-
-  if (expected_jacobian != NULL) {
-    ConstMatrixRef expected_jacobian_matrix(expected_jacobian,
-                                            expected_num_rows,
-                                            expected_num_cols);
-    ConstMatrixRef actual_jacobian_matrix(actual_jacobian,
-                                          expected_num_rows,
-                                          expected_num_cols);
-    EXPECT_TRUE((actual_jacobian_matrix.array() ==
-                 expected_jacobian_matrix.array()).all())
-        << "Actual:\n" << actual_jacobian_matrix
-        << "\nExpected:\n" << expected_jacobian_matrix;
-  }
-}
-
-
 struct EvaluatorTest
     : public ::testing::TestWithParam<pair<LinearSolverType, int> > {
   Evaluator* CreateEvaluator(Program* program) {
@@ -692,272 +634,5 @@
   }
 }
 
-// Simple cost function used for testing Evaluator::Evaluate.
-//
-// r_i = i - (j + 1) * x_ij^2
-template <int kNumResiduals, int kNumParameterBlocks >
-class QuadraticCostFunction : public CostFunction {
- public:
-  QuadraticCostFunction() {
-    CHECK_GT(kNumResiduals, 0);
-    CHECK_GT(kNumParameterBlocks, 0);
-    set_num_residuals(kNumResiduals);
-    for (int i = 0; i < kNumParameterBlocks; ++i) {
-      mutable_parameter_block_sizes()->push_back(kNumResiduals);
-    }
-  }
-
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
-    for (int i = 0; i < kNumResiduals; ++i) {
-      residuals[i] = i;
-      for (int j = 0; j < kNumParameterBlocks; ++j) {
-        residuals[i] -= (j + 1.0) * parameters[j][i] * parameters[j][i];
-      }
-    }
-
-    if (jacobians == NULL) {
-      return true;
-    }
-
-    for (int j = 0; j < kNumParameterBlocks; ++j) {
-      if (jacobians[j] != NULL) {
-        MatrixRef(jacobians[j], kNumResiduals, kNumResiduals) =
-            (-2.0 * (j + 1.0) *
-             ConstVectorRef(parameters[j], kNumResiduals)).asDiagonal();
-      }
-    }
-
-    return true;
-  }
-};
-
-// Convert a CRSMatrix to a dense Eigen matrix.
-void CRSToDenseMatrix(const CRSMatrix& input, Matrix* output) {
-  Matrix& m = *CHECK_NOTNULL(output);
-  m.resize(input.num_rows, input.num_cols);
-  m.setZero();
-  for (int row = 0; row < input.num_rows; ++row) {
-    for (int j = input.rows[row]; j < input.rows[row + 1]; ++j) {
-      const int col = input.cols[j];
-      m(row, col) = input.values[j];
-    }
-  }
-}
-
-
-class StaticEvaluateTest : public ::testing::Test {
- protected:
-  void SetUp() {
-    for (int i = 0; i < 6; ++i) {
-      parameters_[i] = static_cast<double>(i + 1);
-    }
-
-    CostFunction* cost_function = new QuadraticCostFunction<2, 2>;
-
-    // f(x, y)
-    problem_.AddResidualBlock(cost_function,
-                              NULL,
-                              parameters_,
-                              parameters_ + 2);
-    // g(y, z)
-    problem_.AddResidualBlock(cost_function,
-                              NULL, parameters_ + 2,
-                              parameters_ + 4);
-    // h(z, x)
-    problem_.AddResidualBlock(cost_function,
-                              NULL,
-                              parameters_ + 4,
-                              parameters_);
-  }
-
-
-
-  void EvaluateAndCompare(const int expected_num_rows,
-                          const int expected_num_cols,
-                          const double expected_cost,
-                          const double* expected_residuals,
-                          const double* expected_gradient,
-                          const double* expected_jacobian) {
-    double cost;
-    vector<double> residuals;
-    vector<double> gradient;
-    CRSMatrix jacobian;
-
-    EXPECT_TRUE(Evaluator::Evaluate(
-                    problem_.mutable_program(),
-                    1,
-                    &cost,
-                    expected_residuals != NULL ? &residuals : NULL,
-                    expected_gradient != NULL ? &gradient : NULL,
-                    expected_jacobian != NULL ? &jacobian : NULL));
-
-    if (expected_residuals != NULL) {
-      EXPECT_EQ(residuals.size(), expected_num_rows);
-    }
-
-    if (expected_gradient != NULL) {
-      EXPECT_EQ(gradient.size(), expected_num_cols);
-    }
-
-    if (expected_jacobian != NULL) {
-      EXPECT_EQ(jacobian.num_rows, expected_num_rows);
-      EXPECT_EQ(jacobian.num_cols, expected_num_cols);
-    }
-
-    Matrix dense_jacobian;
-    if (expected_jacobian != NULL) {
-      CRSToDenseMatrix(jacobian, &dense_jacobian);
-    }
-
-    CompareEvaluations(expected_num_rows,
-                       expected_num_cols,
-                       expected_cost,
-                       expected_residuals,
-                       expected_gradient,
-                       expected_jacobian,
-                       cost,
-                       residuals.size() > 0 ? &residuals[0] : NULL,
-                       gradient.size() > 0 ? &gradient[0] : NULL,
-                       dense_jacobian.data());
-  }
-
-  void CheckAllEvaluationCombinations(const ExpectedEvaluation& expected ) {
-    for (int i = 0; i < 8; ++i) {
-      EvaluateAndCompare(expected.num_rows,
-                         expected.num_cols,
-                         expected.cost,
-                         (i & 1) ? expected.residuals : NULL,
-                         (i & 2) ? expected.gradient  : NULL,
-                         (i & 4) ? expected.jacobian  : NULL);
-    }
-
-    // The Evaluate call should only depend on the parameter block
-    // values in the user provided pointers, and the current state of
-    // the parameter block should not matter. So, create a new
-    // parameters vector, and update the parameter block states with
-    // it. The results from the Evaluate call should not change.
-    double new_parameters[6];
-    for (int i = 0; i < 6; ++i) {
-      new_parameters[i] = 0.0;
-    }
-
-    problem_.mutable_program()->StateVectorToParameterBlocks(new_parameters);
-
-    for (int i = 0; i < 8; ++i) {
-      EvaluateAndCompare(expected.num_rows,
-                         expected.num_cols,
-                         expected.cost,
-                         (i & 1) ? expected.residuals : NULL,
-                         (i & 2) ? expected.gradient  : NULL,
-                         (i & 4) ? expected.jacobian  : NULL);
-    }
-  }
-
-  ProblemImpl problem_;
-  double parameters_[6];
-};
-
-
-TEST_F(StaticEvaluateTest, MultipleParameterAndResidualBlocks) {
-  ExpectedEvaluation expected = {
-    // Rows/columns
-    6, 6,
-    // Cost
-    7607.0,
-    // Residuals
-    { -19.0, -35.0,  // f
-      -59.0, -87.0,  // g
-      -27.0, -43.0   // h
-    },
-    // Gradient
-    {  146.0,  484.0,   // x
-       582.0, 1256.0,   // y
-      1450.0, 2604.0,   // z
-    },
-    // Jacobian
-    //                       x             y             z
-    { /* f(x, y) */ -2.0,  0.0, -12.0,   0.0,   0.0,   0.0,
-                     0.0, -4.0,   0.0, -16.0,   0.0,   0.0,
-      /* g(y, z) */  0.0,  0.0,  -6.0,   0.0, -20.0,   0.0,
-                     0.0,  0.0,   0.0,  -8.0,   0.0, -24.0,
-      /* h(z, x) */ -4.0,  0.0,   0.0,   0.0, -10.0,   0.0,
-                     0.0, -8.0,   0.0,   0.0,   0.0, -12.0
-    }
-  };
-
-  CheckAllEvaluationCombinations(expected);
-}
-
-TEST_F(StaticEvaluateTest, ConstantParameterBlock) {
-  ExpectedEvaluation expected = {
-    // Rows/columns
-    6, 6,
-    // Cost
-    7607.0,
-    // Residuals
-    { -19.0, -35.0,  // f
-      -59.0, -87.0,  // g
-      -27.0, -43.0   // h
-    },
-
-    // Gradient
-    {  146.0,  484.0,  // x
-         0.0,    0.0,  // y
-      1450.0, 2604.0,  // z
-    },
-
-    // Jacobian
-    //                       x             y             z
-    { /* f(x, y) */ -2.0,  0.0,   0.0,   0.0,   0.0,   0.0,
-                     0.0, -4.0,   0.0,   0.0,   0.0,   0.0,
-      /* g(y, z) */  0.0,  0.0,   0.0,   0.0, -20.0,   0.0,
-                     0.0,  0.0,   0.0,   0.0,   0.0, -24.0,
-      /* h(z, x) */ -4.0,  0.0,   0.0,   0.0, -10.0,   0.0,
-                     0.0, -8.0,   0.0,   0.0,   0.0, -12.0
-    }
-  };
-
-  problem_.SetParameterBlockConstant(parameters_ + 2);
-  CheckAllEvaluationCombinations(expected);
-}
-
-TEST_F(StaticEvaluateTest, LocalParameterization) {
-  ExpectedEvaluation expected = {
-    // Rows/columns
-    6, 5,
-    // Cost
-    7607.0,
-    // Residuals
-    { -19.0, -35.0,  // f
-      -59.0, -87.0,  // g
-      -27.0, -43.0   // h
-    },
-    // Gradient
-    {  146.0,  484.0,  // x
-      1256.0,          // y with SubsetParameterization
-      1450.0, 2604.0,  // z
-    },
-    // Jacobian
-    //                       x      y             z
-    { /* f(x, y) */ -2.0,  0.0,   0.0,   0.0,   0.0,
-                     0.0, -4.0, -16.0,   0.0,   0.0,
-      /* g(y, z) */  0.0,  0.0,   0.0, -20.0,   0.0,
-                     0.0,  0.0,  -8.0,   0.0, -24.0,
-      /* h(z, x) */ -4.0,  0.0,   0.0, -10.0,   0.0,
-                     0.0, -8.0,   0.0,   0.0, -12.0
-    }
-  };
-
-  vector<int> constant_parameters;
-  constant_parameters.push_back(0);
-  problem_.SetParameterization(parameters_ + 2,
-                               new SubsetParameterization(2,
-                                                          constant_parameters));
-
-  CheckAllEvaluationCombinations(expected);
-}
-
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/evaluator_test_utils.cc b/internal/ceres/evaluator_test_utils.cc
new file mode 100644
index 0000000..a09be2d
--- /dev/null
+++ b/internal/ceres/evaluator_test_utils.cc
@@ -0,0 +1,89 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2013 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: keir@google.com (Keir Mierle)
+//         sameeragarwal@google.com (Sameer Agarwal)
+
+#include "ceres/evaluator_test_utils.h"
+#include "ceres/internal/eigen.h"
+#include "gtest/gtest.h"
+
+namespace ceres {
+namespace internal {
+
+void CompareEvaluations(int expected_num_rows,
+                        int expected_num_cols,
+                        double expected_cost,
+                        const double* expected_residuals,
+                        const double* expected_gradient,
+                        const double* expected_jacobian,
+                        const double actual_cost,
+                        const double* actual_residuals,
+                        const double* actual_gradient,
+                        const double* actual_jacobian) {
+  EXPECT_EQ(expected_cost, actual_cost);
+
+  if (expected_residuals != NULL) {
+    ConstVectorRef expected_residuals_vector(expected_residuals,
+                                             expected_num_rows);
+    ConstVectorRef actual_residuals_vector(actual_residuals,
+                                           expected_num_rows);
+    EXPECT_TRUE((actual_residuals_vector.array() ==
+                 expected_residuals_vector.array()).all())
+        << "Actual:\n" << actual_residuals_vector
+        << "\nExpected:\n" << expected_residuals_vector;
+  }
+
+  if (expected_gradient != NULL) {
+    ConstVectorRef expected_gradient_vector(expected_gradient,
+                                            expected_num_cols);
+    ConstVectorRef actual_gradient_vector(actual_gradient,
+                                            expected_num_cols);
+
+    EXPECT_TRUE((actual_gradient_vector.array() ==
+                 expected_gradient_vector.array()).all())
+        << "Actual:\n" << actual_gradient_vector.transpose()
+        << "\nExpected:\n" << expected_gradient_vector.transpose();
+  }
+
+  if (expected_jacobian != NULL) {
+    ConstMatrixRef expected_jacobian_matrix(expected_jacobian,
+                                            expected_num_rows,
+                                            expected_num_cols);
+    ConstMatrixRef actual_jacobian_matrix(actual_jacobian,
+                                          expected_num_rows,
+                                          expected_num_cols);
+    EXPECT_TRUE((actual_jacobian_matrix.array() ==
+                 expected_jacobian_matrix.array()).all())
+        << "Actual:\n" << actual_jacobian_matrix
+        << "\nExpected:\n" << expected_jacobian_matrix;
+  }
+}
+
+}  // namespace internal
+}  // namespace ceres
diff --git a/internal/ceres/evaluator_test_utils.h b/internal/ceres/evaluator_test_utils.h
new file mode 100644
index 0000000..ae0663a
--- /dev/null
+++ b/internal/ceres/evaluator_test_utils.h
@@ -0,0 +1,60 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2013 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: keir@google.com (Keir Mierle)
+//         sameeragarwal@google.com (Sameer Agarwal)
+//
+// Test utils used for evaluation testing.
+
+namespace ceres {
+namespace internal {
+
+// Fixed sized struct for storing an evaluation.
+struct ExpectedEvaluation {
+  int num_rows;
+  int num_cols;
+  double cost;
+  const double residuals[50];
+  const double gradient[50];
+  const double jacobian[200];
+};
+
+// Compare two evaluations.
+void CompareEvaluations(int expected_num_rows,
+                        int expected_num_cols,
+                        double expected_cost,
+                        const double* expected_residuals,
+                        const double* expected_gradient,
+                        const double* expected_jacobian,
+                        const double actual_cost,
+                        const double* actual_residuals,
+                        const double* actual_gradient,
+                        const double* actual_jacobian);
+
+}  // namespace internal
+}  // namespace ceres
diff --git a/internal/ceres/problem_impl.cc b/internal/ceres/problem_impl.cc
index 1fb9e39..21d1144 100644
--- a/internal/ceres/problem_impl.cc
+++ b/internal/ceres/problem_impl.cc
@@ -651,7 +651,12 @@
   program.ParameterBlocksToStateVector(parameters.data());
 
   double tmp_cost = 0;
-  bool status = evaluator->Evaluate(parameters.data(),
+
+  Evaluator::EvaluateOptions evaluator_evaluate_options;
+  evaluator_evaluate_options.apply_loss_function =
+      evaluate_options.apply_loss_function;
+  bool status = evaluator->Evaluate(evaluator_evaluate_options,
+                                    parameters.data(),
                                     &tmp_cost,
                                     residuals != NULL ? &(*residuals)[0] : NULL,
                                     gradient != NULL ? &(*gradient)[0] : NULL,
diff --git a/internal/ceres/problem_test.cc b/internal/ceres/problem_test.cc
index 888eb7c..5f3bc94 100644
--- a/internal/ceres/problem_test.cc
+++ b/internal/ceres/problem_test.cc
@@ -35,6 +35,7 @@
 #include "ceres/casts.h"
 #include "ceres/cost_function.h"
 #include "ceres/crs_matrix.h"
+#include "ceres/evaluator_test_utils.cc"
 #include "ceres/internal/eigen.h"
 #include "ceres/internal/scoped_ptr.h"
 #include "ceres/local_parameterization.h"
@@ -46,7 +47,6 @@
 #include "ceres/types.h"
 #include "gtest/gtest.h"
 
-
 namespace ceres {
 namespace internal {
 
@@ -703,71 +703,6 @@
 
 // Test for Problem::Evaluate
 
-// TODO(sameeragarwal): The following struct and function are shared
-// with evaluator_test.cc. Once things settle down, do an
-// evaluate_utils.h or some such thing to reduce code duplication. The
-// best time is perhaps when we remove the support for
-// Solver::Summary::initial_*
-struct ExpectedEvaluation {
-  int num_rows;
-  int num_cols;
-  double cost;
-  const double residuals[50];
-  const double gradient[50];
-  const double jacobian[200];
-};
-
-void CompareEvaluations(int expected_num_rows,
-                        int expected_num_cols,
-                        double expected_cost,
-                        const double* expected_residuals,
-                        const double* expected_gradient,
-                        const double* expected_jacobian,
-                        const double actual_cost,
-                        const double* actual_residuals,
-                        const double* actual_gradient,
-                        const double* actual_jacobian) {
-  EXPECT_EQ(expected_cost, actual_cost);
-
-  if (expected_residuals != NULL) {
-    ConstVectorRef expected_residuals_vector(expected_residuals,
-                                             expected_num_rows);
-    ConstVectorRef actual_residuals_vector(actual_residuals,
-                                           expected_num_rows);
-    EXPECT_TRUE((actual_residuals_vector.array() ==
-                 expected_residuals_vector.array()).all())
-        << "Actual:\n" << actual_residuals_vector
-        << "\nExpected:\n" << expected_residuals_vector;
-  }
-
-  if (expected_gradient != NULL) {
-    ConstVectorRef expected_gradient_vector(expected_gradient,
-                                            expected_num_cols);
-    ConstVectorRef actual_gradient_vector(actual_gradient,
-                                            expected_num_cols);
-
-    EXPECT_TRUE((actual_gradient_vector.array() ==
-                 expected_gradient_vector.array()).all())
-        << "Actual:\n" << actual_gradient_vector.transpose()
-        << "\nExpected:\n" << expected_gradient_vector.transpose();
-  }
-
-  if (expected_jacobian != NULL) {
-    ConstMatrixRef expected_jacobian_matrix(expected_jacobian,
-                                            expected_num_rows,
-                                            expected_num_cols);
-    ConstMatrixRef actual_jacobian_matrix(actual_jacobian,
-                                          expected_num_rows,
-                                          expected_num_cols);
-    EXPECT_TRUE((actual_jacobian_matrix.array() ==
-                 expected_jacobian_matrix.array()).all())
-        << "Actual:\n" << actual_jacobian_matrix
-        << "\nExpected:\n" << expected_jacobian_matrix;
-  }
-}
-
-// Simple cost function used for testing Problem::Evaluate.
-//
 // r_i = i - (j + 1) * x_ij^2
 template <int kNumResiduals, int kNumParameterBlocks>
 class QuadraticCostFunction : public CostFunction {
diff --git a/internal/ceres/program_evaluator.h b/internal/ceres/program_evaluator.h
index a19cdf8..de56ac2 100644
--- a/internal/ceres/program_evaluator.h
+++ b/internal/ceres/program_evaluator.h
@@ -120,7 +120,8 @@
     return jacobian_writer_.CreateJacobian();
   }
 
-  bool Evaluate(const double* state,
+  bool Evaluate(const Evaluator::EvaluateOptions& evaluate_options,
+                const double* state,
                 double* cost,
                 double* residuals,
                 double* gradient,
@@ -196,6 +197,7 @@
       // Evaluate the cost, residuals, and jacobians.
       double block_cost;
       if (!residual_block->Evaluate(
+              evaluate_options.apply_loss_function,
               &block_cost,
               block_residuals,
               block_jacobians,
diff --git a/internal/ceres/residual_block.cc b/internal/ceres/residual_block.cc
index 7f78960..b91b0ed 100644
--- a/internal/ceres/residual_block.cc
+++ b/internal/ceres/residual_block.cc
@@ -62,7 +62,8 @@
             parameter_blocks_.get());
 }
 
-bool ResidualBlock::Evaluate(double* cost,
+bool ResidualBlock::Evaluate(const bool apply_loss_function,
+                             double* cost,
                              double* residuals,
                              double** jacobians,
                              double* scratch) const {
@@ -154,7 +155,7 @@
     }
   }
 
-  if (loss_function_ == NULL) {
+  if (loss_function_ == NULL || !apply_loss_function) {
     *cost = 0.5 * squared_norm;
     return true;
   }
diff --git a/internal/ceres/residual_block.h b/internal/ceres/residual_block.h
index 3921d1d..9c3671b 100644
--- a/internal/ceres/residual_block.h
+++ b/internal/ceres/residual_block.h
@@ -93,11 +93,16 @@
   // parameterizations applied already; for example, the jacobian for a
   // 4-dimensional quaternion parameter using the "QuaternionParameterization"
   // is num_residuals by 3 instead of num_residuals by 4.
-  bool Evaluate(double* cost,
+  //
+  // apply_loss_function as the name implies allows the user to switch
+  // the application of the loss function on and off.
+  bool Evaluate(bool apply_loss_function,
+                double* cost,
                 double* residuals,
                 double** jacobians,
                 double* scratch) const;
 
+
   const CostFunction* cost_function() const { return cost_function_; }
   const LossFunction* loss_function() const { return loss_function_; }
 
diff --git a/internal/ceres/residual_block_test.cc b/internal/ceres/residual_block_test.cc
index fddd44e..1e03e7d 100644
--- a/internal/ceres/residual_block_test.cc
+++ b/internal/ceres/residual_block_test.cc
@@ -105,12 +105,12 @@
 
   // Verify cost-only evaluation.
   double cost;
-  residual_block.Evaluate(&cost, NULL, NULL, scratch);
+  residual_block.Evaluate(true, &cost, NULL, NULL, scratch);
   EXPECT_EQ(0.5 * (0*0 + 1*1 + 2*2), cost);
 
   // Verify cost and residual evaluation.
   double residuals[3];
-  residual_block.Evaluate(&cost, residuals, NULL, scratch);
+  residual_block.Evaluate(true, &cost, residuals, NULL, scratch);
   EXPECT_EQ(0.5 * (0*0 + 1*1 + 2*2), cost);
   EXPECT_EQ(0.0, residuals[0]);
   EXPECT_EQ(1.0, residuals[1]);
@@ -134,7 +134,7 @@
     jacobian_rz.data()
   };
 
-  residual_block.Evaluate(&cost, residuals, jacobian_ptrs, scratch);
+  residual_block.Evaluate(true, &cost, residuals, jacobian_ptrs, scratch);
   EXPECT_EQ(0.5 * (0*0 + 1*1 + 2*2), cost);
   EXPECT_EQ(0.0, residuals[0]);
   EXPECT_EQ(1.0, residuals[1]);
@@ -153,7 +153,7 @@
 
   jacobian_ptrs[1] = NULL;  // Don't compute the jacobian for y.
 
-  residual_block.Evaluate(&cost, residuals, jacobian_ptrs, scratch);
+  residual_block.Evaluate(true, &cost, residuals, jacobian_ptrs, scratch);
   EXPECT_EQ(0.5 * (0*0 + 1*1 + 2*2), cost);
   EXPECT_EQ(0.0, residuals[0]);
   EXPECT_EQ(1.0, residuals[1]);
@@ -244,12 +244,12 @@
 
   // Verify cost-only evaluation.
   double cost;
-  residual_block.Evaluate(&cost, NULL, NULL, scratch);
+  residual_block.Evaluate(true, &cost, NULL, NULL, scratch);
   EXPECT_EQ(0.5 * (0*0 + 1*1 + 2*2), cost);
 
   // Verify cost and residual evaluation.
   double residuals[3];
-  residual_block.Evaluate(&cost, residuals, NULL, scratch);
+  residual_block.Evaluate(true, &cost, residuals, NULL, scratch);
   EXPECT_EQ(0.5 * (0*0 + 1*1 + 2*2), cost);
   EXPECT_EQ(0.0, residuals[0]);
   EXPECT_EQ(1.0, residuals[1]);
@@ -273,7 +273,7 @@
     jacobian_rz.data()
   };
 
-  residual_block.Evaluate(&cost, residuals, jacobian_ptrs, scratch);
+  residual_block.Evaluate(true, &cost, residuals, jacobian_ptrs, scratch);
   EXPECT_EQ(0.5 * (0*0 + 1*1 + 2*2), cost);
   EXPECT_EQ(0.0, residuals[0]);
   EXPECT_EQ(1.0, residuals[1]);
@@ -311,7 +311,7 @@
 
   jacobian_ptrs[1] = NULL;  // Don't compute the jacobian for y.
 
-  residual_block.Evaluate(&cost, residuals, jacobian_ptrs, scratch);
+  residual_block.Evaluate(true, &cost, residuals, jacobian_ptrs, scratch);
   EXPECT_EQ(0.5 * (0*0 + 1*1 + 2*2), cost);
   EXPECT_EQ(0.0, residuals[0]);
   EXPECT_EQ(1.0, residuals[1]);
diff --git a/internal/ceres/residual_block_utils_test.cc b/internal/ceres/residual_block_utils_test.cc
index 24723b3..d3c917a 100644
--- a/internal/ceres/residual_block_utils_test.cc
+++ b/internal/ceres/residual_block_utils_test.cc
@@ -62,7 +62,8 @@
   double jacobian;
   double* jacobians[] = { &jacobian };
 
-  EXPECT_EQ(residual_block.Evaluate(&cost,
+  EXPECT_EQ(residual_block.Evaluate(true,
+                                    &cost,
                                     &residuals,
                                     jacobians,
                                     scratch.get()), is_good);
diff --git a/internal/ceres/solver_impl.cc b/internal/ceres/solver_impl.cc
index 16fdbf6..0ef0a27 100644
--- a/internal/ceres/solver_impl.cc
+++ b/internal/ceres/solver_impl.cc
@@ -914,8 +914,11 @@
         // The residual is constant and will be removed, so its cost is
         // added to the variable fixed_cost.
         double cost = 0.0;
-        if (!residual_block->Evaluate(
-              &cost, NULL, NULL, residual_block_evaluate_scratch.get())) {
+        if (!residual_block->Evaluate(true,
+                                      &cost,
+                                      NULL,
+                                      NULL,
+                                      residual_block_evaluate_scratch.get())) {
           *error = StringPrintf("Evaluation of the residual %d failed during "
                                 "removal of fixed residual blocks.", i);
           return false;
diff --git a/internal/ceres/solver_impl_test.cc b/internal/ceres/solver_impl_test.cc
index 8e443ba..2471ea2 100644
--- a/internal/ceres/solver_impl_test.cc
+++ b/internal/ceres/solver_impl_test.cc
@@ -242,7 +242,8 @@
   ResidualBlock *expected_removed_block = program.residual_blocks()[0];
   scoped_array<double> scratch(
       new double[expected_removed_block->NumScratchDoublesForEvaluate()]);
-  expected_removed_block->Evaluate(&expected_fixed_cost,
+  expected_removed_block->Evaluate(true,
+                                   &expected_fixed_cost,
                                    NULL,
                                    NULL,
                                    scratch.get());
diff --git a/internal/ceres/trust_region_minimizer_test.cc b/internal/ceres/trust_region_minimizer_test.cc
index 4bc9409..9c2780b 100644
--- a/internal/ceres/trust_region_minimizer_test.cc
+++ b/internal/ceres/trust_region_minimizer_test.cc
@@ -82,7 +82,8 @@
     return dense_jacobian;
   }
 
-  virtual bool Evaluate(const double* state,
+  virtual bool Evaluate(const Evaluator::EvaluateOptions& evaluate_options,
+                        const double* state,
                         double* cost,
                         double* residuals,
                         double* /* gradient */,