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;