Ceres Solver是一个开源的C++库,用于建模和解决大型、复杂的优化问题。它是一个成熟、功能丰富且高性能的库,自2010年以来一直在Google生产中使用。最新发布版本为2.1.0,license为BSD,它支持在Windows、Linux、Mac、Android、iOS上编译,源码地址:https://ceres-solver.googlesource.com/ceres-solver
Ceres Solver可用于解决两类问题:
(1).具有边界约束的非线性最小二乘(Non-linear Least Squares)问题;
(2).一般无约束优化问题。
Ceres Solver依赖项:
(1).必须的:CMake、Eigen、glog、gflags;
(2).可选的:SuiteSparse、BLAS and LAPACK、CUDA。
Ceres Solver在Ubuntu 20.04上编译:eigen, glog, gflags, ceres-solver都在/home/spring/Soft目录下
(1).clone eigen源码:这里使用3.3.7版本,依次执行如下命令:
- git clone https://gitlab.com/libeigen/eigen.git
- cd eigen
- git checkout 3.3.7
编译eigen,在eigen目录下执行build_eigen.sh,其内容如下:
- #! /bin/bash
-
- if [[ ! -d "build" ]]; then
- mkdir build
- cd build
- else
- cd build
- fi
-
- cmake \
- -DCMAKE_CXX_FLAGS=-fPIC \
- -DCMAKE_C_FLAGS=-fPIC \
- -DCMAKE_BUILD_TYPE=Release \
- -DCMAKE_INSTALL_PREFIX=../install \
- ..
- make -j2
- make install
(2).clone glog源码:这里使用v0.4.0版本,依次执行如下命令:
- git clone https://github.com/google/glog.git
- cd glog
- git checkout v0.4.0
编译glog,在glog目录下直接执行build_glog.sh,其内容与build_eigen.sh完全一致。
(3).clone gflags源码:这里使用v2.2.2版本,依次执行如下命令:
- git clone https://github.com/gflags/gflags.git
- cd gflags
- git checkout v2.2.2
编译gflags,在gflags目录执行build_gflags.sh,其内容与build_eigen.sh完全一致。
(4).clone Ceres Solver源码:这里使用1.14.0版本,依次执行如下命令:
- git clone https://ceres-solver.googlesource.com/ceres-solver
- cd ceres-solver
- git checkout 1.14.0
编译ceres-solver,在ceres-solver目录执行build_ceres-solver.sh,其内容如下:
- #! /bin/bash
-
- if [[ ! -d "build" ]]; then
- mkdir build
- cd build
- else
- cd build
- fi
-
- path=/home/spring/Soft
-
- cmake \
- -DCMAKE_CXX_FLAGS=-fPIC \
- -DCMAKE_C_FLAGS=-fPIC \
- -DCMAKE_BUILD_TYPE=Release \
- -DCMAKE_INSTALL_PREFIX=../install \
- -DEigen3_DIR=${path}/eigen/install/share/eigen3/cmake \
- -Dglog_DIR=${path}/glog/install/lib/cmake/glog \
- -Dgflags_DIR=${path}/gflags/install/lib/cmake/gflags \
- ..
- make -j2
- make install
Ceres Solver调用:在/home/spring/Soft目录下新建test目录,此目录内文件内容依次如下
(1).main.cpp:
- #include
- #include
- #include
-
- using namespace ceres;
-
- struct CostFunctor {
- template <typename T>
- bool operator()(const T* const x, T* residual) const {
- residual[0] = 10.0 - x[0];
- return true;
- }
- };
-
- int main(int argc, char** argv)
- {
- // reference: http://ceres-solver.org/nnls_tutorial.html
- google::InitGoogleLogging(argv[0]);
-
- // The variable to solve for with its initial value.
- double initial_x = 5.0;
- double x = initial_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
1, 1>(new CostFunctor); - problem.AddResidualBlock(cost_function, nullptr, &x);
-
- // Run the solver!
- Solver::Options options;
- options.linear_solver_type = ceres::DENSE_QR;
- 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;
- }
(2).build.sh:
- #! /bin/bash
-
- if [[ ! -d "build" ]]; then
- mkdir build
- cd build
- else
- cd build
- fi
-
- path=/home/spring/Soft
-
- cp ${path}/glog/install/lib/libglog.a .
- cp ${path}/gflags/install/lib/libgflags.a .
- cp ${path}/ceres-solver/install/lib/libceres.a .
-
- cmake ..
- make
(3).CMakeLists.txt:
- cmake_minimum_required(VERSION 3.15)
- project(test_ceres-solver)
-
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")
-
- include_directories(
- ${CMAKE_CURRENT_SOURCE_DIR}/../eigen/install/include/eigen3
- ${CMAKE_CURRENT_SOURCE_DIR}/../glog/install/include
- ${CMAKE_CURRENT_SOURCE_DIR}/../gflags/install/include
- ${CMAKE_CURRENT_SOURCE_DIR}/../ceres-solver/install/include
- )
-
- add_executable(${CMAKE_PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp)
- target_link_directories(${CMAKE_PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/build)
- target_link_libraries(${CMAKE_PROJECT_NAME} ceres glog gflags pthread)
执行:
首先执行:./build.sh
然后执行:./build/test_ceres-solver ,结果如下图所示:
