mirror of
https://github.com/ceres-solver/ceres-solver.git
synced 2026-08-30 17:10:38 +08:00
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
This commit is contained in:
@@ -123,12 +123,6 @@ std::vector<std::string> GenerateCodeForFunctor(
|
||||
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;
|
||||
@@ -161,20 +155,6 @@ std::vector<std::string> GenerateCodeForFunctor(
|
||||
output.emplace_back("// http://ceres-solver.org/");
|
||||
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.
|
||||
@@ -198,63 +178,40 @@ std::vector<std::string> GenerateCodeForFunctor(
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user