1. Change the ordering from NUM_PARAMETERS, NUM_RESIDUALS to
NUM_RESIDUALS, NUM_PARAMETERS in docs and in code.
2. TinySolver::solve -> TinySolver::Solve
Change-Id: I4dca87b971fd9168f1200b53c362669cffc82c1b
Tiny solver is targeted towards small dense least square
solves, where the overhead of calling normal Ceres is too
high. For example, when solving for inverse camera
distortion for every pixel location in a many-megapixel
image. Anecdotally, at one point in the past, tiny solver
was ~20x faster than Ceres for the problems it's intended
for. This is due to two key aspects:
1. Memory is allocated up front: repeated solves incur no
allocation overhead beyond a few scalars on the stack.
2. The cost function is fully inlined into the solver
loop, removing even the cost function call overhead.
Tiny solver originated many years ago as part of
libmv/Blender, where it is still used for distortion solving
today, but the time has come for it to migrate into Ceres.
This commit is just the initial import into Ceres. Follow
up patches will add further cleanups, and add CostFunction
and Jet adapters to make it easier to call tiny solver
(though by using adapters, some performance advantages will
be lost).
Change-Id: I8079535cd41382b1e0ac0ca2fca141711c72b7f8
1. Fix a bug which was causing the cost and gradient evaluation
time to not be reported.
2. Add the number of times cost and gradients are evaluated to
the Summary object and to the output of FullReport.
Change-Id: Id0703cd2dafbf437f3e537fbdc30ae81d5f4f540
THIS IS AN API BREAKING CHANGE.
Decouple the algorithm from the sparse linear algebra
library being used to perform the computation.
Before this change
Covariance::AlgorithmType had values
DENSE_SVD
EIGEN_SPARSE_QR
SUITE_SPARSE_QR
This has been replaced by two enums now.
Covariance::Options::sparse_linear_algebra_library_type
which can take values EIGEN_SPARSE, SUITE_SPARSE or CX_SPARSE.
The last one is currently not supported.
And Covariance::Options::algorithm_type takes values
DENSE_SVD
SPARSE_QR
This sets the stage for future extensions of the covariance
computation algorithm.
Also as part of this change, the covariance computation chapter
has been made a top level chapter on its own instead of being
buried deep inside the Solving Non-linear Least Squares problem.
Change-Id: Ibfbf60902d8d17694d9ff585047a5a57d329ab22
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
- 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
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
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
- 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
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
- 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
- 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
- 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
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
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
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
Solver::Options::numeric_derivative_relative_step_size to
Solver::Options::gradient_check_numeric_derivative_relative_step_size
Change-Id: Ib89ae3f87e588d4aba2a75361770d2cec26f07aa
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
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
- 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
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
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
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
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
Accumulate the number of steps of the line search algorithm
and report it as part of Summary::FullReport.
Change-Id: I1de12784009a3e08f2a2c2aff5085d57a3c73828
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
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