Commit Graph

281 Commits

Author SHA1 Message Date
Julien Pilet e5dceb3ab0 Fix Jet/Eigen compatibility for Eigen > 3.3
Honour the digits10 NumTraits member introduced in Eigen 3.3.

Change-Id: If20183332beef8335b7758cdb58859a43fc59970
2017-02-28 10:34:26 +01:00
Sameer Agarwal 5f87f35cec Changes from William Rucklidge
Change-Id: Ia5d724edef947870fe13050a71aa1cba878352a8
2017-02-27 11:09:08 -08:00
Sameer Agarwal 1cfec3c666 Improvements to Schur template specializations
1. Refactor the python code that generates the template specializations
   to remove code duplication.
2. Improved the logic for template specialization selection where
   Eigen::Dynamic now serves as a wildcard.
3. Added schur_templates.h/cc which allows querying the set of available
   template specializations without instantiating a linear solver.
4. Added Solver::Summary::schur_structre_given and
   Solver::Summary::schur_structure_used and expose them in
   Solver::Summary::FullReport for better performance debugging.
5. Updated the templates with newer dates and some minor comments cleanup
   which lead to the the template specializations to be re-generated.

Change-Id: Iaf3c6f714353597899916c300465da01f151c3de
2017-02-23 14:52:59 -08:00
Sameer Agarwal 62a70bc74c Lint cleanup from William Rucklidge
Change-Id: I11ebf9bdb09cfd465a32a61e0a9a045ab650deac
2017-02-15 11:01:27 -08:00
Alex Stewart c1ebbfc79b Require Eigen >= 3.3 to define ScalarBinaryOpTraits in Jet.
- ScalarBinaryOpTraits was introduced in Eigen 3.3, and thus breaks
  compilation of Ceres for Eigen versions < 3.3.
- Reported as issue #252 by AustinDeric:
  https://github.com/ceres-solver/ceres-solver/issues/252

Change-Id: Ie9b7dace17709c348b18b297f2d5306b054ce4b0
2017-02-13 16:14:40 +00:00
Chris Sweeney 9a195d91de Specify ScalarBinaryOpTraits for Jet types.
This commit extends the use of Jets with Eigen matrices and arrays
by enabling the use of binary operators (such as scalar addition,
multiplication, as well as matrix multiplication) when one Eigen
matrix/array is of type Jet and the other is a scalar type. This
should increase performance since Jet types have optimized
scalar-to-jet binary operations.

Change-Id: Ia756064845d845cefcf0abb16d366331d2824b52
2017-02-10 19:50:33 +00:00
Je Hyeong Hong ccfd7f4dbb CERES_EXPORT fix to compile Ceres as DLL
Below fixes are required to compile Ceres as a dynamic library using
MSVC.
1. Added CERES_EXPORT to EigenQuaternionParameterization.
2. Removed CERES_EXPORT from CubicInterpolator and BicubicInterpolator.

EigenQuaternionParameterization has its source embedded in ceres.dll 
whereas Cubic+BicubicInterpolators are defined in the header file and 
therefore do not require __declspec(dllimport).

Change-Id: Idd1f387890c36aab51a1a4177ea7c06933b96f39
2017-02-02 03:07:52 +00:00
Alex Stewart 9321b620ac Fix detection of deprecated Bessel function names on MSVC.
- MSVC deprecated the standard POSIX names for Bessel functions in
  favour of underscore prefixed versions.
- Previously we were checking for the presence of the newer underscore
  functions via a macro, which fails as the functions are not defined
  as macros.
- Now we check via a check_cxx_source_compiles() if the newer underscore
  prefixed versions exist when compiling on MSVC and use a new Ceres
  configuration #define to switch on their presence in jet.h

Change-Id: I430880bde2981d12f4d03dbc94d903b9842e887e
2017-01-27 22:31:53 +00:00
Sameer Agarwal 2dd907744d Ensure that partial evaluation of residuals triggers an error
ResidualBlock evaluation has logic to ensure that CostFunction
should always fill out the residual and jacobian arrays completely
by using a special value to pre-populate these arrays.

This works for CostFunctions with analytical Jacobians but not for
AutoDiffCostFunction and NumericDiffCostFunction Jacobians.

There is no way to fix this for NumericDiffCostFunctions without
introducing significant performance penalties but the residual
evaluation fails, which should be enough to catch such errors.

For AutoDiffCostFunction the way the Jets are default initialized
was sidestepping this check. So now, the Jet that is used to
capture the output residuals is now initialized with
kImpossibleValue, which will ensure that if the user forgets
to fill all output fields, it triggers an evaluation error.

This change required that ceres::internal::kImpossibleValue be moved
out of array_utils.h/cc to types.h.

Change-Id: I35bb0946cf0785a5d43c7b5459a2272848fb2a9b
2017-01-16 10:00:36 -08:00
Alex Stewart 3fa415bd0c Enable support for AVX instructions for Jets.
- Eigen versions < 3.3 only supported SIMD instructions that required
  16-byte alignment (SSE), whereas Eigen >= 3.3 also supports AVX
  instructions which require 32+-byte alignment.
- Previously we only ever requested 16-byte alignment for Jets (if >=
  C++11 was enabled) which resulted in Eigen assertions being triggered
  on some compilers as reported as Issue #251:
  https://github.com/ceres-solver/ceres-solver/issues/251.
- Now we use Eigen’s EIGEN_MAX_ALIGN_BYTES macro, defined in Eigen >=
  3.3 to specify the byte alignment for Jets when C++11 is enabled for
  Eigen >= 3.3.  For Eigen versions < 3.3, we maintain the previous
  behaviour of 16.

Change-Id: I749af7a70ae794e0c2a59301128db781e338422c
2017-01-05 19:12:45 +00:00
Alex Stewart 6519e78920 Fix use of alignas(0) which is not ignored on GCC.
- alignas(0) should be ignored, however it results in a build error on
  GCC, so instead default to the alignment of double in Jets if
  we cannot align to 16-byte boundaries on the platform, but are
  compiling with C++11.

Change-Id: I2e54c69516ea2e1447a8bdc138b2dd70050c6dad
2016-11-12 21:45:57 +00:00
Alex Stewart b4e27240b2 Use default alignment if alignof(std::max_align_t) < 16 with C++11.
- As per Andrew Hunter’s comments in the commit which added Jet
  alignment when using C++11 here:
  https://ceres-solver-review.googlesource.com/#/c/7100, there is wide
  lattitude in the standard about what the maximum supported alignment
  can be.
- Previously, we were forcing the alignment to 1, if the value of
  alignof(std::max_align_t), which we use as a proxy for the maximum
  supported alignment on the platform, was < 16.
- An alignment of 1 is not valid for Jets, as it would weaken the
  natural alignment of the types within a Jet, which would typically be
  4 (32-bit systems) or 8 (64-bit systems), thus resulting in a compiler
  error.
- This was reported as issue 235 for Clang 3.8 on i386:
  https://github.com/ceres-solver/ceres-solver/issues/235.

Change-Id: Ie39e5499c64f9231f29ebf4392992b5c9ce2e385
2016-11-12 17:18:25 +00:00
Sameer Agarwal 78abf0cdfe Introduce a common base class for DynamicAutoDiffCostFunction and DynamicNumericDiffCostFunction.
In the process also move some documentation from the file header to
just above the class declaration.

This change is in response to https://github.com/ceres-solver/ceres-solver/issues/233

Change-Id: I08cff1a94c57b67dd2bd8be4dba8c3fce46b68ab
2016-11-11 07:35:22 -08:00
Sameer Agarwal f21c17064b Add GradientProblemSolver::Options::parameter_tolerance.
Support for parameter tolerance was added to the line search
minimizer was added a while ago, and calling Solve on a
non-linear least squares problem supported it but for some reason
the GradientProblemSolver::Options struct was missing this
option even though the documentation suggested that it was present!

Thanks to Noah Snavely for reporting this bug.

Change-Id: I57cf4ab396bc822c19fa298529e113b89664a349
2016-11-01 12:56:19 +00:00
Rob Carroll e69bd2a206 Add missing T() wrappers for constants.
Needed for instantiation with Jet<float,N>.

Change-Id: I8ec07a844cc911a3c7f24c25797bd21c0bee07b5
2016-10-31 12:51:44 -07:00
Sameer Agarwal 8590e6e8e0 Remove two checks from rotation.h
This allows rotation.h to remove its dependency on glog.

Change-Id: Ia6aede93ee51a4bd4039570dc8edd100a7045329
2016-10-27 12:36:13 -07:00
Sameer Agarwal 195d8d13a6 Remove two DCHECKs from CubicHermiteSpline.
They were present as debugging checks but were causing problems
with the build on 32bit i386 due to numerical cancellation issues,
where x ~ -epsilon.

Removing these checks only changes the behaviour in Debug mode.
We are already handling such small negative numbers in production
if they occur. All that this change does is to remove the crash.

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

Thanks to @NeroBurner and @debalance for reporting this.

Change-Id: I66480e86d4fa0a4b621204f2ff44cc3ff8d01c04
2016-09-06 07:15:20 -07:00
David Gossow 46c5ce89dd Fix compiler errors on some systems
This fixes some signed-unsigned comparisons and a missing header
include.

Change-Id: Ieb2bf6e905faa74851bc4ac4658d2f1da24b6ecc
2016-08-31 20:26:53 +00:00
Sameer Agarwal 79a28d1e49 Rename a confusingly named member of Solver::Options
Solver::Options::numeric_derivative_relative_step_size to
Solver::Options::gradient_check_numeric_derivative_relative_step_size

Change-Id: Ib89ae3f87e588d4aba2a75361770d2cec26f07aa
2016-08-31 07:47:29 -07:00
Sameer Agarwal 358ae741c8 Note that Problem::Evaluate cannot be called from an IterationCallback
Change-Id: Ieabdc2d40715e6b547ab22156ba32e9c8444b7ed
2016-08-31 07:42:00 -07:00
Sameer Agarwal 44044e25b1 Update the NumTraits for Jets
1. Use AVX if EIGEN_VECTORIZE_AVX is defined.
2. Make the cost of division same as the cost of multiplication.

These are updates to the original numtraits update needed for eigen 3.3
that Shaheen Gandhi sent out.

Change-Id: Ic1e3ed7d05a659c7badc79a894679b2dd61c51b9
2016-08-31 06:19:08 -07:00
Shaheen Gandhi bfc916cf1c Allow ceres to be used with the latest version of Eigen
Change-Id: Ief3b0f6b405484ec04ecd9ab6a1e1e5409a594c2
2016-08-31 12:45:47 +00:00
David Gossow ac3b8e8217 Gradient checking cleanup and local parameterization bugfix
Change the Ceres gradient checking API to make is useful for
unit testing, clean up code duplication and fix interaction between
gradient checking and local parameterizations.

There were two gradient checking implementations, one being used
when using the check_gradients flag in the Solver, the other
being a standalone class. The standalone version was restricted
to cost functions with fixed parameter sizes at compile time, which
is being lifted here. This enables it to be used inside the
GradientCheckingCostFunction as well.

In addition, this installs new hooks in the Solver to ensure
that Solve will fail if any incorrect gradients are detected. This
way, you can set the check_gradient flags to true and detect
errors in an automated way, instead of just printing error information
to the log. The error log is now also returned in the Solver summary
instead of being printed directly. The user can then decide what to
do with it. The existing hooks for user callbacks are used for
this purpose to keep the internal API changes minimal and non-invasive.

The last and biggest change is the way the the interaction between
local parameterizations and the gradient checker works. Before,
local parameterizations would be ignored by the checker. However,
if a cost function does not compute its Jacobian along the null
space of the local parameterization, this wil not have any effect
on the solver, but would result in a gradient checker error.
With this change, the Jacobians are multiplied by the Jacobians
of the respective local parameterization and thus being compared
in the tangent space only.

The typical use case for this are quaternion parameters, where
a cost function will typically assume that the quaternion is
always normalized, skipping the correct computation of the Jacobian
along the normal to save computation cost.

Change-Id: I5e1bb97b8a899436cea25101efe5011b0bb13282
2016-08-18 06:18:43 +00:00
Mike Vitus d4264ec10d Add a quaternion local parameterization for Eigen's quaternion element convention.
Change-Id: I7046e8b24805313c5fb6a767de581d0054fcdb83
2016-08-17 18:28:54 -07:00
Alex Stewart ff11d0e63d Use _j[0,1,n]() Bessel functions on MSVC to avoid deprecation errors.
- Microsoft deprecated the POSIX Bessel functions: j[0,1,n]() in favour
  of _j[0,1,n](), it appears since at least MSVC 2005:
  https://msdn.microsoft.com/en-us/library/ms235384(v=vs.100).aspx.
- As this occurs in jet.h (templated public header), although Ceres
  suppresses the warning when it itself is built (to suppress a warning
  about the insecurity of using std::copy), it will crop up again in
  client code (without this fix) unless it is explicitly suppressed
  there also.
- Raised as Issue #190:
  https://github.com/ceres-solver/ceres-solver/issues/190.

Change-Id: If7ac5dbb856748f9900be93ec0452a40c0b00524
2016-06-29 09:33:45 +01:00
Mike Vitus 0c63bd3efb Add floor and ceil functions to the Jet implementation.
Change-Id: I72ebfb0e9ade2964dbf3a014225ead345d5ae352
2016-04-15 10:47:22 -07:00
Thomas Schneider d61e94da52 Add IsParameterBlockConstant to the ceres::Problem class.
Change-Id: I7d0e828e81324443209c17fa54dd1d37605e5bfe
2016-04-06 23:52:18 +02:00
Keir Mierle efe61b089b Make Jet string output more readable
Change-Id: Iebab111ab136c52f88180688ccb684584ab21dea
2016-03-16 11:27:25 -07:00
Sameer Agarwal 46ad4699f4 A complete refactoring of TrustRegionMinimizer.
1. Break up the monolithic loop in TrustRegionMinimizer::Minimize
   into a number of more easily described and analyzed subfunctions.
2. Break out the logic for evaluating the quality of a Trust Region
   step into its own object - TrustRegionStepEvaluator.

Change-Id: I08580ecac074cfd74c096cb8e4880cbda3d48296
2016-02-04 10:05:12 -08:00
Sameer Agarwal 15587dd1a9 Lint changes from William Rucklidge
Change-Id: If05a774c5e7dd318e6b3ee698e313f0fc58ee922
2016-01-05 11:31:13 -08:00
Wannes Van Loock b0bf9fd2a9 Add covariance matrix for a vector of parameters
Computing the covariance matrix for a number of parameter blocks
previously required adding all parameter blocks to the computation and
subsequently assembling the matrix by concatenating all the blocks.

This patch adds the computation of the covariance matrix for a vector
of parameter blocks. All covariance block pairs are added automatically
and the resulting covariance matrix is assembled in the order the
parameter blocks appear.

Change-Id: I3b70c63f16862adc23a1d7fb7a21dde4e68abe9a
2016-01-04 20:26:40 +00:00
Andrew Hunter d80c112168 Tweak alignment hint implementation for Jets
I169b637a1e2a106956b536c41d6a514a266e7cc0 marked Jets (in C++11) as
aligned to 16 bytes, and enabled Eigen vectorization.  However, to
implement this, we added Eigen includes to port.h.

Turns out this broke some other tricks Ceres uses (redefining Eigen
constants for better performance), so we don't want to do that. Move
most of the implementation to jet.h where it is safe.

Change-Id: I47c6fc4180db1ff674bc660723dd5a2b84254e0d
2015-12-11 14:50:19 -08:00
Andrew Hunter 5667505f35 Align Jet matrices where supported
We currently don't align the infinitesimal part of a Jet to a 16-byte
boundary (and thus force Eigen to avoid using SSE ops)--as a member of a
larger struct, we couldn't guarantee Jets would be allocated on
appropriately-aligned boundaries.  However, C++11 adds better support
for requesting alignment: we can use it to guarantee the members will be
properly aligned, and tell Eigen to vectorize.

There is a significant gotcha here: the standard gives wide latitude to
implementations as to which alignments they choose to support.  If we
ask for 16 and the system only supports 8, we may have misaligned
Jets. So we test (using alignof(std::max_align_t)) that the current
system supports 16-byte aligned values; if not, we fall back to the
current solution.

Two other small notes:
- This is obviously gated on C++11 support, and
  thus we put the logic in port.h and export some useful #defines.

- GCC 4.8.x has a
  bug (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56019) that has
  max_align_t in the wrong namespace.  This will not be a problem with a
  modern GCC, but add a small workaround since many systems still ship 4.8.

This results (on a x86 workstation) in a 60% speedup in Jacobian
evaluation on bin/simple_bundle_adjuster problem-16-22106-pre.txt.

Change-Id: I169b637a1e2a106956b536c41d6a514a266e7cc0
2015-12-08 01:09:07 +00:00
Sameer Agarwal 992ae55e84 Report the number of line search steps in FullReport.
Accumulate the number of steps of the line search algorithm
and report it as part of Summary::FullReport.

Change-Id: I1de12784009a3e08f2a2c2aff5085d57a3c73828
2015-12-01 14:26:13 -08:00
Sameer Agarwal ba67ed1e01 A variety of small updates
1. Add answers to a number of FAQs.
2. Add a note to the documentation for NumericDiffCostFunction that
   NumericDiffOptions needs to be documented and mentioned.
3. Update the docs for Solver::Options::numeric_derivative_relative_step_size
   to indicate that this setting only applies to the gradient checker.
4. Remove deprecated constructors from NumericDiffCostFunction and
   DynamicNumericDiffCostFunction.

Change-Id: If8fc011b2a5996dbc2c51268aa477550ed014a1c
2015-11-08 10:59:42 -08:00
Alessandro Gentilini 49c86018e0 Add Bessel functions in order to use them in residual code.
See "How can I use the Bessel function in the residual function?" at
https://groups.google.com/d/msg/ceres-solver/Vh1gpqac8v0/NIK1EiWJCAAJ

Change-Id: I3e80d9f9d1cadaf7177076e493ff46ace5233b76
2015-10-22 18:47:02 +00:00
Sameer Agarwal a66d89dcda Get ready for 1.11.0RC1
Update version numbers.
Drop CERES_VERSION_ABI macro.

Change-Id: Ib3eadabb318afe206bb196a5221b195d26cbeaa0
2015-09-08 14:55:28 -07:00
Sameer Agarwal 67622b080c Fix a pointer access bug in Ridders' algorithm.
A pointer to an Eigen matrix was being used as an array.

Change-Id: Ifaea14fa3416eda5953de49afb78dc5a6ea816eb
2015-09-05 21:37:22 +00:00
Sameer Agarwal 2701429f77 Use Eigen::Dynamic instead of ceres::DYNAMIC in numeric_diff.h
Change-Id: Iccb0284a8fb4c2160748dfae24bcd595f1d4cb5c
2015-08-30 21:33:57 -07:00
Tal Ben-Nun 4f049db7c2 Adaptive numeric differentiation using Ridders' method.
This method numerically computes function derivatives in different
scales, extrapolating between intermediate results to conserve function
evaluations. Adaptive differentiation is essential to produce accurate
results for functions with noisy derivatives.

Full changelist:
-Created a new type of NumericDiffMethod (RIDDERS).
-Implemented EvaluateRiddersJacobianColumn in NumericDiff.
-Created unit tests with f(x) = x^2 + [random noise] and
 f(x) = exp(x).

Change-Id: I2d6e924d7ff686650272f29a8c981351e6f72091
2015-08-30 14:06:13 +03:00
Johannes Schönberger b0cbc0f0b0 Reduce memory footprint of SubsetParameterization
Change-Id: If113cb4696d5aef3e50eed01fba7a3d4143b7ec8
2015-08-22 16:15:26 +00:00
Simon Rutishauser 4c3f8987e7 Add missing CERES_EXPORT to ComposedLoss
Change-Id: Id7db388d41bf53e6e5704039040c9d2c6bf4c29c
2015-08-13 11:10:44 +02:00
Sameer Agarwal 560940fa27 A refactor of the cubic interpolation code
1. Push the boundary handling logic into the underlying array
object. This has two very significant impacts:

a. The interpolation code becomes extremely simple to write
and to test.

b. The user has more flexibility in implementing how out of bounds
values are handled. We provide one default implementation.

Change-Id: Ic2f6cf9257ce7110c62e492688e5a6c8be1e7df2
2015-08-06 14:49:55 -07:00
Sameer Agarwal d9790e7789 Add ProductParameterization
Often a parameter block is the Cartesian product of a number of
manifolds. For example, a rigid transformation SE(3) = SO(3) x R^3
In such cases, where you have the local parameterization
of the individual manifolds available,
ProductParameterization can be used to construct a local
parameterization of the cartesian product.

Change-Id: I4b5bcbd2407a38739c7725b129789db5c3d65a20
2015-07-27 13:37:10 -07:00
Alex Stewart c80ce3525d Fix unused parameter compiler warnings in numeric_diff.h
Change-Id: I2b35babba17229387c6d346c46a2c6960db96e47
2015-07-11 18:27:00 +01:00
David Gossow 2a1dfd2b71 Add DynamicCostFunctionToFunctor.
This adds a new wrapper class called DynamicCostFunctionToFunctor
that closes a gap in the current API: the existing
CostFunctionToFunctor can only be used with a SizedCostFunction, where
the number and sizes of all parameter vectors are known at compile-time.
The DynamicCostFunctionToFunctor allows you to wrap a generic
CostFunction into a templated functor which can then be used in a
DynamicAutoDiffCostFunction.

Also updates the existing CostFunctionToFunctor class to internally use
DynamicCostFunctionToFunctor.

Change-Id: I088adc3271c58d2519126c27037c3576965a36d6
2015-06-18 16:01:15 -07:00
Simon Rutishauser 1e241b7cc3 Allow the LossFunction contained in a LossFunctionWrapper to be NULL.
This is consistent with how NULL LossFunctions are treated everywhere
else.

Change-Id: Ic91e39ccb13137fcad7f85e78613a29ecde30d67
2015-05-19 17:13:57 +02:00
Sameer Agarwal 9064b4ed27 Improve numeric differentation near zero.
Before this change, the default step size
for a function F(x) at x was

step_size = |x| * relative_step_size

if step_size was exactly zero, then to prevent
division by zero we would fall back to relative_step_size.

This however is not good enough, as values of x say 1e-64
would lead to step sizes ~ 1e-70 and dividing by such numbers
leads to inaccurate results. For even smaller numbers, like
1e-300, which I have observed can occur as the optimization
algorithm makes progress, this leads to NaNs.

The key change in this CL is to change the fallback mechanism
to be

step_size = max(|x| * relative_step_size, min_step_size)

where

min_step_size = sqrt(DBL_EPSILON)

This is the recommended minimum value for the step size
for double precision arithmetic on the interwebs.

This results in a small loss of precision in the transcendental
functions test, but that is unavoidable as we are not taking
sufficiently small steps anymore.

On the whole though this will improve the numerical performance
of the algorithm.

To validate this approach, one of the parameter values for the
EasyFunctorTest has been set to 1e-64, which causes the test
to start failing without the corrected fallback logic.

This change should also address some if not all of

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

Change-Id: I4a9013ef358626c1ba7b8abad60b3904163d63f6
2015-05-13 21:37:15 -07:00
Tal Ben-Nun b2dcef36e7 Refactored DynamicNumericDiffCostFunction to use NumericDiff
Change-Id: I2fc4b203e984beaa7af96fb3cbe8ce14e5bca614
2015-05-07 01:48:27 +03:00
Sameer Agarwal 3c52ef2fab More lint changes from William Rucklidge.
Change-Id: I3594ed46e78243034389cad158243e11dd1dc2b0
2015-05-05 11:34:05 -07:00