Commit Graph

57 Commits

Author SHA1 Message Date
Sameer Agarwal 46b8461fd0 Various minor fixes from William Rucklidge.
Change-Id: Ibe731d5db374ad8ee148d62a9fdd8d726b607a3f
2014-09-29 15:10:58 -07:00
Sameer Agarwal b44cfdef25 Let ITERATIVE_SCHUR use an explicit Schur Complement matrix.
Up till now ITERATIVE_SCHUR evaluates matrix-vector products
between the Schur complement and a vector implicitly by exploiting
the algebraic expression for the Schur complement.

This cost of this evaluation scales with the number of non-zeros
in the Jacobian.

For small to medium sized problems there is a sweet spot where
computing the Schur complement is cheap enough that it is much
more efficient to explicitly compute it and use it for evaluating
the matrix-vector products.

This changes implements support for an explicit Schur complement
in ITERATIVE_SCHUR in combination with the SCHUR_JACOBI preconditioner.

API wise a new bool Solver::Options::use_explicit_schur_complement
has been added.

The implementation extends the SparseSchurComplementSolver to use
Conjugate Gradients.

Example speedup:

use_explicit_schur_complement = false

Time (in seconds):
Preprocessor                            0.585

  Residual evaluation                   0.319
  Jacobian evaluation                   1.590
  Linear solver                        25.685
Minimizer                              27.990

Postprocessor                           0.010
Total                                  28.585

use_explicit_schur_complement = true

Time (in seconds):
Preprocessor                            0.638

  Residual evaluation                   0.318
  Jacobian evaluation                   1.507
  Linear solver                         5.930
Minimizer                               8.144

Postprocessor                           0.010
Total                                   8.791

Which indicates an end-to-end speedup of more than 3x, with the linear
solver being sped up by > 4x.

The idea to explore this optimization was inspired by the recent paper:

Mining structure fragments for smart bundle adjustment
L. Carlone, P. Alcantarilla, H. Chiu, K. Zsolt, F. Dellaert
British Machine Vision Conference, 2014

which uses a more complicated algorithm to compute parts of the
Schur complement to speed up the matrix-vector product.

Change-Id: I95324af0ab351faa1600f5204039a1d2a64ae61d
2014-09-29 10:29:32 -07:00
Sameer Agarwal 1aef66eeae Remove errant space.
Change-Id: Iedc06960417a9b938d57f623b4beb87a98e3d081
2014-09-07 21:18:44 -07:00
Sameer Agarwal d76da16f49 Move some routines to solver_utils.h/cc
This moves a couple of routines from solver.cc into solver_utils.h/cc
so that they can also be used by the upcoming GradientProblemSolver.

Change-Id: I627b32ad3dc639422aacde78a8e391459d947e99
2014-09-07 20:39:14 -07:00
Sameer Agarwal 79491a3f4a Solver::FullReport now reports build config.
The header of Summary::FullReport now looks like

Solver Summary (v 1.10.0-suitesparse-cxsparse-lapack-no_openmp)

                                     Original                  Reduced
Parameter blocks                        22122                    22122
Parameters                              66462                    66462
Residual blocks                         83718                    83718
Residual                               167436                   167436

Change-Id: Id1b81bbf90ba412d19e2dd3687eeb9d372b72c1b
2014-08-28 23:30:28 +00:00
Sameer Agarwal 48068c753e Lint cleanup from William Rucklidge.
Change-Id: Ie0e0aa58440be7a4f67dcd633dbb6f1bb0c051a8
2014-08-28 13:03:40 -07:00
Sameer Agarwal 6a51b135e6 Fix solver_test.cc
When Eigen is not installed, Solver::IsValid was not detecting
it correctly.

Change-Id: Id285a84d829a9e20bc5de663adfca66ac31e08f3
2014-08-28 10:48:29 -07:00
Sameer Agarwal 6f89d850fb Further build breakage fixes.
1. Allow the minimum number of linear solver iterations to be zero.
2. Fix conjugate gradients solver's iteration loop to be sane again.

Change-Id: I8594815fec940c2b30e28eb58ec5d8baacf13dae
2014-08-27 11:51:50 -07:00
Sameer Agarwal 8de27be218 Fix a bug in TrustRegionPreprocessor
TrustRegionPreprocessor was not setting Minimizer::Options::is_constrained.
This meant that the line search for bounds constraints was not being
invoked for bounds constrained problems.

And some minor lint cleanup.

Change-Id: I18852cfaf1b33fd90b7d8c196f2063c128126658
2014-08-19 08:39:48 -07:00
Sameer Agarwal 1745dd615b Refactor SolverImpl.
Replace SolverImpl with

 a. A minimizer specific preprocessor class.
 b. A generic Solve function inside solver.cc
 c. Presummarize and Postsummarize functions to handle
    updates to the summary object.

The existing SolverImpl class was a mixture of the above three
things and was increasingly complicated code to follow. This change,
breaks it into its three separate constituents, with the aims of
better separation of concerns and thus better testability and
reliability.

The call to Solver::Solve() now consists of

1. Presummarize - summarize the given state of the problem and solver
   options.
2. Preprocess - Setup everything that is needed to call the minimizer.
   This includes, removing redundant parameter and residual blocks,
   setting up the reordering for the linear solver, creating the
   linear solver, evaluator, inner iteration minimizer etc.
3. Minimize.
4. Post summarize - summarize the result of the preprocessing and the
   solve.

Change-Id: I80f35cfc9f2cbf78f1df4aceace27075779d8a3a
2014-08-18 13:31:31 -07:00
Sameer Agarwal c89e82e001 Drop iostream from solver.cc
Change-Id: I512a247c183113ef5dcf09e13f19c17c83293f21
2014-07-22 10:53:32 -07:00
Sameer Agarwal bb3b865883 Add sstream header to solver.cc
Thanks to Filippo Basso for reporting this.

Change-Id: I45059cd66bad9d26e706fc3011f714cf60121320
2014-07-22 10:47:46 -07:00
Sameer Agarwal 603277d343 Add check for dynamic sparsity in Solver::Options::IsValid.
Dynamic sparsity should only be used with SPARSE_NORMAL_CHOLESKY.

Change-Id: I8dd33c05ec0337b3c13b547ecffe3aefc3e5ab12
2014-06-10 10:07:53 -07:00
Sameer Agarwal 70af9a58f1 Improve logging in Solver::Options::IsValid.
The error message now includes the value of the offending option.

Change-Id: Ic2493709f54f7efe59313d51d1ff9638191c8b38
2014-06-03 16:06:23 +00:00
Sameer Agarwal 5d51e4d4bc Addressing comments from Jim Roseborough.
Change-Id: I9f5bdb4a81cd25ee4ea5de65aeddcaa0c5d18197
2014-06-02 08:12:11 -07:00
Sameer Agarwal 29fe072781 Solver::Options::min_relative_decrease can be zero.
Change-Id: I82ae5227ad0f8f6ff21e859e11f0d18ac7d9828c
2014-06-01 00:25:34 -07:00
Sameer Agarwal 226a95e488 Fix more typos in solver.cc
A number of typos in solver.cc which were hidden behind ifdefs
and were only revealed when building under android.

Change-Id: I89cbe8056da071479d2d1a251a8919b0be1f1cd4
2014-06-01 06:55:18 +00:00
Sameer Agarwal 19dee8d591 Fix a typo in solver.cc
Change-Id: I3f2e058e2d45c72eaa12129ff0b9366332ee87f5
2014-05-31 23:04:44 -07:00
Sameer Agarwal 1693645a67 Add Solver::Options::IsValid.
This provides a user visible way to validate the Solver::Options
before calling Solve.

Change-Id: Ife84fd33532ab2ccb7ac95abe22735843db51fde
2014-05-30 13:00:18 -07:00
Keir Mierle 80a85ca53f Replace broken CERES_VERSION macro
This replaces the broken CERES_VERSION and CERES_ABI_VERSION
defines with a different set, including integer versions for
MAJOR/MINOR/etc.

This also adds the Ceres version to Solver::FullReport().

Example report from powell:

Ceres Solver v1.10.0 Solve Report
----------------------------------
                                     Original                  Reduced
Parameter blocks                            4                        4
Parameters                                  4                        4
Residual blocks                             4                        4
Residual                                    4                        4

Minimizer                        TRUST_REGION

Dense linear algebra library            EIGEN
Trust region strategy     LEVENBERG_MARQUARDT

                                        Given                     Used
Linear solver                        DENSE_QR                 DENSE_QR
Threads                                     1                        1
Linear solver threads                       1                        1

Cost:
Initial                          1.075000e+02
Final                            1.791438e-14
Change                           1.075000e+02

Minimizer iterations                       14
Successful steps                           14
Unsuccessful steps                          0

Time (in seconds):
Preprocessor                            0.001

  Residual evaluation                   0.000
  Jacobian evaluation                   0.000
  Linear solver                         0.000
Minimizer                               0.001

Postprocessor                           0.000
Total                                   0.003

Change-Id: I5bf0e8023693e9195276b1f1e881b13121ba1196
Termination:                      CONVERGENCE (Gradient tolerance reached. Gradient max norm: 3.642190e-11 <= 1.000000e-10)
2014-05-30 05:18:36 +00:00
Sameer Agarwal bb05be341b Solver::Options uses shared_ptr to handle ownership.
Solver::Options::linear_solver_ordering and
Solver::Options::inner_iteration_ordering
were bare pointers even though Solver::Options took ownership of these
objects.

This lead to buggy user code and the inability to copy Solver::Options
objects around.

With this change, these naked pointers have been replaced by a
shared_ptr object which will managed the lifetime of these objects. This
also leads to simplification of the lifetime handling of these objects
inside the solver.

The Android.mk and Application.mk files have also been updated
to use a newer NDK revision which ships with LLVM's libc++.

Change-Id: I25161fb3ddf737be0b3e5dfd8e7a0039b22548cd
2014-04-25 15:54:39 -07:00
Sameer Agarwal 1da9292016 Changes to how gradient based convergence is diagnosed.
The original implementation for computing the norm of the gradient was

gradient_norm = norm(gradient)

when the gradient vector lies in the same space as the parameter
vector, this value is meaningful. When there is a local parameterization
involved, interpreting this value and diagnosing convergence using it
is hard.

Further, this expression does not respect the bounds constraints
on the parmeters. Measuring the norm of the gradient only makes
sense when the optimization being performed is unconstrained.

A better solution, used by LANCELOT is the expression
gradient_norm = norm(x - P(x - gradient))

Here, P is the projection operator onto the bounds constraints.
x - gradient is computed by computing Plus(x, -gradient), thus the
actual expression becomes

gradient_norm = norm(x - P(Plus(x, -gradient)));

Which in the case where there are no bounds constraints, and there
are no local parameterizations, reduces to the usual Euclidean
expression from above, since

Plus(x, -gradient) = x - gradient

and P(x - gradient) = x - gradient.

This change implements this change. Further, the convergence
test using the gradient tolerance now uses an absolute measure
rather than a relative measure. This is a forward looking change
as we start implementing the Augmented Lagrangian solver.

Last but not the least, various "Terminating: Foo" messages
have been changed so that "Terminating: " is logged but is
not part of the Solver::Summary::message string as it is
pointless.

Change-Id: I943146f71a1da47c8c7592986039b4112781b99b
2014-02-24 10:54:46 -08:00
Sameer Agarwal dcee120bac Consolidate SolverTerminationType enum.
1. Rename SolverTerminationType to TerminationType.
2. Consolidate the enum as
  a. CONVERGENCE - subsumes FUNCTION_TOLERANCE, PARAMETER_TOLERANCE and GRADIENT_TOLERANCE
  b. NO_CONVERGENCE
  c. FAILURE - captures all kinds of failures including DID_NOT_RUN.
  d. USER_SUCCESS
  e. USER_FAILURE
3. Solver::Summary::error is renamed to be Solver::Summary::message, to both
reduce confusion as well as capture its true meaning.

Change-Id: I27a382e66e67f5a4750d0ee914d941f6b53c326d
2013-12-17 11:21:33 -08:00
Sameer Agarwal 5794d41be2 Remove overzealous checks in Summary::FullReport.
Thanks to sebi.koch@gmail.com for reporting this.

Change-Id: I1ba9b375e5cf66639e292ba37b34a90446f13162
2013-11-25 13:37:02 -08:00
Alex Stewart 7124c3474c Fixes for some line search bugs & corner cases.
- Increase precision of numeric values output in error messages to
  allow for easier debugging.
- Ensure termination after Wolfe search bracketing phase if bracket
  width has been shrunk to below tolerance.
- Cleaned up return value for BracketingPhase(), now false iff
  optimisation should stop, true otherwise.
- Fix bug whereby we would mark a step size as satisfying the Wolfe
  conditions when it did not due to numerical issues in the cost
  function.
- Adding explanation of a subtlety in which a zoom could still be
  acceptably invoked with bracket_low.f > bracket_high.f.
- Replacing hard check of a pre-condition of ZoomPhase() with a
  conditional return if not satisfied to address issue whereby a
  bracket could be incorrectly identified due to inconsistent values
  & gradients returned from the cost function.
- Adding missing check for step size validity in line search minimizer.
- Adding ToDebugString() for FunctionSample.

Change-Id: Iad98e635749877f80c079ebad126bf022d82232d
2013-11-14 17:40:10 +00:00
Sameer Agarwal 9ba0b352a2 Lint and other cleanups from William Rucklidge
Change-Id: I7fb23c2db85f0f121204560b79f1966f3d584431
2013-11-05 13:04:56 -08:00
Sameer Agarwal f06b9face5 Add support for multiple visibility clustering algorithms.
The original visibility based preconditioning paper and
implementation only used the canonical views algorithm.

This algorithm for large dense graphs can be particularly
expensive. As its worst case complexity is cubic in size
of the graph.

Further, for many uses the SCHUR_JACOBI preconditioner
was both effective enough while being cheap. It however
suffers from a fatal flaw. If the camera parameter blocks
are split between two or more parameter blocks, e.g,
extrinsics and intrinsics. The preconditioner because
it is block diagonal will not capture the interactions
between them.

Using CLUSTER_JACOBI or CLUSTER_TRIDIAGONAL will fix
this problem but as mentioned above this can be quite
expensive depending on the problem.

This change extends the visibility based preconditioner
to allow for multiple clustering algorithms. And adds
a simple thresholded single linkage clustering algorithm
which allows you to construct versions of CLUSTER_JACOBI
and CLUSTER_TRIDIAGONAL preconditioners that are cheap
to construct and are more effective than SCHUR_JACOBI.

Currently the constants controlling the threshold above
which edges are considered in the single linkage algorithm
are not exposed. This would be done in a future change.

Change-Id: I7ddc36790943f24b19c7f08b10694ae9a822f5c9
2013-10-31 13:22:57 -07:00
Sameer Agarwal 367b65e17a Multiple dense linear algebra backends.
1. When a LAPACK implementation is present, then
DENSE_QR, DENSE_NORMAL_CHOLESKY and DENSE_SCHUR
can use it for doing dense linear algebra operations.

2. The user can switch dense linear algebra libraries
by setting Solver::Options::dense_linear_algebra_library_type.

3. Solver::Options::sparse_linear_algebra_library is now
Solver::Options::sparse_linear_algebra_library_type to be consistent
with all the other enums in Solver::Options.

4. Updated documentation as well as Solver::Summary::FullReport
to reflect these changes.

Change-Id: I5ab930bc15e90906b648bc399b551e6bd5d6498f
2013-08-13 14:57:03 -07:00
Sameer Agarwal 7a8f797924 Lint fixes
Change-Id: Ic453597488ef92723a81a224e7443e8f454b25da
2013-07-03 09:03:55 -07:00
Sameer Agarwal 4f010b2db0 Improve Summary::FullReport when line search is used.
Disable reporting of preconditioner when direct factorization
is being used.

Change-Id: Id264d2292c5cab608724a6a8fab5d588db950468
2013-07-01 08:01:01 -07:00
Sameer Agarwal f0b071bac4 Lint and other fixes from William Rucklidge
Change-Id: Ic18561a5cdadccc75e97818fa4422bb5d9d43df9
2013-05-31 13:22:51 -07:00
Sameer Agarwal 9f9488b162 Add iteration and time reporting for inner iterations.
Also

1. Remove an inadvertent LOG(INFO) from trust_region_minimizer.cc
2. Refactor some of the code in FullReport to reduce duplication
   across line search and trust region minimizers.
3. Consistent capitalization.

Change-Id: I9078b1704efab23d2858530636f524e60c7d9016
2013-05-23 21:03:31 +00:00
Keir Mierle ba9442160d Add the number of effective parameters to the final report.
Here is an example report, obtained by running:

  bin/Debug/bundle_adjuster \
  --input=../ceres-solver/data/problem-16-22106-pre.txt \
  --linear_solver=iterative_schur \
  --num_iterations=1 \
  --alsologtostderr \
  --use_local_parameterization \
  --use_quaternions

Note that effective parameters is less than parameters by 16, which is the
number of cameras. In this case the local parameterization has a 3 dimensional
tangent space for the 4-dimensional quaternions.

Ceres Solver Report
-------------------
                                     Original                  Reduced
Parameter blocks                        22138                    22138
Parameters                              66478                    66478
Effective parameters                    66462                    66462
Residual blocks                         83718                    83718
Residual                               167436                   167436

Minimizer                        TRUST_REGION
Trust Region Strategy     LEVENBERG_MARQUARDT

                                        Given                     Used
Linear solver                 ITERATIVE_SCHUR          ITERATIVE_SCHUR
Preconditioner                         JACOBI                   JACOBI
Threads:                                    1                        1
Linear solver threads                       1                        1
Linear solver ordering              AUTOMATIC                22106, 32

Cost:
Initial                          4.185660e+06
Final                            7.221647e+04
Change                           4.113443e+06

Number of iterations:
Successful                                  1
Unsuccessful                                0
Total                                       1

Time (in seconds):
Preprocessor                            0.697

  Residual Evaluations                  0.063
  Jacobian Evaluations                 27.608
  Linear Solver                        13.360
Minimizer                              43.973

Postprocessor                           0.004
Total                                  44.756

Termination:                   NO_CONVERGENCE

Change-Id: I6b6b8ac24f71bd187e67d95651290917642be74f
2013-02-25 12:49:13 -08:00
Sameer Agarwal 36dc14ddf2 Fix a clang warning
Change-Id: I5ef32c6329f1f75efb30b16519b8de146a8339fa
2013-02-25 10:33:10 -08:00
Sameer Agarwal 931c309b27 Cleanup based on comments by William Rucklidge
Change-Id: If269ba8e388965a8ea32260fd6f17a133a19ab9b
2013-02-25 10:13:29 -08:00
Sameer Agarwal 509f68cfe3 Problem::Evaluate implementation.
1. Add Problem::Evaluate and tests.
2. Remove Solver::Summary::initial/final_*
3. Remove Solver::Options::return_* members.
4. Various cpplint cleanups.

Change-Id: I4266de53489896f72d9c6798c5efde6748d68a47
2013-02-24 19:04:21 +00:00
Sameer Agarwal beb4505311 Minor fixes
Based on William Rucklidge's review, including
a nasty bug in parameter block removal.

Change-Id: I3a692e589f600ff560ecae9fa85bb0b76063d403
2013-02-22 13:37:05 -08:00
Sameer Agarwal 290b975d1d Preconditioner refactoring.
1. Added a Preconditioner interface.
2. SCHUR_JACOBI is now its own class and is independent of
SuiteSparse.

Change-Id: Id912ab19cf3736e61d1b90ddaf5bfba33e877ec4
2013-02-17 23:20:41 -08:00
Sameer Agarwal d010de5435 Solver::Summary::FullReport() supports line search now.
Change-Id: Ib08d300198b85d9732cfb5785af4235ca4bd5226
2013-02-16 01:32:44 +00:00
Sameer Agarwal c58e6dc3ea More refined event logging in solver_impl.cc
Change-Id: Ie3061c921c006d2600d16185c690f52ccf816f68
2013-02-11 18:23:27 -08:00
Sameer Agarwal 42a84b87fa Expand reporting of timing information.
1. Add an ExecutionSummary object to record execution
   information about Ceres objects.
2. Add an EventLogger object to log events in a function call.
3. Add a ScopedExecutionTimer object to log times in ExecutionSummary.
4. Instrument ProgramEvaluator and all the linear solvers
   to report their timing statistics.
5. Connect the timing statistics to Summary::FullReport.
6. Add high precision timer on unix systems using
   gettimeofday() call.
7. Various minor clean ups all around.

Change-Id: I5e09804b730b09535484124be7dbc1c58eccd1d4
2013-02-06 01:00:38 -08:00
Sameer Agarwal 977be7cac3 Add support for reporting linear solver and inner iteration
orderings.

Change-Id: I0588a4285e0925ce689e47bd48ddcc61ce596a1f
2013-01-26 16:02:33 -08:00
Sameer Agarwal 68b32a941c ordering -> linear_solver_ordering.
Change-Id: If4af72da90725db2a2d4f397f4cb671c2e863a98
2012-10-06 23:16:04 -07:00
Sameer Agarwal ba8d967f8c Generalization of the inner iterations algorithm.
Add automatic recursive independent set decomposition.
Clean up the naming and the API for inner iterations.

Change-Id: I3d7d6babb9756842d7367e14b7279d2df98fb724
2012-10-05 08:35:53 -07:00
Sameer Agarwal 65625f7782 Solver::Options::ordering* are dead.
Remove the old ordering API, and modify solver_impl.cc
to use the new API everywhere.

In the process also clean up the linear solver instantion
logic in solver_impl.cc a bit too.

Change-Id: Ia66898abc7f622070b184b21fce8cc6140c4cebf
2012-09-17 15:41:10 -07:00
Petter Strandmark 76533b3c46 Adding high-precision timer using OpenMP
(fixes issue #41)

Change-Id: Ieffe5f789a591c1e766ae619b75f0d7f6cd890f4
2012-09-13 18:10:57 -07:00
Sameer Agarwal 1e2892009e Update Summary::FullReport to report dogleg type.
Change-Id: I0b4be8d7486c1c4b36b299693b3fe8b0d3426537
2012-08-22 08:50:17 -07:00
Sameer Agarwal 8b4cb7aa2c Fix sparse linear algebra library logging in Summary::FullReport.
Change-Id: Id2c902dc86c00954fde7749c7b4a67dd94215a31
2012-08-17 13:20:06 -07:00
Keir Mierle 6196cba4e5 Fix broken constant parameter blocks
This fixes the bug introduced in a previous commit,
and adds a test to check that constant parameter
blocks work as expected.

This also refactors the Solver/SolverImpl split so
that SolverImpl is no longer a friend of Problem;
instead, Solver is. This makes it possible to
verify the invariant on parameter block states in
the unit test, and is a more symmetric design
anyway.

Bug: 51
Change-Id: Id503f5b526cfb8bc24aae3aaad2e414b14063d78
2012-06-19 00:09:53 -07:00
Sameer Agarwal 97fb6d9715 Documentation & Logging cleanups.
1. Document the use of dogleg and a general discussion of
   trust region methods.
2. Added a TBD section on compiler/linker flags.
3. Summary::FullReport now prints out sparse_linear_algebra_library
   and trust_region_strategy_type.

Change-Id: I01f680070d510715900f345364855689005d54bb
2012-06-17 18:59:34 -07:00