Add Tukey loss function.

Change-Id: I7c76f13e01863440fc207e99b3fc7ad3fb6f7d1a
diff --git a/internal/ceres/loss_function.cc b/internal/ceres/loss_function.cc
index 62b545b..6500247 100644
--- a/internal/ceres/loss_function.cc
+++ b/internal/ceres/loss_function.cc
@@ -1,5 +1,5 @@
 // Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// Copyright 2014 Google Inc. All rights reserved.
 // http://code.google.com/p/ceres-solver/
 //
 // Redistribution and use in source and binary forms, with or without
@@ -114,6 +114,22 @@
   }
 }
 
+void TukeyLoss::Evaluate(double s, double* rho) const {
+  if (s <= a_squared_) {
+    // Inlier region.
+    const double value = 1.0 - s / a_squared_;
+    const double value_sq = value * value;
+    rho[0] = a_squared_ / 6.0 * (1.0 - value_sq * value);
+    rho[1] = 0.5 * value_sq;
+    rho[2] = -1.0 / a_squared_ * value;
+  } else {
+    // Outlier region.
+    rho[0] = a_squared_ / 6.0;
+    rho[1] = 0.0;
+    rho[2] = 0.0;
+  }
+}
+
 ComposedLoss::ComposedLoss(const LossFunction* f, Ownership ownership_f,
                            const LossFunction* g, Ownership ownership_g)
     : f_(CHECK_NOTNULL(f)),