Recycle numeric factorisation when using Accelerate Sparse.

Change-Id: Id94d77f9437e31c37ae99f48d28800fc9ce841ec
diff --git a/internal/ceres/accelerate_sparse.cc b/internal/ceres/accelerate_sparse.cc
index a82d90b..dc02986 100644
--- a/internal/ceres/accelerate_sparse.cc
+++ b/internal/ceres/accelerate_sparse.cc
@@ -115,6 +115,12 @@
   return SparseFactor(*symbolic_factor, *A);
 }
 
+template<typename Scalar>
+void AccelerateSparse<Scalar>::Cholesky(ASSparseMatrix* A,
+                                        NumericFactorization* numeric_factor) {
+  return SparseRefactor(*A, numeric_factor);
+}
+
 // Instantiate only for the specific template types required/supported s/t the
 // definition can be in the .cc file.
 template class AccelerateSparse<double>;
@@ -169,14 +175,19 @@
     }
   }
 
-  FreeNumericFactorization();
-  numeric_factor_.reset(
-      new typename SparseTypesTrait<Scalar>::NumericFactorization(
-          as_.Cholesky(&as_lhs, symbolic_factor_.get())));
+  if (!numeric_factor_) {
+    numeric_factor_.reset(
+        new typename SparseTypesTrait<Scalar>::NumericFactorization(
+            as_.Cholesky(&as_lhs, symbolic_factor_.get())));
+  } else {
+    // Recycle memory from previous numeric factorization.
+    as_.Cholesky(&as_lhs, numeric_factor_.get());
+  }
   if (numeric_factor_->status != SparseStatusOK) {
     *message = StringPrintf(
         "Apple Accelerate Failure : Numeric factorisation failed: %s",
         SparseStatusToString(numeric_factor_->status));
+    FreeNumericFactorization();
     return LINEAR_SOLVER_FAILURE;
   }
 
diff --git a/internal/ceres/accelerate_sparse.h b/internal/ceres/accelerate_sparse.h
index cb5d084..b849a80 100644
--- a/internal/ceres/accelerate_sparse.h
+++ b/internal/ceres/accelerate_sparse.h
@@ -95,6 +95,9 @@
   // symbolic factorization.
   NumericFactorization Cholesky(ASSparseMatrix* A,
                                 SymbolicFactorization* symbolic_factor);
+  // Reuse the NumericFactorization from a previous matrix with the same
+  // symbolic factorization to represent a new numeric factorization.
+  void Cholesky(ASSparseMatrix* A, NumericFactorization* numeric_factor);
 
  private:
   std::vector<long> column_starts_;