Solver::Options类
- Solver::Options类
方法 | 默认值 | 功能 |
---|---|---|
bool Solver::Options::IsValid(string *error) const | 检查options是否合法,不合法的话返回false,并将错误信息存到error里面 | |
int Solver::Options::max_num_iterations | 默认值:50; | 最大迭代次数 |
double Solver::Options::max_solver_time_in_seconds | 默认值:1e6; | 最长运行时间,单位为秒 |
int Solver::Options::num_threads | 默认值:1; | Ceres用于评估Jacobian的线程数,越多优化速度越快。 |
DenseLinearAlgebraLibrary Solver::Options::dense_linear_algebra_library_type | 默认值:EIGEN; | Ceres支持使用多个密集线性代数库进行稠密矩阵分解。 目前可选的为EIGEN和LAPACK。 EIGEN始终可用;LAPACK指的是BLAS + LAPACK库,可能有也可能没有(得看编译Ceres库时有没有加入BLAS + LAPACK的支持)。此设置会影响DENSE_QR,DENSE_NORMAL_CHOLESKY和DENSE_SCHUR求解器。 对于小到中等大小的求解器(这里的大小应该是指运算量,也就是问题规模的大小),EIGEN是一个很好的选择,但对于大问题,LAPACK + BLAS实现可以在性能上优势很大 |
SparseLinearAlgebraLibrary Solver::Options::sparse_linear_algebra_library_type | 默认值:SUITE_SPARSE > CX_SPARSE > EIGEN_SPARSE > NO_SPARSE;Ceres支持使用三个稀疏线性代数库SuiteSparse、CXSparse、EIGEN_SPARSE ,NO_SPARSE意味着不应使用稀疏线性求解器。 | SuiteSparse是一个非常复杂的稀疏线性代数库,性能最好,推荐使用。如果SuiteSparse不可用(编译Ceres的时候没有加入SuiteSparse支持),请考虑使用=CXSparse,这是一个更小,更容易编译的库。但是,它在大问题上的性能与SuiteSparse的性能相差巨大。也可以使用Eigen中稀疏线性代数库。目前,这个库的表现是三个中最差的。说不定在不久的将来性能会有改善。 |
LoggingType Solver::Options::logging_type | 默认值:PER_MINIMIZER_ITERATION | 每次迭代都打印信息,另一个可选的为SILENT |
bool Solver::Options::minimizer_progress_to_stdout | 默认值:false | 默认情况下,Minimizer(优化器)进度会记录到stderr,具体取决于vlog级别。 如果此标志设置为true,并且Solver::Option:: logging_type不是SILENT,则日志记录输出将发送到stdout(在终端打印出信息) |
bool Solver::Options::check_gradients | 默认值:false | 检查由具有有限差分的每个残差块计算的所有雅可比行列式,比较结果,如果它们大不相同,则优化失败。如果设置为true的花比较耗费性能,一般保持默认。 |
double Solver::Options::gradient_check_relative_precision | 默认值: 1e8 | 在gradient checker中检查的精度。 如果雅可比行列式中的元素之间的相对差异超过此数字,则dump该cost term的雅可比行列式 |
vector Solver::Options::callbacks | 默认情况下,参数仅在优化结束时更新在Minimizer的每次迭代结束时执行的回调。 它们按照在此vector中指定的顺序执行,如果希望在执行回调时访问更新的参数,则将Solver::Options::update_state_every_iteration需要设置为true。 | |
bool Solver::Options::update_state_every_iteration | 默认值:false | 如果为true,则在每个迭代结束时更新参数,否则在优化终止时才更新参数 |
- 输出的信息
1. cost 是目标函数的值。
2. cost_change 是目标函数值的变化。
3. |gradient| 是梯度的最大范数。
4. |step| 是参数向量的变化。
5. tr_ratio是目标函数值的实际变化与信赖域模型值的变化之比。
6. tr_radius是信任区域半径的大小。
7. ls_iter是用于计算信任区域步骤的线性求解器迭代次数。
8. iter_time:本次迭代所用时间
9. total_time是所用的总时间。
Problem::problem类
- 几个重要成员方法:
Problem::AddResidualBlock( )
作用添加残差
ResidualBlockId Problem::AddResidualBlock(CostFunction *cost_function,
LossFunction *loss_function,
const vector<double *> parameter_blocks)
//cost_function:代价函数
//LossFunction:损失函数,可以使用损失函数,是你和数据更接近真实值
//x:待优化参数
Problem::AddParameterBlock( )
作用:添加参数块
用户在调用AddResidualBlock( )时其实已经隐式地向Problem传递了参数模块,但在一些情况下,需要用户显示地向Problem传入参数模块
void Problem::AddParameterBlock(double *values, int size)
//values:值
//size:大小
void Problem::AddParameterBlock(double *values, int size, LocalParameterization *local_parameterization)
//LocalParameterization参数,用于重构优化参数的维数
LocalParameterization()
解决非线性优化中的过参数化问题。所谓过参数化,即待优化参数的实际自由度小于参数本身的自由度。例如在SLAM中,当采用四元数表示位姿时,由于四元数本身的约束(模长为1),实际的自由度为3而非4。此时,若直接传递四元数进行优化,冗余的维数会带来计算资源的浪费,需要使用Ceres预先定义的QuaternionParameterization对优化参数进行重构:
problem.AddParameterBlock(quaternion, 4);// 直接传递4维参数
ceres::LocalParameterization* local_param = new ceres::QuaternionParameterization();
problem.AddParameterBlock(quaternion, 4, local_param)//重构参数,优化时实际使用的是3维的等效旋转矢量