Ceres Solver C ++:细分错误:11

时间:2019-06-04 20:32:27

标签: c++ optimization google-analytics mathematical-optimization ceres-solver

我正在尝试使用Google的Ceres Solver解决非线性系统。以下示例来自此页面:http://terpconnect.umd.edu/~petersd/460/html/newtonex1z.html

我首先创建一个名为MatlabExample的类,在其中计算residualsjacobians

class MatlabExample
: public SizedCostFunction<2,2> {
public:
virtual ~MatlabExample() {}
virtual bool Evaluate(double const* const* parameters,
                    double* residuals,
                    double** jacobians) const {

double x1 = parameters[0][0];
double x2 = parameters[0][1];

residuals[0] = 2*x1+x1*x2-2;
residuals[1] = 2*x2-x1*pow(x2,2)-2 ;

if (jacobians != NULL && jacobians[0] != NULL) {
  jacobians[0][0] = 2+x2;
  jacobians[0][1] = x1;
  jacobians[1][0] = -pow(x2,2);
  jacobians[1][1] = 2-2*x1*x2;
}

return true;
}
};

主文件如下:

int main(int argc, char** argv) {
  google::InitGoogleLogging(argv[0]);

  double x[] = { 0.0,0.0 };

  Problem problem;
  CostFunction* cost_function = new MatlabExample;
  problem.AddResidualBlock(cost_function, NULL, &x);
  Solver::Options options;
  options.minimizer_progress_to_stdout = true;
  Solver::Summary summary;
  Solve(options, &problem, &summary);

  std::cout << summary.BriefReport() << "\n";

  return 0;
}

编译时出现Segmentation fault: 11错误。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

您正在错误地访问jacobians数组。这就是为什么。

添加残差块时,您告诉Ceres成本函数仅取决于大小为2的一个参数块,并产生大小为2的残差。

jacobians数组是行主要的jacobians的数组。每个参数块一个。因此,在这种情况下,它的大小为1,并包含一个指向大小为4的数组的指针,该数组应包含行主要Jacobian。

您的Jacobian填充代码应改为

if (jacobians != NULL && jacobians[0] != NULL) {
  jacobians[0][0] = 2+x2;
  jacobians[0][1] = x1;
  jacobians[0][2] = -pow(x2,2);
  jacobians[0][3] = 2-2*x1*x2;
}