天天看点

使用ceres求f(x)=2(x-5)^2极值

Ceres是一个非线性的优化库,在优化问题中广泛使用,今天我们就来使用这一优化库来求解一个函数的极值点​。非线性优化库优化的原理是在给定初值的条件下不断计算偏移量,使得待优化参数向着目标函数梯度最小处移动。

使用Ceres优化库的步骤可以归纳为以下几步​:

  1. 定义参数块,主要定义待优化参数的形​式;
  2. 定义残差块的计算方式。残差块通常关联若干个参数块,对它们进行一些自定义的计算,然后返回残差值​;
  3. 残差块也需要定义雅可比的计算方式​。在Ceres中,你可以使用它提供的“自动求导”功能,也可以手动指定雅可比的计算过程。如果要使用自动求导,那么残差块需要按照特定的写法书写;残差的计算过程应该是一个带模板的括号运算符;
  4. 将所有的参数块和残差块加入Ceres定义的Problem对象中,调用Slove函数求解即可​。求解之前,我们可以传入一些配置信息,例如迭代次数、终止条件等,也可以使用默认的配置​。
#include <iostream>
#include <ceres/ceres.h>
#include <glog/logging.h>
#include<chrono>
#include <math.h>
#include <algorithm>
using namespace std;
using ceres::AutoDiffCostFunction;
using ceres::CostFunction;
using ceres::Problem;
using ceres::Solve;
using ceres::Solver;
//x表示待优化参数块,residual表示残差块
//通过非线性优化找到函数梯度下降的自变量的取值。
struct CostFunctor {
  template <typename T>
  bool operator()(const T* const x, T* residual) const {
    residual[0] = 2.0*pow(x[0]-5.0,2);
    return true;
  }
};

int main(int argc, char** argv) {
  google::InitGoogleLogging(argv[0]);
  // The variable to solve for with its initial value. It will be
  // mutated in place by the solver.
  double x = 0.5;
  const double initial_x = x;
  // Build the problem.
  Problem problem;
  // Set up the only cost function (also known as residual). This uses
  // auto-differentiation to obtain the derivative (jacobian).
  //定义误差函数,误差类型,输入维度,输出维度
  CostFunction* cost_function =
      new AutoDiffCostFunction<CostFunctor, 1, 1>(new CostFunctor);
      //优化问题添加残差块,不使用核函数
  problem.AddResidualBlock(cost_function, nullptr, &x);
  // Run the solver!
  Solver::Options options;
  options.minimizer_progress_to_stdout = true;
  Solver::Summary summary;
  Solve(options, &problem, &summary);
  std::cout << summary.BriefReport() << "\n";
  std::cout << "x : " << initial_x << " -> " << x << "\n";
  return 0;
}
           
使用ceres求f(x)=2(x-5)^2极值

继续阅读