Commit Graph

482 Commits

Author SHA1 Message Date
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
Sameer Agarwal 8841119134 Two changes to TinySolver
1. Add function_tolerance based termination, updating the
   termination logic to be in line with Ceres.
2. Replace the use of "error" with "residuals" in the code.

Change-Id: I3fd543f3a8226fe7f07eeec358559cba934679b2
2021-09-14 16:33:34 -07:00
Sameer Agarwal 4dff3ea2c4 Fix a number of typos in rotation.h
Thanks to @yiping for reporting these.
https://github.com/ceres-solver/ceres-solver/issues/672

Change-Id: I9c59d2b666430edf33f10aaba0d0ee4cd520e0a4
2021-09-13 17:19:49 -07:00
Sameer Agarwal 42f1d67176 Add accessors to GradientProblem
Change-Id: Ic818eec240fe69b09815f1cc54f7f132cca0abb8
2021-08-14 12:28:19 -07:00
Alexander Karatarakis 0c85c40923 Revert "Reduce copies involved in Jet operations"
This reverts commit c036c78196.

Change-Id: I736f2141d041e7a2c21491a159b48c5565df2bfa
2021-07-01 22:55:31 -07:00
Dmitriy Korchemkin 3a02d5aaf4 Fix typo in LossFunctionWrapper sample code
Change-Id: Ideb47fe8d36b023ea13cf2c23b92871bea54fe58
2021-06-24 19:04:20 +03:00
Alexander Karatarakis 7b2c223be7 Add fmax/fmin overloads for scalars
Comparison operators are defined for Jet-scalar and scalar-Jet.
Add corresponding overloads for fmax and fmix so users
don't have to convert to Jet only to access these functions,
plus it can potentially save an unnecessary conversion.

Change-Id: I20cc2d5874935e019d4ecb2d6a8c2ae631c8a4d3
2021-06-23 13:40:58 -07:00
Alexander Karatarakis c036c78196 Reduce copies involved in Jet operations
- Avoid copies in compound assignment operators (+=, -=, *=, /=)
- Add r-value overloads to +,-,*./ operators

Addition<3>/1000                                  +0.0382         +0.0382          2798          2905          2798          2905
Addition<10>/1000                                 -0.0009         -0.0009          4831          4827          4831          4827
Addition<15>/1000                                 -0.0011         -0.0010          8005          7996          8005          7996
Addition<25>/1000                                 +0.0014         +0.0014         13951         13970         13951         13970
Addition<32>/1000                                 +0.0010         +0.0009         13638         13651         13638         13651
Addition<200>/160                                 -0.1732         -0.1732         40301         33321         40300         33320
AdditionScalar<3>/1000                            +0.0016         +0.0016          2493          2497          2493          2497
AdditionScalar<10>/1000                           +0.0060         +0.0060          2701          2718          2701          2717
AdditionScalar<15>/1000                           -0.0024         -0.0024          2598          2592          2598          2592
AdditionScalar<25>/1000                           -0.0038         -0.0038          3730          3716          3730          3716
AdditionScalar<32>/1000                           +0.0062         +0.0062          4137          4162          4137          4162
AdditionScalar<200>/160                           -0.5626         -0.5626         19355          8466         19355          8466
Subtraction<3>/1000                               -0.0011         -0.0012          3162          3158          3162          3158
Subtraction<10>/1000                              -0.0027         -0.0026          4982          4969          4982          4969
Subtraction<15>/1000                              -0.0112         -0.0112          7820          7733          7820          7733
Subtraction<25>/1000                              +0.0181         +0.0181         13088         13325         13088         13325
Subtraction<32>/1000                              -0.0007         -0.0007         14514         14505         14514         14504
Subtraction<200>/160                              -0.1668         -0.1668         44586         37148         44586         37147
SubtractionScalar<3>/1000                         -0.0028         -0.0028          2540          2533          2540          2533
SubtractionScalar<10>/1000                        -0.0024         -0.0024          2682          2676          2682          2676
SubtractionScalar<15>/1000                        -0.0023         -0.0023          2603          2597          2603          2597
SubtractionScalar<25>/1000                        -0.0018         -0.0018          3570          3563          3570          3563
SubtractionScalar<32>/1000                        -0.0012         -0.0012          4223          4218          4223          4218
SubtractionScalar<200>/160                        -0.5070         -0.5070         20375         10044         20375         10044
Multiplication<3>/1000                            -0.0543         -0.0544          6171          5836          6172          5836
Multiplication<10>/1000                           -0.0617         -0.0617         11860         11128         11860         11128
Multiplication<15>/1000                           -0.0106         -0.0106         17456         17271         17456         17271
Multiplication<25>/1000                           -0.0114         -0.0114         27204         26893         27204         26893
Multiplication<32>/1000                           -0.0125         -0.0125         32704         32293         32703         32293
Multiplication<200>/160                           -0.3849         -0.3849         60557         37246         60557         37246
MultiplicationLeftScalar<3>/1000                  +0.0005         +0.0005          3086          3088          3086          3088
MultiplicationLeftScalar<10>/1000                 -0.0008         -0.0008          4486          4483          4486          4483
MultiplicationLeftScalar<15>/1000                 -0.0010         -0.0010          5840          5834          5840          5834
MultiplicationLeftScalar<25>/1000                 -0.0047         -0.0047         11350         11297         11350         11298
MultiplicationLeftScalar<32>/1000                 -0.0014         -0.0014         13892         13873         13892         13873
MultiplicationLeftScalar<200>/160                 -0.2646         -0.2646         28124         20682         28124         20682
MultiplicationRightScalar<3>/1000                 +0.0024         +0.0025          3090          3098          3090          3098
MultiplicationRightScalar<10>/1000                +0.0008         +0.0009          4596          4600          4596          4600
MultiplicationRightScalar<15>/1000                -0.0033         -0.0033          5832          5812          5832          5812
MultiplicationRightScalar<25>/1000                -0.0005         -0.0005         11353         11347         11353         11347
MultiplicationRightScalar<32>/1000                +0.0043         +0.0043         14041         14102         14041         14102
MultiplicationRightScalar<200>/160                -0.2600         -0.2600         28104         20796         28104         20796
Division<3>/1000                                  -0.0006         -0.0006          8977          8972          8977          8972
Division<10>/1000                                 -0.0095         -0.0095         14613         14474         14613         14473
Division<15>/1000                                 -0.0081         -0.0081         23109         22922         23108         22922
Division<25>/1000                                 -0.0081         -0.0081         37292         36992         37292         36992
Division<32>/1000                                 -0.0234         -0.0234         41693         40718         41692         40717
Division<200>/160                                 -0.1306         -0.1306         44486         38677         44486         38677
DivisionLeftScalar<3>/1000                        -0.0080         -0.0080          6683          6630          6683          6630
DivisionLeftScalar<10>/1000                       -0.0018         -0.0018          9255          9239          9255          9238
DivisionLeftScalar<15>/1000                       -0.0011         -0.0011         12180         12166         12180         12166
DivisionLeftScalar<25>/1000                       +0.0060         +0.0060         22381         22515         22381         22516
DivisionLeftScalar<32>/1000                       -0.0016         -0.0016         20159         20126         20159         20126
DivisionLeftScalar<200>/160                       -0.2528         -0.2528         28773         21499         28772         21499
DivisionRightScalar<3>/1000                       -0.0006         -0.0006          3784          3782          3784          3782
DivisionRightScalar<10>/1000                      -0.0014         -0.0014          5699          5691          5699          5691
DivisionRightScalar<15>/1000                      -0.0009         -0.0009          7490          7484          7490          7484
DivisionRightScalar<25>/1000                      +0.0031         +0.0031         13751         13793         13751         13793
DivisionRightScalar<32>/1000                      -0.0006         -0.0006         16712         16702         16712         16702
DivisionRightScalar<200>/160                      -0.2532         -0.2532         28412         21217         28411         21217
MultiplyAndAdd<3>/1000                            -0.0191         -0.0191          4382          4299          4382          4299
MultiplyAndAdd<10>/1000                           -0.0060         -0.0060         10238         10176         10238         10176
MultiplyAndAdd<15>/1000                           -0.0053         -0.0053         11696         11634         11696         11634
MultiplyAndAdd<25>/1000                           -0.0171         -0.0171         19185         18858         19185         18858
MultiplyAndAdd<32>/1000                           +0.0070         +0.0070         23783         23951         23783         23951
MultiplyAndAdd<200>/160                           -0.1252         -0.1252         61470         53776         61469         53776

Change-Id: Ib366d5753ed4f398667766384e05389d45e0d444
2021-06-18 15:04:17 -07:00
Sameer Agarwal 98f639f542 Add a macro CERES_GET_FLAG.
This is needed to add a layer of indirection which will allow
us to use gflags in the public version and absl inside Google.

Change-Id: I32f3da23200a01c9b658bbf8aaa66cb8fddc2cc3
2021-03-18 11:07:57 -07:00
Tobias Schlüter 8637249945 Use portable expression for constant 2/sqrt(pi)
M_2_SQRTPI is not part of standard C++, replace it with an
equivalent expression.  gcc immediately folds this and thus
generates the same code even at -O0.

Change-Id: I5d38e67a4508c1d43a1a8e5f1639f2243cdb143e
2021-01-30 23:19:07 +09:00
Sameer Agarwal 97873ea658 Add some missing includes for glog/logging.h
Change-Id: Ia10c2809eb360bd30efddc0cd941b0de06ac09d6
2021-01-21 13:49:38 -08:00
Sameer Agarwal e84cf10e13 Fix an errant double in TinySolver.
Thanks to Bogdan Burlacu for pointing this out.

Change-Id: I7a59a589c1bf919954e4905df3376e9aeb1a12d7
2020-12-14 08:55:05 -08:00
Mykyta Kozlov 66b4c33e81 updated unit quaternion rotation
Change-Id: I3e5a2ca8e19c1d66437ac16d615867e2a12f8e60
2020-11-18 17:00:13 +00:00
Sameer Agarwal bb127272f9 Fix typos.
Contributed by Ishamis@, IanBoyanZhang@, gkrobner@ & mithunjacob@.

Change-Id: Iab3c19a07a6f3db2486e3557dcb55bfe5de2aee5
2020-10-19 09:32:47 -07:00
Taylor Braun-Jones 3f6d273676 Unify symbol visibility configuration for all compilers
This makes it possible to build unit tests with shared libraries on MSVC.

Change-Id: I1db66a80b2c78c4f3d354e35235244d17bac9809
2020-10-15 16:56:07 -04:00
Nikolaus Demmel 600e8c529e fix minor typos
all timing values in the summary are initialized to -1, so the one
+1 is likely an oversight.

Change-Id: Ie355f3b7da08a56d49d19ca9a5bc48fe5581dee3
2020-10-12 23:01:02 +02:00
Alex Stewart 1fd0be916d Fix default initialisation of IterationCallback::cost
Change-Id: I9f529093fc09424c90dbff8e9648b90b16990623
2020-09-28 18:54:33 +01:00
Sameer Agarwal 921368ce31 Fix a number of typos in covariance.h
Also some minor cleanups in covariance_impl.h

Thanks to Lorenzo Lamia for pointing these out.

Change-Id: Icb4012a367fdd1f249bc1e7019e0114c868e45b6
2020-09-09 09:39:42 -07:00
Nikolaus Demmel 9d762d74f0 fix formatting for public header files
- ensure all public headers files adhere to clang-format
- preserve one-per-line for enums by adding trailing comma
- preserve include order for en/disable_warning.h

Change-Id: I78dbd0527a294ab2ec5f074fb426e48b20c393e6
2020-09-07 23:14:51 +02:00
Sameer Agarwal 8e1d8e32ad A number of small changes.
1. Add a move constructor to NumericDiffCostFunction, DynamicAutoDiffCostfunction
   and DynamicNumericDiffCostFunction.
2. Add optional ownership of the underlying functor.
3. Update docs to reflect this as well as the variadic templates that allow an
   arbitrary number of parameter blocks.

Change-Id: I57bbb51fb9e75f36ec2a661b603beda270f30a19
2020-09-03 10:57:50 -07:00
Julian Kent 368a738e52 AutoDiffCostFunction: optional ownership
Add Ownership semantics to the AutoDiffCostFunction

This allows several benefits, such as pointer ordering always being the
same for numerical repeatability (due to blocks being ordered by
pointer address), memory adjacency for better cache performance, and
reduced allocator pressure / overhead.

This is then made use of in libmv by preallocating the errors and
cost functions into vectors

Change-Id: Ia5b97e7249b55a463264b6e26f7a02291927c9f2
2020-09-03 19:19:53 +02:00
Morten Hannemose 8cbd721c19 Add erf and erfc to jet.h, including tests in jet_test.cc
erf is necessary for evaluating Gaussian functions.
erfc was added because it is so similar to erf.

Change-Id: I5e470dbe013cc938fabb87cde3b0ebf26a90fff4
2020-09-03 17:54:20 +02:00
Sameer Agarwal db2af1be87 Add Problem::EvaluateResidualBlockAssumingParametersUnchanged
Simplify the semantics for Problem::EvaluateResidualBlock to
not ignore the presence of EvaluationCallback and add another method
EvaluateResidualBlockAssumingParametersUnchanged to handle the case
where the user has an EvaluationCallback but knows that the parameter
blocks do not change between calls.

Updated the documentation for the methods and EvaluationCallback to
reflect these semantics.

Also added tests for Evaluation related methods calling i
EvaluationCallback when its present.

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

Change-Id: If0a0c95c2f1f92e9183a90df240104a69a71c46d
2020-08-04 13:59:42 -07:00