ceres库里面给的例子都是一维情形,并不知道多维怎么写
1. 如果用autodiff,延展性会差一些
2. 采用analytic diff,需要自己求 jacobian,这样要注意维数是怎么分配的,参看下面的问题和解答
https://groups.google.com/forum/#!msg/ceres-solver/nVZdc4hu5zw/omW_02F9BwAJ
class QuadraticCostFunction : public ceres::SizedCostFunction < 4, 1, 1, 1, 1 > { public: virtual ~QuadraticCostFunction() {} virtual bool Evaluate(double const* const* parameters, double* residuals, double** jacobians) const { const double x1 = parameters[0][0]; const double x2 = parameters[1][0]; const double x3 = parameters[2][0]; const double x4 = parameters[3][0]; residuals[0] = x1 + 10.0*x2; residuals[1] = sqrt(5)*(x3 - x4); residuals[2] = pow((x2 - 2.0*x3), 2); residuals[3] = sqrt(10.0)*pow((x1 - x4), 2); if (jacobians != NULL && jacobians[0] != NULL) { jacobians[0][0] = 1.0; jacobians[0][1] = 10.0; jacobians[0][2] = 0.0; jacobians[0][3] = 0.0; jacobians[1][0] = 0.0; jacobians[1][1] = 0.0; jacobians[1][2] = sqrt(5.0); jacobians[1][3] = -sqrt(5.0); jacobians[2][0] = 0.0; jacobians[2][1] = 2.0*(x2 - 2.0*x3); jacobians[2][2] = -4.0*(x2 - 2.0*x3); jacobians[2][3] = 0.0; jacobians[3][0] = 2.0*sqrt(10)*(x1 - x4); jacobians[3][1] = 0.0; jacobians[3][2] = 0.0; jacobians[3][3] = -2.0*sqrt(10)*(x1 - x4); } return true; } };
但是main函数里面如果是如下情形
double params[4] = { 0.0, 0.0, 0.0, 0.0 }; Problem problem; CostFunction * cost_function = new QuadraticCostFunction; problem.AddResidualBlock(cost_function, NULL, params); Solver::Options options; options.linear_solver_type = ceres::DENSE_QR; options.minimizer_progress_to_stdout = true; Solver::Summary summary; Solve(options, &problem, &summary);
就要改成这样的定义方式
class QuadraticCostFunction : public ceres::SizedCostFunction < 4, 4 > /* I believe these entries are Num_residuals, size of x1, x2, x3 & x4... */ { public: virtual ~QuadraticCostFunction() {} virtual bool Evaluate(double const* const* parameters, double* residuals, double** jacobians) const { const double x1 = parameters[0][0]; const double x2 = parameters[0][1]; const double x3 = parameters[0][2]; const double x4 = parameters[0][3]; residuals[0] = x1 + 10.0*x2; residuals[1] = sqrt(5)*(x3 - x4); residuals[2] = pow((x2 - 2.0*x3), 2); residuals[3] = sqrt(10.0)*pow((x1 - x4), 2); if (jacobians != NULL && jacobians[0] != NULL) { jacobians[0][0] = 1.0; jacobians[0][1] = 10.0; jacobians[0][2] = 0.0; jacobians[0][3] = 0.0; //中间省略 jacobians[0][15] = -2.0*sqrt(10)*(x1 - x4); } return true; } };