Simplify GenerateCodeForFunctor

- Don't trace residual -> Use input cost functor instead
- Remove unnecessary copy from tmp jacobian array
- Fix indent of generated Evaluate() function

Change-Id: I23e09987d8ec30f7202a93eb253648505dcaaa4e
diff --git a/include/ceres/codegen/generate_code_for_functor.h b/include/ceres/codegen/generate_code_for_functor.h
index 31ccdb2..d7ed09e 100644
--- a/include/ceres/codegen/generate_code_for_functor.h
+++ b/include/ceres/codegen/generate_code_for_functor.h
@@ -123,12 +123,6 @@
     internal::MakeOutput(J.a, "residuals[" + std::to_string(i) + "]");
   }
 
-  // Make a copy of the current graph so we can generated a function for the
-  // residuals without jacobians.
-  auto residual_graph = *internal::GetCurrentExpressionGraph();
-
-  // Same principle as above for the residuals.
-  //
   // Example code generated by these expressions:
   //    jacobians[0][0] = v_351;
   //    jacobians[0][1] = v_352;
@@ -162,20 +156,6 @@
   output.emplace_back("");
 
   {
-    // Generate C++ code for the EvaluateResidual function and append it to the
-    // output.
-    internal::CodeGenerator::Options generator_options;
-    generator_options.function_name =
-        "void EvaluateResidual(double const* const* parameters, double* "
-        "residuals) const";
-    internal::CodeGenerator gen(residual_graph, generator_options);
-    std::vector<std::string> code = gen.Generate();
-    output.insert(output.end(), code.begin(), code.end());
-  }
-
-  output.emplace_back("");
-
-  {
     // Generate C++ code for the EvaluateResidualAndJacobian function and append
     // it to the output.
     internal::CodeGenerator::Options generator_options;
@@ -198,63 +178,40 @@
   output.emplace_back("              double* residuals,");
   output.emplace_back("              double** jacobians) const {");
 
-  output.emplace_back("   if (!jacobians) {");
-  output.emplace_back("     EvaluateResidual(parameters, residuals);");
-  output.emplace_back("     return true;");
-  output.emplace_back("   }");
+  output.emplace_back("  if (!jacobians) {");
+  output.emplace_back("    // Use the input cost functor");
+  output.emplace_back("    return (*this)(");
+  for (int i = 0; i < kNumParameterBlocks; ++i) {
+    output.emplace_back("      parameters[" + std::to_string(i) + "],");
+  }
+  output.emplace_back("      residuals");
+  output.emplace_back("    );");
+  output.emplace_back("  }");
 
-  // Create a tmp array of all jacobians and use it for evaluation.
-  // The generated code for a <2,3,1,2> cost functor is:
+  // Create a tmp array of all jacobians and use it for evaluation if the input
+  // jacobian is null. The generated code for a <2,3,1,2> cost functor is:
   //   double jacobians_data[6];
   //   double* jacobians_ptrs[] = {
-  //       jacobians_data + 0,
-  //       jacobians_data + 6,
-  //       jacobians_data + 8,
+  //       jacobians[0] ? jacobians[0] : jacobians_data + 0,
+  //       jacobians[1] ? jacobians[1] : jacobians_data + 6,
+  //       jacobians[2] ? jacobians[2] : jacobians_data + 8,
   //   };
-  output.emplace_back("   double jacobians_data[" +
+  output.emplace_back("  double jacobians_data[" +
                       std::to_string(kNumParameters * kNumResiduals) + "];");
-  output.emplace_back("   double* jacobians_ptrs[] = {");
+  output.emplace_back("  double* jacobians_ptrs[] = {");
   for (int i = 0, total_param_id = 0; i < kNumParameterBlocks;
        total_param_id += ParameterDims::GetDim(i), ++i) {
-    output.emplace_back("     jacobians_data + " +
+    output.emplace_back("    jacobians[" + std::to_string(i) +
+                        "] ? jacobians[" + std::to_string(i) +
+                        "] : jacobians_data + " +
                         std::to_string(kNumResiduals * total_param_id) + ",");
   }
-  output.emplace_back("   };");
-
-  // Evaluate into the tmp array.
+  output.emplace_back("  };");
   output.emplace_back(
-      "   EvaluateResidualAndJacobian(parameters, residuals, "
+      "  EvaluateResidualAndJacobian(parameters, residuals, "
       "jacobians_ptrs);");
 
-  // Copy the computed jacobians into the output array. Add an if-statement to
-  // test for null-jacobians. The generated code for a <2,3,1,2> cost functor
-  // is:
-  //    if (jacobians[0]) {
-  //      for (int i = 0; i < 6; ++i) {
-  //        jacobians[0][i] = jacobians_tmp[0][i];
-  //      }
-  //    }
-  //    if (jacobians[1]) {
-  //      for (int i = 0; i < 2; ++i) {
-  //        jacobians[1][i] = jacobians_tmp[1][i];
-  //      }
-  //    }
-  //    if (jacobians[2]) {
-  //      for (int i = 0; i < 4; ++i) {
-  //        jacobians[2][i] = jacobians_tmp[2][i];
-  //      }
-  //    }
-  for (int i = 0; i < kNumParameterBlocks; ++i) {
-    output.emplace_back("   if (jacobians[" + std::to_string(i) + "]) {");
-    output.emplace_back(
-        "     for (int i = 0; i < " +
-        std::to_string(ParameterDims::GetDim(i) * kNumResiduals) + "; ++i) {");
-    output.emplace_back("       jacobians[" + std::to_string(i) +
-                        "][i] = jacobians_ptrs[" + std::to_string(i) + "][i];");
-    output.emplace_back("     }");
-    output.emplace_back("   }");
-  }
-  output.emplace_back("   return true;");
+  output.emplace_back("  return true;");
   output.emplace_back("}");
 
   return output;