Commit Graph

504 Commits

Author SHA1 Message Date
Sergiu Deitsch b0aef211db Allow to store pointers in ProductManifold
Change-Id: I32df7afab3a195efb0407b0d8f35dcd2d7cb95d2
2022-03-03 17:08:24 +00:00
Sergiu Deitsch 284be88ca1 Allow ProductManifold default construction
In many cases, manifolds stored in ProductManifold have a default
constructor which can simplify ProductManifold initialization even
further. Allow default construction of ProductManifold in this case.

Change-Id: I29b2612870c02232556688019a77049709684a55
2022-03-03 14:50:03 +01:00
Sergiu Deitsch 779634164d Fix MSVC linker error
Apparently, MSVC does not like whenever a fully templated class is
exported.

Change-Id: Ie920720d645941925b4ee04d9ae2b92e6c061f2b
2022-03-03 13:39:38 +01:00
Sergiu Deitsch 7743d2e73c Store ProductManifold instances in a tuple
Since the number of manifolds used to initialize ProductManifold and
their types are known at compile-time, it is possible to avoid storing
pointers to the base class as required by a homogeneous, currently
dynamically sized container. Instead, we can use std::tuple<> as a
heterogenous container with the number of elements fixed at compile-time
that allows us to store the concrete manifold realizations.

The advantage of this approach is that we can bypass the vtable when
iterating over each manifold within ProductManifold. The indirection is
invoked only once while accessing the ProductManifoldImpl members.
Additionally, potential dynamic memory allocations by a std::vector can
be completely avoided. This makes the ProductManifold implementation
more efficient both in memory and runtime.

Change-Id: Ic71b0c175ab726f8992e9703f7666bca477baf19
2022-03-02 23:57:10 +00:00
Sameer Agarwal eadfead69d Move LineManifold and SphereManifold into their own headers.
Previously they were defined in manifold.h but their implementations
were in the internal directory and to prevent circular dependencies
the implementation headers were pushed to the bottom of manifold.h

This started out as one header and has become progressively worse
as more manifolds are templated.

This change moves the two manifolds into their own headers which
also contain their implementations.

Change-Id: I671da0279a47cd2ff1f52c69a1d159426f55bd80
2022-03-02 06:51:37 -08:00
Sameer Agarwal 6a37fbf9b4 Add static/compile time sizing to EuclideanManifold
This brings it in line with other manifolds like SphereManifold
and LineManifold, where the user has the choice to specify the size
of the manifold at compile time or runtime.

Most of the time the size is known at compile time so this will
speed up the common case.

Change-Id: I0c7ff8b7a9a64a81203eb11afc074874e208815a
2022-03-01 09:34:23 -08:00
Sergiu Deitsch f0851667be Fix MSVC compilation errors
Disable the definition of `min`/`max` macros by defining `NOMINMAX`
and prevent macro substitution in the public interface.

Also, quiet floating-point comparisons are defined as template functions
by the MSVC STL which causes compilation errors due to ambiguities in
resolving the template parameter types.

Fixes #668
Fixes #716
Fixes #718

Change-Id: I5fe7832a6a3a7ad0421a2557527528c34b88e9c7
2022-02-27 13:24:42 +01:00
Sergiu Deitsch c8658c8992 Modernize more
Apply clang-tidy Google and modernize fixes without trailing return type
using:

$ clang-tidy -p <build-dir> \
  -checks='-*,google-*,modernize-*,-modernize-use-trailing-return-type' {} -fix

Change-Id: I7450cc58ea9abf928f73a467e87876083217fa26
2022-02-26 22:16:56 +00:00
Sameer Agarwal 8fe8ebc3a6 Add final specifier to public classes
Change-Id: Ib7291dc68d5d4141ee821689743481fc84768606
2022-02-18 15:51:17 -08:00
Sameer Agarwal 518970f81e Context should be exported
Change-Id: I451a7f471a6b93d1d32dc003adaa3c5c315fef9f
2022-02-18 09:54:40 -08:00
Sameer Agarwal 47502b8339 Miscellaneous CUDA related changes.
1. Fix a stupid error in types.cc
2. Update documentation for Solver::Options::dense_linear_algebra_library_type
3. Add a note to installation.rst to update the installation docs.
4. Mention GPU acceleration in features.rst

Change-Id: Id63202ff090e23bbb211d2ee458559fb8046281d
2022-02-14 21:45:34 -08:00
Sergiu Deitsch f90833f5fa Simplify symbol export
Currently, the logic for exporting symbols is rather complicated: when
tests are enabled internal symbols are exported in addition to the
public symbols. Such logic causes several problems. (1) Test binaries
link against a Ceres build that is different from the final release
since fewer optimizations are applied if more symbols are exported. (2)
Also, some toolchains hide symbols by default breaking the existing
logic eventually causing linker errors.

Since internal symbols are not intended to be used outside of the
project, we can compile them into object files and use exactly the same
binary code both for the final build and the tests without relying on
conditionals.

By default, all symbols are now hidden unless annotated as public.
Internal symbols are explicitly marked as not being exported in case
users chose not to hide symbols by default.

Change-Id: I589dd10be2f6f438508783cf99d141af0120057b
2022-02-14 20:19:08 +01:00
Sergiu Deitsch c6158e0ab5 Replace NULL by nullptr
Change-Id: I200a40678091b984a01635d8637a487b7ad5cc13
2022-02-14 19:22:21 +01:00
Sameer Agarwal 9c5f29d46d Use compiler attributes instead of [[deprecated]]
This change is needed because compiler attributes and c++
annotations like [[deprecated]] do not mix well and we need that
for our public API.

https://github.com/ceres-solver/ceres-solver/issues/749

Change-Id: I79eda795f2912f9af9ab36ee24b8428b47104743
2022-02-11 09:29:21 -08:00
Sameer Agarwal 0141ca090c Deprecate LocalParameterizations
Add [[deprecate]] notices to everything LocalParameterization
related.

Make sure that Ceres can be compiled without triggering
deprecation warnings.

Update the documentation:

a. Add deprecation notices.
b. Document interaction between LocalParameterization and Manifold
   coexisting in the Problem.
c. Add documentation for Manifold(s)

Change-Id: Ie4ad48963c83fded86e533c8c60561af402fbaff
2022-02-10 06:36:47 -08:00
Johannes Beck 4742bf3862 Add LineManifold.
This MR ports the LineParameterization of manifolds. The unit test are
rewritten to use the manifold test facilities.

The LineManifold is extended so that it can also handle dynamic size
ambient space dimensions.

Change-Id: I1fe3cd34b56f74b72ca028c34f5368e9df9fe4d7
2022-02-10 08:52:01 +01:00
Sergiu Deitsch c14f360e63 Drop trivial special members
Do not define trivial constructors or destructors unless necessary
(e.g., for implementing pimpl) following the rule of zero. Define
virtual base class destructors out-of-line to avoid emitting vtables in
every translation unit.

Change-Id: Iea2d8978e62a8ee5a97b86cbb4e858d56e0fb274
2022-02-09 21:30:14 +01:00
Sergiu Deitsch a35bd1bf90 Use = default for trivial special members
Applied changes correspond to clang-tidy fixes
stemming from the modernize-use-equals-default check.

Change-Id: I254b0908a76d464131564b637cd0e42a6b03fb5a
2022-02-09 18:38:52 +01:00
Sergiu Deitsch 484d3414e4 Replace virtual keyword by override
virtual can be ambiguous. Applied changes correspond to clang-tidy fixes
stemming from the modernize-use-override check.

Change-Id: I973afd4680a5df587419777504aeb94467196b89
2022-02-09 00:34:05 +01:00
Joydeep Biswas 36d6d86908 Add support for dense CUDA solvers #1
1. Add CUDADenseCholesky64Bit, CUDADenseCholesky32Bit, & tests.
   CUDADenseCholesky32Bit uses the legacy versions of potrf/potrs
   in cuSolverDN, while CUDADenseCholesky64Bit uses the new 64-bit
   versions available since Cuda 11.1. The legacy versions are
   provided since some platforms such as the Nvidia Jetsons only
   support Cuda 10.2.
2. Expose CUDA as a new option under DenseLinearAlgebraLibraryType.
   The relevant option to string and string to option helper functions
   are modified accordingly.
3. Add cuda as a dense_linear_algebra_library option in bundle_adjuster
   to demonstrate the use of the new CUDA option.

Change-Id: I23615e1d301df5185ed646b3e33ee802508dae86
2022-02-07 19:26:29 -06:00
Johannes Beck af5e48c71f Add SphereManifold.
This MR adds SphereManifold ported from
HomogeneousVectorParameterization. Additionally the minus operator
and jacobian evaluation was implemented.

The unit tests were almost completly reimplemented and uses the
test facilities provided for manifolds.

Change-Id: Iccf72a2333bc921ff24c4d831db35020c653ee86
2022-02-07 22:19:37 +01:00
Sergiu Deitsch 182cb01c57 Normalize Jet classification and comparison
Complete support for all floating-point classification functions
(fpclassify, signbit) and consistently apply all overloads recursively
to the scalar part of a Jet only. This is now inline with how comparison
operators work. Sanity checks of derivatives should be performed
explicitly on the dual part of a Jet due an ambiguity on reducing the
classification results of multiple values.

Provide an fdim overload (in addition to fmin and fmax) and support
quiet versions of comparison operators also applied recursively to the
scalar part of a Jet but without type promotion.

Additionally, deprecate Ceres legacy classification functions. New code
should use C++11 function names for consistency.

Finally, simplify expressions using introduced scalar classification and
comparison.

Change-Id: I397e37425760717b991eb7ae5da0892f20c5a365
2022-02-07 21:51:42 +01:00
Alex Stewart ce9669003a Add const accessor for functor wrapped by auto/numeric-diff objects
- The intended use-case for these accessors is in client code tests to
  support verification of the configuration with which cost functions
  were constructed.

Change-Id: Ib77afa6409804ba7f724138f579e0c51b154f5ad
2022-02-06 21:14:16 +00:00
Sergiu Deitsch 7d6524daff Support fma Jet
Change-Id: I9b1ad49611e3e6f117190d56512ef2ec4bdbb1c1
2022-02-01 20:52:27 +01:00
Sameer Agarwal a0d81ad63e Fix a bug in AutoDiffManifold
When computing the MinusJacobian we were passing two different
values to AutoDifferentiate for the output dimension. The template
argument was correct which is why the method was working correctly
but the function argument was incorrect (cut and paste error).

This would be fine in release mode, but in debug mode it would
trigger a check failure.

Change-Id: I0327656d1a4d34c82e4d3a8c04f27c264bce80eb
2022-01-28 06:20:17 -08:00
Sameer Agarwal 0572efc57c Fix a compilation warning in autodiff_manifold.h
Change-Id: Iff6c57fb68752440eedb5b1eedc33fd524a19de2
2022-01-24 10:03:20 -08:00
Sameer Agarwal 77c0c4d09c Migrate examples to use Manifolds
Also change NULL to nullptr.

Change-Id: I80a2328185d7891f61e07e64d5c1b59e74588ac7
2022-01-22 11:18:19 -08:00
Sameer Agarwal 19eef54fc2 Rename Quaternion to QuaternionManifold.
Also rename EigenQuaternion to EigenQuaternionManiold.

Change-Id: I7095fa61cfabf97a328b02fb027f5a2a8dd499ae
2022-01-22 11:07:52 -08:00
Sameer Agarwal ca6d841c25 Add AutoDiffManifold
AutoDiffManifold allows the user to define a templated
functor that implements the Plus and Minus operations
on the Manifold and will compute the Jacobians needed
to define the Manifold object using automatic differentiation.

Change-Id: Ibd073c25847389308ca1ab66e6f5fe78aae77205
2022-01-22 10:54:01 -08:00
Sameer Agarwal 97d7e07372 Move the manifold testing matchers to manifold_test_utils.h
Change-Id: Ie295fdf32e056f30b5b533df11755e2674d4dad6
2022-01-19 14:31:00 -08:00
Sameer Agarwal 125a0e9be5 LocalParameterization -> Manifold #1
Manifolds are now part of the public API and co-exist
with LocalParameterizations.

1. Add Manifolds to the Problem API.
   a. AddParameterBlock(double*, int, Manifold*)
   b. SetParameterization(double*, Manifold*)
   b. GetManifold(const double*)
   c. HasManifold(const double*)

2. Internally Ceres now only uses Manifolds. When the user uses
   a LocalParameterization, it is wrapped in a ManifoldAdapter.

3. To preserve the API semantics while keeping the internals clean
   we need a new map in ProblemImpl which stores the association
   between parameter blocks and local parameterizations. This
   is temporary, it will go away once this transition is complete.

4. There are NO algorithmic changes, as in we are not using
   any of the expanded interface of the Manifold objects yet.
   That will come later.

5. All tests that use LocalParameterization have been duplicated
   to use Manifolds, and when this transition is complete the
   LocalParameterization based tests will be deleted.

6. Public documentation for the API has been updated. Deprecation
   notices to the documentation as well as C++ annotations will come
   later.

7. Similar changes have been made to GradientProblem.

Change-Id: I8e03c8ced6e141876ef3eca5740c113afa788f0c
2022-01-18 15:59:45 -08:00
Sameer Agarwal c0cb42e5f9 Add Problem::HasParameterization
This will help the transition from LocalParameterization to Manifolds,
since most uses of Problem::GetParameterization is to just check
whether a parameter block has a local parameterization associated
with it or not.

Change-Id: Ib3539f377eaed853d7542c9844ec1487aa0fb4d6
2022-01-11 21:05:56 -08:00
Sameer Agarwal 7e2f9d9d41 Add EigenQuaternion manifold and tests for it.
Change-Id: I579a45a2921424a07d03b3b4d9cfcbc0ab529f9b
2022-01-11 14:40:21 -08:00
Sameer Agarwal b81a8bbb7a Add the Quaternion manifold and tests.
Change-Id: I0a396a5834168c1526d6f2b8c99a1ad3348ad657
2022-01-07 04:59:02 -08:00
Sameer Agarwal ce1537030b Fixed missing headers in manifold.h
https://github.com/ceres-solver/ceres-solver/issues/739

Change-Id: Ia4079b025c53f75abb7145a4b8f5eacaddf8fc67
2021-12-30 12:16:43 -08:00
Sameer Agarwal 23b204d7e6 LocalParameterization -> Manifold #1
This is the first in a series of changes that will eventually
replace the LocalParameterization interface with the richer
Manifold interface.

1. Add the Manifold interface.
2. Add implementations and test for:
   a. EuclideanManifold (formerly the IdentityParameterization)
   b. SubsetManifold (formerly the SubsetParameterization)
   c. ProductManifold (formerly the ProductParameterization)

The testing has been completely re-done, where instead of adhoc
testing, we now define a number of matchers which explicitly
enforce the invariants demanded by the Manifold interface.

Change-Id: I3f296d0964388d52b027c99dc86b7730d24d55fa
2021-12-29 17:27:28 -08:00
Alex Stewart c2fab6502e Fix docs of supported sparse backends for mixed_precision_solves option
- Also adds documentation of mixed precision solves to Sphinx docs.
- Fix reference to Sphinx theme used (RTD not better).
- Fix NOTE syntax in use_explicit_schur_complement Sphinx docs.

Change-Id: I7bdac0f07eb737f49b05e3fcaa3eebd087355d2d
2021-12-15 20:58:47 +00:00
Sergiu Deitsch 1f374a9fe5 Support promotion in comparison between Jet and scalars
Previously, Jet did not allow comparison between its value and a scalar
of another type. Specifically, the comparison was limited to scalars of
the same type effectively disabling standard promotion rules. Instead,
users would be required either to cast values to target Jet arithmetic
type or explicitly construct a Jet instance that can be eventually used
for comparison purposes.

However, such a behavior is not intuitive and causes problems with types
that rely on standard promotion rules (e.g., std::complex in some
implementations).

This changeset extends the comparison operators by enabling logical
comparisons between a Jet and values compatible to the underlying scalar
type (e.g., int). To be as generic as possible, the types allowed to be
passed to comparison operators are constrained using SFINAE. This in
turn allows a recursive expansion of jets and therefore the comparison
of a nested jets with a scalar.

The changes alleviate problems described in #414 and also allow the use
of special functions from Boost.Math, e.g., for computing the reciprocal
using boost::math::pow<-1>(...).

Change-Id: I3625791e6c8c2c0bfbffbbdb09e179a32e57f306
2021-11-29 21:33:28 +01:00
Sergiu Deitsch 06e68dbc5a Avoid midpoint overflow in the differential
Change-Id: I8c75a819db33f4105e62942cddc83b2653318169
2021-11-28 01:04:27 +01:00
Sergiu Deitsch b1391e0625 Support midpoint Jet
Provide autodiff support for C++20 std::midpoint if the standard is
active.

Change-Id: I1308a1e514bef4c74f08f655cbf803fa43503ce5
2021-11-25 21:14:32 +01:00
Sergiu Deitsch 8426526dff Support lerp Jet
Provide autodiff support for C++20 std::lerp if the standard is active.

Change-Id: I04ef6f17c707dd5f8ac426d9127b221e17aa08d6
2021-11-25 21:02:25 +01:00
Sergiu Deitsch 57c2796890 support 3-argument hypot jet
C++17 provides a three argument hypot(x, y, z) which can now be used
for jets if the standard is active.

Change-Id: Ide62e101f780fe738bb2d4f826b10daf94c585b3
2021-11-22 17:26:01 +01:00
Sergiu Deitsch 48cb54d1b2 fix fmin and fmax NaN handling
fmin and fmax do not handle NaNs correctly. Also, the comparison
operator for floating-point numbers may raise FE_INVALID if one of the
arguments is NaN. Both functions, however, are not subject to any of the
error conditions specified by the error handling for related
floating-point operators and functions.

Change-Id: Ic6bb65f18568066dba3c739a2df06f5fc3131a80
2021-11-19 03:13:56 +00:00
Sergiu Deitsch 552a4e5170 support log10 jet
Change-Id: I1425f7c8fc891cf941a162b8e5b427b5ab4e71da
2021-11-18 23:11:31 +01:00
Sergiu Deitsch 4e49c54223 reuse expm1 result for differential
We can reuse the expm1 result to compute the differential and eliminate
the extra exp call.

Change-Id: Ibd4f0564ab6da99fc23fbf6462408cfc3408fda1
2021-11-18 19:21:40 +01:00
Sergiu Deitsch 2fba61434b support log1p and expm1 jet
Currently, it is not possible to accurately evaluate the derivative of
d/dx log(1 + x) under all circumstances and significant deviations from
the actual derivative d/dx log1p(x) can occur. This changeset introduces
the necessary Jet overload and its inverse, expm1.

Change-Id: Ifcf88f6d684f61ba86bbe49f0d551b703f34ad0d
2021-11-16 00:14:39 +01:00
Sergiu Deitsch a668cabbcf support norm jet
norm allows to compute the squared magnitude both of complex and real
numbers. While Jet does not support decaying of a std::complex to a
scalar performed by norm, the function is still useful when applied to
scalars alone for computing the square.

Change-Id: I27a3513f53f37fb3960411362e80d170d1ae6f74
2021-11-15 22:29:44 +00:00
Sergiu Deitsch a3a4b6d77f support copysign jet
libc++ (default on macOS) uses the copysign function for std::complex
multiplication which causes compilation errors such as these if
std::complex is combined with jets:

/Applications/Xcode_12.4.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/complex:607:19: error: no matching function for call to 'copysign'
            __a = copysign(__libcpp_isinf_or_builtin(__a) ? _Tp(1) : _Tp(0), __a);
                  ^~~~~~~~
foo.hpp:218:39: note: in instantiation of function template specialization 'std::__1::operator*<ceres::Jet<double, 3> >' requested here
    std::complex<Scalar> result = lhs * rhs;

copysign is also useful in other situations where the sign is required
allowing it to compute without branching.

Change-Id: I84b2d23374f1bf3bae32833016bb686d97d74054
2021-11-15 23:27:33 +01:00
Sergiu Deitsch 034bf566f0 use copysign for abs jet
abs() implementation does not correctly handle the sign of the
infinitesimal part when the value is a NaN. Define the function in terms
of copysign which is the only portable way of manipulating the sign of
a NaN value.

Change-Id: I2f13fb1db62d35ca8b09e6bff1c05a736cb91513
2021-11-14 17:07:14 +01:00
Sameer Agarwal 17dccef91b Add NumericDiffFirstOrderFunction
This has been a long requested feature so that users can minimize
functions using numeric differentiation.

As part of this, I have also redone rosenbrock.cc, which now has three
variants.

rosenbrock.cc now uses automatic differentiation.
rosenbrock_numeric_diff.cc uses numeric differentiation.
rosenbrock_analytic_diff.cc uses analytic derivatives.

This is analogus to how the helloworld example code is structured.

The tutorial for GradientProblemSolver has also been updated to reflect
this.

https://github.com/ceres-solver/ceres-solver/issues/691

Change-Id: Ib0fb9e35127fe4c8299d4793bea3558722c70dd7
2021-09-15 06:21:02 -07:00