- include/ceres/autodiff_manifold.h: Replace manual zero-initialization loops with value-initialization ({}) in PlusJacobian and MinusJacobian.
- include/ceres/dynamic_numeric_diff_cost_function.h: Replace std::vector with absl::FixedArray for temporary evaluation buffers and use std::copy_n instead of memcpy in Evaluate.
- include/ceres/numeric_diff_cost_function.h: Replace memcpy with std::copy_n in Evaluate.
Change-Id: I13b546458185d9fdd22b086094ca1072c57c40ed
Use std::clamp for projecting the updated parameter state onto its
box constraints. This provides a more idiomatic and concise
implementation than separate std::min/std::max loops, especially
when both lower and upper bounds are present.
Change-Id: I1f6248ed8f0313338cf9a1c98d79a023ae281e6c
Use if constexpr for kSize checks in InvertPSDMatrix to allow for
dead-code elimination at compile time. This ensures that for small
fixed-size matrices, only the inverse() path is compiled, and for
larger or dynamic matrices, only the LLT path is compiled when
assume_full_rank is true.
Change-Id: I4def2faadd080a4defccf1c0527015ae004f20ce
Refactor the core automatic and numeric differentiation internal helpers
to utilize C++17 features for improved readability and maintainability:
- Added IntegerSequenceTraits to provide a uniform compile-time interface
for accessing head and tail of std::integer_sequence.
- Eliminated recursive template meta-programming in autodiff.h, replacing
it with fold expressions and std::index_sequence.
- Simplified core helper functions like Make1stOrderPerturbation into
unrolled loops.
- Refactored EvaluateJacobianForParameterBlocks from a recursive struct
to a recursive function template using if constexpr.
- Updated NumericDiffCostFunction and NumericDiffFirstOrderFunction
to use the modernized internal helper API.
Change-Id: I934034f7434fc05a8855565b2b534d325f920584
- Add constructors taking std::unique_ptr and ceres::Ownership to
AutoDiffCostFunction, NumericDiffCostFunction, and their dynamic
and first-order counterparts.
- Standardize delegating constructor style to use parentheses.
- Standardize ownership check in destructors.
- Fix documentation typos and example code in headers.
- Add comprehensive tests for Ownership and unique_ptr constructors.
Change-Id: I573abd695cdd89905997b573620e8d99d1cacca2
Modernize ProductManifold using C++17 fold expressions and std::index_sequence
to replace recursive implementations of Plus, Minus, and their Jacobians.
This simplifies the code, removes the need for auxiliary recursive ...Impl
methods, and improves index handling by using std::get<I> instead of
pointer arithmetic.
Change-Id: I28498216d8daae7485c382140613fd85519fa42c
Modernize the construction and initialization logic of AutoDiffCostFunction,
NumericDiffCostFunction, AutoDiffFirstOrderFunction,
NumericDiffFirstOrderFunction, DynamicAutoDiffCostFunction,
DynamicNumericDiffCostFunction, and CostFunctionToFunctor by utilizing
C++17 features:
- Simplify constructor delegation using if constexpr, removing the need for
internal InitTag structures.
- Use std::is_constructible_v for cleaner SFINAE in variadic constructors.
- Add static_assert to catch improper usage of DYNAMIC residuals/parameters
at compile-time.
- Add Ownership support to AutoDiffFirstOrderFunction,
DynamicAutoDiffCostFunction, and DynamicNumericDiffCostFunction.
- Simplify CostFunctionToFunctor::operator() using variadic parameter packs.
- Use this->num_residuals() for consistent and clear access to base class
state.
- Minor code quality improvements and removal of redundant template
parameters.
Change-Id: Id760a26ba2ceca4fb2939ef7632f2f1d9cc430c9
When Ceres is configured with BUILD_TESTING=OFF and BUILD_BENCHMARKS=ON,
benchmarks failed to compile and link due to an unconditional dependency on the
test_util library, which requires Googletest (GTest). This commit addresses the issue
by introducing the CERES_HAS_GTEST macro and making the test utility library
GTest-optional.
Fixes: https://github.com/ceres-solver/ceres-solver/issues/1081
Change-Id: I615c37eb6f21d36a4b87b2d24632016944eda3bd
Compiling Ceres with Schur specializations and Link Time Optimization
(LTO) results in warnings such as
/usr/include/eigen3/Eigen/src/Core/ProductEvaluators.h:31:8: warning: type ‘struct evaluator’ violates the C++ One Definition Rule [-Wodr]
31 | struct evaluator<Product<Lhs, Rhs, Options>> : public product_evaluator<Product<Lhs, Rhs, Options>> {
| ^
due to the redefinition of EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD which
alters internal Eigen class definitions and consequently results in ODR
violations.
Avoid the ODR violation by renaming the Eigen namespace in translation
units that redefine EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD.
While the issue is diagnosed in LTO builds of Ceres only, the problem
exists in non-LTO builds as well and per standard the compiler is not
even required to diagnose ODR issues. ODR violations constitute
undefined behavior.
Change-Id: Idf7c7a30cc8d3a86b0d62cbd33bef58783a62ee4
Resolve the following warnings issue by the latest version of the
benchmark library:
/Users/runner/work/ceres-solver/ceres-solver/internal/ceres/small_blas_gemv_benchmark.cc:71:54: warning: 'Benchmark' is deprecated: Use ::benchmark::Benchmark instead [-Wdeprecated-declarations]
71 | static void MatrixSizeArguments(benchmark::internal::Benchmark* benchmark) {
|
/Users/runner/work/ceres-solver/ceres-solver/internal/ceres/dense_linear_solver_benchmark.cc:67:46: warning: 'Benchmark' is deprecated: Use ::benchmark::Benchmark instead [-Wdeprecated-declarations]
67 | static void MatrixSizes(benchmark::internal::Benchmark* b) {
|
/Users/runner/work/ceres-solver/ceres-solver/internal/ceres/invert_psd_matrix_benchmark.cc:80:37: warning: 'Benchmark' is deprecated: Use ::benchmark::Benchmark instead [-Wdeprecated-declarations]
80 | ->Apply([](benchmark::internal::Benchmark* benchmark) {
|
Change-Id: Ice6fe57dc5635698809e368fda23a018f4d7df5a
Add documentation on the output of DumpLinearLeastSquaresProblem.
This is to clarify confusion brought up on #608
Change-Id: I935cacee1e4345a1d0250aaac322ca2f8e794e66
Normally we expect it to be the case that inner iteration cost
will be less than the trust region cost, but due to round off
error it can be that it is larger, so make the test for inner
iteration being successful to be stricter.
Change-Id: Icbafe9fc6a311940d5368cca78eeac7ccd5fa943
Using a define to determine whether to disable warnings introduces a
dependency on the header inclusion order and thus can prevent the
warnings from being enabled.
Fixes#1173
Change-Id: I21f5bca78a83bfe4642e9b01abd220b9fbba31a4
This CL reorders the fields to group the hot fields together to increase data density. This CL doesn’t change functionality but expects to reduce cache misses and save CPU.
Change-Id: I313493a187ac6ebc607b311c39415c79a94f00c8
This change fixes a bug in ceres::CovarianceImpl where a new thread was always being created even when num_threads=1. After this fix, when num_threads=1, CovarianceImpl should run single-threaded and will not create any additional threads.
Change-Id: I784e359f8afe3e7e6d72930500a10e909bfe9308
Allow to specify the memory layout of quaternion coefficients using a
template parameter which defaults to Ceres coefficients order.
The changes are, for the most part, backwards compatible unless the
floating-point type is explicitly specified, e.g., as
&ceres::QuaternionToAngleAxis<double> to obtain a pointer to the
corresponding function. In such rare use cases, the coefficients order
must be given explicitly first as
ceres::QuaternionToAngleAxis<ceres::CeresQuaternionOrder>. In normal
situations, however, this should not be needed.
Change-Id: I05dd80f0593672dec656cc785cf06fe5268aee74
Define the relation between the axis-angle representation of a rotation
and the corresponding unit quaternion as
q(𝐞) = cos(𝜃/2) + sin(𝜃/2)/𝜃·𝐞
where 𝐞 = 𝜃𝛚 is the rotation vector given by the rotation angle 𝜃 and
the unit axis of rotation 𝛚 instead of
q(𝐞) = cos(𝜃) + sin(𝜃)/𝜃·𝐞 .
This brings the former relation closer to the available functionality
provided by ceres/rotation.h.
Fixes#941
Change-Id: Id40c065f78593887ecc52e67a068737d7eb5bda6
Previously, compiling using GCC failed with
In file included from /usr/include/c++/15.1.1/cassert:46,
from <ceres-prefix>/third_party/abseil-cpp/absl/container/internal/container_memory.h:18,
from <ceres-prefix>/third_party/abseil-cpp/absl/container/flat_hash_map.h:40,
from <ceres-prefix>/third_party/abseil-cpp/absl/flags/reflection.h:29,
from <ceres-prefix>/third_party/abseil-cpp/absl/flags/reflection.cc:16:
<ceres-prefix>/third_party/abseil-cpp/absl/container/internal/container_memory.h: In function ‘void* absl::lts_20240116::container_internal::Allocate(Alloc*, size_t)’:
<ceres-prefix>/third_party/abseil-cpp/absl/container/internal/container_memory.h:66:27: error: ‘uintptr_t’ does not name a type [-Wtemplate-body]
66 | assert(reinterpret_cast<uintptr_t>(p) % Alignment == 0 &&
| ^~~~~~~~~
<ceres-prefix>/third_party/abseil-cpp/absl/container/internal/container_memory.h:31:1: note: ‘uintptr_t’ is defined in header ‘<cstdint>’; this is probably fixable by adding ‘#include <cstdint>’
30 | #include "absl/utility/utility.h"
+++ |+#include <cstdint>
31 |
Additionally, the previous version of Abseil errouneously depends on
googletest when Ceres is consumed which results in issues with
downstream projects. We therefore update both dependencies to avoid
these issues.
Thanks to @adam-ce for figuring out the working versions of Abseil and
googletest.
Fixes#1140
Change-Id: Ie991da04491d42979d51b891a4565cabbb1c604b
Unfortunately, libc++'s 3-argument std::hypot implementation is
numerically unstable until LLVM 19.x. Therefore, checking the arguments
for zeros is insufficient since an underflow can still occur resulting
in a zero norm which requires another check. As such, division by zero
cannot be reliably avoided.
Change-Id: I189c8dc722aaec1ebc3ec8b1a177e1d8ac3b36db
Some of the benchmark functions use the same name as other functions
in the ceres namespace. For example Axpby defines both benchmark but
also an utility function in eigen_vector_ops.h. It seems to confuse
some compilers and leads to a compilation error rooting deeper into
the benchmark header itself: it seems that the compiler can not
deduct which of the instances of such functions to use.
Wrapping the file into an anonymous namespace solves the problem.
Alternative could be to use benchmark namespace to make thins more
explicit, for example ceres::internal::benchmark.
Tested on the following configuration:
- macOS 15.4
- Xcode 16.3
- Apple M3 CPU
- google-benchmark 1.9.2 installed via homebrew
Change-Id: Id127015dd22de99c6c3da88e71f255736e0bed82