Add explicit support for invalid steps

Change-Id: Ib4ff395a044bf053f81d06058d7fd13f5f4f54d7
diff --git a/internal/ceres/levenberg_marquardt_strategy.h b/internal/ceres/levenberg_marquardt_strategy.h
index 274e972..4ed1390 100644
--- a/internal/ceres/levenberg_marquardt_strategy.h
+++ b/internal/ceres/levenberg_marquardt_strategy.h
@@ -55,6 +55,14 @@
       double* step);
   virtual void StepAccepted(double step_quality);
   virtual void StepRejected(double step_quality);
+  virtual void StepIsInvalid() {
+    // Treat the current step as a rejected step with no increase in
+    // solution quality. Since rejected steps lead to decrease in the
+    // size of the trust region, the next time ComputeStep is called,
+    // this will lead to a better conditioned system.
+    StepRejected(0.0);
+  }
+
   virtual double Radius() const;
 
  private:
diff --git a/internal/ceres/trust_region_strategy.h b/internal/ceres/trust_region_strategy.h
index afa4400..2463d64 100644
--- a/internal/ceres/trust_region_strategy.h
+++ b/internal/ceres/trust_region_strategy.h
@@ -96,6 +96,12 @@
   // decrease in the trust region model is step_quality.
   virtual void StepRejected(double step_quality) = 0;
 
+  // Inform the strategy that the current step has been rejected
+  // because it was found to be numerically invalid.
+  // StepRejected/StepAccepted will not be called for this step, and
+  // the strategy is free to do what it wants with this information.
+  virtual void StepIsInvalid() = 0;
+
   // Current trust region radius.
   virtual double Radius() const = 0;