28 ceres::Solver::Options copts;
30 copts.num_threads =
static_cast<int>(std::max(1U, std::thread::hardware_concurrency()));
31 copts.minimizer_progress_to_stdout = opts.verbose;
32 copts.function_tolerance = opts.epsilon;
33 copts.gradient_tolerance = opts.epsilon;
34 copts.parameter_tolerance = opts.epsilon;
35 copts.max_num_iterations = opts.max_iterations;
38 ceres::Solve(copts, &problem, &
summary);
70 ceres::Problem& problem,
double sum_squared_residuals = 0,
71 size_t total_residuals = 0)
72 -> std::optional<Eigen::MatrixXd> {
73 auto param_blocks = problem_param_blocks.get_param_blocks();
74 const size_t total_params = problem_param_blocks.total_params();
76 ceres::Covariance::Options cov_options;
77 ceres::Covariance covariance(cov_options);
78 std::vector<std::pair<const double*, const double*>> cov_blocks;
80 for (
size_t block_i = 0; block_i < param_blocks.size(); ++block_i) {
81 for (
size_t block_j = 0; block_j <= block_i; ++block_j) {
82 cov_blocks.emplace_back(param_blocks[block_i].data, param_blocks[block_j].data);
86 if (!covariance.Compute(cov_blocks, &problem)) {
90 Eigen::MatrixXd cov_matrix = Eigen::MatrixXd::Zero(
static_cast<Eigen::Index
>(total_params),
91 static_cast<Eigen::Index
>(total_params));
92 size_t row_offset = 0;
93 for (
size_t block_i = 0; block_i < param_blocks.size(); ++block_i) {
94 size_t block_i_size = param_blocks[block_i].size;
95 size_t col_offset = 0;
96 for (
size_t block_j = 0; block_j <= block_i; ++block_j) {
97 size_t block_j_size = param_blocks[block_j].size;
98 std::vector<double> block_cov(block_i_size * block_j_size);
99 covariance.GetCovarianceBlock(param_blocks[block_i].data, param_blocks[block_j].data,
101 for (
size_t row_idx = 0; row_idx < block_i_size; ++row_idx) {
102 for (
size_t col_idx = 0; col_idx < block_j_size; ++col_idx) {
103 double value = block_cov[row_idx * block_j_size + col_idx];
104 cov_matrix(
static_cast<Eigen::Index
>(row_offset + row_idx),
105 static_cast<Eigen::Index
>(col_offset + col_idx)) = value;
106 if (block_j < block_i) {
107 cov_matrix(
static_cast<Eigen::Index
>(col_offset + col_idx),
108 static_cast<Eigen::Index
>(row_offset + row_idx)) = value;
112 col_offset += block_j_size;
114 row_offset += block_i_size;
117 if (total_residuals > 0) {
119 int degrees_of_freedom =
120 std::max(1,
static_cast<int>(total_residuals) -
static_cast<int>(total_params));
121 double variance_factor = sum_squared_residuals / degrees_of_freedom;
122 cov_matrix *= variance_factor;