Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'extern/ceres/internal/ceres/covariance_impl.cc')
-rw-r--r--extern/ceres/internal/ceres/covariance_impl.cc136
1 files changed, 66 insertions, 70 deletions
diff --git a/extern/ceres/internal/ceres/covariance_impl.cc b/extern/ceres/internal/ceres/covariance_impl.cc
index 1f86707f5a7..324b5531a04 100644
--- a/extern/ceres/internal/ceres/covariance_impl.cc
+++ b/extern/ceres/internal/ceres/covariance_impl.cc
@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2015 Google Inc. All rights reserved.
+// Copyright 2022 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// Redistribution and use in source and binary forms, with or without
@@ -79,13 +79,12 @@ CovarianceImpl::CovarianceImpl(const Covariance::Options& options)
evaluate_options_.apply_loss_function = options_.apply_loss_function;
}
-CovarianceImpl::~CovarianceImpl() {}
+CovarianceImpl::~CovarianceImpl() = default;
template <typename T>
void CheckForDuplicates(std::vector<T> blocks) {
- sort(blocks.begin(), blocks.end());
- typename std::vector<T>::iterator it =
- std::adjacent_find(blocks.begin(), blocks.end());
+ std::sort(blocks.begin(), blocks.end());
+ auto it = std::adjacent_find(blocks.begin(), blocks.end());
if (it != blocks.end()) {
// In case there are duplicates, we search for their location.
std::map<T, std::vector<int>> blocks_map;
@@ -117,7 +116,7 @@ bool CovarianceImpl::Compute(const CovarianceBlocks& covariance_blocks,
covariance_blocks);
problem_ = problem;
parameter_block_to_row_index_.clear();
- covariance_matrix_.reset(NULL);
+ covariance_matrix_ = nullptr;
is_valid_ = (ComputeCovarianceSparsity(covariance_blocks, problem) &&
ComputeCovarianceValues());
is_computed_ = true;
@@ -162,10 +161,10 @@ bool CovarianceImpl::GetCovarianceBlockInTangentOrAmbientSpace(
const int block1_size = block1->Size();
const int block2_size = block2->Size();
- const int block1_local_size = block1->LocalSize();
- const int block2_local_size = block2->LocalSize();
+ const int block1_tangent_size = block1->TangentSize();
+ const int block2_tangent_size = block2->TangentSize();
if (!lift_covariance_to_ambient_space) {
- MatrixRef(covariance_block, block1_local_size, block2_local_size)
+ MatrixRef(covariance_block, block1_tangent_size, block2_tangent_size)
.setZero();
} else {
MatrixRef(covariance_block, block1_size, block2_size).setZero();
@@ -209,34 +208,34 @@ bool CovarianceImpl::GetCovarianceBlockInTangentOrAmbientSpace(
FindOrDie(parameter_map, const_cast<double*>(parameter_block1));
ParameterBlock* block2 =
FindOrDie(parameter_map, const_cast<double*>(parameter_block2));
- const LocalParameterization* local_param1 = block1->local_parameterization();
- const LocalParameterization* local_param2 = block2->local_parameterization();
+ const Manifold* manifold1 = block1->manifold();
+ const Manifold* manifold2 = block2->manifold();
const int block1_size = block1->Size();
- const int block1_local_size = block1->LocalSize();
+ const int block1_tangent_size = block1->TangentSize();
const int block2_size = block2->Size();
- const int block2_local_size = block2->LocalSize();
+ const int block2_tangent_size = block2->TangentSize();
- ConstMatrixRef cov(
- covariance_matrix_->values() + rows[row_begin], block1_size, row_size);
+ ConstMatrixRef cov(covariance_matrix_->values() + rows[row_begin],
+ block1_tangent_size,
+ row_size);
- // Fast path when there are no local parameterizations or if the
- // user does not want it lifted to the ambient space.
- if ((local_param1 == NULL && local_param2 == NULL) ||
+ // Fast path when there are no manifolds or if the user does not want it
+ // lifted to the ambient space.
+ if ((manifold1 == nullptr && manifold2 == nullptr) ||
!lift_covariance_to_ambient_space) {
if (transpose) {
- MatrixRef(covariance_block, block2_local_size, block1_local_size) =
- cov.block(0, offset, block1_local_size, block2_local_size)
+ MatrixRef(covariance_block, block2_tangent_size, block1_tangent_size) =
+ cov.block(0, offset, block1_tangent_size, block2_tangent_size)
.transpose();
} else {
- MatrixRef(covariance_block, block1_local_size, block2_local_size) =
- cov.block(0, offset, block1_local_size, block2_local_size);
+ MatrixRef(covariance_block, block1_tangent_size, block2_tangent_size) =
+ cov.block(0, offset, block1_tangent_size, block2_tangent_size);
}
return true;
}
- // If local parameterizations are used then the covariance that has
- // been computed is in the tangent space and it needs to be lifted
- // back to the ambient space.
+ // If manifolds are used then the covariance that has been computed is in the
+ // tangent space and it needs to be lifted back to the ambient space.
//
// This is given by the formula
//
@@ -249,36 +248,37 @@ bool CovarianceImpl::GetCovarianceBlockInTangentOrAmbientSpace(
// See Result 5.11 on page 142 of Hartley & Zisserman (2nd Edition)
// for a proof.
//
- // TODO(sameeragarwal): Add caching of local parameterization, so
- // that they are computed just once per parameter block.
- Matrix block1_jacobian(block1_size, block1_local_size);
- if (local_param1 == NULL) {
+ // TODO(sameeragarwal): Add caching the manifold plus_jacobian, so that they
+ // are computed just once per parameter block.
+ Matrix block1_jacobian(block1_size, block1_tangent_size);
+ if (manifold1 == nullptr) {
block1_jacobian.setIdentity();
} else {
- local_param1->ComputeJacobian(parameter_block1, block1_jacobian.data());
+ manifold1->PlusJacobian(parameter_block1, block1_jacobian.data());
}
- Matrix block2_jacobian(block2_size, block2_local_size);
+ Matrix block2_jacobian(block2_size, block2_tangent_size);
// Fast path if the user is requesting a diagonal block.
if (parameter_block1 == parameter_block2) {
block2_jacobian = block1_jacobian;
} else {
- if (local_param2 == NULL) {
+ if (manifold2 == nullptr) {
block2_jacobian.setIdentity();
} else {
- local_param2->ComputeJacobian(parameter_block2, block2_jacobian.data());
+ manifold2->PlusJacobian(parameter_block2, block2_jacobian.data());
}
}
if (transpose) {
MatrixRef(covariance_block, block2_size, block1_size) =
block2_jacobian *
- cov.block(0, offset, block1_local_size, block2_local_size).transpose() *
+ cov.block(0, offset, block1_tangent_size, block2_tangent_size)
+ .transpose() *
block1_jacobian.transpose();
} else {
MatrixRef(covariance_block, block1_size, block2_size) =
block1_jacobian *
- cov.block(0, offset, block1_local_size, block2_local_size) *
+ cov.block(0, offset, block1_tangent_size, block2_tangent_size) *
block2_jacobian.transpose();
}
@@ -309,7 +309,7 @@ bool CovarianceImpl::GetCovarianceMatrixInTangentOrAmbientSpace(
if (lift_covariance_to_ambient_space) {
parameter_sizes.push_back(block->Size());
} else {
- parameter_sizes.push_back(block->LocalSize());
+ parameter_sizes.push_back(block->TangentSize());
}
}
std::partial_sum(parameter_sizes.begin(),
@@ -383,8 +383,7 @@ bool CovarianceImpl::ComputeCovarianceSparsity(
std::vector<ResidualBlock*> residual_blocks;
problem->GetResidualBlocks(&residual_blocks);
- for (int i = 0; i < residual_blocks.size(); ++i) {
- ResidualBlock* residual_block = residual_blocks[i];
+ for (auto* residual_block : residual_blocks) {
parameter_blocks_in_use.insert(residual_block->parameter_blocks(),
residual_block->parameter_blocks() +
residual_block->NumParameterBlocks());
@@ -394,8 +393,7 @@ bool CovarianceImpl::ComputeCovarianceSparsity(
std::vector<double*>& active_parameter_blocks =
evaluate_options_.parameter_blocks;
active_parameter_blocks.clear();
- for (int i = 0; i < all_parameter_blocks.size(); ++i) {
- double* parameter_block = all_parameter_blocks[i];
+ for (auto* parameter_block : all_parameter_blocks) {
ParameterBlock* block = FindOrDie(parameter_map, parameter_block);
if (!block->IsConstant() && (parameter_blocks_in_use.count(block) > 0)) {
active_parameter_blocks.push_back(parameter_block);
@@ -411,10 +409,9 @@ bool CovarianceImpl::ComputeCovarianceSparsity(
// ordering of parameter blocks just constructed.
int num_rows = 0;
parameter_block_to_row_index_.clear();
- for (int i = 0; i < active_parameter_blocks.size(); ++i) {
- double* parameter_block = active_parameter_blocks[i];
+ for (auto* parameter_block : active_parameter_blocks) {
const int parameter_block_size =
- problem->ParameterBlockLocalSize(parameter_block);
+ problem->ParameterBlockTangentSize(parameter_block);
parameter_block_to_row_index_[parameter_block] = num_rows;
num_rows += parameter_block_size;
}
@@ -424,9 +421,7 @@ bool CovarianceImpl::ComputeCovarianceSparsity(
// triangular part of the matrix.
int num_nonzeros = 0;
CovarianceBlocks covariance_blocks;
- for (int i = 0; i < original_covariance_blocks.size(); ++i) {
- const std::pair<const double*, const double*>& block_pair =
- original_covariance_blocks[i];
+ for (const auto& block_pair : original_covariance_blocks) {
if (constant_parameter_blocks_.count(block_pair.first) > 0 ||
constant_parameter_blocks_.count(block_pair.second) > 0) {
continue;
@@ -434,8 +429,8 @@ bool CovarianceImpl::ComputeCovarianceSparsity(
int index1 = FindOrDie(parameter_block_to_row_index_, block_pair.first);
int index2 = FindOrDie(parameter_block_to_row_index_, block_pair.second);
- const int size1 = problem->ParameterBlockLocalSize(block_pair.first);
- const int size2 = problem->ParameterBlockLocalSize(block_pair.second);
+ const int size1 = problem->ParameterBlockTangentSize(block_pair.first);
+ const int size2 = problem->ParameterBlockTangentSize(block_pair.second);
num_nonzeros += size1 * size2;
// Make sure we are constructing a block upper triangular matrix.
@@ -447,9 +442,9 @@ bool CovarianceImpl::ComputeCovarianceSparsity(
}
}
- if (covariance_blocks.size() == 0) {
+ if (covariance_blocks.empty()) {
VLOG(2) << "No non-zero covariance blocks found";
- covariance_matrix_.reset(NULL);
+ covariance_matrix_ = nullptr;
return true;
}
@@ -459,8 +454,8 @@ bool CovarianceImpl::ComputeCovarianceSparsity(
std::sort(covariance_blocks.begin(), covariance_blocks.end());
// Fill the sparsity pattern of the covariance matrix.
- covariance_matrix_.reset(
- new CompressedRowSparseMatrix(num_rows, num_rows, num_nonzeros));
+ covariance_matrix_ = std::make_unique<CompressedRowSparseMatrix>(
+ num_rows, num_rows, num_nonzeros);
int* rows = covariance_matrix_->mutable_rows();
int* cols = covariance_matrix_->mutable_cols();
@@ -480,7 +475,7 @@ bool CovarianceImpl::ComputeCovarianceSparsity(
int cursor = 0; // index into the covariance matrix.
for (const auto& entry : parameter_block_to_row_index_) {
const double* row_block = entry.first;
- const int row_block_size = problem->ParameterBlockLocalSize(row_block);
+ const int row_block_size = problem->ParameterBlockTangentSize(row_block);
int row_begin = entry.second;
// Iterate over the covariance blocks contained in this row block
@@ -493,7 +488,7 @@ bool CovarianceImpl::ComputeCovarianceSparsity(
if (block_pair.first != row_block) {
break;
}
- num_columns += problem->ParameterBlockLocalSize(block_pair.second);
+ num_columns += problem->ParameterBlockTangentSize(block_pair.second);
}
// Fill out all the compressed rows for this parameter block.
@@ -501,7 +496,8 @@ bool CovarianceImpl::ComputeCovarianceSparsity(
rows[row_begin + r] = cursor;
for (int c = 0; c < num_col_blocks; ++c) {
const double* col_block = covariance_blocks[i + c].second;
- const int col_block_size = problem->ParameterBlockLocalSize(col_block);
+ const int col_block_size =
+ problem->ParameterBlockTangentSize(col_block);
int col_begin = FindOrDie(parameter_block_to_row_index_, col_block);
for (int k = 0; k < col_block_size; ++k) {
cols[cursor++] = col_begin++;
@@ -556,13 +552,13 @@ bool CovarianceImpl::ComputeCovarianceValuesUsingSuiteSparseQR() {
"CovarianceImpl::ComputeCovarianceValuesUsingSparseQR");
#ifndef CERES_NO_SUITESPARSE
- if (covariance_matrix_.get() == NULL) {
+ if (covariance_matrix_ == nullptr) {
// Nothing to do, all zeros covariance matrix.
return true;
}
CRSMatrix jacobian;
- problem_->Evaluate(evaluate_options_, NULL, NULL, NULL, &jacobian);
+ problem_->Evaluate(evaluate_options_, nullptr, nullptr, nullptr, &jacobian);
event_logger.AddEvent("Evaluate");
// Construct a compressed column form of the Jacobian.
@@ -601,11 +597,11 @@ bool CovarianceImpl::ComputeCovarianceValuesUsingSuiteSparseQR() {
cholmod_jacobian.nrow = num_rows;
cholmod_jacobian.ncol = num_cols;
cholmod_jacobian.nzmax = num_nonzeros;
- cholmod_jacobian.nz = NULL;
+ cholmod_jacobian.nz = nullptr;
cholmod_jacobian.p = reinterpret_cast<void*>(&transpose_rows[0]);
cholmod_jacobian.i = reinterpret_cast<void*>(&transpose_cols[0]);
cholmod_jacobian.x = reinterpret_cast<void*>(&transpose_values[0]);
- cholmod_jacobian.z = NULL;
+ cholmod_jacobian.z = nullptr;
cholmod_jacobian.stype = 0; // Matrix is not symmetric.
cholmod_jacobian.itype = CHOLMOD_LONG;
cholmod_jacobian.xtype = CHOLMOD_REAL;
@@ -616,8 +612,8 @@ bool CovarianceImpl::ComputeCovarianceValuesUsingSuiteSparseQR() {
cholmod_common cc;
cholmod_l_start(&cc);
- cholmod_sparse* R = NULL;
- SuiteSparse_long* permutation = NULL;
+ cholmod_sparse* R = nullptr;
+ SuiteSparse_long* permutation = nullptr;
// Compute a Q-less QR factorization of the Jacobian. Since we are
// only interested in inverting J'J = R'R, we do not need Q. This
@@ -648,9 +644,9 @@ bool CovarianceImpl::ComputeCovarianceValuesUsingSuiteSparseQR() {
}
if (rank < cholmod_jacobian.ncol) {
- LOG(ERROR) << "Jacobian matrix is rank deficient. "
- << "Number of columns: " << cholmod_jacobian.ncol
- << " rank: " << rank;
+ LOG(WARNING) << "Jacobian matrix is rank deficient. "
+ << "Number of columns: " << cholmod_jacobian.ncol
+ << " rank: " << rank;
free(permutation);
cholmod_l_free_sparse(&R, &cc);
cholmod_l_finish(&cc);
@@ -721,13 +717,13 @@ bool CovarianceImpl::ComputeCovarianceValuesUsingSuiteSparseQR() {
bool CovarianceImpl::ComputeCovarianceValuesUsingDenseSVD() {
EventLogger event_logger(
"CovarianceImpl::ComputeCovarianceValuesUsingDenseSVD");
- if (covariance_matrix_.get() == NULL) {
+ if (covariance_matrix_ == nullptr) {
// Nothing to do, all zeros covariance matrix.
return true;
}
CRSMatrix jacobian;
- problem_->Evaluate(evaluate_options_, NULL, NULL, NULL, &jacobian);
+ problem_->Evaluate(evaluate_options_, nullptr, nullptr, nullptr, &jacobian);
event_logger.AddEvent("Evaluate");
Matrix dense_jacobian(jacobian.num_rows, jacobian.num_cols);
@@ -812,20 +808,20 @@ bool CovarianceImpl::ComputeCovarianceValuesUsingDenseSVD() {
bool CovarianceImpl::ComputeCovarianceValuesUsingEigenSparseQR() {
EventLogger event_logger(
"CovarianceImpl::ComputeCovarianceValuesUsingEigenSparseQR");
- if (covariance_matrix_.get() == NULL) {
+ if (covariance_matrix_ == nullptr) {
// Nothing to do, all zeros covariance matrix.
return true;
}
CRSMatrix jacobian;
- problem_->Evaluate(evaluate_options_, NULL, NULL, NULL, &jacobian);
+ problem_->Evaluate(evaluate_options_, nullptr, nullptr, nullptr, &jacobian);
event_logger.AddEvent("Evaluate");
- typedef Eigen::SparseMatrix<double, Eigen::ColMajor> EigenSparseMatrix;
+ using EigenSparseMatrix = Eigen::SparseMatrix<double, Eigen::ColMajor>;
// Convert the matrix to column major order as required by SparseQR.
EigenSparseMatrix sparse_jacobian =
- Eigen::MappedSparseMatrix<double, Eigen::RowMajor>(
+ Eigen::Map<Eigen::SparseMatrix<double, Eigen::RowMajor>>(
jacobian.num_rows,
jacobian.num_cols,
static_cast<int>(jacobian.values.size()),