Merging r46725 through r46963 from trunk into soc-2011-tomato
authorSergey Sharybin <sergey.vfx@gmail.com>
Thu, 24 May 2012 09:47:29 +0000 (09:47 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Thu, 24 May 2012 09:47:29 +0000 (09:47 +0000)
267 files changed:
doc/python_api/examples/bpy.ops.2.py [deleted file]
doc/python_api/examples/bpy.ops.3.py [deleted file]
extern/libmv/CMakeLists.txt
extern/libmv/SConscript
extern/libmv/bundle.sh
extern/libmv/libmv-capi.cpp
extern/libmv/libmv-capi.h
extern/libmv/libmv/multiview/homography.cc [new file with mode: 0644]
extern/libmv/libmv/multiview/homography.h [new file with mode: 0644]
extern/libmv/libmv/multiview/homography_parameterization.h [new file with mode: 0644]
extern/libmv/libmv/tracking/esm_region_tracker.cc
extern/libmv/libmv/tracking/track_region.cc [new file with mode: 0644]
extern/libmv/libmv/tracking/track_region.h [new file with mode: 0644]
extern/libmv/mkfiles.sh
extern/libmv/third_party/CMakeLists.txt [new file with mode: 0644]
extern/libmv/third_party/SConscript [new file with mode: 0644]
extern/libmv/third_party/ceres/CMakeLists.txt [new file with mode: 0644]
extern/libmv/third_party/ceres/ChangeLog [new file with mode: 0644]
extern/libmv/third_party/ceres/LICENSE [new file with mode: 0644]
extern/libmv/third_party/ceres/README [new file with mode: 0644]
extern/libmv/third_party/ceres/SConscript [new file with mode: 0644]
extern/libmv/third_party/ceres/bundle.sh [new file with mode: 0755]
extern/libmv/third_party/ceres/files.txt [new file with mode: 0644]
extern/libmv/third_party/ceres/include/ceres/autodiff_cost_function.h [new file with mode: 0644]
extern/libmv/third_party/ceres/include/ceres/ceres.h [new file with mode: 0644]
extern/libmv/third_party/ceres/include/ceres/conditioned_cost_function.h [new file with mode: 0644]
extern/libmv/third_party/ceres/include/ceres/cost_function.h [new file with mode: 0644]
extern/libmv/third_party/ceres/include/ceres/internal/autodiff.h [new file with mode: 0644]
extern/libmv/third_party/ceres/include/ceres/internal/eigen.h [new file with mode: 0644]
extern/libmv/third_party/ceres/include/ceres/internal/fixed_array.h [new file with mode: 0644]
extern/libmv/third_party/ceres/include/ceres/internal/macros.h [new file with mode: 0644]
extern/libmv/third_party/ceres/include/ceres/internal/manual_constructor.h [new file with mode: 0644]
extern/libmv/third_party/ceres/include/ceres/internal/port.h [new file with mode: 0644]
extern/libmv/third_party/ceres/include/ceres/internal/scoped_ptr.h [new file with mode: 0644]
extern/libmv/third_party/ceres/include/ceres/iteration_callback.h [new file with mode: 0644]
extern/libmv/third_party/ceres/include/ceres/jet.h [new file with mode: 0644]
extern/libmv/third_party/ceres/include/ceres/local_parameterization.h [new file with mode: 0644]
extern/libmv/third_party/ceres/include/ceres/loss_function.h [new file with mode: 0644]
extern/libmv/third_party/ceres/include/ceres/normal_prior.h [new file with mode: 0644]
extern/libmv/third_party/ceres/include/ceres/numeric_diff_cost_function.h [new file with mode: 0644]
extern/libmv/third_party/ceres/include/ceres/problem.h [new file with mode: 0644]
extern/libmv/third_party/ceres/include/ceres/rotation.h [new file with mode: 0644]
extern/libmv/third_party/ceres/include/ceres/sized_cost_function.h [new file with mode: 0644]
extern/libmv/third_party/ceres/include/ceres/solver.h [new file with mode: 0644]
extern/libmv/third_party/ceres/include/ceres/types.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/block_evaluate_preparer.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/block_evaluate_preparer.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/block_jacobian_writer.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/block_jacobian_writer.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/block_random_access_dense_matrix.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/block_random_access_dense_matrix.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/block_random_access_matrix.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/block_random_access_matrix.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/block_random_access_sparse_matrix.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/block_random_access_sparse_matrix.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/block_sparse_matrix.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/block_sparse_matrix.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/block_structure.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/block_structure.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/canonical_views_clustering.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/canonical_views_clustering.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/casts.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/cgnr_linear_operator.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/cgnr_solver.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/cgnr_solver.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/collections_port.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/compressed_row_jacobian_writer.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/compressed_row_jacobian_writer.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/compressed_row_sparse_matrix.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/compressed_row_sparse_matrix.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/conditioned_cost_function.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/conjugate_gradients_solver.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/conjugate_gradients_solver.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/corrector.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/corrector.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/dense_jacobian_writer.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/dense_qr_solver.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/dense_qr_solver.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/detect_structure.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/detect_structure.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/evaluator.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/evaluator.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/file.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/file.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_2.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_3.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_4.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_d.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_3.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_4.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_9.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_d.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_3.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_4.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_d.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_2.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_3.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_4.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_d.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_d_d_d.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/gradient_checking_cost_function.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/gradient_checking_cost_function.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/graph.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/graph_algorithms.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/implicit_schur_complement.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/implicit_schur_complement.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/integral_types.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/iterative_schur_complement_solver.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/iterative_schur_complement_solver.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/levenberg_marquardt.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/levenberg_marquardt.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/linear_least_squares_problems.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/linear_least_squares_problems.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/linear_operator.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/linear_operator.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/linear_solver.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/linear_solver.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/local_parameterization.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/loss_function.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/map_util.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/matrix_proto.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/minimizer.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/mutex.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/normal_prior.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/parameter_block.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/partitioned_matrix_view.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/partitioned_matrix_view.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/problem.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/problem_impl.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/problem_impl.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/program.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/program.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/program_evaluator.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/random.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/residual_block.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/residual_block.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/residual_block_utils.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/residual_block_utils.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/runtime_numeric_diff_cost_function.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/runtime_numeric_diff_cost_function.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/schur_eliminator.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/schur_eliminator.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/schur_eliminator_impl.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/schur_ordering.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/schur_ordering.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/scratch_evaluate_preparer.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/scratch_evaluate_preparer.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/solver.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/solver_impl.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/solver_impl.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/sparse_matrix.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/sparse_matrix.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/split.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/stl_util.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/stringprintf.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/stringprintf.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/suitesparse.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/suitesparse.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/triplet_sparse_matrix.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/triplet_sparse_matrix.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/types.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/visibility.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/visibility.h [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.cc [new file with mode: 0644]
extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.h [new file with mode: 0644]
extern/libmv/third_party/ceres/mkfiles.sh [new file with mode: 0755]
extern/libmv/third_party/ceres/patches/msvc_isfinite.patch [new file with mode: 0644]
extern/libmv/third_party/ceres/patches/series [new file with mode: 0644]
intern/CMakeLists.txt
intern/SConscript
intern/cycles/bvh/bvh_binning.cpp
intern/raskter/CMakeLists.txt [new file with mode: 0644]
intern/raskter/SConscript [new file with mode: 0644]
intern/raskter/raskter.c [new file with mode: 0644]
intern/raskter/raskter.h [new file with mode: 0644]
release/datafiles/splash.png
release/scripts/modules/bpy_extras/keyconfig_utils.py
release/scripts/presets/camera/Nikon_D35.py [new file with mode: 0644]
release/scripts/startup/bl_ui/space_clip.py
source/blender/CMakeLists.txt
source/blender/blenkernel/BKE_context.h
source/blender/blenkernel/BKE_library.h
source/blender/blenkernel/BKE_main.h
source/blender/blenkernel/BKE_mask.h [new file with mode: 0644]
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/BKE_tracking.h
source/blender/blenkernel/CMakeLists.txt
source/blender/blenkernel/SConscript
source/blender/blenkernel/intern/context.c
source/blender/blenkernel/intern/depsgraph.c
source/blender/blenkernel/intern/idcode.c
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/mask.c [new file with mode: 0644]
source/blender/blenkernel/intern/movieclip.c
source/blender/blenkernel/intern/node.c
source/blender/blenkernel/intern/scene.c
source/blender/blenkernel/intern/tracking.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/editors/CMakeLists.txt
source/blender/editors/SConscript
source/blender/editors/datafiles/splash.png.c
source/blender/editors/gpencil/gpencil_buttons.c
source/blender/editors/gpencil/gpencil_edit.c
source/blender/editors/gpencil/gpencil_paint.c
source/blender/editors/include/ED_clip.h
source/blender/editors/include/ED_mask.h [new file with mode: 0644]
source/blender/editors/include/ED_screen.h
source/blender/editors/include/ED_transform.h
source/blender/editors/interface/interface_templates.c
source/blender/editors/mask/CMakeLists.txt [new file with mode: 0644]
source/blender/editors/mask/SConscript [new file with mode: 0644]
source/blender/editors/mask/mask_draw.c [new file with mode: 0644]
source/blender/editors/mask/mask_editor.c [new file with mode: 0644]
source/blender/editors/mask/mask_intern.h [new file with mode: 0644]
source/blender/editors/mask/mask_ops.c [new file with mode: 0644]
source/blender/editors/mask/mask_relationships.c [new file with mode: 0644]
source/blender/editors/mask/mask_select.c [new file with mode: 0644]
source/blender/editors/screen/screen_ops.c
source/blender/editors/space_api/spacetypes.c
source/blender/editors/space_clip/clip_buttons.c
source/blender/editors/space_clip/clip_dopesheet_ops.c
source/blender/editors/space_clip/clip_draw.c
source/blender/editors/space_clip/clip_editor.c
source/blender/editors/space_clip/space_clip.c
source/blender/editors/space_clip/tracking_ops.c
source/blender/editors/space_node/drawnode.c
source/blender/editors/space_node/space_node.c
source/blender/editors/transform/transform.c
source/blender/editors/transform/transform.h
source/blender/editors/transform/transform_conversions.c
source/blender/editors/transform/transform_generics.c
source/blender/editors/transform/transform_ops.c
source/blender/makesdna/DNA_ID.h
source/blender/makesdna/DNA_mask_types.h [new file with mode: 0644]
source/blender/makesdna/DNA_space_types.h
source/blender/makesdna/DNA_tracking_types.h
source/blender/makesdna/intern/makesdna.c
source/blender/makesrna/RNA_access.h
source/blender/makesrna/intern/CMakeLists.txt
source/blender/makesrna/intern/makesrna.c
source/blender/makesrna/intern/rna_ID.c
source/blender/makesrna/intern/rna_internal.h
source/blender/makesrna/intern/rna_main.c
source/blender/makesrna/intern/rna_main_api.c
source/blender/makesrna/intern/rna_mask.c [new file with mode: 0644]
source/blender/makesrna/intern/rna_movieclip.c
source/blender/makesrna/intern/rna_nodetree.c
source/blender/makesrna/intern/rna_nodetree_types.h
source/blender/makesrna/intern/rna_space.c
source/blender/makesrna/intern/rna_tracking.c
source/blender/nodes/CMakeLists.txt
source/blender/nodes/NOD_composite.h
source/blender/nodes/composite/node_composite_tree.c
source/blender/nodes/composite/nodes/node_composite_mask.c [new file with mode: 0644]
source/blender/windowmanager/WM_types.h
source/blenderplayer/CMakeLists.txt
source/blenderplayer/bad_level_call_stubs/stubs.c
source/creator/CMakeLists.txt

diff --git a/doc/python_api/examples/bpy.ops.2.py b/doc/python_api/examples/bpy.ops.2.py
deleted file mode 100644 (file)
index 86b7438..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-"""
-Overriding Context
-++++++++++++++++++
-
-It is possible to override context members that the operator sees, so that they
-act on specified rather than the selected or active data, or to execute an
-operator in the different part of the user interface.
-
-The context overrides are passed as a dictionary, with keys matching the context
-member names in bpy.context. For example to override bpy.context.active_object,
-you would pass {'active_object': object}.
-"""
-
-# remove all objects in scene rather than the selected ones
-import bpy
-override = {'selected_bases': list(bpy.context.scene.object_bases)}
-bpy.ops.object.delete(override)
-
diff --git a/doc/python_api/examples/bpy.ops.3.py b/doc/python_api/examples/bpy.ops.3.py
deleted file mode 100644 (file)
index 0b5bcaf..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-"""
-It is also possible to run an operator in a particular part of the user
-interface. For this we need to pass the window, screen, area and sometimes
-a region.
-"""
-
-# maximize 3d view in all windows
-import bpy
-
-for window in bpy.context.window_manager.windows:
-    screen = window.screen
-    
-    for area in screen.areas:
-        if area.type == 'VIEW_3D':
-            override = {'window': window, 'screen': screen, 'area': area}
-            bpy.ops.screen.screen_full_area(override)
-            break
-
index 6be8138..60cd84d 100644 (file)
@@ -32,6 +32,7 @@ set(INC
        third_party/ssba
        third_party/ldl/Include
        ../colamd/Include
+       third_party/ceres/include
 )
 
 set(INC_SYS
@@ -61,6 +62,7 @@ set(SRC
        libmv/multiview/fundamental.cc
        libmv/multiview/projection.cc
        libmv/multiview/triangulation.cc
+       libmv/multiview/homography.cc
        libmv/numeric/numeric.cc
        libmv/numeric/poly.cc
        libmv/simple_pipeline/bundle.cc
@@ -83,6 +85,7 @@ set(SRC
        libmv/tracking/pyramid_region_tracker.cc
        libmv/tracking/retrack_region_tracker.cc
        libmv/tracking/trklt_region_tracker.cc
+       libmv/tracking/track_region.cc
 
        third_party/fast/fast_10.c
        third_party/fast/fast_11.c
@@ -250,3 +253,5 @@ add_definitions(
 )
 
 blender_add_lib(extern_libmv "${SRC}" "${INC}" "${INC_SYS}")
+
+add_subdirectory(third_party)
index fbb6ee3..b47086f 100644 (file)
@@ -30,7 +30,7 @@ src += env.Glob('third_party/ldl/Source/*.c')
 src += env.Glob('third_party/ssba/Geometry/*.cpp')
 src += env.Glob('third_party/ssba/Math/*.cpp')
 
-incs = '. ../Eigen3'
+incs = '. ../Eigen3 third_party/ceres/include'
 incs += ' ' + env['BF_PNG_INC']
 incs += ' ' + env['BF_ZLIB_INC']
 
@@ -65,3 +65,5 @@ else:
 incs += ' ./third_party/ssba ./third_party/ldl/Include ../colamd/Include'
 
 env.BlenderLib ( libname = 'extern_libmv', sources=src, includes=Split(incs), defines=defs, libtype=['extern', 'player'], priority=[20,137], compileflags=cflags_libmv, cc_compileflags=ccflags_libmv, cxx_compileflags=cxxflags_libmv )
+
+SConscript(['third_party/SConscript'])
index 3f58097..3f87750 100755 (executable)
@@ -25,7 +25,9 @@ for p in `cat ./patches/series`; do
 done
 
 find libmv -type f -not -iwholename '*.svn*' -exec rm -rf {} \;
-find third_party -type f -not -iwholename '*.svn*' -exec rm -rf {} \;
+find third_party -type f -not -iwholename '*.svn*' -not -iwholename '*third_party/ceres*' \
+    -not -iwholename '*third_party/SConscript*' -not -iwholename '*third_party/CMakeLists.txt*' \
+    -exec rm -rf {} \;
 
 cat "files.txt" | while read f; do
   mkdir -p `dirname $f`
@@ -39,14 +41,14 @@ chmod 664 ./third_party/glog/src/windows/*.cc ./third_party/glog/src/windows/*.h
 sources=`find ./libmv -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | sed -r 's/^\.\//\t/' | sort -d`
 headers=`find ./libmv -type f -iname '*.h' | sed -r 's/^\.\//\t/' | sort -d`
 
-third_sources=`find ./third_party -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | grep -v glog | sed -r 's/^\.\//\t/' | sort -d`
-third_headers=`find ./third_party -type f -iname '*.h' | grep -v glog | sed -r 's/^\.\//\t/' | sort -d`
+third_sources=`find ./third_party -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | grep -v glog | grep -v ceres | sed -r 's/^\.\//\t/' | sort -d`
+third_headers=`find ./third_party -type f -iname '*.h' | grep -v glog | grep -v ceres | sed -r 's/^\.\//\t/' | sort -d`
 
 third_glog_sources=`find ./third_party -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | grep glog | grep -v windows | sed -r 's/^\.\//\t\t/' | sort -d`
 third_glog_headers=`find ./third_party -type f -iname '*.h' | grep glog | grep -v windows | sed -r 's/^\.\//\t\t/' | sort -d`
 
 src_dir=`find ./libmv -type f -iname '*.cc' -exec dirname {} \; -or -iname '*.cpp' -exec dirname {} \; -or -iname '*.c' -exec dirname {} \; | sed -r 's/^\.\//\t/' | sort -d | uniq`
-src_third_dir=`find ./third_party -type f -iname '*.cc' -exec dirname {} \; -or -iname '*.cpp' -exec dirname {} \; -or -iname '*.c' -exec dirname {} \; | sed -r 's/^\.\//\t/'  | sort -d | uniq`
+src_third_dir=`find ./third_party -type f -iname '*.cc' -exec dirname {} \; -or -iname '*.cpp' -exec dirname {} \; -or -iname '*.c' -exec dirname {} \;  | grep -v ceres | sed -r 's/^\.\//\t/'  | sort -d | uniq`
 src=""
 win_src=""
 for x in $src_dir $src_third_dir; do
@@ -126,6 +128,7 @@ set(INC
        third_party/ssba
        third_party/ldl/Include
        ../colamd/Include
+       third_party/ceres/include
 )
 
 set(INC_SYS
@@ -220,6 +223,8 @@ add_definitions(
 )
 
 blender_add_lib(extern_libmv "\${SRC}" "\${INC}" "\${INC_SYS}")
+
+add_subdirectory(third_party)
 EOF
 
 cat > SConscript << EOF
@@ -246,7 +251,7 @@ defs.append('GOOGLE_GLOG_DLL_DECL=')
 src = env.Glob("*.cpp")
 $src
 
-incs = '. ../Eigen3'
+incs = '. ../Eigen3 third_party/ceres/include'
 incs += ' ' + env['BF_PNG_INC']
 incs += ' ' + env['BF_ZLIB_INC']
 
@@ -281,4 +286,6 @@ else:
 incs += ' ./third_party/ssba ./third_party/ldl/Include ../colamd/Include'
 
 env.BlenderLib ( libname = 'extern_libmv', sources=src, includes=Split(incs), defines=defs, libtype=['extern', 'player'], priority=[20,137], compileflags=cflags_libmv, cc_compileflags=ccflags_libmv, cxx_compileflags=cxxflags_libmv )
+
+SConscript(['third_party/SConscript'])
 EOF
index 6c20d76..eba4698 100644 (file)
    tracking between which failed */
 #undef DUMP_FAILURE
 
+/* define this to generate PNG images with content of search areas
+   on every itteration of tracking */
+#undef DUMP_ALWAYS
+
 #include "libmv-capi.h"
 
 #include "third_party/gflags/gflags/gflags.h"
@@ -45,6 +49,7 @@
 #include "libmv/tracking/trklt_region_tracker.h"
 #include "libmv/tracking/lmicklt_region_tracker.h"
 #include "libmv/tracking/pyramid_region_tracker.h"
+#include "libmv/tracking/track_region.h"
 
 #include "libmv/simple_pipeline/callbacks.h"
 #include "libmv/simple_pipeline/tracks.h"
@@ -59,7 +64,7 @@
 #include <stdlib.h>
 #include <assert.h>
 
-#ifdef DUMP_FAILURE
+#if defined(DUMP_FAILURE) || defined (DUMP_ALWAYS)
 #  include <png.h>
 #endif
 
@@ -97,7 +102,7 @@ void libmv_initLogging(const char *argv0)
 void libmv_startDebugLogging(void)
 {
        google::SetCommandLineOption("logtostderr", "1");
-       google::SetCommandLineOption("v", "0");
+       google::SetCommandLineOption("v", "2");
        google::SetCommandLineOption("stderrthreshold", "1");
        google::SetCommandLineOption("minloglevel", "0");
        V3D::optimizerVerbosenessLevel = 1;
@@ -171,7 +176,7 @@ static void floatBufToImage(const float *buf, int width, int height, libmv::Floa
        }
 }
 
-#ifdef DUMP_FAILURE
+#if defined(DUMP_FAILURE) || defined (DUMP_ALWAYS)
 void savePNGImage(png_bytep *row_pointers, int width, int height, int depth, int color_type, char *file_name)
 {
        png_infop info_ptr;
@@ -234,14 +239,14 @@ static void saveImage(char *prefix, libmv::FloatImage image, int x0, int y0)
                row_pointers[y]= (png_bytep)malloc(sizeof(png_byte)*4*image.Width());
 
                for (x = 0; x < image.Width(); x++) {
-                       if (x0 == x && y0 == y) {
+                       if (x0 == x && image.Height() - y0 - 1 == y) {
                                row_pointers[y][x*4+0]= 255;
                                row_pointers[y][x*4+1]= 0;
                                row_pointers[y][x*4+2]= 0;
                                row_pointers[y][x*4+3]= 255;
                        }
                        else {
-                               float pixel = image(y, x, 0);
+                               float pixel = image(image.Height() - y - 1, x, 0);
                                row_pointers[y][x*4+0]= pixel*255;
                                row_pointers[y][x*4+1]= pixel*255;
                                row_pointers[y][x*4+2]= pixel*255;
@@ -305,16 +310,20 @@ int libmv_regionTrackerTrack(libmv_RegionTracker *libmv_tracker, const float *im
        floatBufToImage(ima1, width, height, &old_patch);
        floatBufToImage(ima2, width, height, &new_patch);
 
-#ifndef DUMP_FAILURE
+#if !defined(DUMP_FAILURE) && !defined(DUMP_ALWAYS)
        return region_tracker->Track(old_patch, new_patch, x1, y1, x2, y2);
 #else
        {
-               double sx2 = *x2, sy2 = *y2;
+               /* double sx2 = *x2, sy2 = *y2; */
                int result = region_tracker->Track(old_patch, new_patch, x1, y1, x2, y2);
 
+#if defined(DUMP_ALWAYS)
+               {
+#else
                if (!result) {
+#endif
                        saveImage("old_patch", old_patch, x1, y1);
-                       saveImage("new_patch", new_patch, sx2, sy2);
+                       saveImage("new_patch", new_patch, *x2, *y2);
                }
 
                return result;
@@ -329,6 +338,88 @@ void libmv_regionTrackerDestroy(libmv_RegionTracker *libmv_tracker)
        delete region_tracker;
 }
 
+/* ************ Planar tracker ************ */
+
+/* TrackRegion (new planar tracker) */
+int libmv_trackRegion(const struct libmv_trackRegionOptions *options,
+                      const float *image1, const float *image2,
+                      int width, int height, 
+                      const double *x1, const double *y1,
+                      struct libmv_trackRegionResult *result,
+                      double *x2, double *y2)
+{
+       double xx1[5], yy1[5];
+       double xx2[5], yy2[5];
+       bool tracking_result = false;
+
+       /* Convert to doubles for the libmv api. The four corners and the center. */
+       for (int i = 0; i < 5; ++i) {
+               xx1[i] = x1[i];
+               yy1[i] = y1[i];
+               xx2[i] = x2[i];
+               yy2[i] = y2[i];
+       }
+
+       libmv::TrackRegionOptions track_region_options;
+       switch (options->motion_model) {
+#define LIBMV_CONVERT(the_model) \
+    case libmv::TrackRegionOptions::the_model: \
+               track_region_options.mode = libmv::TrackRegionOptions::the_model; \
+               break;
+               LIBMV_CONVERT(TRANSLATION)
+               LIBMV_CONVERT(TRANSLATION_ROTATION)
+               LIBMV_CONVERT(TRANSLATION_SCALE)
+               LIBMV_CONVERT(TRANSLATION_ROTATION_SCALE)
+               LIBMV_CONVERT(AFFINE)
+               LIBMV_CONVERT(HOMOGRAPHY)
+#undef LIBMV_CONVERT
+       }
+
+       track_region_options.minimum_correlation = options->minimum_correlation;
+       track_region_options.max_iterations = options->num_iterations;
+       track_region_options.sigma = options->sigma;
+       track_region_options.num_extra_points = 1;
+       track_region_options.image1_mask = NULL;
+       track_region_options.use_brute_initialization = options->use_brute;
+       track_region_options.use_normalized_intensities = options->use_normalization;
+
+       /* Convert from raw float buffers to libmv's FloatImage. */
+       libmv::FloatImage old_patch, new_patch;
+       floatBufToImage(image1, width, height, &old_patch);
+       floatBufToImage(image2, width, height, &new_patch);
+
+       libmv::TrackRegionResult track_region_result;
+       libmv::TrackRegion(old_patch, new_patch, xx1, yy1, track_region_options, xx2, yy2, &track_region_result);
+
+       /* Convert to floats for the blender api. */
+       for (int i = 0; i < 5; ++i) {
+               x2[i] = xx2[i];
+               y2[i] = yy2[i];
+       }
+
+       /* TODO(keir): Update the termination string with failure details. */
+       if (track_region_result.termination == libmv::TrackRegionResult::PARAMETER_TOLERANCE ||
+           track_region_result.termination == libmv::TrackRegionResult::FUNCTION_TOLERANCE  ||
+           track_region_result.termination == libmv::TrackRegionResult::GRADIENT_TOLERANCE  ||
+           track_region_result.termination == libmv::TrackRegionResult::NO_CONVERGENCE)
+       {
+               tracking_result = true;
+       }
+
+#if defined(DUMP_FAILURE) || defined(DUMP_ALWAYS)
+#if defined(DUMP_ALWAYS)
+       {
+#else
+       if (!tracking_result) {
+#endif
+               saveImage("old_patch", old_patch, x1[4], y1[4]);
+               saveImage("new_patch", new_patch, x2[4], y2[4]);
+       }
+#endif
+
+       return tracking_result;
+}
+
 /* ************ Tracks ************ */
 
 libmv_Tracks *libmv_tracksNew(void)
index bccc470..bbd8f0c 100644 (file)
@@ -50,6 +50,27 @@ int libmv_regionTrackerTrack(struct libmv_RegionTracker *libmv_tracker, const fl
                        int width, int height, double  x1, double  y1, double *x2, double *y2);
 void libmv_regionTrackerDestroy(struct libmv_RegionTracker *libmv_tracker);
 
+/* TrackRegion (new planar tracker) */
+struct libmv_trackRegionOptions {
+  int motion_model;
+  int num_iterations;
+  int use_brute;
+  int use_normalization;
+  double minimum_correlation;
+  double sigma;
+};
+struct libmv_trackRegionResult {
+  int termination;
+  const char *termination_reason;
+  double correlation;
+};
+int libmv_trackRegion(const struct libmv_trackRegionOptions *options,
+                      const float *image1, const float *image2,
+                      int width, int height, 
+                      const double *x1, const double *y1,
+                      struct libmv_trackRegionResult *result,
+                      double *x2, double *y2);
+
 /* Tracks */
 struct libmv_Tracks *libmv_tracksNew(void);
 void libmv_tracksInsert(struct libmv_Tracks *libmv_tracks, int image, int track, double x, double y);
diff --git a/extern/libmv/libmv/multiview/homography.cc b/extern/libmv/libmv/multiview/homography.cc
new file mode 100644 (file)
index 0000000..366392f
--- /dev/null
@@ -0,0 +1,267 @@
+// Copyright (c) 2008, 2009 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#include "libmv/logging/logging.h"
+#include "libmv/multiview/homography.h"
+#include "libmv/multiview/homography_parameterization.h"
+
+namespace libmv {
+/** 2D Homography transformation estimation in the case that points are in 
+ * euclidean coordinates.
+ *
+ * x = H y
+ * x and y vector must have the same direction, we could write
+ * crossproduct(|x|, * H * |y| ) = |0|
+ *
+ * | 0 -1  x2|   |a b c|   |y1|    |0|
+ * | 1  0 -x1| * |d e f| * |y2| =  |0|
+ * |-x2  x1 0|   |g h 1|   |1 |    |0|
+ *
+ * That gives :
+ *
+ * (-d+x2*g)*y1    + (-e+x2*h)*y2 + -f+x2          |0|
+ * (a-x1*g)*y1     + (b-x1*h)*y2  + c-x1         = |0|
+ * (-x2*a+x1*d)*y1 + (-x2*b+x1*e)*y2 + -x2*c+x1*f  |0|
+ */
+bool Homography2DFromCorrespondencesLinearEuc(
+    const Mat &x1,
+    const Mat &x2,
+    Mat3 *H,
+    double expected_precision) {
+  assert(2 == x1.rows());
+  assert(4 <= x1.cols());
+  assert(x1.rows() == x2.rows());
+  assert(x1.cols() == x2.cols());
+
+  int n = x1.cols();
+  MatX8 L = Mat::Zero(n * 3, 8);
+  Mat b = Mat::Zero(n * 3, 1);
+  for (int i = 0; i < n; ++i) {
+    int j = 3 * i;
+    L(j, 0) =  x1(0, i);            // a
+    L(j, 1) =  x1(1, i);            // b
+    L(j, 2) =  1.0;                 // c
+    L(j, 6) = -x2(0, i) * x1(0, i); // g
+    L(j, 7) = -x2(0, i) * x1(1, i); // h
+    b(j, 0) =  x2(0, i);            // i
+
+    ++j;
+    L(j, 3) =  x1(0, i);            // d
+    L(j, 4) =  x1(1, i);            // e
+    L(j, 5) =  1.0;                 // f
+    L(j, 6) = -x2(1, i) * x1(0, i); // g
+    L(j, 7) = -x2(1, i) * x1(1, i); // h
+    b(j, 0) =  x2(1, i);            // i
+    
+    // This ensures better stability
+    // TODO(julien) make a lite version without this 3rd set
+    ++j;
+    L(j, 0) =  x2(1, i) * x1(0, i); // a
+    L(j, 1) =  x2(1, i) * x1(1, i); // b
+    L(j, 2) =  x2(1, i);            // c
+    L(j, 3) = -x2(0, i) * x1(0, i); // d
+    L(j, 4) = -x2(0, i) * x1(1, i); // e
+    L(j, 5) = -x2(0, i) ;           // f
+  }
+  // Solve Lx=B
+  Vec h = L.fullPivLu().solve(b);
+  Homography2DNormalizedParameterization<double>::To(h, H);
+  if ((L * h).isApprox(b, expected_precision))  {
+    return true;
+  } else {
+    return false;
+  }
+}
+
+/** 2D Homography transformation estimation in the case that points are in 
+ * homogeneous coordinates.
+ *
+ * | 0 -x3  x2|   |a b c|   |y1|   -x3*d+x2*g -x3*e+x2*h -x3*f+x2*1    |y1|   (-x3*d+x2*g)*y1 (-x3*e+x2*h)*y2 (-x3*f+x2*1)*y3   |0|
+ * | x3  0 -x1| * |d e f| * |y2| =  x3*a-x1*g  x3*b-x1*h  x3*c-x1*1  * |y2| =  (x3*a-x1*g)*y1  (x3*b-x1*h)*y2  (x3*c-x1*1)*y3 = |0|
+ * |-x2  x1  0|   |g h 1|   |y3|   -x2*a+x1*d -x2*b+x1*e -x2*c+x1*f    |y3|   (-x2*a+x1*d)*y1 (-x2*b+x1*e)*y2 (-x2*c+x1*f)*y3   |0|
+ * X = |a b c d e f g h|^t
+ */
+bool Homography2DFromCorrespondencesLinear(const Mat &x1,
+                                           const Mat &x2,
+                                           Mat3 *H,
+                                           double expected_precision) {
+  if (x1.rows() == 2) {
+    return Homography2DFromCorrespondencesLinearEuc(x1, x2, H, 
+                                                    expected_precision);
+  }
+  assert(3 == x1.rows());
+  assert(4 <= x1.cols());
+  assert(x1.rows() == x2.rows());
+  assert(x1.cols() == x2.cols());
+
+  const int x = 0;
+  const int y = 1;
+  const int w = 2;
+  int n = x1.cols();
+  MatX8 L = Mat::Zero(n * 3, 8);
+  Mat b = Mat::Zero(n * 3, 1);
+  for (int i = 0; i < n; ++i) {
+    int j = 3 * i;
+    L(j, 0) =  x2(w, i) * x1(x, i);//a
+    L(j, 1) =  x2(w, i) * x1(y, i);//b
+    L(j, 2) =  x2(w, i) * x1(w, i);//c
+    L(j, 6) = -x2(x, i) * x1(x, i);//g
+    L(j, 7) = -x2(x, i) * x1(y, i);//h
+    b(j, 0) =  x2(x, i) * x1(w, i);
+
+    ++j;
+    L(j, 3) =  x2(w, i) * x1(x, i);//d
+    L(j, 4) =  x2(w, i) * x1(y, i);//e
+    L(j, 5) =  x2(w, i) * x1(w, i);//f
+    L(j, 6) = -x2(y, i) * x1(x, i);//g
+    L(j, 7) = -x2(y, i) * x1(y, i);//h
+    b(j, 0) =  x2(y, i) * x1(w, i);
+
+    // This ensures better stability
+    ++j;
+    L(j, 0) =  x2(y, i) * x1(x, i);//a
+    L(j, 1) =  x2(y, i) * x1(y, i);//b
+    L(j, 2) =  x2(y, i) * x1(w, i);//c
+    L(j, 3) = -x2(x, i) * x1(x, i);//d
+    L(j, 4) = -x2(x, i) * x1(y, i);//e
+    L(j, 5) = -x2(x, i) * x1(w, i);//f
+  }
+  // Solve Lx=B
+  Vec h = L.fullPivLu().solve(b);
+  if ((L * h).isApprox(b, expected_precision))  {
+    Homography2DNormalizedParameterization<double>::To(h, H);
+    return true;
+  } else {
+    return false;
+  }
+}
+/**
+ * x2 ~ A * x1
+ * x2^t * Hi * A *x1 = 0
+ * H1 =              H2 =               H3 = 
+ * | 0 0 0 1|     |-x2w|  |0 0 0 0|      |  0 |  | 0 0 1 0|     |-x2z|
+ * | 0 0 0 0|  -> |  0 |  |0 0 1 0|   -> |-x2z|  | 0 0 0 0|  -> |  0 |
+ * | 0 0 0 0|     |  0 |  |0-1 0 0|      | x2y|  |-1 0 0 0|     | x2x|
+ * |-1 0 0 0|     | x2x|  |0 0 0 0|      |  0 |  | 0 0 0 0|     |  0 |
+ * H4 =              H5 =               H6 = 
+ *  |0 0 0 0|     |  0 |  | 0 1 0 0|     |-x2y|   |0 0 0 0|     |  0 |
+ *  |0 0 0 1|  -> |-x2w|  |-1 0 0 0|  -> | x2x|   |0 0 0 0|  -> |  0 |
+ *  |0 0 0 0|     |  0 |  | 0 0 0 0|     |  0 |   |0 0 0 1|     |-x2w|
+ *  |0-1 0 0|     | x2y|  | 0 0 0 0|     |  0 |   |0 0-1 0|     | x2z|
+ *     |a b c d| 
+ * A = |e f g h| 
+ *     |i j k l|
+ *     |m n o 1| 
+ *     
+ * x2^t * H1 * A *x1 = (-x2w*a +x2x*m )*x1x + (-x2w*b +x2x*n )*x1y + (-x2w*c +x2x*o )*x1z + (-x2w*d +x2x*1 )*x1w = 0
+ * x2^t * H2 * A *x1 = (-x2z*e +x2y*i )*x1x + (-x2z*f +x2y*j )*x1y + (-x2z*g +x2y*k )*x1z + (-x2z*h +x2y*l )*x1w = 0
+ * x2^t * H3 * A *x1 = (-x2z*a +x2x*i )*x1x + (-x2z*b +x2x*j )*x1y + (-x2z*c +x2x*k )*x1z + (-x2z*d +x2x*l )*x1w = 0
+ * x2^t * H4 * A *x1 = (-x2w*e +x2y*m )*x1x + (-x2w*f +x2y*n )*x1y + (-x2w*g +x2y*o )*x1z + (-x2w*h +x2y*1 )*x1w = 0
+ * x2^t * H5 * A *x1 = (-x2y*a +x2x*e )*x1x + (-x2y*b +x2x*f )*x1y + (-x2y*c +x2x*g )*x1z + (-x2y*d +x2x*h )*x1w = 0
+ * x2^t * H6 * A *x1 = (-x2w*i +x2z*m )*x1x + (-x2w*j +x2z*n )*x1y + (-x2w*k +x2z*o )*x1z + (-x2w*l +x2z*1 )*x1w = 0
+ *
+ * X = |a b c d e f g h i j k l m n o|^t
+*/
+bool Homography3DFromCorrespondencesLinear(const Mat &x1,
+                                           const Mat &x2,
+                                           Mat4 *H,
+                                           double expected_precision) {
+  assert(4 == x1.rows());
+  assert(5 <= x1.cols());
+  assert(x1.rows() == x2.rows());
+  assert(x1.cols() == x2.cols());
+  const int x = 0;
+  const int y = 1;
+  const int z = 2;
+  const int w = 3;
+  int n = x1.cols();
+  MatX15 L = Mat::Zero(n * 6, 15);
+  Mat b = Mat::Zero(n * 6, 1);
+  for (int i = 0; i < n; ++i) {
+    int j = 6 * i;
+    L(j, 0) = -x2(w, i) * x1(x, i);//a
+    L(j, 1) = -x2(w, i) * x1(y, i);//b
+    L(j, 2) = -x2(w, i) * x1(z, i);//c
+    L(j, 3) = -x2(w, i) * x1(w, i);//d
+    L(j,12) =  x2(x, i) * x1(x, i);//m
+    L(j,13) =  x2(x, i) * x1(y, i);//n
+    L(j,14) =  x2(x, i) * x1(z, i);//o
+    b(j, 0) = -x2(x, i) * x1(w, i);
+    
+    ++j;
+    L(j, 4) = -x2(z, i) * x1(x, i);//e
+    L(j, 5) = -x2(z, i) * x1(y, i);//f
+    L(j, 6) = -x2(z, i) * x1(z, i);//g
+    L(j, 7) = -x2(z, i) * x1(w, i);//h
+    L(j, 8) =  x2(y, i) * x1(x, i);//i
+    L(j, 9) =  x2(y, i) * x1(y, i);//j
+    L(j,10) =  x2(y, i) * x1(z, i);//k
+    L(j,11) =  x2(y, i) * x1(w, i);//l
+    
+    ++j;
+    L(j, 0) = -x2(z, i) * x1(x, i);//a
+    L(j, 1) = -x2(z, i) * x1(y, i);//b
+    L(j, 2) = -x2(z, i) * x1(z, i);//c
+    L(j, 3) = -x2(z, i) * x1(w, i);//d
+    L(j, 8) =  x2(x, i) * x1(x, i);//i
+    L(j, 9) =  x2(x, i) * x1(y, i);//j
+    L(j,10) =  x2(x, i) * x1(z, i);//k
+    L(j,11) =  x2(x, i) * x1(w, i);//l
+    
+    ++j;
+    L(j, 4) = -x2(w, i) * x1(x, i);//e
+    L(j, 5) = -x2(w, i) * x1(y, i);//f
+    L(j, 6) = -x2(w, i) * x1(z, i);//g
+    L(j, 7) = -x2(w, i) * x1(w, i);//h
+    L(j,12) =  x2(y, i) * x1(x, i);//m
+    L(j,13) =  x2(y, i) * x1(y, i);//n
+    L(j,14) =  x2(y, i) * x1(z, i);//o
+    b(j, 0) = -x2(y, i) * x1(w, i);
+    
+    ++j;
+    L(j, 0) = -x2(y, i) * x1(x, i);//a
+    L(j, 1) = -x2(y, i) * x1(y, i);//b
+    L(j, 2) = -x2(y, i) * x1(z, i);//c
+    L(j, 3) = -x2(y, i) * x1(w, i);//d
+    L(j, 4) =  x2(x, i) * x1(x, i);//e
+    L(j, 5) =  x2(x, i) * x1(y, i);//f
+    L(j, 6) =  x2(x, i) * x1(z, i);//g
+    L(j, 7) =  x2(x, i) * x1(w, i);//h
+    
+    ++j;
+    L(j, 8) = -x2(w, i) * x1(x, i);//i
+    L(j, 9) = -x2(w, i) * x1(y, i);//j
+    L(j,10) = -x2(w, i) * x1(z, i);//k
+    L(j,11) = -x2(w, i) * x1(w, i);//l
+    L(j,12) =  x2(z, i) * x1(x, i);//m
+    L(j,13) =  x2(z, i) * x1(y, i);//n
+    L(j,14) =  x2(z, i) * x1(z, i);//o
+    b(j, 0) = -x2(z, i) * x1(w, i);
+  }
+  // Solve Lx=B
+  Vec h = L.fullPivLu().solve(b);
+  if ((L * h).isApprox(b, expected_precision))  {
+    Homography3DNormalizedParameterization<double>::To(h, H);
+    return true;
+  } else {
+    return false;
+  }
+}
+}  // namespace libmv
diff --git a/extern/libmv/libmv/multiview/homography.h b/extern/libmv/libmv/multiview/homography.h
new file mode 100644 (file)
index 0000000..786fd3d
--- /dev/null
@@ -0,0 +1,84 @@
+// Copyright (c) 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_MULTIVIEW_HOMOGRAPHY_H_
+#define LIBMV_MULTIVIEW_HOMOGRAPHY_H_
+
+#include "libmv/numeric/numeric.h"
+
+namespace libmv {
+
+/**
+ * 2D homography transformation estimation.
+ * 
+ * This function estimates the homography transformation from a list of 2D
+ * correspondences which represents either:
+ *
+ * - 3D points on a plane, with a general moving camera.
+ * - 3D points with a rotating camera (pure rotation).
+ * - 3D points + different planar projections
+ * 
+ * \param x1 The first 2xN or 3xN matrix of euclidean or homogeneous points.
+ * \param x2 The second 2xN or 3xN matrix of euclidean or homogeneous points.
+ * \param  H The 3x3 homography transformation matrix (8 dof) such that
+ *               x2 = H * x1   with       |a b c| 
+ *                                    H = |d e f|
+ *                                        |g h 1| 
+ * \param expected_precision The expected precision in order for instance 
+ *                           to accept almost homography matrices.
+ *
+ * \return True if the transformation estimation has succeeded.
+ * \note There must be at least 4 non-colinear points.
+ */
+bool Homography2DFromCorrespondencesLinear(const Mat &x1,
+                                           const Mat &x2,
+                                           Mat3 *H,
+                                           double expected_precision = 
+                                             EigenDouble::dummy_precision());
+
+/**
+ * 3D Homography transformation estimation.
+ * 
+ * This function can be used in order to estimate the homography transformation
+ * from a list of 3D correspondences.
+ *
+ * \param[in] x1 The first 4xN matrix of homogeneous points
+ * \param[in] x2 The second 4xN matrix of homogeneous points
+ * \param[out] H The 4x4 homography transformation matrix (15 dof) such that
+ *               x2 = H * x1   with       |a b c d| 
+ *                                    H = |e f g h|
+ *                                        |i j k l|
+ *                                        |m n o 1| 
+ * \param[in] expected_precision The expected precision in order for instance 
+ *        to accept almost homography matrices.
+ * 
+ * \return true if the transformation estimation has succeeded
+ * 
+ * \note Need at least 5 non coplanar points 
+ * \note Points coordinates must be in homogeneous coordinates
+ */
+bool Homography3DFromCorrespondencesLinear(const Mat &x1,
+                                           const Mat &x2,
+                                           Mat4 *H,
+                                           double expected_precision = 
+                                             EigenDouble::dummy_precision());
+} // namespace libmv
+
+#endif  // LIBMV_MULTIVIEW_HOMOGRAPHY_H_
diff --git a/extern/libmv/libmv/multiview/homography_parameterization.h b/extern/libmv/libmv/multiview/homography_parameterization.h
new file mode 100644 (file)
index 0000000..b31642e
--- /dev/null
@@ -0,0 +1,91 @@
+// Copyright (c) 2011 libmv authors.
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+// 
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_MULTIVIEW_HOMOGRAPHY_PARAMETERIZATION_H_
+#define LIBMV_MULTIVIEW_HOMOGRAPHY_PARAMETERIZATION_H_
+
+#include "libmv/numeric/numeric.h"
+
+namespace libmv {
+
+/** A parameterization of the 2D homography matrix that uses 8 parameters so 
+ * that the matrix is normalized (H(2,2) == 1).
+ * The homography matrix H is built from a list of 8 parameters (a, b,...g, h)
+ * as follows
+ *         |a b c| 
+ *     H = |d e f|
+ *         |g h 1| 
+ */
+template<typename T = double>
+class Homography2DNormalizedParameterization {
+ public:
+  typedef Eigen::Matrix<T, 8, 1> Parameters;     // a, b, ... g, h
+  typedef Eigen::Matrix<T, 3, 3> Parameterized;  // H
+
+  /// Convert from the 8 parameters to a H matrix.
+  static void To(const Parameters &p, Parameterized *h) {    
+    *h << p(0), p(1), p(2),
+          p(3), p(4), p(5),
+          p(6), p(7), 1.0;
+  }
+
+  /// Convert from a H matrix to the 8 parameters.
+  static void From(const Parameterized &h, Parameters *p) {
+    *p << h(0, 0), h(0, 1), h(0, 2),
+          h(1, 0), h(1, 1), h(1, 2),
+          h(2, 0), h(2, 1);
+  }
+};
+
+/** A parameterization of the 2D homography matrix that uses 15 parameters so 
+ * that the matrix is normalized (H(3,3) == 1).
+ * The homography matrix H is built from a list of 15 parameters (a, b,...n, o)
+ * as follows
+ *          |a b c d| 
+ *      H = |e f g h|
+ *          |i j k l|
+ *          |m n o 1| 
+ */
+template<typename T = double>
+class Homography3DNormalizedParameterization {
+ public:
+  typedef Eigen::Matrix<T, 15, 1> Parameters;     // a, b, ... n, o
+  typedef Eigen::Matrix<T, 4, 4>  Parameterized;  // H
+
+  /// Convert from the 15 parameters to a H matrix.
+  static void To(const Parameters &p, Parameterized *h) {   
+    *h << p(0), p(1), p(2), p(3),
+          p(4), p(5), p(6), p(7),
+          p(8), p(9), p(10), p(11),
+          p(12), p(13), p(14), 1.0;
+  }
+
+  /// Convert from a H matrix to the 15 parameters.
+  static void From(const Parameterized &h, Parameters *p) {
+    *p << h(0, 0), h(0, 1), h(0, 2), h(0, 3),
+          h(1, 0), h(1, 1), h(1, 2), h(1, 3),
+          h(2, 0), h(2, 1), h(2, 2), h(2, 3),
+          h(3, 0), h(3, 1), h(3, 2);
+  }
+};
+
+} // namespace libmv
+
+#endif  // LIBMV_MULTIVIEW_HOMOGRAPHY_PARAMETERIZATION_H_
index 221fa4d..a8dc46d 100644 (file)
@@ -29,6 +29,7 @@
 #include "libmv/image/correlation.h"
 #include "libmv/image/sample.h"
 #include "libmv/numeric/numeric.h"
+#include "libmv/tracking/track_region.h"
 
 namespace libmv {
 
@@ -72,6 +73,44 @@ bool EsmRegionTracker::Track(const FloatImage &image1,
     return false;
   }
   
+  // XXX
+  // TODO(keir): Delete the block between the XXX's once the planar tracker is
+  // integrated into blender.
+  //
+  // For now, to test, replace the ESM tracker with the Ceres tracker in
+  // translation mode. In the future, this should get removed and alloed to
+  // co-exist, since Ceres is not as fast as the ESM implementation since it
+  // specializes for translation.
+  double xx1[4], yy1[4];
+  double xx2[4], yy2[4];
+  // Clockwise winding, starting from the "origin" (top-left).
+  xx1[0] = xx2[0] = x1 - half_window_size;
+  yy1[0] = yy2[0] = y1 - half_window_size;
+
+  xx1[1] = xx2[1] = x1 + half_window_size;
+  yy1[1] = yy2[1] = y1 - half_window_size;
+
+  xx1[2] = xx2[2] = x1 + half_window_size;
+  yy1[2] = yy2[2] = y1 + half_window_size;
+
+  xx1[3] = xx2[3] = x1 - half_window_size;
+  yy1[3] = yy2[3] = y1 + half_window_size;
+
+  TrackRegionOptions options;
+  options.mode = TrackRegionOptions::TRANSLATION;
+  options.max_iterations = 20;
+  options.sigma = sigma;
+  options.use_esm = true;
+  
+  TrackRegionResult result;
+  TrackRegion(image1, image2, xx1, yy1, options, xx2, yy2, &result);
+
+  *x2 = xx2[0] + half_window_size;
+  *y2 = yy2[0] + half_window_size;
+
+  return true;
+
+  // XXX
   int width = 2 * half_window_size + 1;
 
   // TODO(keir): Avoid recomputing gradients for e.g. the pyramid tracker.
diff --git a/extern/libmv/libmv/tracking/track_region.cc b/extern/libmv/libmv/tracking/track_region.cc
new file mode 100644 (file)
index 0000000..62cc432
--- /dev/null
@@ -0,0 +1,1245 @@
+// Copyright (c) 2012 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//
+// Author: mierle@google.com (Keir Mierle)
+//
+// TODO(keir): While this tracking code works rather well, it has some
+// outragous inefficiencies. There is probably a 5-10x speedup to be had if a
+// smart coder went through the TODO's and made the suggested performance
+// enhancements.
+
+// Necessary for M_E when building with MSVC.
+#define _USE_MATH_DEFINES
+
+#include "libmv/tracking/track_region.h"
+
+#include <Eigen/SVD>
+#include <Eigen/QR>
+#include <iostream>
+#include "ceres/ceres.h"
+#include "libmv/logging/logging.h"
+#include "libmv/image/image.h"
+#include "libmv/image/sample.h"
+#include "libmv/image/convolve.h"
+#include "libmv/multiview/homography.h"
+#include "libmv/numeric/numeric.h"
+
+namespace libmv {
+
+TrackRegionOptions::TrackRegionOptions()
+    : mode(TRANSLATION),
+      minimum_correlation(0),
+      max_iterations(20),
+      use_esm(true),
+      use_brute_initialization(true),
+      use_normalized_intensities(false),
+      sigma(0.9),
+      num_extra_points(0),
+      image1_mask(NULL) {
+}
+
+namespace {
+
+// TODO(keir): Consider adding padding.
+template<typename T>
+bool InBounds(const FloatImage &image,
+              const T &x,
+              const T &y) {
+  return 0.0 <= x && x < image.Width() &&
+         0.0 <= y && y < image.Height();
+}
+
+bool AllInBounds(const FloatImage &image,
+                 const double *x,
+                 const double *y) {
+  for (int i = 0; i < 4; ++i) {
+    if (!InBounds(image, x[i], y[i])) {
+      return false;
+    }
+  }
+  return true;
+}
+
+// Because C++03 doesn't support partial template specializations for
+// functions, but at the same time member function specializations are not
+// supported, the sample function must be inside a template-specialized class
+// with a non-templated static member.
+
+// The "AutoDiff::Sample()" function allows sampling an image at an x, y
+// position such that if x and y are jets, then the derivative information is
+// correctly propagated.
+
+// Empty default template.
+template<typename T>
+struct AutoDiff {
+  // Sample only the image when the coordinates are scalars.
+  static T Sample(const FloatImage &image_and_gradient,
+                  const T &x, const T &y) {
+    return SampleLinear(image_and_gradient, y, x, 0);
+  }
+
+  static void SetScalarPart(double scalar, T *value) {
+    *value = scalar;
+  }
+  static void ScaleDerivative(double scale_by, T *value) {
+    // For double, there is no derivative to scale.
+  }
+};
+
+// Sample the image and gradient when the coordinates are jets, applying the
+// jacobian appropriately to propagate the derivatives from the coordinates.
+template<typename T, int N>
+struct AutoDiff<ceres::Jet<T, N> > {
+  static ceres::Jet<T, N> Sample(const FloatImage &image_and_gradient,
+                                 const ceres::Jet<T, N> &x,
+                                 const ceres::Jet<T, N> &y) {
+    // Sample the image and its derivatives in x and y. One way to think of
+    // this is that the image is a scalar function with a single vector
+    // argument, xy, of dimension 2. Call this s(xy).
+    const T s    = SampleLinear(image_and_gradient, y.a, x.a, 0);
+    const T dsdx = SampleLinear(image_and_gradient, y.a, x.a, 1);
+    const T dsdy = SampleLinear(image_and_gradient, y.a, x.a, 2);
+
+    // However, xy is itself a function of another variable ("z"); xy(z) =
+    // [x(z), y(z)]^T. What this function needs to return is "s", but with the
+    // derivative with respect to z attached to the jet. So combine the
+    // derivative part of x and y's jets to form a Jacobian matrix between x, y
+    // and z (i.e. dxy/dz).
+    Eigen::Matrix<T, 2, N> dxydz;
+    dxydz.row(0) = x.v.transpose();
+    dxydz.row(1) = y.v.transpose();
+
+    // Now apply the chain rule to obtain ds/dz. Combine the derivative with
+    // the scalar part to obtain s with full derivative information.
+    ceres::Jet<T, N> jet_s;
+    jet_s.a = s;
+    jet_s.v = Matrix<T, 1, 2>(dsdx, dsdy) * dxydz;
+    return jet_s;
+  }
+
+  static void SetScalarPart(double scalar, ceres::Jet<T, N> *value) {
+    value->a = scalar;
+  }
+  static void ScaleDerivative(double scale_by, ceres::Jet<T, N> *value) {
+    value->v *= scale_by;
+  }
+};
+
+template<typename Warp>
+class BoundaryCheckingCallback : public ceres::IterationCallback {
+ public:
+  BoundaryCheckingCallback(const FloatImage& image2,
+                           const Warp &warp,
+                           const double *x1, const double *y1)
+      : image2_(image2), warp_(warp), x1_(x1), y1_(y1) {}
+
+  virtual ceres::CallbackReturnType operator()(
+      const ceres::IterationSummary& summary) {
+    // Warp the original 4 points with the current warp into image2.
+    double x2[4];
+    double y2[4];
+    for (int i = 0; i < 4; ++i) {
+      warp_.Forward(warp_.parameters, x1_[i], y1_[i], x2 + i, y2 + i);
+    }
+    // Enusre they are all in bounds.
+    if (!AllInBounds(image2_, x2, y2)) {
+      return ceres::SOLVER_ABORT;
+    }
+    return ceres::SOLVER_CONTINUE;
+  }
+
+ private:
+  const FloatImage &image2_;
+  const Warp &warp_;
+  const double *x1_;
+  const double *y1_;
+};
+
+template<typename Warp>
+class WarpCostFunctor {
+ public:
+  WarpCostFunctor(const TrackRegionOptions &options,
+                  const FloatImage &image_and_gradient1,
+                  const FloatImage &image_and_gradient2,
+                  const Mat3 &canonical_to_image1,
+                  int num_samples_x,
+                  int num_samples_y,
+                  const Warp &warp)
+      : options_(options),
+        image_and_gradient1_(image_and_gradient1),       
+        image_and_gradient2_(image_and_gradient2),       
+        canonical_to_image1_(canonical_to_image1),
+        num_samples_x_(num_samples_x),
+        num_samples_y_(num_samples_y),
+        warp_(warp) {}
+
+  template<typename T>
+  bool operator()(const T *warp_parameters, T *residuals) const {
+    for (int i = 0; i < Warp::NUM_PARAMETERS; ++i) {
+      VLOG(2) << "warp_parameters[" << i << "]: " << warp_parameters[i];
+    }
+
+    T src_mean = T(1.0);
+    T dst_mean = T(1.0);
+    if (options_.use_normalized_intensities) {
+      ComputeNormalizingCoefficients(warp_parameters,
+                                     &src_mean,
+                                     &dst_mean);
+    }
+
+    int cursor = 0;
+    for (int r = 0; r < num_samples_y_; ++r) {
+      for (int c = 0; c < num_samples_x_; ++c) {
+        // Compute the location of the source pixel (via homography).
+        Vec3 image1_position = canonical_to_image1_ * Vec3(c, r, 1);
+        image1_position /= image1_position(2);
+        
+        // Sample the mask early; if it's zero, this pixel has no effect. This
+        // allows early bailout from the expensive sampling that happens below.
+        double mask_value = 1.0;
+        if (options_.image1_mask != NULL) {
+          mask_value = AutoDiff<double>::Sample(*options_.image1_mask,
+                                                image1_position[0],
+                                                image1_position[1]);
+          if (mask_value == 0.0) {
+            residuals[cursor++] = T(0.0);
+            continue;
+          }
+        }
+
+        // Compute the location of the destination pixel.
+        T image2_position[2];
+        warp_.Forward(warp_parameters,
+                      T(image1_position[0]),
+                      T(image1_position[1]),
+                      &image2_position[0],
+                      &image2_position[1]);
+
+        // Sample the destination, propagating derivatives.
+        T dst_sample = AutoDiff<T>::Sample(image_and_gradient2_,
+                                           image2_position[0],
+                                           image2_position[1]);
+
+        // Sample the source. This is made complicated by ESM mode.
+        T src_sample;
+        if (options_.use_esm) {
+          // In ESM mode, the derivative of the source is also taken into
+          // account. This changes the linearization in a way that causes
+          // better convergence. Copy the derivative of the warp parameters
+          // onto the jets for the image1 position. This is the ESM hack.
+          T image1_position_x = image2_position[0];
+          T image1_position_y = image2_position[1];
+          AutoDiff<T>::SetScalarPart(image1_position[0], &image1_position_x);
+          AutoDiff<T>::SetScalarPart(image1_position[1], &image1_position_y);
+          src_sample = AutoDiff<T>::Sample(image_and_gradient1_,
+                                           image1_position_x,
+                                           image1_position_y);
+
+          // The jacobians for these should be averaged. Due to the subtraction
+          // below, flip the sign of the src derivative so that the effect
+          // after subtraction of the jets is that they are averaged.
+          AutoDiff<T>::ScaleDerivative(-0.5, &src_sample);
+          AutoDiff<T>::ScaleDerivative(0.5, &dst_sample);
+        } else {
+          // This is the traditional, forward-mode KLT solution.
+          src_sample = T(AutoDiff<double>::Sample(image_and_gradient1_,
+                                                  image1_position[0],
+                                                  image1_position[1]));
+        }
+
+        // Normalize the samples by the mean values of each signal. The typical
+        // light model assumes multiplicative intensity changes with changing
+        // light, so this is a reasonable choice. Note that dst_mean has
+        // derivative information attached thanks to autodiff.
+        if (options_.use_normalized_intensities) {
+          src_sample /= src_mean;
+          dst_sample /= dst_mean;
+        }
+
+        // The difference is the error.
+        T error = src_sample - dst_sample;
+
+        // Weight the error by the mask, if one is present.
+        if (options_.image1_mask != NULL) {
+          error *= T(AutoDiff<double>::Sample(*options_.image1_mask,
+                                              image1_position[0],
+                                              image1_position[1]));
+        }
+        residuals[cursor++] = error;
+      }
+    }
+    return true;
+  }
+
+  // For normalized matching, the average and 
+  template<typename T>
+  void ComputeNormalizingCoefficients(const T *warp_parameters,
+                                      T *src_mean,
+                                      T *dst_mean) const {
+
+    *src_mean = T(0.0);
+    *dst_mean = T(0.0);
+    double num_samples = 0.0;
+    for (int r = 0; r < num_samples_y_; ++r) {
+      for (int c = 0; c < num_samples_x_; ++c) {
+        // Compute the location of the source pixel (via homography).
+        Vec3 image1_position = canonical_to_image1_ * Vec3(c, r, 1);
+        image1_position /= image1_position(2);
+        
+        // Sample the mask early; if it's zero, this pixel has no effect. This
+        // allows early bailout from the expensive sampling that happens below.
+        double mask_value = 1.0;
+        if (options_.image1_mask != NULL) {
+          mask_value = AutoDiff<double>::Sample(*options_.image1_mask,
+                                                image1_position[0],
+                                                image1_position[1]);
+          if (mask_value == 0.0) {
+            continue;
+          }
+        }
+
+        // Compute the location of the destination pixel.
+        T image2_position[2];
+        warp_.Forward(warp_parameters,
+                      T(image1_position[0]),
+                      T(image1_position[1]),
+                      &image2_position[0],
+                      &image2_position[1]);
+
+
+        // Sample the destination, propagating derivatives.
+        // TODO(keir): This accumulation can, surprisingly, be done as a
+        // pre-pass by using integral images. This is complicated by the need
+        // to store the jets in the integral image, but it is possible.
+        T dst_sample = AutoDiff<T>::Sample(image_and_gradient2_,
+                                           image2_position[0],
+                                           image2_position[1]);
+
+        // Sample the source.
+        // TODO(keir): There is no reason to do this inside the loop;
+        // precompute this and reuse it.
+        T src_sample = T(AutoDiff<double>::Sample(image_and_gradient1_,
+                                                  image1_position[0],
+                                                  image1_position[1]));
+
+        // Weight the sample by the mask, if one is present.
+        if (options_.image1_mask != NULL) {
+          src_sample *= T(mask_value);
+          dst_sample *= T(mask_value);
+        }
+
+        *src_mean += src_sample;
+        *dst_mean += dst_sample;
+        num_samples += mask_value;
+      }
+    }
+    *src_mean /= T(num_samples);
+    *dst_mean /= T(num_samples);
+    LG << "Normalization for src:" << *src_mean;
+    LG << "Normalization for dst:" << *dst_mean;
+  }
+
+ // TODO(keir): Consider also computing the cost here.
+ double PearsonProductMomentCorrelationCoefficient(
+     const double *warp_parameters) const {
+   for (int i = 0; i < Warp::NUM_PARAMETERS; ++i) {
+     VLOG(2) << "Correlation warp_parameters[" << i << "]: "
+             << warp_parameters[i];
+   }
+
+   // The single-pass PMCC computation is somewhat numerically unstable, but
+   // it's sufficient for the tracker.
+   double sX = 0, sY = 0, sXX = 0, sYY = 0, sXY = 0;
+
+   // Due to masking, it's important to account for fractional samples.
+   // Samples with a 50% mask get counted as a half sample.
+   double num_samples = 0;
+
+   for (int r = 0; r < num_samples_y_; ++r) {
+     for (int c = 0; c < num_samples_x_; ++c) {
+        // Compute the location of the source pixel (via homography).
+        // TODO(keir): Cache these projections.
+        Vec3 image1_position = canonical_to_image1_ * Vec3(c, r, 1);
+        image1_position /= image1_position(2);
+        
+        // Compute the location of the destination pixel.
+        double image2_position[2];
+        warp_.Forward(warp_parameters,
+                      image1_position[0],
+                      image1_position[1],
+                      &image2_position[0],
+                      &image2_position[1]);
+
+        double x = AutoDiff<double>::Sample(image_and_gradient2_,
+                                            image2_position[0],
+                                            image2_position[1]);
+
+        double y = AutoDiff<double>::Sample(image_and_gradient1_,
+                                            image1_position[0],
+                                            image1_position[1]);
+
+        // Weight the signals by the mask, if one is present.
+        if (options_.image1_mask != NULL) {
+          double mask_value = AutoDiff<double>::Sample(*options_.image1_mask,
+                                                       image1_position[0],
+                                                       image1_position[1]);
+          x *= mask_value;
+          y *= mask_value;
+          num_samples += mask_value;
+        } else {
+          num_samples++;
+        }
+        sX += x;
+        sY += y;
+        sXX += x*x;
+        sYY += y*y;
+        sXY += x*y;
+      }
+    }
+    // Normalize.
+    sX /= num_samples;
+    sY /= num_samples;
+    sXX /= num_samples;
+    sYY /= num_samples;
+    sXY /= num_samples;
+
+    double var_x = sXX - sX*sX;
+    double var_y = sYY - sY*sY;
+    double covariance_xy = sXY - sX*sY;
+
+    double correlation = covariance_xy / sqrt(var_x * var_y);
+    LG << "Covariance xy: " << covariance_xy
+       << ", var 1: " << var_x << ", var 2: " << var_y
+       << ", correlation: " << correlation;
+    return correlation;
+  }
+
+ private:
+  const TrackRegionOptions &options_;
+  const FloatImage &image_and_gradient1_;
+  const FloatImage &image_and_gradient2_;
+  const Mat3 &canonical_to_image1_;
+  int num_samples_x_;
+  int num_samples_y_;
+  const Warp &warp_;
+};
+
+// Compute the warp from rectangular coordinates, where one corner is the
+// origin, and the opposite corner is at (num_samples_x, num_samples_y).
+Mat3 ComputeCanonicalHomography(const double *x1,
+                                const double *y1,
+                                int num_samples_x,
+                                int num_samples_y) {
+  Mat canonical(2, 4);
+  canonical << 0, num_samples_x, num_samples_x, 0,
+               0, 0,             num_samples_y, num_samples_y;
+
+  Mat xy1(2, 4);
+  xy1 << x1[0], x1[1], x1[2], x1[3],
+         y1[0], y1[1], y1[2], y1[3];
+
+  Mat3 H;
+  if (!Homography2DFromCorrespondencesLinear(canonical, xy1, &H, 1e-12)) {
+    LG << "Couldn't construct homography.";
+  }
+  return H;
+}
+
+class Quad {
+ public:
+  Quad(const double *x, const double *y) : x_(x), y_(y) {
+    // Compute the centroid and store it.
+    centroid_ = Vec2(0.0, 0.0);
+    for (int i = 0; i < 4; ++i) {
+      centroid_ += Vec2(x_[i], y_[i]);
+    }
+    centroid_ /= 4.0;
+  }
+
+  // The centroid of the four points representing the quad.
+  const Vec2& Centroid() const {
+    return centroid_;
+  }
+
+  // The average magnitude of the four points relative to the centroid.
+  double Scale() const {
+    double scale = 0.0;
+    for (int i = 0; i < 4; ++i) {
+      scale += (Vec2(x_[i], y_[i]) - Centroid()).norm();
+    }
+    return scale / 4.0;
+  }
+
+  Vec2 CornerRelativeToCentroid(int i) const {
+    return Vec2(x_[i], y_[i]) - centroid_;
+  }
+
+ private:
+  const double *x_;
+  const double *y_;
+  Vec2 centroid_;
+};
+
+struct TranslationWarp {
+  TranslationWarp(const double *x1, const double *y1,
+                  const double *x2, const double *y2) {
+    Vec2 t = Quad(x2, y2).Centroid() - Quad(x1, y1).Centroid();
+    parameters[0] = t[0];
+    parameters[1] = t[1];
+  }
+
+  template<typename T>
+  void Forward(const T *warp_parameters,
+               const T &x1, const T& y1, T *x2, T* y2) const {
+    *x2 = x1 + warp_parameters[0];
+    *y2 = y1 + warp_parameters[1];
+  }
+
+  // Translation x, translation y.
+  enum { NUM_PARAMETERS = 2 };
+  double parameters[NUM_PARAMETERS];
+};
+
+struct TranslationScaleWarp {
+  TranslationScaleWarp(const double *x1, const double *y1,
+                       const double *x2, const double *y2)
+      : q1(x1, y1) {
+    Quad q2(x2, y2);
+
+    // The difference in centroids is the best guess for translation.
+    Vec2 t = q2.Centroid() - q1.Centroid();
+    parameters[0] = t[0];
+    parameters[1] = t[1];
+
+    // The difference in scales is the estimate for the scale.
+    parameters[2] = 1.0 - q2.Scale() / q1.Scale();
+  }
+
+  // The strange way of parameterizing the translation and scaling is to make
+  // the knobs that the optimizer sees easy to adjust. This is less important
+  // for the scaling case than the rotation case.
+  template<typename T>
+  void Forward(const T *warp_parameters,
+               const T &x1, const T& y1, T *x2, T* y2) const {
+    // Make the centroid of Q1 the origin.
+    const T x1_origin = x1 - q1.Centroid()(0);
+    const T y1_origin = y1 - q1.Centroid()(1);
+
+    // Scale uniformly about the origin.
+    const T scale = 1.0 + warp_parameters[2];
+    const T x1_origin_scaled = scale * x1_origin;
+    const T y1_origin_scaled = scale * y1_origin;
+
+    // Translate back into the space of Q1 (but scaled).
+    const T x1_scaled = x1_origin_scaled + q1.Centroid()(0);
+    const T y1_scaled = y1_origin_scaled + q1.Centroid()(1);
+
+    // Translate into the space of Q2.
+    *x2 = x1_scaled + warp_parameters[0];
+    *y2 = y1_scaled + warp_parameters[1];
+  }
+
+  // Translation x, translation y, scale.
+  enum { NUM_PARAMETERS = 3 };
+  double parameters[NUM_PARAMETERS];
+
+  Quad q1;
+};
+
+// Assumes the given points are already zero-centroid and the same size.
+Mat2 OrthogonalProcrustes(const Mat2 &correlation_matrix) {
+  Eigen::JacobiSVD<Mat2> svd(correlation_matrix,
+                             Eigen::ComputeFullU | Eigen::ComputeFullV);
+  return svd.matrixV() * svd.matrixU().transpose();
+}
+
+struct TranslationRotationWarp {
+  TranslationRotationWarp(const double *x1, const double *y1,
+                          const double *x2, const double *y2)
+      : q1(x1, y1) {
+    Quad q2(x2, y2);
+
+    // The difference in centroids is the best guess for translation.
+    Vec2 t = q2.Centroid() - q1.Centroid();
+    parameters[0] = t[0];
+    parameters[1] = t[1];
+
+    // Obtain the rotation via orthorgonal procrustes.
+    Mat2 correlation_matrix;
+    for (int i = 0; i < 4; ++i) {
+      correlation_matrix += q1.CornerRelativeToCentroid(i) * 
+                            q2.CornerRelativeToCentroid(i).transpose();
+    }
+    Mat2 R = OrthogonalProcrustes(correlation_matrix);
+    parameters[2] = atan2(R(1, 0), R(0, 0));
+
+    LG << "Correlation_matrix:\n" << correlation_matrix;
+    LG << "R:\n" << R;
+    LG << "Theta:" << parameters[2];
+  }
+
+  // The strange way of parameterizing the translation and rotation is to make
+  // the knobs that the optimizer sees easy to adjust. The reason is that while
+  // it is always the case that it is possible to express composed rotations
+  // and translations as a single translation and rotation, the numerical
+  // values needed for the composition are often large in magnitude. This is
+  // enough to throw off any minimizer, since it must do the equivalent of
+  // compose rotations and translations.
+  //
+  // Instead, use the parameterization below that offers a parameterization
+  // that exposes the degrees of freedom in a way amenable to optimization.
+  template<typename T>
+  void Forward(const T *warp_parameters,
+                      const T &x1, const T& y1, T *x2, T* y2) const {
+    // Make the centroid of Q1 the origin.
+    const T x1_origin = x1 - q1.Centroid()(0);
+    const T y1_origin = y1 - q1.Centroid()(1);
+
+    // Rotate about the origin (i.e. centroid of Q1).
+    const T theta = warp_parameters[2];
+    const T costheta = cos(theta);
+    const T sintheta = sin(theta);
+    const T x1_origin_rotated = costheta * x1_origin - sintheta * y1_origin;
+    const T y1_origin_rotated = sintheta * x1_origin + costheta * y1_origin;
+
+    // Translate back into the space of Q1 (but scaled).
+    const T x1_rotated = x1_origin_rotated + q1.Centroid()(0);
+    const T y1_rotated = y1_origin_rotated + q1.Centroid()(1);
+
+    // Translate into the space of Q2.
+    *x2 = x1_rotated + warp_parameters[0];
+    *y2 = y1_rotated + warp_parameters[1];
+  }
+
+  // Translation x, translation y, rotation about the center of Q1 degrees.
+  enum { NUM_PARAMETERS = 3 };
+  double parameters[NUM_PARAMETERS];
+
+  Quad q1;
+};
+
+struct TranslationRotationScaleWarp {
+  TranslationRotationScaleWarp(const double *x1, const double *y1,
+                               const double *x2, const double *y2)
+      : q1(x1, y1) {
+    Quad q2(x2, y2);
+
+    // The difference in centroids is the best guess for translation.
+    Vec2 t = q2.Centroid() - q1.Centroid();
+    parameters[0] = t[0];
+    parameters[1] = t[1];
+
+    // The difference in scales is the estimate for the scale.
+    parameters[2] = 1.0 - q2.Scale() / q1.Scale();
+
+    // Obtain the rotation via orthorgonal procrustes.
+    Mat2 correlation_matrix;
+    for (int i = 0; i < 4; ++i) {
+      correlation_matrix += q1.CornerRelativeToCentroid(i) * 
+                            q2.CornerRelativeToCentroid(i).transpose();
+    }
+    Mat2 R = OrthogonalProcrustes(correlation_matrix);
+    parameters[3] = atan2(R(1, 0), R(0, 0));
+
+    LG << "Correlation_matrix:\n" << correlation_matrix;
+    LG << "R:\n" << R;
+    LG << "Theta:" << parameters[3];
+  }
+
+  // The strange way of parameterizing the translation and rotation is to make
+  // the knobs that the optimizer sees easy to adjust. The reason is that while
+  // it is always the case that it is possible to express composed rotations
+  // and translations as a single translation and rotation, the numerical
+  // values needed for the composition are often large in magnitude. This is
+  // enough to throw off any minimizer, since it must do the equivalent of
+  // compose rotations and translations.
+  //
+  // Instead, use the parameterization below that offers a parameterization
+  // that exposes the degrees of freedom in a way amenable to optimization.
+  template<typename T>
+  void Forward(const T *warp_parameters,
+                      const T &x1, const T& y1, T *x2, T* y2) const {
+    // Make the centroid of Q1 the origin.
+    const T x1_origin = x1 - q1.Centroid()(0);
+    const T y1_origin = y1 - q1.Centroid()(1);
+
+    // Rotate about the origin (i.e. centroid of Q1).
+    const T theta = warp_parameters[3];
+    const T costheta = cos(theta);
+    const T sintheta = sin(theta);
+    const T x1_origin_rotated = costheta * x1_origin - sintheta * y1_origin;
+    const T y1_origin_rotated = sintheta * x1_origin + costheta * y1_origin;
+
+    // Scale uniformly about the origin.
+    const T scale = 1.0 + warp_parameters[2];
+    const T x1_origin_rotated_scaled = scale * x1_origin_rotated;
+    const T y1_origin_rotated_scaled = scale * y1_origin_rotated;
+
+    // Translate back into the space of Q1 (but scaled and rotated).
+    const T x1_rotated_scaled = x1_origin_rotated_scaled + q1.Centroid()(0);
+    const T y1_rotated_scaled = y1_origin_rotated_scaled + q1.Centroid()(1);
+
+    // Translate into the space of Q2.
+    *x2 = x1_rotated_scaled + warp_parameters[0];
+    *y2 = y1_rotated_scaled + warp_parameters[1];
+  }
+
+  // Translation x, translation y, rotation about the center of Q1 degrees,
+  // scale.
+  enum { NUM_PARAMETERS = 4 };
+  double parameters[NUM_PARAMETERS];
+
+  Quad q1;
+};
+
+struct AffineWarp {
+  AffineWarp(const double *x1, const double *y1,
+             const double *x2, const double *y2)
+      : q1(x1, y1) {
+    Quad q2(x2, y2);
+
+    // The difference in centroids is the best guess for translation.
+    Vec2 t = q2.Centroid() - q1.Centroid();
+    parameters[0] = t[0];
+    parameters[1] = t[1];
+
+    // Estimate the four affine parameters with the usual least squares.
+    Mat Q1(8, 4);
+    Vec Q2(8);
+    for (int i = 0; i < 4; ++i) {
+      Vec2 v1 = q1.CornerRelativeToCentroid(i);
+      Vec2 v2 = q2.CornerRelativeToCentroid(i);
+
+      Q1.row(2 * i + 0) << v1[0], v1[1],   0,     0  ;
+      Q1.row(2 * i + 1) <<   0,     0,   v1[0], v1[1];
+
+      Q2(2 * i + 0) = v2[0];
+      Q2(2 * i + 1) = v2[1];
+    }
+
+    // TODO(keir): Check solution quality.
+    Vec4 a = Q1.jacobiSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(Q2);
+    parameters[2] = a[0];
+    parameters[3] = a[1];
+    parameters[4] = a[2];
+    parameters[5] = a[3];
+
+    LG << "a:" << a.transpose();
+    LG << "t:" << t.transpose();
+  }
+
+  // See comments in other parameterizations about why the centroid is used.
+  template<typename T>
+  void Forward(const T *p, const T &x1, const T& y1, T *x2, T* y2) const {
+    // Make the centroid of Q1 the origin.
+    const T x1_origin = x1 - q1.Centroid()(0);
+    const T y1_origin = y1 - q1.Centroid()(1);
+
+    // Apply the affine transformation.
+    const T x1_origin_affine = p[2] * x1_origin + p[3] * y1_origin;
+    const T y1_origin_affine = p[4] * x1_origin + p[5] * y1_origin;
+
+    // Translate back into the space of Q1 (but affine transformed).
+    const T x1_affine = x1_origin_affine + q1.Centroid()(0);
+    const T y1_affine = y1_origin_affine + q1.Centroid()(1);
+
+    // Translate into the space of Q2.
+    *x2 = x1_affine + p[0];
+    *y2 = y1_affine + p[1];
+  }
+
+  // Translation x, translation y, rotation about the center of Q1 degrees,
+  // scale.
+  enum { NUM_PARAMETERS = 6 };
+  double parameters[NUM_PARAMETERS];
+
+  Quad q1;
+};
+
+struct HomographyWarp {
+  HomographyWarp(const double *x1, const double *y1,
+                 const double *x2, const double *y2) {
+    Mat quad1(2, 4);
+    quad1 << x1[0], x1[1], x1[2], x1[3],
+             y1[0], y1[1], y1[2], y1[3];
+
+    Mat quad2(2, 4);
+    quad2 << x2[0], x2[1], x2[2], x2[3],
+             y2[0], y2[1], y2[2], y2[3];
+
+    Mat3 H;
+    if (!Homography2DFromCorrespondencesLinear(quad1, quad2, &H, 1e-12)) {
+      LG << "Couldn't construct homography.";
+    }
+
+    // Assume H(2, 2) != 0, and fix scale at H(2, 2) == 1.0.
+    H /= H(2, 2);
+
+    // Assume H is close to identity, so subtract out the diagonal.
+    H(0, 0) -= 1.0;
+    H(1, 1) -= 1.0;
+
+    CHECK_NE(H(2, 2), 0.0) << H;
+    for (int i = 0; i < 8; ++i) {
+      parameters[i] = H(i / 3, i % 3);
+      LG << "Parameters[" << i << "]: " << parameters[i];
+    }
+  }
+
+  template<typename T>
+  static void Forward(const T *p,
+                      const T &x1, const T& y1, T *x2, T* y2) {
+    // Homography warp with manual 3x3 matrix multiply.
+    const T xx2 = (1.0 + p[0]) * x1 +     p[1]     * y1 + p[2];
+    const T yy2 =     p[3]     * x1 + (1.0 + p[4]) * y1 + p[5];
+    const T zz2 =     p[6]     * x1 +     p[7]     * y1 + 1.0;
+    *x2 = xx2 / zz2;
+    *y2 = yy2 / zz2;
+  }
+
+  enum { NUM_PARAMETERS = 8 };
+  double parameters[NUM_PARAMETERS];
+};
+
+// Determine the number of samples to use for x and y. Quad winding goes:
+//
+//    0 1
+//    3 2
+//
+// The idea is to take the maximum x or y distance. This may be oversampling.
+// TODO(keir): Investigate the various choices; perhaps average is better?
+void PickSampling(const double *x1, const double *y1,
+                  const double *x2, const double *y2,
+                  int *num_samples_x, int *num_samples_y) {
+  Vec2 a0(x1[0], y1[0]);
+  Vec2 a1(x1[1], y1[1]);
+  Vec2 a2(x1[2], y1[2]);
+  Vec2 a3(x1[3], y1[3]);
+
+  Vec2 b0(x1[0], y1[0]);
+  Vec2 b1(x1[1], y1[1]);
+  Vec2 b2(x1[2], y1[2]);
+  Vec2 b3(x1[3], y1[3]);
+
+  double x_dimensions[4] = {
+    (a1 - a0).norm(),
+    (a3 - a2).norm(),
+    (b1 - b0).norm(),
+    (b3 - b2).norm()
+  };
+
+  double y_dimensions[4] = {
+    (a3 - a0).norm(),
+    (a1 - a2).norm(),
+    (b3 - b0).norm(),
+    (b1 - b2).norm()
+  };
+  const double kScaleFactor = 1.0;
+  *num_samples_x = static_cast<int>(
+      kScaleFactor * *std::max_element(x_dimensions, x_dimensions + 4));
+  *num_samples_y = static_cast<int>(
+      kScaleFactor * *std::max_element(y_dimensions, y_dimensions + 4));
+  LG << "Automatic num_samples_x: " << *num_samples_x
+     << ", num_samples_y: " << *num_samples_y;
+}
+
+bool SearchAreaTooBigForDescent(const FloatImage &image2,
+                                const double *x2, const double *y2) {
+  // TODO(keir): Check the bounds and enable only when it makes sense.
+  return true;
+}
+
+bool PointOnRightHalfPlane(const Vec2 &a, const Vec2 &b, double x, double y) {
+  Vec2 ba = b - a;
+  return ((Vec2(x, y) - b).transpose() * Vec2(-ba.y(), ba.x())) > 0;
+}
+
+// Determine if a point is in a quad. The quad is arranged as:
+//
+//    +-------> x
+//    |
+//    |  a0------a1
+//    |   |       |
+//    |   |       |
+//    |   |       |
+//    |  a3------a2
+//    v
+//    y
+//
+// The implementation does up to four half-plane comparisons.
+bool PointInQuad(const double *xs, const double *ys, double x, double y) {
+  Vec2 a0(xs[0], ys[0]);
+  Vec2 a1(xs[1], ys[1]);
+  Vec2 a2(xs[2], ys[2]);
+  Vec2 a3(xs[3], ys[3]);
+
+  return PointOnRightHalfPlane(a0, a1, x, y) &&
+         PointOnRightHalfPlane(a1, a2, x, y) &&
+         PointOnRightHalfPlane(a2, a3, x, y) &&
+         PointOnRightHalfPlane(a3, a0, x, y);
+}
+
+// This makes it possible to map between Eigen float arrays and FloatImage
+// without using comparisons.
+typedef Eigen::Array<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> FloatArray;
+
+// This creates a pattern in the frame of image2, from the pixel is image1,
+// based on the initial guess represented by the two quads x1, y1, and x2, y2.
+template<typename Warp>
+void CreateBrutePattern(const double *x1, const double *y1,
+                        const double *x2, const double *y2,
+                        const FloatImage &image1,
+                        const FloatImage *image1_mask,
+                        FloatArray *pattern,
+                        FloatArray *mask,
+                        int *origin_x,
+                        int *origin_y) {
+  // Get integer bounding box of quad2 in image2.
+  int min_x = static_cast<int>(floor(*std::min_element(x2, x2 + 4)));
+  int min_y = static_cast<int>(floor(*std::min_element(y2, y2 + 4)));
+  int max_x = static_cast<int>(ceil (*std::max_element(x2, x2 + 4)));
+  int max_y = static_cast<int>(ceil (*std::max_element(y2, y2 + 4)));
+
+  int w = max_x - min_x;
+  int h = max_y - min_y;
+
+  pattern->resize(h, w);
+  mask->resize(h, w);
+
+  Warp inverse_warp(x2, y2, x1, y1);
+
+  // r,c are in the coordinate frame of image2.
+  for (int r = min_y; r < max_y; ++r) {
+    for (int c = min_x; c < max_x; ++c) {
+      // i and j are in the coordinate frame of the pattern in image2.
+      int i = r - min_y;
+      int j = c - min_x;
+
+      double dst_x = c;
+      double dst_y = r;
+      double src_x;
+      double src_y;
+      inverse_warp.Forward(inverse_warp.parameters,
+                           dst_x, dst_y,
+                           &src_x, &src_y);
+      
+      if (PointInQuad(x1, y1, src_x, src_y)) {
+        (*pattern)(i, j) = SampleLinear(image1, src_y, src_x);
+        (*mask)(i, j) = 1.0;
+        if (image1_mask) {
+          (*mask)(i, j) = SampleLinear(*image1_mask, src_y, src_x);;
+        }
+      } else {
+        (*pattern)(i, j) = 0.0;
+        (*mask)(i, j) = 0.0;
+      }
+    }
+  }
+  *origin_x = min_x;
+  *origin_y = min_y;
+}
+
+// Compute a translation-only estimate of the warp, using brute force search. A
+// smarter implementation would use the FFT to compute the normalized cross
+// correlation. Instead, this is a dumb implementation. Surprisingly, it is
+// fast enough in practice.
+//
+// TODO(keir): The normalization is less effective for the brute force search
+// than it is with the Ceres solver. It's unclear if this is a bug or due to
+// the original frame being too different from the reprojected reference in the
+// destination frame.
+//
+// The likely solution is to use the previous frame, instead of the original
+// pattern, when doing brute initialization. Unfortunately that implies a
+// totally different warping interface, since access to more than a the source
+// and current destination frame is necessary.
+template<typename Warp>
+void BruteTranslationOnlyInitialize(const FloatImage &image1,
+                                    const FloatImage *image1_mask,
+                                    const FloatImage &image2,
+                                    const int num_extra_points,
+                                    const bool use_normalized_intensities,
+                                    const double *x1, const double *y1,
+                                    double *x2, double *y2) {
+  // Create the pattern to match in the space of image2, assuming our inital
+  // guess isn't too far from the template in image1. If there is no image1
+  // mask, then the resulting mask is binary.
+  FloatArray pattern;
+  FloatArray mask;
+  int origin_x = -1, origin_y = -1;
+  CreateBrutePattern<Warp>(x1, y1, x2, y2,
+                           image1, image1_mask,
+                           &pattern, &mask,
+                           &origin_x, &origin_y);
+
+  // For normalization, premultiply the pattern by the inverse pattern mean.
+  double mask_sum = 1.0;
+  if (use_normalized_intensities) {
+    mask_sum = mask.sum();
+    double inverse_pattern_mean = mask_sum / ((mask * pattern).sum());
+    pattern *= inverse_pattern_mean;
+  }
+
+  // Use Eigen on the images via maps for strong vectorization.
+  Map<const FloatArray> search(image2.Data(), image2.Height(), image2.Width());
+
+  // Try all possible locations inside the search area. Yes, everywhere.
+  //
+  // TODO(keir): There are a number of possible optimizations here. One choice
+  // is to make a grid and only try one out of every N possible samples.
+  // 
+  // Another, slightly more clever idea, is to compute some sort of spatial
+  // frequency distribution of the pattern patch. If the spatial resolution is
+  // high (e.g. a grating pattern or fine lines) then checking every possible
+  // translation is necessary, since a 1-pixel shift may induce a massive
+  // change in the cost function. If the image is a blob or splotch with blurry
+  // edges, then fewer samples are necessary since a few pixels offset won't
+  // change the cost function much.
+  double best_sad = std::numeric_limits<double>::max();
+  int best_r = -1;
+  int best_c = -1;
+  int w = pattern.cols();
+  int h = pattern.rows();
+  for (int r = 0; r < (image2.Height() - h); ++r) {
+    for (int c = 0; c < (image2.Width() - w); ++c) {
+      // Compute the weighted sum of absolute differences, Eigen style. Note
+      // that the block from the search image is never stored in a variable, to
+      // avoid copying overhead and permit inlining.
+      double sad;
+      if (use_normalized_intensities) {
+        // TODO(keir): It's really dumb to recompute the search mean for every
+        // shift. A smarter implementation would use summed area tables
+        // instead, reducing the mean calculation to an O(1) operation.
+        double inverse_search_mean =
+            mask_sum / ((mask * search.block(r, c, h, w)).sum());
+        sad = (mask * (pattern - (search.block(r, c, h, w) *
+                                  inverse_search_mean))).abs().sum();
+      } else {
+        sad = (mask * (pattern - search.block(r, c, h, w))).abs().sum();
+      }
+      if (sad < best_sad) {
+        best_r = r;
+        best_c = c;
+        best_sad = sad;
+      }
+    }
+  }
+  CHECK_NE(best_r, -1);
+  CHECK_NE(best_c, -1);
+
+  LG << "Brute force translation found a shift. "
+     << "best_c: " << best_c << ", best_r: " << best_r << ", "
+     << "origin_x: " << origin_x << ", origin_y: " << origin_y << ", "
+     << "dc: " << (best_c - origin_x) << ", "
+     << "dr: " << (best_r - origin_y)
+     << ", tried " << ((image2.Height() - h) * (image2.Width() - w))
+     << " shifts.";
+
+  // Apply the shift.
+  for (int i = 0; i < 4 + num_extra_points; ++i) {
+    x2[i] += best_c - origin_x;
+    y2[i] += best_r - origin_y;
+  }
+}
+
+}  // namespace
+
+template<typename Warp>
+void TemplatedTrackRegion(const FloatImage &image1,
+                          const FloatImage &image2,
+                          const double *x1, const double *y1,
+                          const TrackRegionOptions &options,
+                          double *x2, double *y2,
+                          TrackRegionResult *result) {
+  for (int i = 0; i < 4; ++i) {
+    LG << "P" << i << ": (" << x1[i] << ", " << y1[i] << "); guess ("
+       << x2[i] << ", " << y2[i] << "); (dx, dy): (" << (x2[i] - x1[i]) << ", "
+       << (y2[i] - y1[i]) << ").";
+  }
+
+  // Bail early if the points are already outside.
+  if (!AllInBounds(image1, x1, y1)) {
+    result->termination = TrackRegionResult::SOURCE_OUT_OF_BOUNDS;
+    return;
+  }
+  if (!AllInBounds(image2, x2, y2)) {
+    result->termination = TrackRegionResult::DESTINATION_OUT_OF_BOUNDS;
+    return;
+  }
+  // TODO(keir): Check quads to ensure there is some area.
+
+  // Prepare the image and gradient.
+  Array3Df image_and_gradient1;
+  Array3Df image_and_gradient2;
+  BlurredImageAndDerivativesChannels(image1, options.sigma,
+                                     &image_and_gradient1);
+  BlurredImageAndDerivativesChannels(image2, options.sigma,
+                                     &image_and_gradient2);
+
+  // Possibly do a brute-force translation-only initialization.
+  if (SearchAreaTooBigForDescent(image2, x2, y2) &&
+      options.use_brute_initialization) {
+    LG << "Running brute initialization...";
+    BruteTranslationOnlyInitialize<Warp>(image_and_gradient1,
+                                         options.image1_mask,
+                                         image2,
+                                         options.num_extra_points,
+                                         options.use_normalized_intensities,
+                                         x1, y1, x2, y2);
+    for (int i = 0; i < 4; ++i) {
+      LG << "P" << i << ": (" << x1[i] << ", " << y1[i] << "); brute ("
+         << x2[i] << ", " << y2[i] << "); (dx, dy): (" << (x2[i] - x1[i]) << ", "
+         << (y2[i] - y1[i]) << ").";
+    }
+  }
+
+  // Prepare the initial warp parameters from the four correspondences.
+  // Note: This must happen after the brute initialization runs.
+  Warp warp(x1, y1, x2, y2);
+
+  // Decide how many samples to use in the x and y dimensions.
+  int num_samples_x;
+  int num_samples_y;
+  PickSampling(x1, y1, x2, y2, &num_samples_x, &num_samples_y);
+
+  ceres::Solver::Options solver_options;
+  solver_options.linear_solver_type = ceres::DENSE_QR;
+  solver_options.max_num_iterations = options.max_iterations;
+  solver_options.update_state_every_iteration = true;
+  solver_options.parameter_tolerance = 1e-16;
+  solver_options.function_tolerance = 1e-16;
+
+  // TODO(keir): Consider removing these options before committing.
+  solver_options.numeric_derivative_relative_step_size = 1e-3;
+  solver_options.check_gradients = false;
+  solver_options.gradient_check_relative_precision = 1e-10;
+  solver_options.minimizer_progress_to_stdout = false;
+
+  // Prevent the corners from going outside the destination image.
+  BoundaryCheckingCallback<Warp> callback(image2, warp, x1, y1);
+  solver_options.callbacks.push_back(&callback);
+
+  // Compute the warp from rectangular coordinates.
+  Mat3 canonical_homography = ComputeCanonicalHomography(x1, y1,
+                                                         num_samples_x,
+                                                         num_samples_y);
+
+  // Construct the warp cost function. AutoDiffCostFunction takes ownership.
+  WarpCostFunctor<Warp> *warp_cost_function =
+      new WarpCostFunctor<Warp>(options,
+                                image_and_gradient1,
+                                image_and_gradient2,
+                                canonical_homography,
+                                num_samples_x,
+                                num_samples_y,
+                                warp);
+
+  // Construct the problem with a single residual.
+  ceres::Problem::Options problem_options;
+  problem_options.cost_function_ownership = ceres::DO_NOT_TAKE_OWNERSHIP;
+  ceres::Problem problem(problem_options);
+  problem.AddResidualBlock(
+      new ceres::AutoDiffCostFunction<
+          WarpCostFunctor<Warp>,
+          ceres::DYNAMIC,
+          Warp::NUM_PARAMETERS>(warp_cost_function,
+                                num_samples_x * num_samples_y),
+      NULL,
+      warp.parameters);
+
+  ceres::Solver::Summary summary;
+  ceres::Solve(solver_options, &problem, &summary);
+
+  LG << "Summary:\n" << summary.FullReport();
+
+  // Update the four points with the found solution; if the solver failed, then
+  // the warp parameters are the identity (so ignore failure).
+  //
+  // Also warp any extra points on the end of the array.
+  for (int i = 0; i < 4 + options.num_extra_points; ++i) {
+    warp.Forward(warp.parameters, x1[i], y1[i], x2 + i, y2 + i);
+    LG << "Warped point " << i << ": (" << x1[i] << ", " << y1[i] << ") -> ("
+       << x2[i] << ", " << y2[i] << "); (dx, dy): (" << (x2[i] - x1[i]) << ", "
+       << (y2[i] - y1[i]) << ").";
+  }
+
+  // TODO(keir): Update the result statistics.
+  // TODO(keir): Add a normalize-cross-correlation variant.
+
+  CHECK_NE(summary.termination_type, ceres::USER_ABORT) << "Libmv bug.";
+  if (summary.termination_type == ceres::USER_ABORT) {
+    result->termination = TrackRegionResult::FELL_OUT_OF_BOUNDS;
+    return;
+  }
+#define HANDLE_TERMINATION(termination_enum) \
+  if (summary.termination_type == ceres::termination_enum) { \
+    result->termination = TrackRegionResult::termination_enum; \
+    return; \
+  }
+
+  // Avoid computing correlation for tracking failures.
+  HANDLE_TERMINATION(DID_NOT_RUN);
+  HANDLE_TERMINATION(NUMERICAL_FAILURE);
+
+  // Otherwise, run a final correlation check.
+  if (options.minimum_correlation > 0.0) {
+    result->correlation = warp_cost_function->
+          PearsonProductMomentCorrelationCoefficient(warp.parameters);
+    if (result->correlation < options.minimum_correlation) {
+      LG << "Failing with insufficient correlation.";
+      result->termination = TrackRegionResult::INSUFFICIENT_CORRELATION;
+      return;
+    }
+  }
+
+  HANDLE_TERMINATION(PARAMETER_TOLERANCE);
+  HANDLE_TERMINATION(FUNCTION_TOLERANCE);
+  HANDLE_TERMINATION(GRADIENT_TOLERANCE);
+  HANDLE_TERMINATION(NO_CONVERGENCE);
+#undef HANDLE_TERMINATION
+};
+
+void TrackRegion(const FloatImage &image1,
+                 const FloatImage &image2,
+                 const double *x1, const double *y1,
+                 const TrackRegionOptions &options,
+                 double *x2, double *y2,
+                 TrackRegionResult *result) {
+  // Enum is necessary due to templated nature of autodiff.
+#define HANDLE_MODE(mode_enum, mode_type) \
+  if (options.mode == TrackRegionOptions::mode_enum) { \
+    TemplatedTrackRegion<mode_type>(image1, image2, \
+                                    x1, y1, \
+                                    options, \
+                                    x2, y2, \
+                                    result); \
+    return; \
+  }
+
+  HANDLE_MODE(TRANSLATION,                TranslationWarp);
+  HANDLE_MODE(TRANSLATION_SCALE,          TranslationScaleWarp);
+  HANDLE_MODE(TRANSLATION_ROTATION,       TranslationRotationWarp);
+  HANDLE_MODE(TRANSLATION_ROTATION_SCALE, TranslationRotationScaleWarp);
+  HANDLE_MODE(AFFINE,                     AffineWarp);
+  HANDLE_MODE(HOMOGRAPHY,                 HomographyWarp);
+#undef HANDLE_MODE
+}
+
+}  // namespace libmv
diff --git a/extern/libmv/libmv/tracking/track_region.h b/extern/libmv/libmv/tracking/track_region.h
new file mode 100644 (file)
index 0000000..4a1427a
--- /dev/null
@@ -0,0 +1,118 @@
+// Copyright (c) 2012 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_TRACKING_TRACK_REGION_H_
+
+// Necessary for M_E when building with MSVC.
+#define _USE_MATH_DEFINES
+
+#include "libmv/tracking/esm_region_tracker.h"
+
+#include "libmv/image/image.h"
+#include "libmv/image/sample.h"
+#include "libmv/numeric/numeric.h"
+
+namespace libmv {
+
+struct TrackRegionOptions {
+  TrackRegionOptions();
+
+  enum Mode {
+    TRANSLATION,
+    TRANSLATION_ROTATION,
+    TRANSLATION_SCALE,
+    TRANSLATION_ROTATION_SCALE,
+    AFFINE,
+    HOMOGRAPHY,
+  };
+  Mode mode;
+
+  double minimum_correlation;
+  int max_iterations;
+
+  // Use the "Efficient Second-order Minimization" scheme. This increases
+  // convergence speed at the cost of more per-iteration work.
+  bool use_esm;
+
+  // If true, apply a brute-force translation-only search before attempting the
+  // full search. This is not enabled if the destination image ("image2") is
+  // too small; in that case eithen the basin of attraction is close enough
+  // that the nearby minima is correct, or the search area is too small.
+  bool use_brute_initialization;
+
+  // If true, normalize the image patches by their mean before doing the sum of
+  // squared error calculation. This is reasonable since the effect of
+  // increasing light intensity is multiplicative on the pixel intensities.
+  //
+  // Note: This does nearly double the solving time, so it is not advised to
+  // turn this on all the time.
+  bool use_normalized_intensities;
+
+  // The size in pixels of the blur kernel used to both smooth the image and
+  // take the image derivative.
+  double sigma;
+
+  // Extra points that should get transformed by the warp. This is useful
+  // because the actual warp parameters are not exposed.
+  int num_extra_points;
+
+  // If non-null, this is used as the pattern mask. It should match the size of
+  // image1, even though only values inside the image1 quad are examined. The
+  // values must be in the range 0.0 to 0.1.
+  FloatImage *image1_mask;
+};
+
+struct TrackRegionResult {
+  enum Termination {
+    // Ceres termination types, duplicated; though, not the int values.
+    PARAMETER_TOLERANCE,
+    FUNCTION_TOLERANCE,
+    GRADIENT_TOLERANCE,
+    NO_CONVERGENCE,
+    DID_NOT_RUN,
+    NUMERICAL_FAILURE,
+
+    // Libmv specific errors.
+    SOURCE_OUT_OF_BOUNDS,
+    DESTINATION_OUT_OF_BOUNDS,
+    FELL_OUT_OF_BOUNDS,
+    INSUFFICIENT_CORRELATION,
+    CONFIGURATION_ERROR,
+  };
+  Termination termination;
+
+  int num_iterations;
+  double correlation;
+
+  // Final parameters?
+  bool used_brute_translation_initialization;
+};
+
+// Always needs 4 correspondences.
+void TrackRegion(const FloatImage &image1,
+                 const FloatImage &image2,
+                 const double *x1, const double *y1,
+                 const TrackRegionOptions &options,
+                 double *x2, double *y2,
+                 TrackRegionResult *result);
+
+}  // namespace libmv
+
+#endif  // LIBMV_TRACKING_TRACK_REGION_H_
index fe84c35..c7c8c33 100755 (executable)
@@ -1,4 +1,4 @@
 #!/bin/sh
 
 find ./libmv/ -type f | sed -r 's/^\.\///' | sort > files.txt
-find ./third_party/ -type f | sed -r 's/^\.\///' | sort >> files.txt
+find ./third_party/ -mindepth 2 -type f | grep -v third_party/ceres | sed -r 's/^\.\///' | sort >> files.txt
diff --git a/extern/libmv/third_party/CMakeLists.txt b/extern/libmv/third_party/CMakeLists.txt
new file mode 100644 (file)
index 0000000..6212fe4
--- /dev/null
@@ -0,0 +1,2 @@
+
+add_subdirectory(ceres)
diff --git a/extern/libmv/third_party/SConscript b/extern/libmv/third_party/SConscript
new file mode 100644 (file)
index 0000000..b05692e
--- /dev/null
@@ -0,0 +1,3 @@
+#!/usr/bin/python
+
+SConscript(['ceres/SConscript'])
diff --git a/extern/libmv/third_party/ceres/CMakeLists.txt b/extern/libmv/third_party/ceres/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5207bdd
--- /dev/null
@@ -0,0 +1,218 @@
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# The Original Code is Copyright (C) 2012, Blender Foundation
+# All rights reserved.
+#
+# Contributor(s): Blender Foundation,
+#                 Sergey Sharybin
+#
+# ***** END GPL LICENSE BLOCK *****
+
+# NOTE: This file is automatically generated by bundle.sh script
+#       If you're doing changes in this file, please update template
+#       in that script too
+
+set(INC
+       .
+       ../../../Eigen3
+       include
+       internal
+       ../gflags
+)
+
+set(INC_SYS
+)
+
+set(SRC
+       internal/ceres/block_evaluate_preparer.cc
+       internal/ceres/block_jacobian_writer.cc
+       internal/ceres/block_jacobi_preconditioner.cc
+       internal/ceres/block_random_access_dense_matrix.cc
+       internal/ceres/block_random_access_matrix.cc
+       internal/ceres/block_random_access_sparse_matrix.cc
+       internal/ceres/block_sparse_matrix.cc
+       internal/ceres/block_structure.cc
+       internal/ceres/canonical_views_clustering.cc
+       internal/ceres/cgnr_solver.cc
+       internal/ceres/compressed_row_jacobian_writer.cc
+       internal/ceres/compressed_row_sparse_matrix.cc
+       internal/ceres/conditioned_cost_function.cc
+       internal/ceres/conjugate_gradients_solver.cc
+       internal/ceres/corrector.cc
+       internal/ceres/dense_qr_solver.cc
+       internal/ceres/dense_sparse_matrix.cc
+       internal/ceres/detect_structure.cc
+       internal/ceres/evaluator.cc
+       internal/ceres/file.cc
+       internal/ceres/generated/schur_eliminator_2_2_2.cc
+       internal/ceres/generated/schur_eliminator_2_2_3.cc
+       internal/ceres/generated/schur_eliminator_2_2_4.cc
+       internal/ceres/generated/schur_eliminator_2_2_d.cc
+       internal/ceres/generated/schur_eliminator_2_3_3.cc
+       internal/ceres/generated/schur_eliminator_2_3_4.cc
+       internal/ceres/generated/schur_eliminator_2_3_9.cc
+       internal/ceres/generated/schur_eliminator_2_3_d.cc
+       internal/ceres/generated/schur_eliminator_2_4_3.cc
+       internal/ceres/generated/schur_eliminator_2_4_4.cc
+       internal/ceres/generated/schur_eliminator_2_4_d.cc
+       internal/ceres/generated/schur_eliminator_4_4_2.cc
+       internal/ceres/generated/schur_eliminator_4_4_3.cc
+       internal/ceres/generated/schur_eliminator_4_4_4.cc
+       internal/ceres/generated/schur_eliminator_4_4_d.cc
+       internal/ceres/generated/schur_eliminator_d_d_d.cc
+       internal/ceres/gradient_checking_cost_function.cc
+       internal/ceres/implicit_schur_complement.cc
+       internal/ceres/iterative_schur_complement_solver.cc
+       internal/ceres/levenberg_marquardt.cc
+       internal/ceres/linear_least_squares_problems.cc
+       internal/ceres/linear_operator.cc
+       internal/ceres/linear_solver.cc
+       internal/ceres/local_parameterization.cc
+       internal/ceres/loss_function.cc
+       internal/ceres/normal_prior.cc
+       internal/ceres/partitioned_matrix_view.cc
+       internal/ceres/problem.cc
+       internal/ceres/problem_impl.cc
+       internal/ceres/program.cc
+       internal/ceres/residual_block.cc
+       internal/ceres/residual_block_utils.cc
+       internal/ceres/runtime_numeric_diff_cost_function.cc
+       internal/ceres/schur_complement_solver.cc
+       internal/ceres/schur_eliminator.cc
+       internal/ceres/schur_ordering.cc
+       internal/ceres/scratch_evaluate_preparer.cc
+       internal/ceres/solver.cc
+       internal/ceres/solver_impl.cc
+       internal/ceres/sparse_matrix.cc
+       internal/ceres/sparse_normal_cholesky_solver.cc
+       internal/ceres/split.cc
+       internal/ceres/stringprintf.cc
+       internal/ceres/suitesparse.cc
+       internal/ceres/triplet_sparse_matrix.cc
+       internal/ceres/types.cc
+       internal/ceres/visibility_based_preconditioner.cc
+       internal/ceres/visibility.cc
+
+       include/ceres/autodiff_cost_function.h
+       include/ceres/ceres.h
+       include/ceres/conditioned_cost_function.h
+       include/ceres/cost_function.h
+       include/ceres/internal/autodiff.h
+       include/ceres/internal/eigen.h
+       include/ceres/internal/fixed_array.h
+       include/ceres/internal/macros.h
+       include/ceres/internal/manual_constructor.h
+       include/ceres/internal/port.h
+       include/ceres/internal/scoped_ptr.h
+       include/ceres/iteration_callback.h
+       include/ceres/jet.h
+       include/ceres/local_parameterization.h
+       include/ceres/loss_function.h
+       include/ceres/normal_prior.h
+       include/ceres/numeric_diff_cost_function.h
+       include/ceres/problem.h
+       include/ceres/rotation.h
+       include/ceres/sized_cost_function.h
+       include/ceres/solver.h
+       include/ceres/types.h
+       internal/ceres/block_evaluate_preparer.h
+       internal/ceres/block_jacobian_writer.h
+       internal/ceres/block_jacobi_preconditioner.h
+       internal/ceres/block_random_access_dense_matrix.h
+       internal/ceres/block_random_access_matrix.h
+       internal/ceres/block_random_access_sparse_matrix.h
+       internal/ceres/block_sparse_matrix.h
+       internal/ceres/block_structure.h
+       internal/ceres/canonical_views_clustering.h
+       internal/ceres/casts.h
+       internal/ceres/cgnr_linear_operator.h
+       internal/ceres/cgnr_solver.h
+       internal/ceres/collections_port.h
+       internal/ceres/compressed_row_jacobian_writer.h
+       internal/ceres/compressed_row_sparse_matrix.h
+       internal/ceres/conjugate_gradients_solver.h
+       internal/ceres/corrector.h
+       internal/ceres/dense_jacobian_writer.h
+       internal/ceres/dense_qr_solver.h
+       internal/ceres/dense_sparse_matrix.h
+       internal/ceres/detect_structure.h
+       internal/ceres/evaluator.h
+       internal/ceres/file.h
+       internal/ceres/gradient_checking_cost_function.h
+       internal/ceres/graph_algorithms.h
+       internal/ceres/graph.h
+       internal/ceres/implicit_schur_complement.h
+       internal/ceres/integral_types.h
+       internal/ceres/iterative_schur_complement_solver.h
+       internal/ceres/levenberg_marquardt.h
+       internal/ceres/linear_least_squares_problems.h
+       internal/ceres/linear_operator.h
+       internal/ceres/linear_solver.h
+       internal/ceres/map_util.h
+       internal/ceres/matrix_proto.h
+       internal/ceres/minimizer.h
+       internal/ceres/mutex.h
+       internal/ceres/parameter_block.h
+       internal/ceres/partitioned_matrix_view.h
+       internal/ceres/problem_impl.h
+       internal/ceres/program_evaluator.h
+       internal/ceres/program.h
+       internal/ceres/random.h
+       internal/ceres/residual_block.h
+       internal/ceres/residual_block_utils.h
+       internal/ceres/runtime_numeric_diff_cost_function.h
+       internal/ceres/schur_complement_solver.h
+       internal/ceres/schur_eliminator.h
+       internal/ceres/schur_eliminator_impl.h
+       internal/ceres/schur_ordering.h
+       internal/ceres/scratch_evaluate_preparer.h
+       internal/ceres/solver_impl.h
+       internal/ceres/sparse_matrix.h
+       internal/ceres/sparse_normal_cholesky_solver.h
+       internal/ceres/stl_util.h
+       internal/ceres/stringprintf.h
+       internal/ceres/suitesparse.h
+       internal/ceres/triplet_sparse_matrix.h
+       internal/ceres/visibility_based_preconditioner.h
+       internal/ceres/visibility.h
+)
+
+if(WIN32)
+       list(APPEND INC
+               ../glog/src/windows
+       )
+
+       if(NOT MINGW)
+               list(APPEND INC
+                       third_party/msinttypes
+               )
+       endif()
+else()
+       list(APPEND INC
+               ../glog/src
+       )
+endif()
+
+add_definitions(
+       -DCERES_HAVE_PTHREAD
+       -D"CERES_HASH_NAMESPACE_START=namespace std { namespace tr1 {"
+       -D"CERES_HASH_NAMESPACE_END=}}"
+       -DCERES_NO_SUITESPARSE
+       -DCERES_DONT_HAVE_PROTOCOL_BUFFERS
+)
+
+blender_add_lib(extern_ceres "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/extern/libmv/third_party/ceres/ChangeLog b/extern/libmv/third_party/ceres/ChangeLog
new file mode 100644 (file)
index 0000000..6e91965
--- /dev/null
@@ -0,0 +1,324 @@
+commit ca72152362ae1f4b9928c012e74b4d49d094a4ca
+Merge: d297f8d 0a04199
+Author: Keir Mierle <mierle@gmail.com>
+Date:   Wed May 9 13:10:59 2012 -0700
+
+    Merge branch 'master' into windows
+
+commit 0a04199ef279cc9ea97f665fed8e7fae717813c3
+Merge: fdeb577 f2571f1
+Author: Keir Mierle <mierle@gmail.com>
+Date:   Wed May 9 12:54:56 2012 -0700
+
+    Merge branch 'master' of https://code.google.com/p/ceres-solver
+
+commit fdeb5772cc5eeebca4d776d220d80cc91b6d0f74
+Author: Keir Mierle <mierle@gmail.com>
+Date:   Wed May 9 07:38:07 2012 -0700
+
+    Support varying numbers of residuals in autodiff.
+    
+    This commit modifies the only function in autodiff that takes a
+    templated number of outputs (i.e. residuals) and makes that
+    template parameter a normal parameter. With that change, it
+    is a trivial matter to support a dynamic number of residuals.
+    
+    The API for dynamic residuals is to pass a fake number of
+    residuals as the second template argument to
+    AutoDiffCostFunction, and to pass the real number of
+    parameters as a second constructor argument.
+
+commit da3e0563cc12e08e7b3e0fbf11d9cc8cfe9658aa
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date:   Wed May 9 11:57:47 2012 -0700
+
+    Typo corrections in the documentation from Bing
+
+commit aa9526d8e8fb34c23d63e3af5bf9239b0c4ea603
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date:   Tue May 8 21:22:09 2012 -0700
+
+    Share search paths across various library searches.
+    Fix typos in glog search.
+    Split the error messages for include and lib.
+    Enable building of tests by default.
+    Made building on homebrew installations a bit better.
+    Remove temporary variables for glog and gflags.
+
+commit f2571f186850ed3dd316236ac4be488979df7d30
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date:   Wed May 9 11:57:47 2012 -0700
+
+    Typo corrections in the documentation from Bing
+
+commit 8f7f11ff7d07737435428a2620c52419cf99f98e
+Merge: e6c17c4 eaccbb3
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date:   Wed May 9 11:34:15 2012 -0700
+
+    Merge branch 'master' of https://code.google.com/p/ceres-solver
+
+commit e6c17c4c9d9307218f6f739cea39bc2d87733d4d
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date:   Tue May 8 21:22:09 2012 -0700
+
+    Share search paths across various library searches.
+    Fix typos in glog search.
+    Split the error messages for include and lib.
+    Enable building of tests by default.
+    Made building on homebrew installations a bit better.
+    Remove temporary variables for glog and gflags.
+
+commit eaccbb345614c0d24c5e21fa931f470cfda874df
+Author: Keir Mierle <mierle@gmail.com>
+Date:   Wed May 9 05:31:29 2012 -0700
+
+    Remove unused template parameter from VariadicEvaluate.
+
+commit 82f4b88c34b0b2cf85064e5fc20e374e978b2e3b
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date:   Sun May 6 21:05:28 2012 -0700
+
+    Extend support writing linear least squares problems to disk.
+    
+    1. Make the mechanism for writing problems to disk, generic and
+    controllable using an enum DumpType visible in the API.
+    
+    2. Instead of single file containing protocol buffers, now matrices can
+    be written in a matlab/octave friendly format. This is now the default.
+    
+    3. The support for writing problems to disk is moved into
+    linear_least_squares_problem.cc/h
+    
+    4. SparseMatrix now has a ToTextFile virtual method which is
+    implemented by each of its subclasses to write a (i,j,s) triplets.
+    
+    5. Minor changes to simple_bundle_adjuster to enable logging at startup.
+
+commit d297f8d3d3f5025c24752f0f4c1ec2469a769f99
+Merge: 7e74d81 f8bd7fa
+Author: Keir Mierle <mierle@gmail.com>
+Date:   Tue May 8 05:39:56 2012 -0700
+
+    Merge branch 'master' into windows
+
+commit f8bd7fa9aa9dbf64b6165606630287cf8cf21194
+Author: Keir Mierle <mierle@gmail.com>
+Date:   Tue May 8 05:39:32 2012 -0700
+
+    Small tweaks to the block jacobi preconditioner.
+
+commit 7e74d81ad57a159f14110eb5348b3bc7990b8bd4
+Merge: ecd7c8d e2a6cdc
+Author: Keir Mierle <mierle@gmail.com>
+Date:   Mon May 7 07:02:49 2012 -0700
+
+    Merge branch 'master' into windows
+
+commit e2a6cdc0816af9d0c77933f5017f137da3d52a35
+Author: Keir Mierle <mierle@gmail.com>
+Date:   Mon May 7 06:39:56 2012 -0700
+
+    Address some of the comments on CGNR patch
+    
+    - Rename BlockDiagonalPreconditioner to BlockJacobiPreconditioner
+    - Include the diagonal in the block jacobi preconditioner.
+    - Better flag help for eta.
+    - Enable test for CGNR
+    - Rename CONJUGATE_GRADIENTS to CGNR.
+    - etc.
+
+commit 1b95dc580aa5d89be021c0915e26df83f18013bb
+Merge: 211812a 7646039
+Author: Keir Mierle <mierle@gmail.com>
+Date:   Mon May 7 04:34:10 2012 -0700
+
+    Merge branch 'master' of https://code.google.com/p/ceres-solver
+
+commit 211812a57360d2011cbcfd115cd55e0eb73600db
+Author: Keir Mierle <mierle@gmail.com>
+Date:   Mon May 7 04:33:50 2012 -0700
+
+    Better error handling in bundle_adjuster.cc
+
+commit 7646039ad9672b267495f5b31925473ad3022ac8
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date:   Sun May 6 22:02:19 2012 -0700
+
+    Kashif's corrections to the docs
+
+commit 0d2d34148d10c5c7e924b3ca82ad2b237573ef64
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date:   Sun May 6 21:16:03 2012 -0700
+
+    glog minimum version requirements
+    
+    Building Ceres requires version 0.3.1 or better of glog.
+    Fedora 16 ships with a busted version 0.3.
+    
+    issue 15 contains the gory details.
+    
+    Added a note to the build documentation to this effect.
+
+commit 39efc5ec4b64b8f5a2c5a3dbacdbc45421221547
+Author: Keir Mierle <mierle@gmail.com>
+Date:   Sun May 6 16:09:52 2012 -0700
+
+    Fix tests broken by the CGNR change.
+
+commit 3faa08b7f7c4ac73661c6a15a6824c12080dfcb1
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date:   Sun May 6 16:08:22 2012 -0700
+
+    Formatting fixed based on Keir's comments and extended the tests
+
+commit 4f21c68409bc478c431a9b6aedf9e5cfdf11d2f3
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date:   Sun May 6 15:33:47 2012 -0700
+
+    Fix the struct weak ordering used by independent set ordering, tests for it
+
+commit 887b156b917ccd4c172484452b059d33ea45f4f0
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date:   Sun May 6 15:14:47 2012 -0700
+
+    fix he degree ordering routine
+
+commit ecd7c8df2af19404dc394b36bbe96e9db3bce840
+Author: Keir Mierle <mierle@gmail.com>
+Date:   Sun May 6 00:09:41 2012 -0700
+
+    First step towards windows compatibilty
+    
+    This adds some small changes to Ceres to make it mostly
+    compile on Windows. There are still issues with the
+    hash map use in schur_ordering.cc but I will fix those
+    shortly.
+
+commit f7898fba1b92f0e996571b5bfa22a37f5e3644de
+Author: Keir Mierle <mierle@gmail.com>
+Date:   Sat May 5 20:55:08 2012 -0700
+
+    Add a general sparse iterative solver: CGNR
+    
+    This adds a new LinearOperator which implements symmetric
+    products of a matrix, and a new CGNR solver to leverage
+    CG to directly solve the normal equations. This also
+    includes a block diagonal preconditioner. In experiments
+    on problem-16, the non-preconditioned version is about
+    1/5 the speed of SPARSE_SCHUR, and the preconditioned
+    version using block cholesky is about 20% slower than
+    SPARSE_SCHUR.
+
+commit 0a359d6198d257776a8831c3eb98f64ee91cf836
+Author: Keir Mierle <mierle@gmail.com>
+Date:   Sat May 5 20:33:46 2012 -0700
+
+    Comment formatting.
+
+commit db4ec9312bb2f1ca7b2337812f6bad6cdd75b227
+Author: Keir Mierle <mierle@gmail.com>
+Date:   Sat May 5 20:33:16 2012 -0700
+
+    Comment formatting
+
+commit f10163aaf3e57f52551bcd60bbdae873890a49dd
+Author: Keir Mierle <mierle@gmail.com>
+Date:   Fri May 4 21:33:53 2012 -0700
+
+    Warn about disabled schur specializations.
+    
+    This commit brought to you from 30,000ft.
+
+commit ad7b2b4aaf3ccc51f2b854febd53a9df54686cfe
+Author: Keir Mierle <mierle@gmail.com>
+Date:   Fri May 4 20:15:28 2012 -0700
+
+    Add vim swapfiles to .gitignore
+
+commit 6447219826bf6e47b0c99d9ff0eaf5e2ba573d79
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date:   Thu May 3 21:53:07 2012 -0700
+
+    1. Changes the tutorial to refer to BriefReport.
+    2. Some of the enums have commas at the end.
+    3. Fix a bug in the default value of circle_fit.cc in the examples.
+
+commit 30c5f93c7f88dec49f76168663372772e06f17f5
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date:   Thu May 3 10:44:43 2012 -0700
+
+    Rework the glog and gtest path checking to be consistent with the rest of the file and disable the dashboard support enabled by the earlier ctesting related patch.
+
+commit f10b033eb4aca77919987bc551d16d8a88b10110
+Merge: cc38774 e0a52a9
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date:   Thu May 3 08:45:20 2012 -0700
+
+    Merge branch 'ctest'
+
+commit e0a52a993394e73bc7f7db8d520728926feab83e
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date:   Thu May 3 08:43:34 2012 -0700
+
+    Arnaus Gelas' patch to add better path searching for gflags and glog
+
+commit a9b8e815e1c026599734510399b10f4cf014c9cd
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date:   Thu May 3 08:41:52 2012 -0700
+
+    Arnaus Gelas' patch to add .gitignore
+
+commit a0cefc3347c32b2065053bbaff4f34d11529d931
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date:   Thu May 3 08:38:33 2012 -0700
+
+    Arnaus Gelas' patch to move to Ctest
+
+commit cc38774d74e287704915282425fbd16818a72ec3
+Author: Keir Mierle <mierle@gmail.com>
+Date:   Thu May 3 01:27:50 2012 -0700
+
+    Clarify ProgramEvaluator comments.
+
+commit 017c9530df557863f78212fb5ccd02814baa9fa8
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date:   Wed May 2 08:21:59 2012 -0700
+
+    Mac OS X build instructions are much simpler, as homebrew takes care of gflags when glog is brought in. Also CMAKE does not need any flags to do the default thing
+
+commit 92d5ab5f8ae6fe355c30b606a5f230415ee0494b
+Author: Keir Mierle <mierle@gmail.com>
+Date:   Tue May 1 18:33:08 2012 -0700
+
+    Link BLAS explicitly on non-Mac platforms
+    
+    Fixes issue #3.
+
+commit df3e54eb4a6b001b7f0560a2da73a5bd7f18615e
+Author: Keir Mierle <mierle@gmail.com>
+Date:   Tue May 1 18:22:51 2012 -0700
+
+    Fix link order of CHOLMOD
+    
+    This was working by accident due to dynamic linking. Fixes issue #2.
+
+commit f477a3835329e2b48eb20c34c631a480b0f0d5bf
+Author: Keir Mierle <mierle@gmail.com>
+Date:   Tue May 1 18:10:48 2012 -0700
+
+    Fix Eigen search paths
+    
+    Fixes issue #1 on http://code.google.com/p/ceres-solver.
+
+commit 17fbc8ebb894c1d22bb3b0b02ea1394b580120f8
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date:   Tue May 1 00:21:19 2012 -0700
+
+    Minor changes to the documentation. Formatting, and typos.
+
+commit 8ebb0730388045570f22b89fe8672c860cd2ad1b
+Author: Keir Mierle <mierle@gmail.com>
+Date:   Mon Apr 30 23:09:08 2012 -0700
+
+    Initial commit of Ceres Solver.
diff --git a/extern/libmv/third_party/ceres/LICENSE b/extern/libmv/third_party/ceres/LICENSE
new file mode 100644 (file)
index 0000000..2e3ead5
--- /dev/null
@@ -0,0 +1,27 @@
+Ceres Solver - A fast non-linear least squares minimizer
+Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+http://code.google.com/p/ceres-solver/
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+  this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+  this list of conditions and the following disclaimer in the documentation
+  and/or other materials provided with the distribution.
+* Neither the name of Google Inc. nor the names of its contributors may be
+  used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/extern/libmv/third_party/ceres/README b/extern/libmv/third_party/ceres/README
new file mode 100644 (file)
index 0000000..8dd8ccf
--- /dev/null
@@ -0,0 +1,3 @@
+Ceres Solver - A non-linear least squares minimizer
+==================================================
+Please see ceres.pdf in docs/ for a tutorial and reference.
diff --git a/extern/libmv/third_party/ceres/SConscript b/extern/libmv/third_party/ceres/SConscript
new file mode 100644 (file)
index 0000000..d8b2b85
--- /dev/null
@@ -0,0 +1,34 @@
+#!/usr/bin/python
+
+# NOTE: This file is automatically generated by bundle.sh script
+#       If you're doing changes in this file, please update template
+#       in that script too
+
+import sys
+import os
+
+Import('env')
+
+src = []
+defs = []
+
+src += env.Glob('internal/ceres/*.cc')
+src += env.Glob('internal/ceres/generated/*.cc')
+
+defs.append('CERES_HAVE_PTHREAD')
+defs.append('CERES_HASH_NAMESPACE_START=namespace std { namespace tr1 {')
+defs.append('CERES_HASH_NAMESPACE_END=}}')
+defs.append('CERES_NO_SUITESPARSE')
+defs.append('CERES_DONT_HAVE_PROTOCOL_BUFFERS')
+
+incs = '. ../../ ../../../Eigen3 ./include ./internal ../gflags'
+
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
+    if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
+        incs += ' ../msinttypes'
+
+    incs += ' ../glog/src/windows'
+else:
+    incs += ' ../glog/src'
+
+env.BlenderLib ( libname = 'extern_ceres', sources=src, includes=Split(incs), defines=defs, libtype=['extern', 'player'], priority=[20,137])
diff --git a/extern/libmv/third_party/ceres/bundle.sh b/extern/libmv/third_party/ceres/bundle.sh
new file mode 100755 (executable)
index 0000000..f543421
--- /dev/null
@@ -0,0 +1,185 @@
+#!/bin/sh
+
+if [ "x$1" = "x--i-really-know-what-im-doing" ] ; then
+  echo Proceeding as requested by command line ...
+else
+  echo "*** Please run again with --i-really-know-what-im-doing ..."
+  exit 1
+fi
+
+repo="https://code.google.com/p/ceres-solver/"
+branch="windows"
+tmp=`mktemp -d`
+
+GIT="git --git-dir $tmp/ceres/.git --work-tree $tmp/ceres"
+
+git clone $repo $tmp/ceres
+
+if [ $branch != "master" ]; then
+    $GIT checkout -t remotes/origin/$branch
+fi
+
+$GIT log -n 50 > ChangeLog
+
+for p in `cat ./patches/series`; do
+  echo "Applying patch $p..."
+  cat ./patches/$p | patch -d $tmp/ceres -p1
+done
+
+find include -type f -not -iwholename '*.svn*' -exec rm -rf {} \;
+find internal -type f -not -iwholename '*.svn*' -exec rm -rf {} \;
+
+cat "files.txt" | while read f; do
+  mkdir -p `dirname $f`
+  cp $tmp/ceres/$f $f
+done
+
+rm -rf $tmp
+
+sources=`find ./include ./internal -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | sed -r 's/^\.\//\t/' | sort -d`
+headers=`find ./include ./internal -type f -iname '*.h' | sed -r 's/^\.\//\t/' | sort -d`
+
+src_dir=`find ./internal -type f -iname '*.cc' -exec dirname {} \; -or -iname '*.cpp' -exec dirname {} \; -or -iname '*.c' -exec dirname {} \; | sed -r 's/^\.\//\t/' | sort -d | uniq`
+src=""
+for x in $src_dir $src_third_dir; do
+  t=""
+
+  if test  `echo "$x" | grep -c glog ` -eq 1; then
+    continue;
+  fi
+
+  if stat $x/*.cpp > /dev/null 2>&1; then
+    t="src += env.Glob('`echo $x'/*.cpp'`')"
+  fi
+
+  if stat $x/*.c > /dev/null 2>&1; then
+    if [ -z "$t" ]; then
+      t="src += env.Glob('`echo $x'/*.c'`')"
+    else
+      t="$t + env.Glob('`echo $x'/*.c'`')"
+    fi
+  fi
+
+  if stat $x/*.cc > /dev/null 2>&1; then
+    if [ -z "$t" ]; then
+      t="src += env.Glob('`echo $x'/*.cc'`')"
+    else
+      t="$t + env.Glob('`echo $x'/*.cc'`')"
+    fi
+  fi
+
+  if [ -z "$src" ]; then
+    src=$t
+  else
+    src=`echo "$src\n$t"`
+  fi
+done
+
+cat > CMakeLists.txt << EOF
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# The Original Code is Copyright (C) 2012, Blender Foundation
+# All rights reserved.
+#
+# Contributor(s): Blender Foundation,
+#                 Sergey Sharybin
+#
+# ***** END GPL LICENSE BLOCK *****
+
+# NOTE: This file is automatically generated by bundle.sh script
+#       If you're doing changes in this file, please update template
+#       in that script too
+
+set(INC
+       .
+       ../../../Eigen3
+       include
+       internal
+       ../gflags
+)
+
+set(INC_SYS
+)
+
+set(SRC
+${sources}
+
+${headers}
+)
+
+if(WIN32)
+       list(APPEND INC
+               ../glog/src/windows
+       )
+
+       if(NOT MINGW)
+               list(APPEND INC
+                       third_party/msinttypes
+               )
+       endif()
+else()
+       list(APPEND INC
+               ../glog/src
+       )
+endif()
+
+add_definitions(
+       -DCERES_HAVE_PTHREAD
+       -D"CERES_HASH_NAMESPACE_START=namespace std { namespace tr1 {"
+       -D"CERES_HASH_NAMESPACE_END=}}"
+       -DCERES_NO_SUITESPARSE
+       -DCERES_DONT_HAVE_PROTOCOL_BUFFERS
+)
+
+blender_add_lib(extern_ceres "\${SRC}" "\${INC}" "\${INC_SYS}")
+EOF
+
+cat > SConscript << EOF
+#!/usr/bin/python
+
+# NOTE: This file is automatically generated by bundle.sh script
+#       If you're doing changes in this file, please update template
+#       in that script too
+
+import sys
+import os
+
+Import('env')
+
+src = []
+defs = []
+
+$src
+
+defs.append('CERES_HAVE_PTHREAD')
+defs.append('CERES_HASH_NAMESPACE_START=namespace std { namespace tr1 {')
+defs.append('CERES_HASH_NAMESPACE_END=}}')
+defs.append('CERES_NO_SUITESPARSE')
+defs.append('CERES_DONT_HAVE_PROTOCOL_BUFFERS')
+
+incs = '. ../../ ../../../Eigen3 ./include ./internal ../gflags'
+
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
+    if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
+        incs += ' ../msinttypes'
+
+    incs += ' ../glog/src/windows'
+else:
+    incs += ' ../glog/src'
+
+env.BlenderLib ( libname = 'extern_ceres', sources=src, includes=Split(incs), defines=defs, libtype=['extern', 'player'], priority=[20,137])
+EOF
diff --git a/extern/libmv/third_party/ceres/files.txt b/extern/libmv/third_party/ceres/files.txt
new file mode 100644 (file)
index 0000000..e9d7f58
--- /dev/null
@@ -0,0 +1,150 @@
+include/ceres/autodiff_cost_function.h
+include/ceres/ceres.h
+include/ceres/conditioned_cost_function.h
+include/ceres/cost_function.h
+include/ceres/internal/autodiff.h
+include/ceres/internal/eigen.h
+include/ceres/internal/fixed_array.h
+include/ceres/internal/macros.h
+include/ceres/internal/manual_constructor.h
+include/ceres/internal/port.h
+include/ceres/internal/scoped_ptr.h
+include/ceres/iteration_callback.h
+include/ceres/jet.h
+include/ceres/local_parameterization.h
+include/ceres/loss_function.h
+include/ceres/normal_prior.h
+include/ceres/numeric_diff_cost_function.h
+include/ceres/problem.h
+include/ceres/rotation.h
+include/ceres/sized_cost_function.h
+include/ceres/solver.h
+include/ceres/types.h
+internal/ceres/block_evaluate_preparer.cc
+internal/ceres/block_evaluate_preparer.h
+internal/ceres/block_jacobian_writer.cc
+internal/ceres/block_jacobian_writer.h
+internal/ceres/block_jacobi_preconditioner.cc
+internal/ceres/block_jacobi_preconditioner.h
+internal/ceres/block_random_access_dense_matrix.cc
+internal/ceres/block_random_access_dense_matrix.h
+internal/ceres/block_random_access_matrix.cc
+internal/ceres/block_random_access_matrix.h
+internal/ceres/block_random_access_sparse_matrix.cc
+internal/ceres/block_random_access_sparse_matrix.h
+internal/ceres/block_sparse_matrix.cc
+internal/ceres/block_sparse_matrix.h
+internal/ceres/block_structure.cc
+internal/ceres/block_structure.h
+internal/ceres/canonical_views_clustering.cc
+internal/ceres/canonical_views_clustering.h
+internal/ceres/casts.h
+internal/ceres/cgnr_linear_operator.h
+internal/ceres/cgnr_solver.cc
+internal/ceres/cgnr_solver.h
+internal/ceres/collections_port.h
+internal/ceres/compressed_row_jacobian_writer.cc
+internal/ceres/compressed_row_jacobian_writer.h
+internal/ceres/compressed_row_sparse_matrix.cc
+internal/ceres/compressed_row_sparse_matrix.h
+internal/ceres/conditioned_cost_function.cc
+internal/ceres/conjugate_gradients_solver.cc
+internal/ceres/conjugate_gradients_solver.h
+internal/ceres/corrector.cc
+internal/ceres/corrector.h
+internal/ceres/dense_jacobian_writer.h
+internal/ceres/dense_qr_solver.cc
+internal/ceres/dense_qr_solver.h
+internal/ceres/dense_sparse_matrix.cc
+internal/ceres/dense_sparse_matrix.h
+internal/ceres/detect_structure.cc
+internal/ceres/detect_structure.h
+internal/ceres/evaluator.cc
+internal/ceres/evaluator.h
+internal/ceres/file.cc
+internal/ceres/file.h
+internal/ceres/generated/schur_eliminator_2_2_2.cc
+internal/ceres/generated/schur_eliminator_2_2_3.cc
+internal/ceres/generated/schur_eliminator_2_2_4.cc
+internal/ceres/generated/schur_eliminator_2_2_d.cc
+internal/ceres/generated/schur_eliminator_2_3_3.cc
+internal/ceres/generated/schur_eliminator_2_3_4.cc
+internal/ceres/generated/schur_eliminator_2_3_9.cc
+internal/ceres/generated/schur_eliminator_2_3_d.cc
+internal/ceres/generated/schur_eliminator_2_4_3.cc
+internal/ceres/generated/schur_eliminator_2_4_4.cc
+internal/ceres/generated/schur_eliminator_2_4_d.cc
+internal/ceres/generated/schur_eliminator_4_4_2.cc
+internal/ceres/generated/schur_eliminator_4_4_3.cc
+internal/ceres/generated/schur_eliminator_4_4_4.cc
+internal/ceres/generated/schur_eliminator_4_4_d.cc
+internal/ceres/generated/schur_eliminator_d_d_d.cc
+internal/ceres/gradient_checking_cost_function.cc
+internal/ceres/gradient_checking_cost_function.h
+internal/ceres/graph_algorithms.h
+internal/ceres/graph.h
+internal/ceres/implicit_schur_complement.cc
+internal/ceres/implicit_schur_complement.h
+internal/ceres/integral_types.h
+internal/ceres/iterative_schur_complement_solver.cc
+internal/ceres/iterative_schur_complement_solver.h
+internal/ceres/levenberg_marquardt.cc
+internal/ceres/levenberg_marquardt.h
+internal/ceres/linear_least_squares_problems.cc
+internal/ceres/linear_least_squares_problems.h
+internal/ceres/linear_operator.cc
+internal/ceres/linear_operator.h
+internal/ceres/linear_solver.cc
+internal/ceres/linear_solver.h
+internal/ceres/local_parameterization.cc
+internal/ceres/loss_function.cc
+internal/ceres/map_util.h
+internal/ceres/matrix_proto.h
+internal/ceres/minimizer.h
+internal/ceres/mutex.h
+internal/ceres/normal_prior.cc
+internal/ceres/parameter_block.h
+internal/ceres/partitioned_matrix_view.cc
+internal/ceres/partitioned_matrix_view.h
+internal/ceres/problem.cc
+internal/ceres/problem_impl.cc
+internal/ceres/problem_impl.h
+internal/ceres/program.cc
+internal/ceres/program_evaluator.h
+internal/ceres/program.h
+internal/ceres/random.h
+internal/ceres/residual_block.cc
+internal/ceres/residual_block.h
+internal/ceres/residual_block_utils.cc
+internal/ceres/residual_block_utils.h
+internal/ceres/runtime_numeric_diff_cost_function.cc
+internal/ceres/runtime_numeric_diff_cost_function.h
+internal/ceres/schur_complement_solver.cc
+internal/ceres/schur_complement_solver.h
+internal/ceres/schur_eliminator.cc
+internal/ceres/schur_eliminator.h
+internal/ceres/schur_eliminator_impl.h
+internal/ceres/schur_ordering.cc
+internal/ceres/schur_ordering.h
+internal/ceres/scratch_evaluate_preparer.cc
+internal/ceres/scratch_evaluate_preparer.h
+internal/ceres/solver.cc
+internal/ceres/solver_impl.cc
+internal/ceres/solver_impl.h
+internal/ceres/sparse_matrix.cc
+internal/ceres/sparse_matrix.h
+internal/ceres/sparse_normal_cholesky_solver.cc
+internal/ceres/sparse_normal_cholesky_solver.h
+internal/ceres/split.cc
+internal/ceres/stl_util.h
+internal/ceres/stringprintf.cc
+internal/ceres/stringprintf.h
+internal/ceres/suitesparse.cc
+internal/ceres/suitesparse.h
+internal/ceres/triplet_sparse_matrix.cc
+internal/ceres/triplet_sparse_matrix.h
+internal/ceres/types.cc
+internal/ceres/visibility_based_preconditioner.cc
+internal/ceres/visibility_based_preconditioner.h
+internal/ceres/visibility.cc
+internal/ceres/visibility.h
diff --git a/extern/libmv/third_party/ceres/include/ceres/autodiff_cost_function.h b/extern/libmv/third_party/ceres/include/ceres/autodiff_cost_function.h
new file mode 100644 (file)
index 0000000..da9ee2c
--- /dev/null
@@ -0,0 +1,211 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: sameeragarwal@google.com (Sameer Agarwal)
+//
+// Helpers for making CostFunctions as needed by the least squares framework,
+// with Jacobians computed via automatic differentiation. For more information
+// on automatic differentation, see the wikipedia article at
+// http://en.wikipedia.org/wiki/Automatic_differentiation
+//
+// To get an auto differentiated cost function, you must define a class with a
+// templated operator() (a functor) that computes the cost function in terms of
+// the template parameter T. The autodiff framework substitutes appropriate
+// "jet" objects for T in order to compute the derivative when necessary, but
+// this is hidden, and you should write the function as if T were a scalar type
+// (e.g. a double-precision floating point number).
+//
+// The function must write the computed value in the last argument (the only
+// non-const one) and return true to indicate success.
+//
+// For example, consider a scalar error e = k - x'y, where both x and y are
+// two-dimensional column vector parameters, the prime sign indicates
+// transposition, and k is a constant. The form of this error, which is the
+// difference between a constant and an expression, is a common pattern in least
+// squares problems. For example, the value x'y might be the model expectation
+// for a series of measurements, where there is an instance of the cost function
+// for each measurement k.
+//
+// The actual cost added to the total problem is e^2, or (k - x'k)^2; however,
+// the squaring is implicitly done by the optimization framework.
+//
+// To write an auto-differentiable cost function for the above model, first
+// define the object
+//
+//   class MyScalarCostFunction {
+//     MyScalarCostFunction(double k): k_(k) {}
+//
+//     template <typename T>
+//     bool operator()(const T* const x , const T* const y, T* e) const {
+//       e[0] = T(k_) - x[0] * y[0] + x[1] * y[1];
+//       return true;
+//     }
+//
+//    private:
+//     double k_;
+//   };
+//
+// Note that in the declaration of operator() the input parameters x and y come
+// first, and are passed as const pointers to arrays of T. If there were three
+// input parameters, then the third input parameter would come after y. The
+// output is always the last parameter, and is also a pointer to an array. In
+// the example above, e is a scalar, so only e[0] is set.
+//
+// Then given this class definition, the auto differentiated cost function for
+// it can be constructed as follows.
+//
+//   CostFunction* cost_function
+//       = new AutoDiffCostFunction<MyScalarCostFunction, 1, 2, 2>(
+//           new MyScalarCostFunction(1.0));              ^  ^  ^
+//                                                        |  |  |
+//                            Dimension of residual ------+  |  |
+//                            Dimension of x ----------------+  |
+//                            Dimension of y -------------------+
+//
+// In this example, there is usually an instance for each measumerent of k.
+//
+// In the instantiation above, the template parameters following
+// "MyScalarCostFunction", "1, 2, 2", describe the functor as computing a
+// 1-dimensional output from two arguments, both 2-dimensional.
+//
+// The autodiff cost function also supports cost functions with a
+// runtime-determined number of residuals. For example:
+//
+//   CostFunction* cost_function
+//       = new AutoDiffCostFunction<MyScalarCostFunction, DYNAMIC, 2, 2>(
+//           new CostFunctionWithDynamicNumResiduals(1.0),   ^     ^  ^
+//           runtime_number_of_residuals); <----+            |     |  |
+//                                              |            |     |  |
+//                                              |            |     |  |
+//             Actual number of residuals ------+            |     |  |
+//             Indicate dynamic number of residuals ---------+     |  |
+//             Dimension of x -------------------------------------+  |
+//             Dimension of y ----------------------------------------+
+//
+// The framework can currently accommodate cost functions of up to 6 independent
+// variables, and there is no limit on the dimensionality of each of them.
+//
+// WARNING #1: Since the functor will get instantiated with different types for
+// T, you must to convert from other numeric types to T before mixing
+// computations with other variables of type T. In the example above, this is
+// seen where instead of using k_ directly, k_ is wrapped with T(k_).
+//
+// WARNING #2: A common beginner's error when first using autodiff cost
+// functions is to get the sizing wrong. In particular, there is a tendency to
+// set the template parameters to (dimension of residual, number of parameters)
+// instead of passing a dimension parameter for *every parameter*. In the
+// example above, that would be <MyScalarCostFunction, 1, 2>, which is missing
+// the last '2' argument. Please be careful when setting the size parameters.
+
+#ifndef CERES_PUBLIC_AUTODIFF_COST_FUNCTION_H_
+#define CERES_PUBLIC_AUTODIFF_COST_FUNCTION_H_
+
+#include <glog/logging.h>
+#include "ceres/internal/autodiff.h"
+#include "ceres/internal/scoped_ptr.h"
+#include "ceres/sized_cost_function.h"
+#include "ceres/types.h"
+
+namespace ceres {
+
+// A cost function which computes the derivative of the cost with respect to
+// the parameters (a.k.a. the jacobian) using an autodifferentiation framework.
+// The first template argument is the functor object, described in the header
+// comment. The second argument is the dimension of the residual (or
+// ceres::DYNAMIC to indicate it will be set at runtime), and subsequent
+// arguments describe the size of the Nth parameter, one per parameter.
+//
+// The constructors take ownership of the cost functor.
+//
+// If the number of residuals (argument "M" below) is ceres::DYNAMIC, then the
+// two-argument constructor must be used. The second constructor takes a number
+// of residuals (in addition to the templated number of residuals). This allows
+// for varying the number of residuals for a single autodiff cost function at
+// runtime.
+template <typename CostFunctor,
+          int M,        // Number of residuals, or ceres::DYNAMIC.
+          int N0,       // Number of parameters in block 0.
+          int N1 = 0,   // Number of parameters in block 1.
+          int N2 = 0,   // Number of parameters in block 2.
+          int N3 = 0,   // Number of parameters in block 3.
+          int N4 = 0,   // Number of parameters in block 4.
+          int N5 = 0>   // Number of parameters in block 5.
+class AutoDiffCostFunction :
+  public SizedCostFunction<M, N0, N1, N2, N3, N4, N5> {
+ public:
+  // Takes ownership of functor. Uses the template-provided value for the
+  // number of residuals ("M").
+  explicit AutoDiffCostFunction(CostFunctor* functor)
+      : functor_(functor) {
+    CHECK_NE(M, DYNAMIC) << "Can't run the fixed-size constructor if the "
+                          << "number of residuals is set to ceres::DYNAMIC.";
+  }
+
+  // Takes ownership of functor. Ignores the template-provided number of
+  // residuals ("M") in favor of the "num_residuals" argument provided.
+  //
+  // This allows for having autodiff cost functions which return varying
+  // numbers of residuals at runtime.
+  AutoDiffCostFunction(CostFunctor* functor, int num_residuals)
+      : functor_(functor) {
+    CHECK_EQ(M, DYNAMIC) << "Can't run the dynamic-size constructor if the "
+                          << "number of residuals is not ceres::DYNAMIC.";
+    SizedCostFunction<M, N0, N1, N2, N3, N4, N5>::set_num_residuals(num_residuals);
+  }
+
+  virtual ~AutoDiffCostFunction() {}
+
+  // Implementation details follow; clients of the autodiff cost function should
+  // not have to examine below here.
+  //
+  // To handle varardic cost functions, some template magic is needed. It's
+  // mostly hidden inside autodiff.h.
+  virtual bool Evaluate(double const* const* parameters,
+                        double* residuals,
+                        double** jacobians) const {
+    if (!jacobians) {
+      return internal::VariadicEvaluate<
+          CostFunctor, double, N0, N1, N2, N3, N4, N5>
+          ::Call(*functor_, parameters, residuals);
+    }
+    return internal::AutoDiff<CostFunctor, double,
+           N0, N1, N2, N3, N4, N5>::Differentiate(
+               *functor_,
+               parameters,
+               SizedCostFunction<M, N0, N1, N2, N3, N4, N5>::num_residuals(),
+               residuals,
+               jacobians);
+  }
+
+ private:
+  internal::scoped_ptr<CostFunctor> functor_;
+};
+
+}  // namespace ceres
+
+#endif  // CERES_PUBLIC_AUTODIFF_COST_FUNCTION_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/ceres.h b/extern/libmv/third_party/ceres/include/ceres/ceres.h
new file mode 100644 (file)
index 0000000..22aaf8f
--- /dev/null
@@ -0,0 +1,48 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: keir@google.com (Keir Mierle)
+//
+// This is a forwarding header containing the public symbols exported from
+// Ceres. Anything in the "ceres" namespace is available for use.
+
+#ifndef CERES_PUBLIC_CERES_H_
+#define CERES_PUBLIC_CERES_H_
+
+#include "ceres/autodiff_cost_function.h"
+#include "ceres/cost_function.h"
+#include "ceres/iteration_callback.h"
+#include "ceres/local_parameterization.h"
+#include "ceres/loss_function.h"
+#include "ceres/numeric_diff_cost_function.h"
+#include "ceres/problem.h"
+#include "ceres/sized_cost_function.h"
+#include "ceres/solver.h"
+#include "ceres/types.h"
+
+#endif  // CERES_PUBLIC_CERES_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/conditioned_cost_function.h b/extern/libmv/third_party/ceres/include/ceres/conditioned_cost_function.h
new file mode 100644 (file)
index 0000000..498d36e
--- /dev/null
@@ -0,0 +1,97 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wjr@google.com (William Rucklidge)
+//
+// This file contains a cost function that can apply a transformation to
+// each residual value before they are square-summed.
+
+#ifndef CERES_PUBLIC_CONDITIONED_COST_FUNCTION_H_
+#define CERES_PUBLIC_CONDITIONED_COST_FUNCTION_H_
+
+#include <vector>
+
+#include "ceres/cost_function.h"
+#include "ceres/internal/scoped_ptr.h"
+#include "ceres/types.h"
+
+namespace ceres {
+
+// This class allows you to apply different conditioning to the residual
+// values of a wrapped cost function. An example where this is useful is
+// where you have an existing cost function that produces N values, but you
+// want the total cost to be something other than just the sum of these
+// squared values - maybe you want to apply a different scaling to some
+// values, to change their contribution to the cost.
+//
+// Usage:
+//
+//   // my_cost_function produces N residuals
+//   CostFunction* my_cost_function = ...
+//   CHECK_EQ(N, my_cost_function->num_residuals());
+//   vector<CostFunction*> conditioners;
+//
+//   // Make N 1x1 cost functions (1 parameter, 1 residual)
+//   CostFunction* f_1 = ...
+//   conditioners.push_back(f_1);
+//   ...
+//   CostFunction* f_N = ...
+//   conditioners.push_back(f_N);
+//   ConditionedCostFunction* ccf =
+//     new ConditionedCostFunction(my_cost_function, conditioners);
+//
+// Now ccf's residual i (i=0..N-1) will be passed though the i'th conditioner.
+//
+//   ccf_residual[i] = f_i(my_cost_function_residual[i])
+//
+// and the Jacobian will be affected appropriately.
+class ConditionedCostFunction : public CostFunction {
+ public:
+  // Builds a cost function based on a wrapped cost function, and a
+  // per-residual conditioner. Takes ownership of all of the wrapped cost
+  // functions, or not, depending on the ownership parameter. Conditioners
+  // may be NULL, in which case the corresponding residual is not modified.
+  ConditionedCostFunction(CostFunction* wrapped_cost_function,
+                          const vector<CostFunction*>& conditioners,
+                          Ownership ownership);
+  virtual ~ConditionedCostFunction();
+
+  virtual bool Evaluate(double const* const* parameters,
+                        double* residuals,
+                        double** jacobians) const;
+
+ private:
+  internal::scoped_ptr<CostFunction> wrapped_cost_function_;
+  vector<CostFunction*> conditioners_;
+  Ownership ownership_;
+};
+
+}  // namespace ceres
+
+
+#endif  // CERES_PUBLIC_CONDITIONED_COST_FUNCTION_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/cost_function.h b/extern/libmv/third_party/ceres/include/ceres/cost_function.h
new file mode 100644 (file)
index 0000000..84403d9
--- /dev/null
@@ -0,0 +1,127 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: sameeragarwal@google.com (Sameer Agarwal)
+//         keir@google.m (Keir Mierle)
+//
+// This is the interface through which the least squares solver accesses the
+// residual and Jacobian of the least squares problem. Users are expected to
+// subclass CostFunction to define their own terms in the least squares problem.
+//
+// It is recommended that users define templated residual functors for use as
+// arguments for AutoDiffCostFunction (see autodiff_cost_function.h), instead of
+// directly implementing the CostFunction interface. This often results in both
+// shorter code and faster execution than hand-coded derivatives. However,
+// specialized cases may demand direct implementation of the lower-level
+// CostFunction interface; for example, this is true when calling legacy code
+// which is not templated on numeric types.
+
+#ifndef CERES_PUBLIC_COST_FUNCTION_H_
+#define CERES_PUBLIC_COST_FUNCTION_H_
+
+#include <vector>
+#include "ceres/internal/macros.h"
+#include "ceres/internal/port.h"
+#include "ceres/types.h"
+
+namespace ceres {
+
+// This class implements the computation of the cost (a.k.a. residual) terms as
+// a function of the input (control) variables, and is the interface for users
+// to describe their least squares problem to Ceres. In other words, this is the
+// modelling layer between users and the Ceres optimizer. The signature of the
+// function (number and sizes of input parameter blocks and number of outputs)
+// is stored in parameter_block_sizes_ and num_residuals_ respectively. User
+// code inheriting from this class is expected to set these two members with the
+// corresponding accessors. This information will be verified by the Problem
+// when added with AddResidualBlock().
+class CostFunction {
+ public:
+  CostFunction() : num_residuals_(0) {}
+
+  virtual ~CostFunction() {}
+
+  // Inputs:
+  //
+  // parameters is an array of pointers to arrays containing the
+  // various parameter blocks. parameters has the same number of
+  // elements as parameter_block_sizes_.  Parameter blocks are in the
+  // same order as parameter_block_sizes_.i.e.,
+  //
+  //   parameters_[i] = double[parameter_block_sizes_[i]]
+  //
+  // Outputs:
+  //
+  // residuals is an array of size num_residuals_.
+  //
+  // jacobians is an array of size parameter_block_sizes_ containing
+  // pointers to storage for jacobian blocks corresponding to each
+  // parameter block. Jacobian blocks are in the same order as
+  // parameter_block_sizes, i.e. jacobians[i], is an
+  // array that contains num_residuals_* parameter_block_sizes_[i]
+  // elements. Each jacobian block is stored in row-major order, i.e.,
+  //
+  //   jacobians[i][r*parameter_block_size_[i] + c] =
+  //                              d residual[r] / d parameters[i][c]
+  //
+  // If jacobians is NULL, then no derivatives are returned; this is
+  // the case when computing cost only. If jacobians[i] is NULL, then
+  // the jacobian block corresponding to the i'th parameter block must
+  // not to be returned.
+  virtual bool Evaluate(double const* const* parameters,
+                        double* residuals,
+                        double** jacobians) const = 0;
+
+  const vector<int16>& parameter_block_sizes() const {
+    return parameter_block_sizes_;
+  }
+
+  int num_residuals() const {
+    return num_residuals_;
+  }
+
+ protected:
+  vector<int16>* mutable_parameter_block_sizes() {
+    return &parameter_block_sizes_;
+  }
+
+  void set_num_residuals(int num_residuals) {
+    num_residuals_ = num_residuals;
+  }
+
+ private:
+  // Cost function signature metadata: number of inputs & their sizes,
+  // number of outputs (residuals).
+  vector<int16> parameter_block_sizes_;
+  int num_residuals_;
+  DISALLOW_COPY_AND_ASSIGN(CostFunction);
+};
+
+}  // namespace ceres
+
+#endif  // CERES_PUBLIC_COST_FUNCTION_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/internal/autodiff.h b/extern/libmv/third_party/ceres/include/ceres/internal/autodiff.h
new file mode 100644 (file)
index 0000000..4f5081f
--- /dev/null
@@ -0,0 +1,370 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: keir@google.com (Keir Mierle)
+//
+// Computation of the Jacobian matrix for vector-valued functions of multiple
+// variables, using automatic differentiation based on the implementation of
+// dual numbers in jet.h. Before reading the rest of this file, it is adivsable
+// to read jet.h's header comment in detail.
+//
+// The helper wrapper AutoDiff::Differentiate() computes the jacobian of
+// functors with templated operator() taking this form:
+//
+//   struct F {
+//     template<typename T>
+//     bool operator(const T *x, const T *y, ..., T *z) {
+//       // Compute z[] based on x[], y[], ...
+//       // return true if computation succeeded, false otherwise.
+//     }
+//   };
+//
+// All inputs and outputs may be vector-valued.
+//
+// To understand how jets are used to compute the jacobian, a
+// picture may help. Consider a vector-valued function, F, returning 3
+// dimensions and taking a vector-valued parameter of 4 dimensions:
+//
+//     y            x
+//   [ * ]    F   [ * ]
+//   [ * ]  <---  [ * ]
+//   [ * ]        [ * ]
+//                [ * ]
+//
+// Similar to the 2-parameter example for f described in jet.h, computing the
+// jacobian dy/dx is done by substutiting a suitable jet object for x and all
+// intermediate steps of the computation of F. Since x is has 4 dimensions, use
+// a Jet<double, 4>.
+//
+// Before substituting a jet object for x, the dual components are set
+// appropriately for each dimension of x:
+//
+//          y                       x
+//   [ * | * * * * ]    f   [ * | 1 0 0 0 ]   x0
+//   [ * | * * * * ]  <---  [ * | 0 1 0 0 ]   x1
+//   [ * | * * * * ]        [ * | 0 0 1 0 ]   x2
+//         ---+---          [ * | 0 0 0 1 ]   x3
+//            |                   ^ ^ ^ ^
+//          dy/dx                 | | | +----- infinitesimal for x3
+//                                | | +------- infinitesimal for x2
+//                                | +--------- infinitesimal for x1
+//                                +----------- infinitesimal for x0
+//
+// The reason to set the internal 4x4 submatrix to the identity is that we wish
+// to take the derivative of y separately with respect to each dimension of x.
+// Each column of the 4x4 identity is therefore for a single component of the
+// independent variable x.
+//
+// Then the jacobian of the mapping, dy/dx, is the 3x4 sub-matrix of the
+// extended y vector, indicated in the above diagram.
+//
+// Functors with multiple parameters
+// ---------------------------------
+// In practice, it is often convenient to use a function f of two or more
+// vector-valued parameters, for example, x[3] and z[6]. Unfortunately, the jet
+// framework is designed for a single-parameter vector-valued input. The wrapper
+// in this file addresses this issue adding support for functions with one or
+// more parameter vectors.
+//
+// To support multiple parameters, all the parameter vectors are concatenated
+// into one and treated as a single parameter vector, except that since the
+// functor expects different inputs, we need to construct the jets as if they
+// were part of a single parameter vector. The extended jets are passed
+// separately for each parameter.
+//
+// For example, consider a functor F taking two vector parameters, p[2] and
+// q[3], and producing an output y[4]:
+//
+//   struct F {
+//     template<typename T>
+//     bool operator(const T *p, const T *q, T *z) {
+//       // ...
+//     }
+//   };
+//
+// In this case, the necessary jet type is Jet<double, 5>. Here is a
+// visualization of the jet objects in this case:
+//
+//          Dual components for p ----+
+//                                    |
+//                                   -+-
+//           y                 [ * | 1 0 | 0 0 0 ]    --- p[0]
+//                             [ * | 0 1 | 0 0 0 ]    --- p[1]
+//   [ * | . . | + + + ]         |
+//   [ * | . . | + + + ]         v
+//   [ * | . . | + + + ]  <--- F(p, q)
+//   [ * | . . | + + + ]            ^
+//         ^^^   ^^^^^              |
+//        dy/dp  dy/dq            [ * | 0 0 | 1 0 0 ] --- q[0]
+//                                [ * | 0 0 | 0 1 0 ] --- q[1]
+//                                [ * | 0 0 | 0 0 1 ] --- q[2]
+//                                            --+--
+//                                              |
+//          Dual components for q --------------+
+//
+// where the 4x2 submatrix (marked with ".") and 4x3 submatrix (marked with "+"
+// of y in the above diagram are the derivatives of y with respect to p and q
+// respectively. This is how autodiff works for functors taking multiple vector
+// valued arguments (up to 6).
+//
+// Jacobian NULL pointers
+// ----------------------
+// In general, the functions below will accept NULL pointers for all or some of
+// the Jacobian parameters, meaning that those Jacobians will not be computed.
+
+#ifndef CERES_PUBLIC_INTERNAL_AUTODIFF_H_
+#define CERES_PUBLIC_INTERNAL_AUTODIFF_H_
+
+#include <stddef.h>
+
+#include <glog/logging.h>
+#include "ceres/jet.h"
+#include "ceres/internal/eigen.h"
+#include "ceres/internal/fixed_array.h"
+
+namespace ceres {
+namespace internal {
+
+// Extends src by a 1st order pertubation for every dimension and puts it in
+// dst. The size of src is N. Since this is also used for perturbations in
+// blocked arrays, offset is used to shift which part of the jet the
+// perturbation occurs. This is used to set up the extended x augmented by an
+// identity matrix. The JetT type should be a Jet type, and T should be a
+// numeric type (e.g. double). For example,
+//
+//             0   1 2   3 4 5   6 7 8
+//   dst[0]  [ * | . . | 1 0 0 | . . . ]
+//   dst[1]  [ * | . . | 0 1 0 | . . . ]
+//   dst[2]  [ * | . . | 0 0 1 | . . . ]
+//
+// is what would get put in dst if N was 3, offset was 3, and the jet type JetT
+// was 8-dimensional.
+template <typename JetT, typename T>
+inline void Make1stOrderPerturbation(int offset, int N, const T *src,
+                                     JetT *dst) {
+  DCHECK(src);
+  DCHECK(dst);
+  for (int j = 0; j < N; ++j) {
+    dst[j] = JetT(src[j], offset + j);
+  }
+}
+
+// Takes the 0th order part of src, assumed to be a Jet type, and puts it in
+// dst. This is used to pick out the "vector" part of the extended y.
+template <typename JetT, typename T>
+inline void Take0thOrderPart(int M, const JetT *src, T dst) {
+  DCHECK(src);
+  for (int i = 0; i < M; ++i) {
+    dst[i] = src[i].a;
+  }
+}
+
+// Takes N 1st order parts, starting at index N0, and puts them in the M x N
+// matrix 'dst'. This is used to pick out the "matrix" parts of the extended y.
+template <typename JetT, typename T, int N0, int N>
+inline void Take1stOrderPart(const int M, const JetT *src, T *dst) {
+  DCHECK(src);
+  DCHECK(dst);
+  for (int i = 0; i < M; ++i) {
+    Eigen::Map<Eigen::Matrix<T, N, 1> >(dst + N * i, N) = src[i].v.template segment<N>(N0);
+  }
+}
+
+// This block of quasi-repeated code calls the user-supplied functor, which may
+// take a variable number of arguments. This is accomplished by specializing the
+// struct based on the size of the trailing parameters; parameters with 0 size
+// are assumed missing.
+//
+// Supporting variadic functions is the primary source of complexity in the
+// autodiff implementation.
+
+template<typename Functor, typename T,
+         int N0, int N1, int N2, int N3, int N4, int N5>
+struct VariadicEvaluate {
+  static bool Call(const Functor& functor, T const *const *input, T* output) {
+    return functor(input[0],
+                   input[1],
+                   input[2],
+                   input[3],
+                   input[4],
+                   input[5],
+                   output);
+  }
+};
+
+template<typename Functor, typename T,
+         int N0, int N1, int N2, int N3, int N4>
+struct VariadicEvaluate<Functor, T, N0, N1, N2, N3, N4, 0> {
+  static bool Call(const Functor& functor, T const *const *input, T* output) {
+    return functor(input[0],
+                   input[1],
+                   input[2],
+                   input[3],
+                   input[4],
+                   output);
+  }
+};
+
+template<typename Functor, typename T,
+         int N0, int N1, int N2, int N3>
+struct VariadicEvaluate<Functor, T, N0, N1, N2, N3, 0, 0> {
+  static bool Call(const Functor& functor, T const *const *input, T* output) {
+    return functor(input[0],
+                   input[1],
+                   input[2],
+                   input[3],
+                   output);
+  }
+};
+
+template<typename Functor, typename T,
+         int N0, int N1, int N2>
+struct VariadicEvaluate<Functor, T, N0, N1, N2, 0, 0, 0> {
+  static bool Call(const Functor& functor, T const *const *input, T* output) {
+    return functor(input[0],
+                   input[1],
+                   input[2],
+                   output);
+  }
+};
+
+template<typename Functor, typename T,
+         int N0, int N1>
+struct VariadicEvaluate<Functor, T, N0, N1, 0, 0, 0, 0> {
+  static bool Call(const Functor& functor, T const *const *input, T* output) {
+    return functor(input[0],
+                   input[1],
+                   output);
+  }
+};
+
+template<typename Functor, typename T, int N0>
+struct VariadicEvaluate<Functor, T, N0, 0, 0, 0, 0, 0> {
+  static bool Call(const Functor& functor, T const *const *input, T* output) {
+    return functor(input[0],
+                   output);
+  }
+};
+
+// This is in a struct because default template parameters on a function are not
+// supported in C++03 (though it is available in C++0x). N0 through N5 are the
+// dimension of the input arguments to the user supplied functor.
+template <typename Functor, typename T,
+          int N0 = 0, int N1 = 0, int N2 = 0, int N3 = 0, int N4 = 0, int N5=0>
+struct AutoDiff {
+  static bool Differentiate(const Functor& functor,
+                            T const *const *parameters,
+                            int num_outputs,
+                            T *function_value,
+                            T **jacobians) {
+    typedef Jet<T, N0 + N1 + N2 + N3 + N4 + N5> JetT;
+
+    DCHECK_GT(N0, 0)
+        << "Cost functions must have at least one parameter block.";
+    DCHECK((!N1 && !N2 && !N3 && !N4 && !N5) ||
+           ((N1 > 0) && !N2 && !N3 && !N4 && !N5) ||
+           ((N1 > 0) && (N2 > 0) && !N3 && !N4 && !N5) ||
+           ((N1 > 0) && (N2 > 0) && (N3 > 0) && !N4 && !N5) ||
+           ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && !N5) ||
+           ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0)))
+        << "Zero block cannot precede a non-zero block. Block sizes are "
+        << "(ignore trailing 0s): " << N0 << ", " << N1 << ", " << N2 << ", "
+        << N3 << ", " << N4 << ", " << N5;
+
+    DCHECK_GT(num_outputs, 0);
+
+    FixedArray<JetT, (256 * 7) / sizeof(JetT)> x(
+        N0 + N1 + N2 + N3 + N4 + N5 + num_outputs);
+
+    // It's ugly, but it works.
+    const int jet0 = 0;
+    const int jet1 = N0;
+    const int jet2 = N0 + N1;
+    const int jet3 = N0 + N1 + N2;
+    const int jet4 = N0 + N1 + N2 + N3;
+    const int jet5 = N0 + N1 + N2 + N3 + N4;
+    const int jet6 = N0 + N1 + N2 + N3 + N4 + N5;
+
+    const JetT *unpacked_parameters[6] = {
+        x.get() + jet0,
+        x.get() + jet1,
+        x.get() + jet2,
+        x.get() + jet3,
+        x.get() + jet4,
+        x.get() + jet5,
+    };
+    JetT *output = x.get() + jet6;
+
+#define CERES_MAKE_1ST_ORDER_PERTURBATION(i) \
+    if (N ## i) { \
+      internal::Make1stOrderPerturbation(jet ## i, \
+                                         N ## i, \
+                                         parameters[i], \
+                                         x.get() + jet ## i); \
+    }
+    CERES_MAKE_1ST_ORDER_PERTURBATION(0);
+    CERES_MAKE_1ST_ORDER_PERTURBATION(1);
+    CERES_MAKE_1ST_ORDER_PERTURBATION(2);
+    CERES_MAKE_1ST_ORDER_PERTURBATION(3);
+    CERES_MAKE_1ST_ORDER_PERTURBATION(4);
+    CERES_MAKE_1ST_ORDER_PERTURBATION(5);
+#undef CERES_MAKE_1ST_ORDER_PERTURBATION
+
+    if (!VariadicEvaluate<Functor, JetT,
+                          N0, N1, N2, N3, N4, N5>::Call(
+        functor, unpacked_parameters, output)) {
+      return false;
+    }
+
+    internal::Take0thOrderPart(num_outputs, output, function_value);
+
+#define CERES_TAKE_1ST_ORDER_PERTURBATION(i) \
+    if (N ## i) { \
+      if (jacobians[i]) { \
+        internal::Take1stOrderPart<JetT, T, \
+                                   jet ## i, \
+                                   N ## i>(num_outputs, \
+                                           output, \
+                                           jacobians[i]); \
+      } \
+    }
+    CERES_TAKE_1ST_ORDER_PERTURBATION(0);
+    CERES_TAKE_1ST_ORDER_PERTURBATION(1);
+    CERES_TAKE_1ST_ORDER_PERTURBATION(2);
+    CERES_TAKE_1ST_ORDER_PERTURBATION(3);
+    CERES_TAKE_1ST_ORDER_PERTURBATION(4);
+    CERES_TAKE_1ST_ORDER_PERTURBATION(5);
+#undef CERES_TAKE_1ST_ORDER_PERTURBATION
+    return true;
+  }
+};
+
+}  // namespace internal
+}  // namespace ceres
+
+#endif  // CERES_PUBLIC_INTERNAL_AUTODIFF_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/internal/eigen.h b/extern/libmv/third_party/ceres/include/ceres/internal/eigen.h
new file mode 100644 (file)
index 0000000..be76f9e
--- /dev/null
@@ -0,0 +1,80 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: sameeragarwal@google.com (Sameer Agarwal)
+
+#ifndef CERES_INTERNAL_EIGEN_H_
+#define CERES_INTERNAL_EIGEN_H_
+
+#include "Eigen/Core"
+
+namespace ceres {
+
+using Eigen::Dynamic;
+using Eigen::RowMajor;
+
+typedef Eigen::Matrix<double, Dynamic, 1> Vector;
+typedef Eigen::Matrix<double, Dynamic, Dynamic, RowMajor> Matrix;
+typedef Eigen::Map<Vector> VectorRef;
+typedef Eigen::Map<Matrix> MatrixRef;
+typedef Eigen::Map<Matrix, Eigen::Aligned> AlignedMatrixRef;
+typedef Eigen::Map<const Vector> ConstVectorRef;
+typedef Eigen::Map<const Matrix, Eigen::Aligned> ConstAlignedMatrixRef;
+typedef Eigen::Map<const Matrix> ConstMatrixRef;
+
+// C++ does not support templated typdefs, thus the need for this
+// struct so that we can support statically sized Matrix and Maps.
+template <int num_rows = Eigen::Dynamic, int num_cols = Eigen::Dynamic>
+struct EigenTypes {
+  typedef Eigen::Matrix <double, num_rows, num_cols, RowMajor>
+  Matrix;
+
+  typedef Eigen::Map<
+    Eigen::Matrix<double, num_rows, num_cols, RowMajor> >
+  MatrixRef;
+
+  typedef Eigen::Matrix <double, num_rows, 1>
+  Vector;
+
+  typedef Eigen::Map <
+    Eigen::Matrix<double, num_rows, 1> >
+  VectorRef;
+
+
+  typedef Eigen::Map<
+    const Eigen::Matrix<double, num_rows, num_cols, RowMajor> >
+  ConstMatrixRef;
+
+  typedef Eigen::Map <
+    const Eigen::Matrix<double, num_rows, 1> >
+  ConstVectorRef;
+};
+
+}  // namespace ceres
+
+#endif  // CERES_INTERNAL_EIGEN_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/internal/fixed_array.h b/extern/libmv/third_party/ceres/include/ceres/internal/fixed_array.h
new file mode 100644 (file)
index 0000000..30cc5fc
--- /dev/null
@@ -0,0 +1,193 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: rennie@google.com (Jeffrey Rennie)
+// Author: sanjay@google.com (Sanjay Ghemawat) -- renamed to FixedArray
+
+#ifndef CERES_PUBLIC_INTERNAL_FIXED_ARRAY_H_
+#define CERES_PUBLIC_INTERNAL_FIXED_ARRAY_H_
+
+#include <cstddef>
+#include <glog/logging.h>
+#include "ceres/internal/manual_constructor.h"
+
+namespace ceres {
+namespace internal {
+
+// A FixedArray<T> represents a non-resizable array of T where the
+// length of the array does not need to be a compile time constant.
+//
+// FixedArray allocates small arrays inline, and large arrays on
+// the heap.  It is a good replacement for non-standard and deprecated
+// uses of alloca() and variable length arrays (a GCC extension).
+//
+// FixedArray keeps performance fast for small arrays, because it
+// avoids heap operations.  It also helps reduce the chances of
+// accidentally overflowing your stack if large input is passed to
+// your function.
+//
+// Also, FixedArray is useful for writing portable code.  Not all
+// compilers support arrays of dynamic size.
+
+// Most users should not specify an inline_elements argument and let
+// FixedArray<> automatically determine the number of elements
+// to store inline based on sizeof(T).
+//
+// If inline_elements is specified, the FixedArray<> implementation
+// will store arrays of length <= inline_elements inline.
+//
+// Finally note that unlike vector<T> FixedArray<T> will not zero-initialize
+// simple types like int, double, bool, etc.
+//
+// Non-POD types will be default-initialized just like regular vectors or
+// arrays.
+
+#if defined(_WIN64)
+   typedef __int64      ssize_t;
+#elif defined(_WIN32)
+   typedef __int32      ssize_t;
+#endif
+
+template <typename T, ssize_t inline_elements = -1>
+class FixedArray {
+ public:
+  // For playing nicely with stl:
+  typedef T value_type;
+  typedef T* iterator;
+  typedef T const* const_iterator;
+  typedef T& reference;
+  typedef T const& const_reference;
+  typedef T* pointer;
+  typedef std::ptrdiff_t difference_type;
+  typedef size_t size_type;
+
+  // REQUIRES: n >= 0
+  // Creates an array object that can store "n" elements.
+  //
+  // FixedArray<T> will not zero-initialiaze POD (simple) types like int,
+  // double, bool, etc.
+  // Non-POD types will be default-initialized just like regular vectors or
+  // arrays.
+  explicit FixedArray(size_type n);
+
+  // Releases any resources.
+  ~FixedArray();
+
+  // Returns the length of the array.
+  inline size_type size() const { return size_; }
+
+  // Returns the memory size of the array in bytes.
+  inline size_t memsize() const { return size_ * sizeof(T); }
+
+  // Returns a pointer to the underlying element array.
+  inline const T* get() const { return &array_[0].element; }
+  inline T* get() { return &array_[0].element; }
+
+  // REQUIRES: 0 <= i < size()
+  // Returns a reference to the "i"th element.
+  inline T& operator[](size_type i) {
+    DCHECK_GE(i, 0);
+    DCHECK_LT(i, size_);
+    return array_[i].element;
+  }
+
+  // REQUIRES: 0 <= i < size()
+  // Returns a reference to the "i"th element.
+  inline const T& operator[](size_type i) const {
+    DCHECK_GE(i, 0);
+    DCHECK_LT(i, size_);
+    return array_[i].element;
+  }
+
+  inline iterator begin() { return &array_[0].element; }
+  inline iterator end() { return &array_[size_].element; }
+
+  inline const_iterator begin() const { return &array_[0].element; }
+  inline const_iterator end() const { return &array_[size_].element; }
+
+ private:
+  // Container to hold elements of type T.  This is necessary to handle
+  // the case where T is a a (C-style) array.  The size of InnerContainer
+  // and T must be the same, otherwise callers' assumptions about use
+  // of this code will be broken.
+  struct InnerContainer {
+    T element;
+  };
+
+  // How many elements should we store inline?
+  //   a. If not specified, use a default of 256 bytes (256 bytes
+  //      seems small enough to not cause stack overflow or unnecessary
+  //      stack pollution, while still allowing stack allocation for
+  //      reasonably long character arrays.
+  //   b. Never use 0 length arrays (not ISO C++)
+  static const size_type S1 = ((inline_elements < 0)
+                               ? (256/sizeof(T)) : inline_elements);
+  static const size_type S2 = (S1 <= 0) ? 1 : S1;
+  static const size_type kInlineElements = S2;
+
+  size_type const       size_;
+  InnerContainer* const array_;
+
+  // Allocate some space, not an array of elements of type T, so that we can
+  // skip calling the T constructors and destructors for space we never use.
+  ManualConstructor<InnerContainer> inline_space_[kInlineElements];
+};
+
+// Implementation details follow
+
+template <class T, ssize_t S>
+inline FixedArray<T, S>::FixedArray(typename FixedArray<T, S>::size_type n)
+    : size_(n),
+      array_((n <= kInlineElements
+              ? reinterpret_cast<InnerContainer*>(inline_space_)
+              : new InnerContainer[n])) {
+  DCHECK_GE(n, 0);
+
+  // Construct only the elements actually used.
+  if (array_ == reinterpret_cast<InnerContainer*>(inline_space_)) {
+    for (int i = 0; i != size_; ++i) {
+      inline_space_[i].Init();
+    }
+  }
+}
+
+template <class T, ssize_t S>
+inline FixedArray<T, S>::~FixedArray() {
+  if (array_ != reinterpret_cast<InnerContainer*>(inline_space_)) {
+    delete[] array_;
+  } else {
+    for (int i = 0; i != size_; ++i) {
+      inline_space_[i].Destroy();
+    }
+  }
+}
+
+}  // namespace internal
+}  // namespace ceres
+
+#endif  // CERES_PUBLIC_INTERNAL_FIXED_ARRAY_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/internal/macros.h b/extern/libmv/third_party/ceres/include/ceres/internal/macros.h
new file mode 100644 (file)
index 0000000..0cfd773
--- /dev/null
@@ -0,0 +1,154 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//
+// Various Google-specific macros.
+//
+// This code is compiled directly on many platforms, including client
+// platforms like Windows, Mac, and embedded systems.  Before making
+// any changes here, make sure that you're not breaking any platforms.
+
+#ifndef CERES_PUBLIC_INTERNAL_MACROS_H_
+#define CERES_PUBLIC_INTERNAL_MACROS_H_
+
+#include <cstddef>  // For size_t.
+
+// A macro to disallow the copy constructor and operator= functions
+// This should be used in the private: declarations for a class
+//
+// For disallowing only assign or copy, write the code directly, but declare
+// the intend in a comment, for example:
+// void operator=(const TypeName&);  // DISALLOW_ASSIGN
+// Note, that most uses of DISALLOW_ASSIGN and DISALLOW_COPY are broken
+// semantically, one should either use disallow both or neither. Try to
+// avoid these in new code.
+#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
+  TypeName(const TypeName&);               \
+  void operator=(const TypeName&)
+
+// A macro to disallow all the implicit constructors, namely the
+// default constructor, copy constructor and operator= functions.
+//
+// This should be used in the private: declarations for a class
+// that wants to prevent anyone from instantiating it. This is
+// especially useful for classes containing only static methods.
+#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
+  TypeName();                                    \
+  DISALLOW_COPY_AND_ASSIGN(TypeName)
+
+// The arraysize(arr) macro returns the # of elements in an array arr.
+// The expression is a compile-time constant, and therefore can be
+// used in defining new arrays, for example.  If you use arraysize on
+// a pointer by mistake, you will get a compile-time error.
+//
+// One caveat is that arraysize() doesn't accept any array of an
+// anonymous type or a type defined inside a function.  In these rare
+// cases, you have to use the unsafe ARRAYSIZE() macro below.  This is
+// due to a limitation in C++'s template system.  The limitation might
+// eventually be removed, but it hasn't happened yet.
+
+// This template function declaration is used in defining arraysize.
+// Note that the function doesn't need an implementation, as we only
+// use its type.
+template <typename T, size_t N>
+char (&ArraySizeHelper(T (&array)[N]))[N];
+
+// That gcc wants both of these prototypes seems mysterious. VC, for
+// its part, can't decide which to use (another mystery). Matching of
+// template overloads: the final frontier.
+#ifndef _WIN32
+template <typename T, size_t N>
+char (&ArraySizeHelper(const T (&array)[N]))[N];
+#endif
+
+#define arraysize(array) (sizeof(ArraySizeHelper(array)))
+
+// ARRAYSIZE performs essentially the same calculation as arraysize,
+// but can be used on anonymous types or types defined inside
+// functions.  It's less safe than arraysize as it accepts some
+// (although not all) pointers.  Therefore, you should use arraysize
+// whenever possible.
+//
+// The expression ARRAYSIZE(a) is a compile-time constant of type
+// size_t.
+//
+// ARRAYSIZE catches a few type errors.  If you see a compiler error
+//
+//   "warning: division by zero in ..."
+//
+// when using ARRAYSIZE, you are (wrongfully) giving it a pointer.
+// You should only use ARRAYSIZE on statically allocated arrays.
+//
+// The following comments are on the implementation details, and can
+// be ignored by the users.
+//
+// ARRAYSIZE(arr) works by inspecting sizeof(arr) (the # of bytes in
+// the array) and sizeof(*(arr)) (the # of bytes in one array
+// element).  If the former is divisible by the latter, perhaps arr is
+// indeed an array, in which case the division result is the # of
+// elements in the array.  Otherwise, arr cannot possibly be an array,
+// and we generate a compiler error to prevent the code from
+// compiling.
+//
+// Since the size of bool is implementation-defined, we need to cast
+// !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final
+// result has type size_t.
+//
+// This macro is not perfect as it wrongfully accepts certain
+// pointers, namely where the pointer size is divisible by the pointee
+// size.  Since all our code has to go through a 32-bit compiler,
+// where a pointer is 4 bytes, this means all pointers to a type whose
+// size is 3 or greater than 4 will be (righteously) rejected.
+//
+// Kudos to Jorg Brown for this simple and elegant implementation.
+//
+// - wan 2005-11-16
+//
+// Starting with Visual C++ 2005, WinNT.h includes ARRAYSIZE. However,
+// the definition comes from the over-broad windows.h header that 
+// introduces a macro, ERROR, that conflicts with the logging framework
+// that Ceres uses. Instead, rename ARRAYSIZE to CERES_ARRAYSIZE.
+#define CERES_ARRAYSIZE(a) \
+  ((sizeof(a) / sizeof(*(a))) / \
+   static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
+
+// Tell the compiler to warn about unused return values for functions declared
+// with this macro.  The macro should be used on function declarations
+// following the argument list:
+//
+//   Sprocket* AllocateSprocket() MUST_USE_RESULT;
+//
+#undef MUST_USE_RESULT
+#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) \
+  && !defined(COMPILER_ICC)
+#define MUST_USE_RESULT __attribute__ ((warn_unused_result))
+#else
+#define MUST_USE_RESULT
+#endif
+
+#endif  // CERES_PUBLIC_INTERNAL_MACROS_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/internal/manual_constructor.h b/extern/libmv/third_party/ceres/include/ceres/internal/manual_constructor.h
new file mode 100644 (file)
index 0000000..a1d1f44
--- /dev/null
@@ -0,0 +1,214 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: kenton@google.com (Kenton Varda)
+//
+// ManualConstructor statically-allocates space in which to store some
+// object, but does not initialize it.  You can then call the constructor
+// and destructor for the object yourself as you see fit.  This is useful
+// for memory management optimizations, where you want to initialize and
+// destroy an object multiple times but only allocate it once.
+//
+// (When I say ManualConstructor statically allocates space, I mean that
+// the ManualConstructor object itself is forced to be the right size.)
+
+#ifndef CERES_PUBLIC_INTERNAL_MANUAL_CONSTRUCTOR_H_
+#define CERES_PUBLIC_INTERNAL_MANUAL_CONSTRUCTOR_H_
+
+#include <new>
+
+namespace ceres {
+namespace internal {
+
+// ------- Define ALIGNED_CHAR_ARRAY --------------------------------
+
+#ifndef ALIGNED_CHAR_ARRAY
+
+// Because MSVC and older GCCs require that the argument to their alignment
+// construct to be a literal constant integer, we use a template instantiated
+// at all the possible powers of two.
+template<int alignment, int size> struct AlignType { };
+template<int size> struct AlignType<0, size> { typedef char result[size]; };
+#if defined(_MSC_VER)
+#define BASE_PORT_H_ALIGN_ATTRIBUTE(X) __declspec(align(X))
+#define BASE_PORT_H_ALIGN_OF(T) __alignof(T)
+#elif defined(__GNUC__)
+#define BASE_PORT_H_ALIGN_ATTRIBUTE(X) __attribute__((aligned(X)))
+#define BASE_PORT_H_ALIGN_OF(T) __alignof__(T)
+#endif
+
+#if defined(BASE_PORT_H_ALIGN_ATTRIBUTE)
+
+#define BASE_PORT_H_ALIGNTYPE_TEMPLATE(X) \
+  template<int size> struct AlignType<X, size> { \
+    typedef BASE_PORT_H_ALIGN_ATTRIBUTE(X) char result[size]; \
+  }
+
+BASE_PORT_H_ALIGNTYPE_TEMPLATE(1);
+BASE_PORT_H_ALIGNTYPE_TEMPLATE(2);
+BASE_PORT_H_ALIGNTYPE_TEMPLATE(4);
+BASE_PORT_H_ALIGNTYPE_TEMPLATE(8);
+BASE_PORT_H_ALIGNTYPE_TEMPLATE(16);
+BASE_PORT_H_ALIGNTYPE_TEMPLATE(32);
+BASE_PORT_H_ALIGNTYPE_TEMPLATE(64);
+BASE_PORT_H_ALIGNTYPE_TEMPLATE(128);
+BASE_PORT_H_ALIGNTYPE_TEMPLATE(256);
+BASE_PORT_H_ALIGNTYPE_TEMPLATE(512);
+BASE_PORT_H_ALIGNTYPE_TEMPLATE(1024);
+BASE_PORT_H_ALIGNTYPE_TEMPLATE(2048);
+BASE_PORT_H_ALIGNTYPE_TEMPLATE(4096);
+BASE_PORT_H_ALIGNTYPE_TEMPLATE(8192);
+// Any larger and MSVC++ will complain.
+
+#define ALIGNED_CHAR_ARRAY(T, Size) \
+  typename AlignType<BASE_PORT_H_ALIGN_OF(T), sizeof(T) * Size>::result
+
+#undef BASE_PORT_H_ALIGNTYPE_TEMPLATE
+#undef BASE_PORT_H_ALIGN_ATTRIBUTE
+
+#else  // defined(BASE_PORT_H_ALIGN_ATTRIBUTE)
+#define ALIGNED_CHAR_ARRAY you_must_define_ALIGNED_CHAR_ARRAY_for_your_compiler
+#endif // defined(BASE_PORT_H_ALIGN_ATTRIBUTE)
+
+#undef BASE_PORT_H_ALIGNTYPE_TEMPLATE
+#undef BASE_PORT_H_ALIGN_ATTRIBUTE
+
+#endif  // ALIGNED_CHAR_ARRAY
+
+template <typename Type>
+class ManualConstructor {
+ public:
+  // No constructor or destructor because one of the most useful uses of
+  // this class is as part of a union, and members of a union cannot have
+  // constructors or destructors.  And, anyway, the whole point of this
+  // class is to bypass these.
+
+  inline Type* get() {
+    return reinterpret_cast<Type*>(space_);
+  }
+  inline const Type* get() const  {
+    return reinterpret_cast<const Type*>(space_);
+  }
+
+  inline Type* operator->() { return get(); }
+  inline const Type* operator->() const { return get(); }
+
+  inline Type& operator*() { return *get(); }
+  inline const Type& operator*() const { return *get(); }
+
+  // You can pass up to four constructor arguments as arguments of Init().
+  inline void Init() {
+    new(space_) Type;
+  }
+
+  template <typename T1>
+  inline void Init(const T1& p1) {
+    new(space_) Type(p1);
+  }
+
+  template <typename T1, typename T2>
+  inline void Init(const T1& p1, const T2& p2) {
+    new(space_) Type(p1, p2);
+  }
+
+  template <typename T1, typename T2, typename T3>
+  inline void Init(const T1& p1, const T2& p2, const T3& p3) {
+    new(space_) Type(p1, p2, p3);
+  }
+
+  template <typename T1, typename T2, typename T3, typename T4>
+  inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4) {
+    new(space_) Type(p1, p2, p3, p4);
+  }
+
+  template <typename T1, typename T2, typename T3, typename T4, typename T5>
+  inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4,
+                   const T5& p5) {
+    new(space_) Type(p1, p2, p3, p4, p5);
+  }
+
+  template <typename T1, typename T2, typename T3, typename T4, typename T5,
+            typename T6>
+  inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4,
+                   const T5& p5, const T6& p6) {
+    new(space_) Type(p1, p2, p3, p4, p5, p6);
+  }
+
+  template <typename T1, typename T2, typename T3, typename T4, typename T5,
+            typename T6, typename T7>
+  inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4,
+                   const T5& p5, const T6& p6, const T7& p7) {
+    new(space_) Type(p1, p2, p3, p4, p5, p6, p7);
+  }
+
+  template <typename T1, typename T2, typename T3, typename T4, typename T5,
+            typename T6, typename T7, typename T8>
+  inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4,
+                   const T5& p5, const T6& p6, const T7& p7, const T8& p8) {
+    new(space_) Type(p1, p2, p3, p4, p5, p6, p7, p8);
+  }
+
+  template <typename T1, typename T2, typename T3, typename T4, typename T5,
+            typename T6, typename T7, typename T8, typename T9>
+  inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4,
+                   const T5& p5, const T6& p6, const T7& p7, const T8& p8,
+                   const T9& p9) {
+    new(space_) Type(p1, p2, p3, p4, p5, p6, p7, p8, p9);
+  }
+
+  template <typename T1, typename T2, typename T3, typename T4, typename T5,
+            typename T6, typename T7, typename T8, typename T9, typename T10>
+  inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4,
+                   const T5& p5, const T6& p6, const T7& p7, const T8& p8,
+                   const T9& p9, const T10& p10) {
+    new(space_) Type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
+  }
+
+  template <typename T1, typename T2, typename T3, typename T4, typename T5,
+            typename T6, typename T7, typename T8, typename T9, typename T10,
+            typename T11>
+  inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4,
+                   const T5& p5, const T6& p6, const T7& p7, const T8& p8,
+                   const T9& p9, const T10& p10, const T11& p11) {
+    new(space_) Type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
+  }
+
+  inline void Destroy() {
+    get()->~Type();
+  }
+
+ private:
+  ALIGNED_CHAR_ARRAY(Type, 1) space_;
+};
+
+#undef ALIGNED_CHAR_ARRAY
+
+}  // namespace internal
+}  // namespace ceres
+
+#endif  // CERES_PUBLIC_INTERNAL_MANUAL_CONSTRUCTOR_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/internal/port.h b/extern/libmv/third_party/ceres/include/ceres/internal/port.h
new file mode 100644 (file)
index 0000000..9a3e5cc
--- /dev/null
@@ -0,0 +1,44 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: keir@google.com (Keir Mierle)
+
+#ifndef CERES_PUBLIC_INTERNAL_PORT_H_
+#define CERES_PUBLIC_INTERNAL_PORT_H_
+
+namespace ceres {
+
+// It is unfortunate that this import of the entire standard namespace is
+// necessary. The reasons are historical and won't be explained here, but
+// suffice to say it is not a mistake and can't be removed without breaking
+// things outside of the Ceres optimization package.
+using namespace std;
+
+}  // namespace ceres
+
+#endif  // CERES_PUBLIC_INTERNAL_PORT_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/internal/scoped_ptr.h b/extern/libmv/third_party/ceres/include/ceres/internal/scoped_ptr.h
new file mode 100644 (file)
index 0000000..44f198b
--- /dev/null
@@ -0,0 +1,311 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: jorg@google.com (Jorg Brown)
+//
+// This is an implementation designed to match the anticipated future TR2
+// implementation of the scoped_ptr class, and its closely-related brethren,
+// scoped_array, scoped_ptr_malloc, and make_scoped_ptr.
+
+#ifndef CERES_PUBLIC_INTERNAL_SCOPED_PTR_H_
+#define CERES_PUBLIC_INTERNAL_SCOPED_PTR_H_
+
+#include <assert.h>
+#include <stdlib.h>
+#include <cstddef>
+
+namespace ceres {
+namespace internal {
+
+template <class C> class scoped_ptr;
+template <class C, class Free> class scoped_ptr_malloc;
+template <class C> class scoped_array;
+
+template <class C>
+scoped_ptr<C> make_scoped_ptr(C *);
+
+// A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T>
+// automatically deletes the pointer it holds (if any). That is, scoped_ptr<T>
+// owns the T object that it points to. Like a T*, a scoped_ptr<T> may hold
+// either NULL or a pointer to a T object. Also like T*, scoped_ptr<T> is
+// thread-compatible, and once you dereference it, you get the threadsafety
+// guarantees of T.
+//
+// The size of a scoped_ptr is small: sizeof(scoped_ptr<C>) == sizeof(C*)
+template <class C>
+class scoped_ptr {
+ public:
+
+  // The element type
+  typedef C element_type;
+
+  // Constructor.  Defaults to intializing with NULL.
+  // There is no way to create an uninitialized scoped_ptr.
+  // The input parameter must be allocated with new.
+  explicit scoped_ptr(C* p = NULL) : ptr_(p) { }
+
+  // Destructor.  If there is a C object, delete it.
+  // We don't need to test ptr_ == NULL because C++ does that for us.
+  ~scoped_ptr() {
+    enum { type_must_be_complete = sizeof(C) };
+    delete ptr_;
+  }
+
+  // Reset.  Deletes the current owned object, if any.
+  // Then takes ownership of a new object, if given.
+  // this->reset(this->get()) works.
+  void reset(C* p = NULL) {
+    if (p != ptr_) {
+      enum { type_must_be_complete = sizeof(C) };
+      delete ptr_;
+      ptr_ = p;
+    }
+  }
+
+  // Accessors to get the owned object.
+  // operator* and operator-> will assert() if there is no current object.
+  C& operator*() const {
+    assert(ptr_ != NULL);
+    return *ptr_;
+  }
+  C* operator->() const  {
+    assert(ptr_ != NULL);
+    return ptr_;
+  }
+  C* get() const { return ptr_; }
+
+  // Comparison operators.
+  // These return whether a scoped_ptr and a raw pointer refer to
+  // the same object, not just to two different but equal objects.
+  bool operator==(const C* p) const { return ptr_ == p; }
+  bool operator!=(const C* p) const { return ptr_ != p; }
+
+  // Swap two scoped pointers.
+  void swap(scoped_ptr& p2) {
+    C* tmp = ptr_;
+    ptr_ = p2.ptr_;
+    p2.ptr_ = tmp;
+  }
+
+  // Release a pointer.
+  // The return value is the current pointer held by this object.
+  // If this object holds a NULL pointer, the return value is NULL.
+  // After this operation, this object will hold a NULL pointer,
+  // and will not own the object any more.
+  C* release() {
+    C* retVal = ptr_;
+    ptr_ = NULL;
+    return retVal;
+  }
+
+ private:
+  C* ptr_;
+
+  // google3 friend class that can access copy ctor (although if it actually
+  // calls a copy ctor, there will be a problem) see below
+  friend scoped_ptr<C> make_scoped_ptr<C>(C *p);
+
+  // Forbid comparison of scoped_ptr types.  If C2 != C, it totally doesn't
+  // make sense, and if C2 == C, it still doesn't make sense because you should
+  // never have the same object owned by two different scoped_ptrs.
+  template <class C2> bool operator==(scoped_ptr<C2> const& p2) const;
+  template <class C2> bool operator!=(scoped_ptr<C2> const& p2) const;
+
+  // Disallow evil constructors
+  scoped_ptr(const scoped_ptr&);
+  void operator=(const scoped_ptr&);
+};
+
+// Free functions
+template <class C>
+inline void swap(scoped_ptr<C>& p1, scoped_ptr<C>& p2) {
+  p1.swap(p2);
+}
+
+template <class C>
+inline bool operator==(const C* p1, const scoped_ptr<C>& p2) {
+  return p1 == p2.get();
+}
+
+template <class C>
+inline bool operator==(const C* p1, const scoped_ptr<const C>& p2) {
+  return p1 == p2.get();
+}
+
+template <class C>
+inline bool operator!=(const C* p1, const scoped_ptr<C>& p2) {
+  return p1 != p2.get();
+}
+
+template <class C>
+inline bool operator!=(const C* p1, const scoped_ptr<const C>& p2) {
+  return p1 != p2.get();
+}
+
+template <class C>
+scoped_ptr<C> make_scoped_ptr(C *p) {
+  // This does nothing but to return a scoped_ptr of the type that the passed
+  // pointer is of.  (This eliminates the need to specify the name of T when
+  // making a scoped_ptr that is used anonymously/temporarily.)  From an
+  // access control point of view, we construct an unnamed scoped_ptr here
+  // which we return and thus copy-construct.  Hence, we need to have access
+  // to scoped_ptr::scoped_ptr(scoped_ptr const &).  However, it is guaranteed
+  // that we never actually call the copy constructor, which is a good thing
+  // as we would call the temporary's object destructor (and thus delete p)
+  // if we actually did copy some object, here.
+  return scoped_ptr<C>(p);
+}
+
+// scoped_array<C> is like scoped_ptr<C>, except that the caller must allocate
+// with new [] and the destructor deletes objects with delete [].
+//
+// As with scoped_ptr<C>, a scoped_array<C> either points to an object
+// or is NULL.  A scoped_array<C> owns the object that it points to.
+// scoped_array<T> is thread-compatible, and once you index into it,
+// the returned objects have only the threadsafety guarantees of T.
+//
+// Size: sizeof(scoped_array<C>) == sizeof(C*)
+template <class C>
+class scoped_array {
+ public:
+
+  // The element type
+  typedef C element_type;
+
+  // Constructor.  Defaults to intializing with NULL.
+  // There is no way to create an uninitialized scoped_array.
+  // The input parameter must be allocated with new [].
+  explicit scoped_array(C* p = NULL) : array_(p) { }
+
+  // Destructor.  If there is a C object, delete it.
+  // We don't need to test ptr_ == NULL because C++ does that for us.
+  ~scoped_array() {
+    enum { type_must_be_complete = sizeof(C) };
+    delete[] array_;
+  }
+
+  // Reset. Deletes the current owned object, if any.
+  // Then takes ownership of a new object, if given.
+  // this->reset(this->get()) works.
+  void reset(C* p = NULL) {
+    if (p != array_) {
+      enum { type_must_be_complete = sizeof(C) };
+      delete[] array_;
+      array_ = p;
+    }
+  }
+
+  // Get one element of the current object.
+  // Will assert() if there is no current object, or index i is negative.
+  C& operator[](std::ptrdiff_t i) const {
+    assert(i >= 0);
+    assert(array_ != NULL);
+    return array_[i];
+  }
+
+  // Get a pointer to the zeroth element of the current object.
+  // If there is no current object, return NULL.
+  C* get() const {
+    return array_;
+  }
+
+  // Comparison operators.
+  // These return whether a scoped_array and a raw pointer refer to
+  // the same array, not just to two different but equal arrays.
+  bool operator==(const C* p) const { return array_ == p; }
+  bool operator!=(const C* p) const { return array_ != p; }
+
+  // Swap two scoped arrays.
+  void swap(scoped_array& p2) {
+    C* tmp = array_;
+    array_ = p2.array_;
+    p2.array_ = tmp;
+  }
+
+  // Release an array.
+  // The return value is the current pointer held by this object.
+  // If this object holds a NULL pointer, the return value is NULL.
+  // After this operation, this object will hold a NULL pointer,
+  // and will not own the object any more.
+  C* release() {
+    C* retVal = array_;
+    array_ = NULL;
+    return retVal;
+  }
+
+ private:
+  C* array_;
+
+  // Forbid comparison of different scoped_array types.
+  template <class C2> bool operator==(scoped_array<C2> const& p2) const;
+  template <class C2> bool operator!=(scoped_array<C2> const& p2) const;
+
+  // Disallow evil constructors
+  scoped_array(const scoped_array&);
+  void operator=(const scoped_array&);
+};
+
+// Free functions
+template <class C>
+inline void swap(scoped_array<C>& p1, scoped_array<C>& p2) {
+  p1.swap(p2);
+}
+
+template <class C>
+inline bool operator==(const C* p1, const scoped_array<C>& p2) {
+  return p1 == p2.get();
+}
+
+template <class C>
+inline bool operator==(const C* p1, const scoped_array<const C>& p2) {
+  return p1 == p2.get();
+}
+
+template <class C>
+inline bool operator!=(const C* p1, const scoped_array<C>& p2) {
+  return p1 != p2.get();
+}
+
+template <class C>
+inline bool operator!=(const C* p1, const scoped_array<const C>& p2) {
+  return p1 != p2.get();
+}
+
+// This class wraps the c library function free() in a class that can be
+// passed as a template argument to scoped_ptr_malloc below.
+class ScopedPtrMallocFree {
+ public:
+  inline void operator()(void* x) const {
+    free(x);
+  }
+};
+
+}  // namespace internal
+}  // namespace ceres
+
+#endif  // CERES_PUBLIC_INTERNAL_SCOPED_PTR_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/iteration_callback.h b/extern/libmv/third_party/ceres/include/ceres/iteration_callback.h
new file mode 100644 (file)
index 0000000..88da992
--- /dev/null
@@ -0,0 +1,159 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: sameeragarwal@google.com (Sameer Agarwal)
+//
+// When an iteration callback is specified, Ceres calls the callback after each
+// optimizer step and pass it an IterationSummary object, defined below.
+
+#ifndef CERES_PUBLIC_ITERATION_CALLBACK_H_
+#define CERES_PUBLIC_ITERATION_CALLBACK_H_
+
+#include "ceres/types.h"
+
+namespace ceres {
+
+// This struct describes the state of the optimizer after each
+// iteration of the minimization.
+struct IterationSummary {
+  // Current iteration number.
+  int32 iteration;
+
+  // Whether or not the algorithm made progress in this iteration.
+  bool step_is_successful;
+
+  // Value of the objective function.
+  double cost;
+
+  // Change in the value of the objective function in this
+  // iteration. This can be positive or negative. Negative change
+  // means that the step was not successful.
+  double cost_change;
+
+  // Infinity norm of the gradient vector.
+  double gradient_max_norm;
+
+  // 2-norm of the size of the step computed by the optimization
+  // algorithm.
+  double step_norm;
+
+  // For trust region algorithms, the ratio of the actual change in
+  // cost and the change in the cost of the linearized approximation.
+  double relative_decrease;
+
+  // Value of the regularization parameter for Levenberg-Marquardt
+  // algorithm at the end of the current iteration.
+  double mu;
+
+  // For the inexact step Levenberg-Marquardt algorithm, this is the
+  // relative accuracy with which the Newton(LM) step is solved. This
+  // number affects only the iterative solvers capable of solving
+  // linear systems inexactly. Factorization-based exact solvers
+  // ignore it.
+  double eta;
+
+  // Number of iterations taken by the linear solver to solve for the
+  // Newton step.
+  int linear_solver_iterations;
+
+  // TODO(sameeragarwal): Change to use a higher precision timer using
+  // clock_gettime.
+  // Time (in seconds) spent inside the linear least squares solver.
+  int iteration_time_sec;
+
+  // Time (in seconds) spent inside the linear least squares solver.
+  int linear_solver_time_sec;
+};
+
+// Interface for specifying callbacks that are executed at the end of
+// each iteration of the Minimizer. The solver uses the return value
+// of operator() to decide whether to continue solving or to
+// terminate. The user can return three values.
+//
+// SOLVER_ABORT indicates that the callback detected an abnormal
+// situation. The solver returns without updating the parameter blocks
+// (unless Solver::Options::update_state_every_iteration is set
+// true). Solver returns with Solver::Summary::termination_type set to
+// USER_ABORT.
+//
+// SOLVER_TERMINATE_SUCCESSFULLY indicates that there is no need to
+// optimize anymore (some user specified termination criterion has
+// been met). Solver returns with Solver::Summary::termination_type
+// set to USER_SUCCESS.
+//
+// SOLVER_CONTINUE indicates that the solver should continue
+// optimizing.
+//
+// For example, the following Callback is used internally by Ceres to
+// log the progress of the optimization.
+//
+// Callback for logging the state of the minimizer to STDERR or STDOUT
+// depending on the user's preferences and logging level.
+//
+//   class LoggingCallback : public IterationCallback {
+//    public:
+//     explicit LoggingCallback(bool log_to_stdout)
+//         : log_to_stdout_(log_to_stdout) {}
+//
+//     ~LoggingCallback() {}
+//
+//     CallbackReturnType operator()(const IterationSummary& summary) {
+//       const char* kReportRowFormat =
+//           "% 4d: f:% 8e d:% 3.2e g:% 3.2e h:% 3.2e "
+//           "rho:% 3.2e mu:% 3.2e eta:% 3.2e li:% 3d";
+//       string output = StringPrintf(kReportRowFormat,
+//                                    summary.iteration,
+//                                    summary.cost,
+//                                    summary.cost_change,
+//                                    summary.gradient_max_norm,
+//                                    summary.step_norm,
+//                                    summary.relative_decrease,
+//                                    summary.mu,
+//                                    summary.eta,
+//                                    summary.linear_solver_iterations);
+//       if (log_to_stdout_) {
+//         cout << output << endl;
+//       } else {
+//         VLOG(1) << output;
+//       }
+//       return SOLVER_CONTINUE;
+//     }
+//
+//    private:
+//     const bool log_to_stdout_;
+//   };
+//
+class IterationCallback {
+ public:
+  virtual ~IterationCallback() {}
+  virtual CallbackReturnType operator()(const IterationSummary& summary) = 0;
+};
+
+}  // namespace ceres
+
+#endif  // CERES_PUBLIC_ITERATION_CALLBACK_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/jet.h b/extern/libmv/third_party/ceres/include/ceres/jet.h
new file mode 100644 (file)
index 0000000..f73c698
--- /dev/null
@@ -0,0 +1,671 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: keir@google.com (Keir Mierle)
+//
+// A simple implementation of N-dimensional dual numbers, for automatically
+// computing exact derivatives of functions.
+//
+// While a complete treatment of the mechanics of automatic differentation is
+// beyond the scope of this header (see
+// http://en.wikipedia.org/wiki/Automatic_differentiation for details), the
+// basic idea is to extend normal arithmetic with an extra element, "e," often
+// denoted with the greek symbol epsilon, such that e != 0 but e^2 = 0. Dual
+// numbers are extensions of the real numbers analogous to complex numbers:
+// whereas complex numbers augment the reals by introducing an imaginary unit i
+// such that i^2 = -1, dual numbers introduce an "infinitesimal" unit e such
+// that e^2 = 0. Dual numbers have two components: the "real" component and the
+// "infinitesimal" component, generally written as x + y*e. Surprisingly, this
+// leads to a convenient method for computing exact derivatives without needing
+// to manipulate complicated symbolic expressions.
+//
+// For example, consider the function
+//
+//   f(x) = x^2 ,
+//
+// evaluated at 10. Using normal arithmetic, f(10) = 100, and df/dx(10) = 20.
+// Next, augument 10 with an infinitesimal to get:
+//
+//   f(10 + e) = (10 + e)^2
+//             = 100 + 2 * 10 * e + e^2
+//             = 100 + 20 * e       -+-
+//                     --            |
+//                     |             +--- This is zero, since e^2 = 0
+//                     |
+//                     +----------------- This is df/dx!
+//
+// Note that the derivative of f with respect to x is simply the infinitesimal
+// component of the value of f(x + e). So, in order to take the derivative of
+// any function, it is only necessary to replace the numeric "object" used in
+// the function with one extended with infinitesimals. The class Jet, defined in
+// this header, is one such example of this, where substitution is done with
+// templates.
+//
+// To handle derivatives of functions taking multiple arguments, different
+// infinitesimals are used, one for each variable to take the derivative of. For
+// example, consider a scalar function of two scalar parameters x and y:
+//
+//   f(x, y) = x^2 + x * y
+//
+// Following the technique above, to compute the derivatives df/dx and df/dy for
+// f(1, 3) involves doing two evaluations of f, the first time replacing x with
+// x + e, the second time replacing y with y + e.
+//
+// For df/dx:
+//
+//   f(1 + e, y) = (1 + e)^2 + (1 + e) * 3
+//               = 1 + 2 * e + 3 + 3 * e
+//               = 4 + 5 * e
+//
+//               --> df/dx = 5
+//
+// For df/dy:
+//
+//   f(1, 3 + e) = 1^2 + 1 * (3 + e)
+//               = 1 + 3 + e
+//               = 4 + e
+//
+//               --> df/dy = 1
+//
+// To take the gradient of f with the implementation of dual numbers ("jets") in
+// this file, it is necessary to create a single jet type which has components
+// for the derivative in x and y, and passing them to a templated version of f:
+//
+//   template<typename T>
+//   T f(const T &x, const T &y) {
+//     return x * x + x * y;
+//   }
+//
+//   // The "2" means there should be 2 dual number components.
+//   Jet<double, 2> x(0);  // Pick the 0th dual number for x.
+//   Jet<double, 2> y(1);  // Pick the 1st dual number for y.
+//   Jet<double, 2> z = f(x, y);
+//
+//   LG << "df/dx = " << z.a[0]
+//      << "df/dy = " << z.a[1];
+//
+// Most users should not use Jet objects directly; a wrapper around Jet objects,
+// which makes computing the derivative, gradient, or jacobian of templated
+// functors simple, is in autodiff.h. Even autodiff.h should not be used
+// directly; instead autodiff_cost_function.h is typically the file of interest.
+//
+// For the more mathematically inclined, this file implements first-order
+// "jets". A 1st order jet is an element of the ring
+//
+//   T[N] = T[t_1, ..., t_N] / (t_1, ..., t_N)^2
+//
+// which essentially means that each jet consists of a "scalar" value 'a' from T
+// and a 1st order perturbation vector 'v' of length N:
+//
+//   x = a + \sum_i v[i] t_i
+//
+// A shorthand is to write an element as x = a + u, where u is the pertubation.
+// Then, the main point about the arithmetic of jets is that the product of
+// perturbations is zero:
+//
+//   (a + u) * (b + v) = ab + av + bu + uv
+//                     = ab + (av + bu) + 0
+//
+// which is what operator* implements below. Addition is simpler:
+//
+//   (a + u) + (b + v) = (a + b) + (u + v).
+//
+// The only remaining question is how to evaluate the function of a jet, for
+// which we use the chain rule:
+//
+//   f(a + u) = f(a) + f'(a) u
+//
+// where f'(a) is the (scalar) derivative of f at a.
+//
+// By pushing these things through sufficiently and suitably templated
+// functions, we can do automatic differentiation. Just be sure to turn on
+// function inlining and common-subexpression elimination, or it will be very
+// slow!
+//
+// WARNING: Most Ceres users should not directly include this file or know the
+// details of how jets work. Instead the suggested method for automatic
+// derivatives is to use autodiff_cost_function.h, which is a wrapper around
+// both jets.h and autodiff.h to make taking derivatives of cost functions for
+// use in Ceres easier.
+
+#ifndef CERES_PUBLIC_JET_H_
+#define CERES_PUBLIC_JET_H_
+
+#include <cmath>
+#include <iosfwd>
+#include <iostream>  // NOLINT
+#include <string>
+
+#include "Eigen/Core"
+
+// Visual Studio 2010 or older version
+#if defined(_MSC_VER) && _MSC_VER <= 1600
+namespace std {
+inline bool isfinite(double x) { return _finite(x);                }
+inline bool isinf   (double x) { return !_finite(x) && !_isnan(x); }
+inline bool isnan   (double x) { return _isnan(x);                 }
+inline bool isnormal(double x) { return _finite(x) && x != 0.0;    }
+}  // namespace std
+#endif
+
+namespace ceres {
+
+template <typename T, int N>
+struct Jet {
+  enum { DIMENSION = N };
+
+  // Default-construct "a" because otherwise this can lead to false errors about
+  // uninitialized uses when other classes relying on default constructed T
+  // (where T is a Jet<T, N>). This usually only happens in opt mode. Note that
+  // the C++ standard mandates that e.g. default constructed doubles are
+  // initialized to 0.0; see sections 8.5 of the C++03 standard.
+  Jet() : a() {}
+
+  // Constructor from scalar: a + 0.
+  explicit Jet(const T& value) {
+    a = value;
+    v.setZero();
+  }
+
+  // Constructor from scalar plus variable: a + t_i.
+  Jet(const T& value, int k) {
+    a = value;
+    v.setZero();
+    v[k] = T(1.0);
+  }
+
+  // Compound operators
+  Jet<T, N>& operator+=(const Jet<T, N> &y) {
+    *this = *this + y;
+    return *this;
+  }
+
+  Jet<T, N>& operator-=(const Jet<T, N> &y) {
+    *this = *this - y;
+    return *this;
+  }
+
+  Jet<T, N>& operator*=(const Jet<T, N> &y) {
+    *this = *this * y;
+    return *this;
+  }
+
+  Jet<T, N>& operator/=(const Jet<T, N> &y) {
+    *this = *this / y;
+    return *this;
+  }
+
+  T a;  // The scalar part.
+  Eigen::Matrix<T, N, 1> v;  // The infinitesimal part.
+};
+
+// Unary +
+template<typename T, int N> inline
+Jet<T, N> const& operator+(const Jet<T, N>& f) {
+  return f;
+}
+
+// TODO(keir): Try adding __attribute__((always_inline)) to these functions to
+// see if it causes a performance increase.
+
+// Unary -
+template<typename T, int N> inline
+Jet<T, N> operator-(const Jet<T, N>&f) {
+  Jet<T, N> g;
+  g.a = -f.a;
+  g.v = -f.v;
+  return g;
+}
+
+// Binary +
+template<typename T, int N> inline
+Jet<T, N> operator+(const Jet<T, N>& f,
+                    const Jet<T, N>& g) {
+  Jet<T, N> h;
+  h.a = f.a + g.a;
+  h.v = f.v + g.v;
+  return h;
+}
+
+// Binary + with a scalar: x + s
+template<typename T, int N> inline
+Jet<T, N> operator+(const Jet<T, N>& f, T s) {
+  Jet<T, N> h;
+  h.a = f.a + s;
+  h.v = f.v;
+  return h;
+}
+
+// Binary + with a scalar: s + x
+template<typename T, int N> inline
+Jet<T, N> operator+(T s, const Jet<T, N>& f) {
+  Jet<T, N> h;
+  h.a = f.a + s;
+  h.v = f.v;
+  return h;
+}
+
+// Binary -
+template<typename T, int N> inline
+Jet<T, N> operator-(const Jet<T, N>& f,
+                    const Jet<T, N>& g) {
+  Jet<T, N> h;
+  h.a = f.a - g.a;
+  h.v = f.v - g.v;
+  return h;
+}
+
+// Binary - with a scalar: x - s
+template<typename T, int N> inline
+Jet<T, N> operator-(const Jet<T, N>& f, T s) {
+  Jet<T, N> h;
+  h.a = f.a - s;
+  h.v = f.v;
+  return h;
+}
+
+// Binary - with a scalar: s - x
+template<typename T, int N> inline
+Jet<T, N> operator-(T s, const Jet<T, N>& f) {
+  Jet<T, N> h;
+  h.a = s - f.a;
+  h.v = -f.v;
+  return h;
+}
+
+// Binary *
+template<typename T, int N> inline
+Jet<T, N> operator*(const Jet<T, N>& f,
+                    const Jet<T, N>& g) {
+  Jet<T, N> h;
+  h.a = f.a * g.a;
+  h.v = f.a * g.v + f.v * g.a;
+  return h;
+}
+
+// Binary * with a scalar: x * s
+template<typename T, int N> inline
+Jet<T, N> operator*(const Jet<T, N>& f, T s) {
+  Jet<T, N> h;
+  h.a = f.a * s;
+  h.v = f.v * s;
+  return h;
+}
+
+// Binary * with a scalar: s * x
+template<typename T, int N> inline
+Jet<T, N> operator*(T s, const Jet<T, N>& f) {
+  Jet<T, N> h;
+  h.a = f.a * s;
+  h.v = f.v * s;
+  return h;
+}
+
+// Binary /
+template<typename T, int N> inline
+Jet<T, N> operator/(const Jet<T, N>& f,
+                    const Jet<T, N>& g) {
+  Jet<T, N> h;
+  // This uses:
+  //
+  //   a + u   (a + u)(b - v)   (a + u)(b - v)
+  //   ----- = -------------- = --------------
+  //   b + v   (b + v)(b - v)        b^2
+  //
+  // which holds because v*v = 0.
+  h.a = f.a / g.a;
+  h.v = (f.v - f.a / g.a * g.v) / g.a;
+  return h;
+}
+
+// Binary / with a scalar: s / x
+template<typename T, int N> inline
+Jet<T, N> operator/(T s, const Jet<T, N>& g) {
+  Jet<T, N> h;
+  h.a = s / g.a;
+  h.v = - s * g.v / (g.a * g.a);
+  return h;
+}
+
+// Binary / with a scalar: x / s
+template<typename T, int N> inline
+Jet<T, N> operator/(const Jet<T, N>& f, T s) {
+  Jet<T, N> h;
+  h.a = f.a / s;
+  h.v = f.v / s;
+  return h;
+}
+
+// Binary comparison operators for both scalars and jets.
+#define CERES_DEFINE_JET_COMPARISON_OPERATOR(op) \
+template<typename T, int N> inline \
+bool operator op(const Jet<T, N>& f, const Jet<T, N>& g) { \
+  return f.a op g.a; \
+} \
+template<typename T, int N> inline \
+bool operator op(const T& s, const Jet<T, N>& g) { \
+  return s op g.a; \
+} \
+template<typename T, int N> inline \
+bool operator op(const Jet<T, N>& f, const T& s) { \
+  return f.a op s; \
+}
+CERES_DEFINE_JET_COMPARISON_OPERATOR( <  )  // NOLINT
+CERES_DEFINE_JET_COMPARISON_OPERATOR( <= )  // NOLINT
+CERES_DEFINE_JET_COMPARISON_OPERATOR( >  )  // NOLINT
+CERES_DEFINE_JET_COMPARISON_OPERATOR( >= )  // NOLINT
+CERES_DEFINE_JET_COMPARISON_OPERATOR( == )  // NOLINT
+CERES_DEFINE_JET_COMPARISON_OPERATOR( != )  // NOLINT
+#undef CERES_DEFINE_JET_COMPARISON_OPERATOR
+
+// Pull some functions from namespace std.
+//
+// This is necessary because we want to use the same name (e.g. 'sqrt') for
+// double-valued and Jet-valued functions, but we are not allowed to put
+// Jet-valued functions inside namespace std.
+//
+// Missing: cosh, sinh, tanh, tan
+// TODO(keir): Switch to "using".
+inline double abs     (double x) { return std::abs(x);      }
+inline double log     (double x) { return std::log(x);      }
+inline double exp     (double x) { return std::exp(x);      }
+inline double sqrt    (double x) { return std::sqrt(x);     }
+inline double cos     (double x) { return std::cos(x);      }
+inline double acos    (double x) { return std::acos(x);     }
+inline double sin     (double x) { return std::sin(x);      }
+inline double asin    (double x) { return std::asin(x);     }
+inline bool   isfinite(double x) { return std::isfinite(x); }
+inline bool   isinf   (double x) { return std::isinf(x);    }
+inline bool   isnan   (double x) { return std::isnan(x);    }
+inline bool   isnormal(double x) { return std::isnormal(x); }
+inline double pow  (double x, double y) { return std::pow(x, y);   }
+inline double atan2(double y, double x) { return std::atan2(y, x); }
+
+// In general, f(a + h) ~= f(a) + f'(a) h, via the chain rule.
+
+// abs(x + h) ~= x + h or -(x + h)
+template <typename T, int N> inline
+Jet<T, N> abs(const Jet<T, N>& f) {
+  return f.a < T(0.0) ? -f : f;
+}
+
+// log(a + h) ~= log(a) + h / a
+template <typename T, int N> inline
+Jet<T, N> log(const Jet<T, N>& f) {
+  Jet<T, N> g;
+  g.a = log(f.a);
+  g.v = f.v / f.a;
+  return g;
+}
+
+// exp(a + h) ~= exp(a) + exp(a) h
+template <typename T, int N> inline
+Jet<T, N> exp(const Jet<T, N>& f) {
+  Jet<T, N> g;
+  g.a = exp(f.a);
+  g.v = g.a * f.v;
+  return g;
+}
+
+// sqrt(a + h) ~= sqrt(a) + h / (2 sqrt(a))
+template <typename T, int N> inline
+Jet<T, N> sqrt(const Jet<T, N>& f) {
+  Jet<T, N> g;
+  g.a = sqrt(f.a);
+  g.v = f.v / (T(2.0) * g.a);
+  return g;
+}
+
+// cos(a + h) ~= cos(a) - sin(a) h
+template <typename T, int N> inline
+Jet<T, N> cos(const Jet<T, N>& f) {
+  Jet<T, N> g;
+  g.a = cos(f.a);
+  T sin_a = sin(f.a);
+  g.v = - sin_a * f.v;
+  return g;
+}
+
+// acos(a + h) ~= acos(a) - 1 / sqrt(1 - a^2) h
+template <typename T, int N> inline
+Jet<T, N> acos(const Jet<T, N>& f) {
+  Jet<T, N> g;
+  g.a = acos(f.a);
+  g.v = - T(1.0) / sqrt(T(1.0) - f.a * f.a) * f.v;
+  return g;
+}
+
+// sin(a + h) ~= sin(a) + cos(a) h
+template <typename T, int N> inline
+Jet<T, N> sin(const Jet<T, N>& f) {
+  Jet<T, N> g;
+  g.a = sin(f.a);
+  T cos_a = cos(f.a);
+  g.v = cos_a * f.v;
+  return g;
+}
+
+// asin(a + h) ~= asin(a) + 1 / sqrt(1 - a^2) h
+template <typename T, int N> inline
+Jet<T, N> asin(const Jet<T, N>& f) {
+  Jet<T, N> g;
+  g.a = asin(f.a);
+  g.v = T(1.0) / sqrt(T(1.0) - f.a * f.a) * f.v;
+  return g;
+}
+
+// Jet Classification. It is not clear what the appropriate semantics are for
+// these classifications. This picks that isfinite and isnormal are "all"
+// operations, i.e. all elements of the jet must be finite for the jet itself to
+// be finite (or normal). For isnan and isinf, the answer is less clear. This
+// takes a "any" approach for isnan and isinf such that if any part of a jet is
+// nan or inf, then the entire jet is nan or inf. This leads to strange
+// situations like a jet can be both isinf and isnan, but in practice the "any"
+// semantics are the most useful for e.g. checking that derivatives are sane.
+
+// The jet is finite if all parts of the jet are finite.
+template <typename T, int N> inline
+bool isfinite(const Jet<T, N>& f) {
+  if (!isfinite(f.a)) {
+    return false;
+  }
+  for (int i = 0; i < N; ++i) {
+    if (!isfinite(f.v[i])) {
+      return false;
+    }
+  }
+  return true;
+}
+
+// The jet is infinite if any part of the jet is infinite.
+template <typename T, int N> inline
+bool isinf(const Jet<T, N>& f) {
+  if (isinf(f.a)) {
+    return true;
+  }
+  for (int i = 0; i < N; i++) {
+    if (isinf(f.v[i])) {
+      return true;
+    }
+  }
+  return false;
+}
+
+// The jet is NaN if any part of the jet is NaN.
+template <typename T, int N> inline
+bool isnan(const Jet<T, N>& f) {
+  if (isnan(f.a)) {
+    return true;
+  }
+  for (int i = 0; i < N; ++i) {
+    if (isnan(f.v[i])) {
+      return true;
+    }
+  }
+  return false;
+}
+
+// The jet is normal if all parts of the jet are normal.
+template <typename T, int N> inline
+bool isnormal(const Jet<T, N>& f) {
+  if (!isnormal(f.a)) {
+    return false;
+  }
+  for (int i = 0; i < N; ++i) {
+    if (!isnormal(f.v[i])) {
+      return false;
+    }
+  }
+  return true;
+}
+
+// atan2(b + db, a + da) ~= atan2(b, a) + (- b da + a db) / (a^2 + b^2)
+//
+// In words: the rate of change of theta is 1/r times the rate of
+// change of (x, y) in the positive angular direction.
+template <typename T, int N> inline
+Jet<T, N> atan2(const Jet<T, N>& g, const Jet<T, N>& f) {
+  // Note order of arguments:
+  //
+  //   f = a + da
+  //   g = b + db
+
+  Jet<T, N> out;
+
+  out.a = atan2(g.a, f.a);
+
+  T const temp = T(1.0) / (f.a * f.a + g.a * g.a);
+  out.v = temp * (- g.a * f.v + f.a * g.v);
+  return out;
+}
+
+
+// pow -- base is a differentiatble function, exponent is a constant.
+// (a+da)^p ~= a^p + p*a^(p-1) da
+template <typename T, int N> inline
+Jet<T, N> pow(const Jet<T, N>& f, double g) {
+  Jet<T, N> out;
+  out.a = pow(f.a, g);
+  T const temp = g * pow(f.a, g - T(1.0));
+  out.v = temp * f.v;
+  return out;
+}
+
+// pow -- base is a constant, exponent is a differentiable function.
+// (a)^(p+dp) ~= a^p + a^p log(a) dp
+template <typename T, int N> inline
+Jet<T, N> pow(double f, const Jet<T, N>& g) {
+  Jet<T, N> out;
+  out.a = pow(f, g.a);
+  T const temp = log(f) * out.a;
+  out.v = temp * g.v;
+  return out;
+}
+
+
+// pow -- both base and exponent are differentiable functions.
+// (a+da)^(b+db) ~= a^b + b * a^(b-1) da + a^b log(a) * db
+template <typename T, int N> inline
+Jet<T, N> pow(const Jet<T, N>& f, const Jet<T, N>& g) {
+  Jet<T, N> out;
+
+  T const temp1 = pow(f.a, g.a);
+  T const temp2 = g.a * pow(f.a, g.a - T(1.0));
+  T const temp3 = temp1 * log(f.a);
+
+  out.a = temp1;
+  out.v = temp2 * f.v + temp3 * g.v;
+  return out;
+}
+
+// Define the helper functions Eigen needs to embed Jet types.
+//
+// NOTE(keir): machine_epsilon() and precision() are missing, because they don't
+// work with nested template types (e.g. where the scalar is itself templated).
+// Among other things, this means that decompositions of Jet's does not work,
+// for example
+//
+//   Matrix<Jet<T, N> ... > A, x, b;
+//   ...
+//   A.solve(b, &x)
+//
+// does not work and will fail with a strange compiler error.
+//
+// TODO(keir): This is an Eigen 2.0 limitation that is lifted in 3.0. When we
+// switch to 3.0, also add the rest of the specialization functionality.
+template<typename T, int N> inline const Jet<T, N>& ei_conj(const Jet<T, N>& x) { return x;              }  // NOLINT
+template<typename T, int N> inline const Jet<T, N>& ei_real(const Jet<T, N>& x) { return x;              }  // NOLINT
+template<typename T, int N> inline       Jet<T, N>  ei_imag(const Jet<T, N>&  ) { return Jet<T, N>(0.0); }  // NOLINT
+template<typename T, int N> inline       Jet<T, N>  ei_abs (const Jet<T, N>& x) { return fabs(x);        }  // NOLINT
+template<typename T, int N> inline       Jet<T, N>  ei_abs2(const Jet<T, N>& x) { return x * x;          }  // NOLINT
+template<typename T, int N> inline       Jet<T, N>  ei_sqrt(const Jet<T, N>& x) { return sqrt(x);        }  // NOLINT
+template<typename T, int N> inline       Jet<T, N>  ei_exp (const Jet<T, N>& x) { return exp(x);         }  // NOLINT
+template<typename T, int N> inline       Jet<T, N>  ei_log (const Jet<T, N>& x) { return log(x);         }  // NOLINT
+template<typename T, int N> inline       Jet<T, N>  ei_sin (const Jet<T, N>& x) { return sin(x);         }  // NOLINT
+template<typename T, int N> inline       Jet<T, N>  ei_cos (const Jet<T, N>& x) { return cos(x);         }  // NOLINT
+template<typename T, int N> inline       Jet<T, N>  ei_pow (const Jet<T, N>& x, Jet<T, N> y) { return pow(x, y); }  // NOLINT
+
+// Note: This has to be in the ceres namespace for argument dependent lookup to
+// function correctly. Otherwise statements like CHECK_LE(x, 2.0) fail with
+// strange compile errors.
+template <typename T, int N>
+inline std::ostream &operator<<(std::ostream &s, const Jet<T, N>& z) {
+  return s << "[" << z.a << " ; " << z.v.transpose() << "]";
+}
+
+}  // namespace ceres
+
+namespace Eigen {
+
+// Creating a specialization of NumTraits enables placing Jet objects inside
+// Eigen arrays, getting all the goodness of Eigen combined with autodiff.
+template<typename T, int N>
+struct NumTraits<ceres::Jet<T, N> > {
+  typedef ceres::Jet<T, N> Real;
+  typedef ceres::Jet<T, N> NonInteger;
+  typedef ceres::Jet<T, N> Nested;
+
+  static typename ceres::Jet<T, N> dummy_precision() {
+    return ceres::Jet<T, N>(1e-12);
+  }
+
+  enum {
+    IsComplex = 0,
+    IsInteger = 0,
+    IsSigned,
+    ReadCost = 1,
+    AddCost = 1,
+    // For Jet types, multiplication is more expensive than addition.
+    MulCost = 3,
+    HasFloatingPoint = 1
+  };
+};
+
+}  // namespace Eigen
+
+#endif  // CERES_PUBLIC_JET_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/local_parameterization.h b/extern/libmv/third_party/ceres/include/ceres/local_parameterization.h
new file mode 100644 (file)
index 0000000..c0f7dc7
--- /dev/null
@@ -0,0 +1,189 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: keir@google.com (Keir Mierle)
+//         sameeragarwal@google.com (Sameer Agarwal)
+
+#ifndef CERES_PUBLIC_LOCAL_PARAMETERIZATION_H_
+#define CERES_PUBLIC_LOCAL_PARAMETERIZATION_H_
+
+#include <vector>
+#include "ceres/internal/port.h"
+
+namespace ceres {
+
+// Purpose: Sometimes parameter blocks x can overparameterize a problem
+//
+//   min f(x)
+//    x
+//
+// In that case it is desirable to choose a parameterization for the
+// block itself to remove the null directions of the cost. More
+// generally, if x lies on a manifold of a smaller dimension than the
+// ambient space that it is embedded in, then it is numerically and
+// computationally more effective to optimize it using a
+// parameterization that lives in the tangent space of that manifold
+// at each point.
+//
+// For example, a sphere in three dimensions is a 2 dimensional
+// manifold, embedded in a three dimensional space. At each point on
+// the sphere, the plane tangent to it defines a two dimensional
+// tangent space. For a cost function defined on this sphere, given a
+// point x, moving in the direction normal to the sphere at that point
+// is not useful. Thus a better way to do a local optimization is to
+// optimize over two dimensional vector delta in the tangent space at
+// that point and then "move" to the point x + delta, where the move
+// operation involves projecting back onto the sphere. Doing so
+// removes a redundent dimension from the optimization, making it
+// numerically more robust and efficient.
+//
+// More generally we can define a function
+//
+//   x_plus_delta = Plus(x, delta),
+//
+// where x_plus_delta has the same size as x, and delta is of size
+// less than or equal to x. The function Plus, generalizes the
+// definition of vector addition. Thus it satisfies the identify
+//
+//   Plus(x, 0) = x, for all x.
+//
+// A trivial version of Plus is when delta is of the same size as x
+// and
+//
+//   Plus(x, delta) = x + delta
+//
+// A more interesting case if x is two dimensional vector, and the
+// user wishes to hold the first coordinate constant. Then, delta is a
+// scalar and Plus is defined as
+//
+//   Plus(x, delta) = x + [0] * delta
+//                        [1]
+//
+// An example that occurs commonly in Structure from Motion problems
+// is when camera rotations are parameterized using Quaternion. There,
+// it is useful only make updates orthogonal to that 4-vector defining
+// the quaternion. One way to do this is to let delta be a 3
+// dimensional vector and define Plus to be
+//
+//   Plus(x, delta) = [cos(|delta|), sin(|delta|) delta / |delta|] * x
+//
+// The multiplication between the two 4-vectors on the RHS is the
+// standard quaternion product.
+//
+// Given g and a point x, optimizing f can now be restated as
+//
+//     min  f(Plus(x, delta))
+//    delta
+//
+// Given a solution delta to this problem, the optimal value is then
+// given by
+//
+//   x* = Plus(x, delta)
+//
+// The class LocalParameterization defines the function Plus and its
+// Jacobian which is needed to compute the Jacobian of f w.r.t delta.
+class LocalParameterization {
+ public:
+  virtual ~LocalParameterization() {}
+
+  // Generalization of the addition operation,
+  //
+  //   x_plus_delta = Plus(x, delta)
+  //
+  // with the condition that Plus(x, 0) = x.
+  virtual bool Plus(const double* x,
+                    const double* delta,
+                    double* x_plus_delta) const = 0;
+
+  // The jacobian of Plus(x, delta) w.r.t delta at delta = 0.
+  virtual bool ComputeJacobian(const double* x, double* jacobian) const = 0;
+
+  // Size of x.
+  virtual int GlobalSize() const = 0;
+
+  // Size of delta.
+  virtual int LocalSize() const = 0;
+};
+
+// Some basic parameterizations
+
+// Identity Parameterization: Plus(x, delta) = x + delta
+class IdentityParameterization : public LocalParameterization {
+ public:
+  explicit IdentityParameterization(int size);
+  virtual ~IdentityParameterization() {}
+  virtual bool Plus(const double* x,
+                    const double* delta,
+                    double* x_plus_delta) const;
+  virtual bool ComputeJacobian(const double* x,
+                               double* jacobian) const;
+  virtual int GlobalSize() const { return size_; }
+  virtual int LocalSize() const { return size_; }
+
+ private:
+  const int size_;
+};
+
+// Hold a subset of the parameters inside a parameter block constant.
+class SubsetParameterization : public LocalParameterization {
+ public:
+  explicit SubsetParameterization(int size,
+                                  const vector<int>& constant_parameters);
+  virtual ~SubsetParameterization() {}
+  virtual bool Plus(const double* x,
+                    const double* delta,
+                    double* x_plus_delta) const;
+  virtual bool ComputeJacobian(const double* x,
+                               double* jacobian) const;
+  virtual int GlobalSize() const { return constancy_mask_.size(); }
+  virtual int LocalSize() const { return local_size_; }
+
+ private:
+  const int local_size_;
+  vector<int> constancy_mask_;
+};
+
+// Plus(x, delta) = [cos(|delta|), sin(|delta|) delta / |delta|] * x
+// with * being the quaternion multiplication operator. Here we assume
+// that the first element of the quaternion vector is the real (cos
+// theta) part.
+class QuaternionParameterization : public LocalParameterization {
+ public:
+  virtual ~QuaternionParameterization() {}
+  virtual bool Plus(const double* x,
+                    const double* delta,
+                    double* x_plus_delta) const;
+  virtual bool ComputeJacobian(const double* x,
+                               double* jacobian) const;
+  virtual int GlobalSize() const { return 4; }
+  virtual int LocalSize() const { return 3; }
+};
+
+}  // namespace ceres
+
+#endif  // CERES_PUBLIC_LOCAL_PARAMETERIZATION_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/loss_function.h b/extern/libmv/third_party/ceres/include/ceres/loss_function.h
new file mode 100644 (file)
index 0000000..81add02
--- /dev/null
@@ -0,0 +1,322 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: sameeragarwal@google.com (Sameer Agarwal)
+//
+// The LossFunction interface is the way users describe how residuals
+// are converted to cost terms for the overall problem cost function.
+// For the exact manner in which loss functions are converted to the
+// overall cost for a problem, see problem.h.
+//
+// For least squares problem where there are no outliers and standard
+// squared loss is expected, it is not necessary to create a loss
+// function; instead passing a NULL to the problem when adding
+// residuals implies a standard squared loss.
+//
+// For least squares problems where the minimization may encounter
+// input terms that contain outliers, that is, completely bogus
+// measurements, it is important to use a loss function that reduces
+// their associated penalty.
+//
+// Consider a structure from motion problem. The unknowns are 3D
+// points and camera parameters, and the measurements are image
+// coordinates describing the expected reprojected position for a
+// point in a camera. For example, we want to model the geometry of a
+// street scene with fire hydrants and cars, observed by a moving
+// camera with unknown parameters, and the only 3D points we care
+// about are the pointy tippy-tops of the fire hydrants. Our magic
+// image processing algorithm, which is responsible for producing the
+// measurements that are input to Ceres, has found and matched all
+// such tippy-tops in all image frames, except that in one of the
+// frame it mistook a car's headlight for a hydrant. If we didn't do
+// anything special (i.e. if we used a basic quadratic loss), the
+// residual for the erroneous measurement will result in extreme error
+// due to the quadratic nature of squared loss. This results in the
+// entire solution getting pulled away from the optimimum to reduce
+// the large error that would otherwise be attributed to the wrong
+// measurement.
+//
+// Using a robust loss function, the cost for large residuals is
+// reduced. In the example above, this leads to outlier terms getting
+// downweighted so they do not overly influence the final solution.
+//
+// What cost function is best?
+//
+// In general, there isn't a principled way to select a robust loss
+// function. The authors suggest starting with a non-robust cost, then
+// only experimenting with robust loss functions if standard squared
+// loss doesn't work.
+
+#ifndef CERES_PUBLIC_LOSS_FUNCTION_H_
+#define CERES_PUBLIC_LOSS_FUNCTION_H_
+
+#include <glog/logging.h>
+#include "ceres/internal/macros.h"
+#include "ceres/internal/scoped_ptr.h"
+#include "ceres/types.h"
+
+namespace ceres {
+
+class LossFunction {
+ public:
+  virtual ~LossFunction() {}
+
+  // For a residual vector with squared 2-norm 'sq_norm', this method
+  // is required to fill in the value and derivatives of the loss
+  // function (rho in this example):
+  //
+  //   out[0] = rho(sq_norm),
+  //   out[1] = rho'(sq_norm),
+  //   out[2] = rho''(sq_norm),
+  //
+  // Here the convention is that the contribution of a term to the
+  // cost function is given by 1/2 rho(s),  where
+  //
+  //   s = ||residuals||^2.
+  //
+  // Calling the method with a negative value of 's' is an error and
+  // the implementations are not required to handle that case.
+  //
+  // Most sane choices of rho() satisfy:
+  //
+  //   rho(0) = 0,
+  //   rho'(0) = 1,
+  //   rho'(s) < 1 in outlier region,
+  //   rho''(s) < 0 in outlier region,
+  //
+  // so that they mimic the least squares cost for small residuals.
+  virtual void Evaluate(double sq_norm, double out[3]) const = 0;
+};
+
+// Some common implementations follow below.
+//
+// Note: in the region of interest (i.e. s < 3) we have:
+//   TrivialLoss >= HuberLoss >= SoftLOneLoss >= CauchyLoss
+
+
+// This corresponds to no robustification.
+//
+//   rho(s) = s
+//
+// At s = 0: rho = [0, 1, 0].
+//
+// It is not normally necessary to use this, as passing NULL for the
+// loss function when building the problem accomplishes the same
+// thing.
+class TrivialLoss : public LossFunction {
+ public:
+  virtual void Evaluate(double, double*) const;
+};
+
+// Scaling
+// -------
+// Given one robustifier
+//   s -> rho(s)
+// one can change the length scale at which robustification takes
+// place, by adding a scale factor 'a' as follows:
+//
+//   s -> a^2 rho(s / a^2).
+//
+// The first and second derivatives are:
+//
+//   s -> rho'(s / a^2),
+//   s -> (1 / a^2) rho''(s / a^2),
+//
+// but the behaviour near s = 0 is the same as the original function,
+// i.e.
+//
+//   rho(s) = s + higher order terms,
+//   a^2 rho(s / a^2) = s + higher order terms.
+//
+// The scalar 'a' should be positive.
+//
+// The reason for the appearance of squaring is that 'a' is in the
+// units of the residual vector norm whereas 's' is a squared
+// norm. For applications it is more convenient to specify 'a' than
+// its square. The commonly used robustifiers below are described in
+// un-scaled format (a = 1) but their implementations work for any
+// non-zero value of 'a'.
+
+// Huber.
+//
+//   rho(s) = s               for s <= 1,
+//   rho(s) = 2 sqrt(s) - 1   for s >= 1.
+//
+// At s = 0: rho = [0, 1, 0].
+//
+// The scaling parameter 'a' corresponds to 'delta' on this page:
+//   http://en.wikipedia.org/wiki/Huber_Loss_Function
+class HuberLoss : public LossFunction {
+ public:
+  explicit HuberLoss(double a) : a_(a), b_(a * a) { }
+  virtual void Evaluate(double, double*) const;
+ private:
+  const double a_;
+  // b = a^2.
+  const double b_;
+};
+
+// Soft L1, similar to Huber but smooth.
+//
+//   rho(s) = 2 (sqrt(1 + s) - 1).
+//
+// At s = 0: rho = [0, 1, -1/2].
+class SoftLOneLoss : public LossFunction {
+ public:
+  explicit SoftLOneLoss(double a) : b_(a * a), c_(1 / b_) { }
+  virtual void Evaluate(double, double*) const;
+ private:
+  // b = a^2.
+  const double b_;
+  // c = 1 / a^2.
+  const double c_;
+};
+
+// Inspired by the Cauchy distribution
+//
+//   rho(s) = log(1 + s).
+//
+// At s = 0: rho = [0, 1, -1].
+class CauchyLoss : public LossFunction {
+ public:
+  explicit CauchyLoss(double a) : b_(a * a), c_(1 / b_) { }
+  virtual void Evaluate(double, double*) const;
+ private:
+  // b = a^2.
+  const double b_;
+  // c = 1 / a^2.
+  const double c_;
+};
+
+// The discussion above has to do with length scaling: it affects the space
+// in which s is measured. Sometimes you want to simply scale the output
+// value of the robustifier. For example, you might want to weight
+// different error terms differently (e.g., weight pixel reprojection
+// errors differently from terrain errors).
+//
+// If rho is the wrapped robustifier, then this simply outputs
+// s -> a * rho(s)
+//
+// The first and second derivatives are, not surprisingly
+// s -> a * rho'(s)
+// s -> a * rho''(s)
+//
+// Since we treat the a NULL Loss function as the Identity loss
+// function, rho = NULL is a valid input and will result in the input
+// being scaled by a. This provides a simple way of implementing a
+// scaled ResidualBlock.
+class ScaledLoss : public LossFunction {
+ public:
+  // Constructs a ScaledLoss wrapping another loss function. Takes
+  // ownership of the wrapped loss function or not depending on the
+  // ownership parameter.
+  ScaledLoss(const LossFunction* rho, double a, Ownership ownership) :
+      rho_(rho), a_(a), ownership_(ownership) { }
+
+  virtual ~ScaledLoss() {
+    if (ownership_ == DO_NOT_TAKE_OWNERSHIP) {
+      rho_.release();
+    }
+  }
+  virtual void Evaluate(double, double*) const;
+
+ private:
+  internal::scoped_ptr<const LossFunction> rho_;
+  const double a_;
+  const Ownership ownership_;
+  DISALLOW_COPY_AND_ASSIGN(ScaledLoss);
+};
+
+// Sometimes after the optimization problem has been constructed, we
+// wish to mutate the scale of the loss function. For example, when
+// performing estimation from data which has substantial outliers,
+// convergence can be improved by starting out with a large scale,
+// optimizing the problem and then reducing the scale. This can have
+// better convergence behaviour than just using a loss function with a
+// small scale.
+//
+// This templated class allows the user to implement a loss function
+// whose scale can be mutated after an optimization problem has been
+// constructed.
+//
+// Example usage
+//
+//  Problem problem;
+//
+//  // Add parameter blocks
+//
+//  CostFunction* cost_function =
+//    new AutoDiffCostFunction < UW_Camera_Mapper, 2, 9, 3>(
+//      new UW_Camera_Mapper(data->observations[2*i + 0],
+//                           data->observations[2*i + 1]));
+//
+//  LossFunctionWrapper* loss_function(new HuberLoss(1.0), TAKE_OWNERSHIP);
+//
+//  problem.AddResidualBlock(cost_function, loss_function, parameters);
+//
+//  Solver::Options options;
+//  scoped_ptr<Solver::Summary> summary1(Solve(problem, options));
+//
+//  loss_function->Reset(new HuberLoss(1.0), TAKE_OWNERSHIP);
+//
+//  scoped_ptr<Solver::Summary> summary2(Solve(problem, options));
+//
+class LossFunctionWrapper : public LossFunction {
+ public:
+  LossFunctionWrapper(LossFunction* rho, Ownership ownership)
+      : rho_(rho), ownership_(ownership) {
+  }
+
+  virtual ~LossFunctionWrapper() {
+    if (ownership_ == DO_NOT_TAKE_OWNERSHIP) {
+      rho_.release();
+    }
+  }
+
+  virtual void Evaluate(double sq_norm, double out[3]) const {
+    CHECK_NOTNULL(rho_.get());
+    rho_->Evaluate(sq_norm, out);
+  }
+
+  void Reset(LossFunction* rho, Ownership ownership) {
+    if (ownership_ == DO_NOT_TAKE_OWNERSHIP) {
+      rho_.release();
+    }
+    rho_.reset(rho);
+    ownership_ = ownership;
+  }
+
+ private:
+  internal::scoped_ptr<const LossFunction> rho_;
+  Ownership ownership_;
+  DISALLOW_COPY_AND_ASSIGN(LossFunctionWrapper);
+};
+
+}  // namespace ceres
+
+#endif  // CERES_PUBLIC_LOSS_FUNCTION_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/normal_prior.h b/extern/libmv/third_party/ceres/include/ceres/normal_prior.h
new file mode 100644 (file)
index 0000000..480a074
--- /dev/null
@@ -0,0 +1,75 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: sameeragarwal@google.com (Sameer Agarwal)
+//
+// Cost term that implements a prior on a parameter block using a
+// normal distribution.
+
+#ifndef CERES_PUBLIC_NORMAL_PRIOR_H_
+#define CERES_PUBLIC_NORMAL_PRIOR_H_
+
+#include "ceres/cost_function.h"
+#include "ceres/internal/eigen.h"
+
+namespace ceres {
+
+// Implements a cost function of the form
+//
+//   cost(x) = ||A(x - b)||^2
+//
+// where, the matrix A and the vector b are fixed and x is the
+// variable. In case the user is interested in implementing a cost
+// function of the form
+//
+//   cost(x) = (x - mu)^T S^{-1} (x - mu)
+//
+// where, mu is a vector and S is a covariance matrix, then, A =
+// S^{-1/2}, i.e the matrix A is the square root of the inverse of the
+// covariance, also known as the stiffness matrix. There are however
+// no restrictions on the shape of A. It is free to be rectangular,
+// which would be the case if the covariance matrix S is rank
+// deficient.
+
+class NormalPrior: public CostFunction {
+ public:
+  // Check that the number of rows in the vector b are the same as the
+  // number of columns in the matrix A, crash otherwise.
+  NormalPrior(const Matrix& A, const Vector& b);
+
+  virtual bool Evaluate(double const* const* parameters,
+                        double* residuals,
+                        double** jacobians) const;
+ private:
+  Matrix A_;
+  Vector b_;
+};
+
+}  // namespace ceres
+
+#endif  // CERES_PUBLIC_NORMAL_PRIOR_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/numeric_diff_cost_function.h b/extern/libmv/third_party/ceres/include/ceres/numeric_diff_cost_function.h
new file mode 100644 (file)
index 0000000..bbaefca
--- /dev/null
@@ -0,0 +1,283 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: keir@google.com (Keir Mierle)
+//
+// Create CostFunctions as needed by the least squares framework with jacobians
+// computed via numeric (a.k.a. finite) differentiation. For more details see
+// http://en.wikipedia.org/wiki/Numerical_differentiation.
+//
+// To get a numerically differentiated cost function, define a subclass of
+// CostFunction such that the Evaluate() function ignores the jacobian
+// parameter. The numeric differentiation wrapper will fill in the jacobian
+// parameter if nececssary by repeatedly calling the Evaluate() function with
+// small changes to the appropriate parameters, and computing the slope. For
+// performance, the numeric differentiation wrapper class is templated on the
+// concrete cost function, even though it could be implemented only in terms of
+// the virtual CostFunction interface.
+//
+// The numerically differentiated version of a cost function for a cost function
+// can be constructed as follows:
+//
+//   CostFunction* cost_function
+//       = new NumericDiffCostFunction<MyCostFunction, CENTRAL, 1, 4, 8>(
+//           new MyCostFunction(...), TAKE_OWNERSHIP);
+//
+// where MyCostFunction has 1 residual and 2 parameter blocks with sizes 4 and 8
+// respectively. Look at the tests for a more detailed example.
+//
+// The central difference method is considerably more accurate at the cost of
+// twice as many function evaluations than forward difference. Consider using
+// central differences begin with, and only after that works, trying forward
+// difference to improve performance.
+//
+// TODO(keir): Characterize accuracy; mention pitfalls; provide alternatives.
+
+#ifndef CERES_PUBLIC_NUMERIC_DIFF_COST_FUNCTION_H_
+#define CERES_PUBLIC_NUMERIC_DIFF_COST_FUNCTION_H_
+
+#include <cstring>
+#include <glog/logging.h>
+#include "Eigen/Dense"
+#include "ceres/internal/scoped_ptr.h"
+#include "ceres/sized_cost_function.h"
+#include "ceres/types.h"
+
+namespace ceres {
+
+enum NumericDiffMethod {
+  CENTRAL,
+  FORWARD
+};
+
+// This is split from the main class because C++ doesn't allow partial template
+// specializations for member functions. The alternative is to repeat the main
+// class for differing numbers of parameters, which is also unfortunate.
+template <typename CostFunctionNoJacobian,
+          int num_residuals,
+          int parameter_block_size,
+          int parameter_block,
+          NumericDiffMethod method>
+struct Differencer {
+  // Mutates parameters but must restore them before return.
+  static bool EvaluateJacobianForParameterBlock(
+      const CostFunctionNoJacobian *function,
+      double const* residuals_at_eval_point,
+      double **parameters,
+      double **jacobians) {
+    using Eigen::Map;
+    using Eigen::Matrix;
+    using Eigen::RowMajor;
+
+    typedef Matrix<double, num_residuals, 1> ResidualVector;
+    typedef Matrix<double, parameter_block_size, 1> ParameterVector;
+    typedef Matrix<double, num_residuals, parameter_block_size, RowMajor>
+        JacobianMatrix;
+
+    Map<JacobianMatrix> parameter_jacobian(jacobians[parameter_block],
+                                           num_residuals,
+                                           parameter_block_size);
+
+    // Mutate 1 element at a time and then restore.
+    Map<ParameterVector> x_plus_delta(parameters[parameter_block],
+                                      parameter_block_size);
+    ParameterVector x(x_plus_delta);
+
+    // TODO(keir): Pick a smarter number! In theory a good choice is sqrt(eps) *
+    // x, which for doubles means about 1e-8 * x. However, I have found this
+    // number too optimistic. This number should be exposed for users to change.
+    const double kRelativeStepSize = 1e-6;
+
+    ParameterVector step_size = x.array().abs() * kRelativeStepSize;
+
+    // To handle cases where a parameter is exactly zero, instead use the mean
+    // step_size for the other dimensions.
+    double fallback_step_size = step_size.sum() / step_size.rows();
+    if (fallback_step_size == 0.0) {
+      // If all the parameters are zero, there's no good answer. Take
+      // kRelativeStepSize as a guess and hope for the best.
+      fallback_step_size = kRelativeStepSize;
+    }
+
+    // For each parameter in the parameter block, use finite differences to
+    // compute the derivative for that parameter.
+    for (int j = 0; j < parameter_block_size; ++j) {
+      if (step_size(j) == 0.0) {
+        // The parameter is exactly zero, so compromise and use the mean
+        // step_size from the other parameters. This can break in many cases,
+        // but it's hard to pick a good number without problem specific
+        // knowledge.
+        step_size(j) = fallback_step_size;
+      }
+      x_plus_delta(j) = x(j) + step_size(j);
+
+      double residuals[num_residuals];  // NOLINT
+      if (!function->Evaluate(parameters, residuals, NULL)) {
+        // Something went wrong; bail.
+        return false;
+      }
+
+      // Compute this column of the jacobian in 3 steps:
+      // 1. Store residuals for the forward part.
+      // 2. Subtract residuals for the backward (or 0) part.
+      // 3. Divide out the run.
+      parameter_jacobian.col(j) =
+          Map<const ResidualVector>(residuals, num_residuals);
+
+      double one_over_h = 1 / step_size(j);
+      if (method == CENTRAL) {
+        // Compute the function on the other side of x(j).
+        x_plus_delta(j) = x(j) - step_size(j);
+
+        if (!function->Evaluate(parameters, residuals, NULL)) {
+          // Something went wrong; bail.
+          return false;
+        }
+        parameter_jacobian.col(j) -=
+            Map<ResidualVector>(residuals, num_residuals, 1);
+        one_over_h /= 2;
+      } else {
+        // Forward difference only; reuse existing residuals evaluation.
+        parameter_jacobian.col(j) -=
+            Map<const ResidualVector>(residuals_at_eval_point, num_residuals);
+      }
+      x_plus_delta(j) = x(j);  // Restore x_plus_delta.
+
+      // Divide out the run to get slope.
+      parameter_jacobian.col(j) *= one_over_h;
+    }
+    return true;
+  }
+};
+
+// Prevent invalid instantiations.
+template <typename CostFunctionNoJacobian,
+          int num_residuals,
+          int parameter_block,
+          NumericDiffMethod method>
+struct Differencer<CostFunctionNoJacobian,
+                  num_residuals,
+                  0 /* parameter_block_size */,
+                  parameter_block,
+                  method> {
+  static bool EvaluateJacobianForParameterBlock(
+      const CostFunctionNoJacobian *function,
+      double const* residuals_at_eval_point,
+      double **parameters,
+      double **jacobians) {
+    LOG(FATAL) << "Shouldn't get here.";
+    return true;
+  }
+};
+
+template <typename CostFunctionNoJacobian,
+         NumericDiffMethod method = CENTRAL, int M = 0,
+         int N0 = 0, int N1 = 0, int N2 = 0, int N3 = 0, int N4 = 0, int N5 = 0>
+class NumericDiffCostFunction
+    : public SizedCostFunction<M, N0, N1, N2, N3, N4, N5> {
+ public:
+  NumericDiffCostFunction(CostFunctionNoJacobian* function,
+                          Ownership ownership)
+      : function_(function), ownership_(ownership) {}
+
+  virtual ~NumericDiffCostFunction() {
+    if (ownership_ != TAKE_OWNERSHIP) {
+      function_.release();
+    }
+  }
+
+  virtual bool Evaluate(double const* const* parameters,
+                        double* residuals,
+                        double** jacobians) const {
+    // Get the function value (residuals) at the the point to evaluate.
+    bool success = function_->Evaluate(parameters, residuals, NULL);
+    if (!success) {
+      // Something went wrong; ignore the jacobian.
+      return false;
+    }
+    if (!jacobians) {
+      // Nothing to do; just forward.
+      return true;
+    }
+
+    // Create a copy of the parameters which will get mutated.
+    const int kParametersSize = N0 + N1 + N2 + N3 + N4 + N5;
+    double parameters_copy[kParametersSize];
+    double *parameters_references_copy[6];
+    parameters_references_copy[0] = &parameters_copy[0];
+    parameters_references_copy[1] = &parameters_copy[0] + N0;
+    parameters_references_copy[2] = &parameters_copy[0] + N0 + N1;
+    parameters_references_copy[3] = &parameters_copy[0] + N0 + N1 + N2;
+    parameters_references_copy[4] = &parameters_copy[0] + N0 + N1 + N2 + N3;
+    parameters_references_copy[5] =
+        &parameters_copy[0] + N0 + N1 + N2 + N3 + N4;
+
+#define COPY_PARAMETER_BLOCK(block) \
+    if (N ## block) memcpy(parameters_references_copy[block], \
+                           parameters[block], \
+                           sizeof(double) * N ## block);  // NOLINT
+    COPY_PARAMETER_BLOCK(0);
+    COPY_PARAMETER_BLOCK(1);
+    COPY_PARAMETER_BLOCK(2);
+    COPY_PARAMETER_BLOCK(3);
+    COPY_PARAMETER_BLOCK(4);
+    COPY_PARAMETER_BLOCK(5);
+#undef COPY_PARAMETER_BLOCK
+
+#define EVALUATE_JACOBIAN_FOR_BLOCK(block) \
+    if (N ## block && jacobians[block]) { \
+      if (!Differencer<CostFunctionNoJacobian, /* NOLINT */ \
+                       M, \
+                       N ## block, \
+                       block, \
+                       method>::EvaluateJacobianForParameterBlock( \
+          function_.get(), \
+          residuals, \
+          parameters_references_copy, \
+          jacobians)) { \
+        return false; \
+      } \
+    }
+    EVALUATE_JACOBIAN_FOR_BLOCK(0);
+    EVALUATE_JACOBIAN_FOR_BLOCK(1);
+    EVALUATE_JACOBIAN_FOR_BLOCK(2);
+    EVALUATE_JACOBIAN_FOR_BLOCK(3);
+    EVALUATE_JACOBIAN_FOR_BLOCK(4);
+    EVALUATE_JACOBIAN_FOR_BLOCK(5);
+#undef EVALUATE_JACOBIAN_FOR_BLOCK
+    return true;
+  }
+
+ private:
+  internal::scoped_ptr<CostFunctionNoJacobian> function_;
+  Ownership ownership_;
+};
+
+}  // namespace ceres
+
+#endif  // CERES_PUBLIC_NUMERIC_DIFF_COST_FUNCTION_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/problem.h b/extern/libmv/third_party/ceres/include/ceres/problem.h
new file mode 100644 (file)
index 0000000..0ca6100
--- /dev/null
@@ -0,0 +1,265 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: sameeragarwal@google.com (Sameer Agarwal)
+//         keir@google.com (Keir Mierle)
+//
+// The Problem object is used to build and hold least squares problems.
+
+#ifndef CERES_PUBLIC_PROBLEM_H_
+#define CERES_PUBLIC_PROBLEM_H_
+
+#include <cstddef>
+#include <map>
+#include <set>
+#include <vector>
+
+#include <glog/logging.h>
+#include "ceres/internal/macros.h"
+#include "ceres/internal/port.h"
+#include "ceres/internal/scoped_ptr.h"
+#include "ceres/types.h"
+
+namespace ceres {
+
+class CostFunction;
+class LossFunction;
+class LocalParameterization;
+
+namespace internal {
+class Preprocessor;
+class ProblemImpl;
+class ParameterBlock;
+class ResidualBlock;
+class SolverImpl;
+}  // namespace internal
+
+// A ResidualBlockId is a handle clients can use to delete residual
+// blocks after creating them. They are opaque for any purposes other
+// than that.
+typedef const internal::ResidualBlock* ResidualBlockId;
+
+// A class to represent non-linear least squares problems. Such
+// problems have a cost function that is a sum of error terms (known
+// as "residuals"), where each residual is a function of some subset
+// of the parameters. The cost function takes the form
+//
+//    N    1
+//   SUM  --- loss( || r_i1, r_i2,..., r_ik ||^2  ),
+//   i=1   2
+//
+// where
+//
+//   r_ij     is residual number i, component j; the residual is a
+//            function of some subset of the parameters x1...xk. For
+//            example, in a structure from motion problem a residual
+//            might be the difference between a measured point in an
+//            image and the reprojected position for the matching
+//            camera, point pair. The residual would have two
+//            components, error in x and error in y.
+//
+//   loss(y)  is the loss function; for example, squared error or
+//            Huber L1 loss. If loss(y) = y, then the cost function is
+//            non-robustified least squares.
+//
+// This class is specifically designed to address the important subset
+// of "sparse" least squares problems, where each component of the
+// residual depends only on a small number number of parameters, even
+// though the total number of residuals and parameters may be very
+// large. This property affords tremendous gains in scale, allowing
+// efficient solving of large problems that are otherwise
+// inaccessible.
+//
+// The canonical example of a sparse least squares problem is
+// "structure-from-motion" (SFM), where the parameters are points and
+// cameras, and residuals are reprojection errors. Typically a single
+// residual will depend only on 9 parameters (3 for the point, 6 for
+// the camera).
+//
+// To create a least squares problem, use the AddResidualBlock() and
+// AddParameterBlock() methods, documented below. Here is an example least
+// squares problem containing 3 parameter blocks of sizes 3, 4 and 5
+// respectively and two residual terms of size 2 and 6:
+//
+//   double x1[] = { 1.0, 2.0, 3.0 };
+//   double x2[] = { 1.0, 2.0, 3.0, 5.0 };
+//   double x3[] = { 1.0, 2.0, 3.0, 6.0, 7.0 };
+//
+//   Problem problem;
+//
+//   problem.AddResidualBlock(new MyUnaryCostFunction(...), x1);
+//   problem.AddResidualBlock(new MyBinaryCostFunction(...), x2, x3);
+//
+// Please see cost_function.h for details of the CostFunction object.
+class Problem {
+ public:
+  struct Options {
+    Options()
+        : cost_function_ownership(TAKE_OWNERSHIP),
+          loss_function_ownership(TAKE_OWNERSHIP),
+          local_parameterization_ownership(TAKE_OWNERSHIP) {}
+
+    // These flags control whether the Problem object owns the cost
+    // functions, loss functions, and parameterizations passed into
+    // the Problem. If set to TAKE_OWNERSHIP, then the problem object
+    // will delete the corresponding cost or loss functions on
+    // destruction. The destructor is careful to delete the pointers
+    // only once, since sharing cost/loss/parameterizations is
+    // allowed.
+    Ownership cost_function_ownership;
+    Ownership loss_function_ownership;
+    Ownership local_parameterization_ownership;
+  };
+
+  // The default constructor is equivalent to the
+  // invocation Problem(Problem::Options()).
+  Problem();
+  explicit Problem(const Options& options);
+
+  ~Problem();
+
+  // Add a residual block to the overall cost function. The cost
+  // function carries with it information about the sizes of the
+  // parameter blocks it expects. The function checks that these match
+  // the sizes of the parameter blocks listed in parameter_blocks. The
+  // program aborts if a mismatch is detected. loss_function can be
+  // NULL, in which case the cost of the term is just the squared norm
+  // of the residuals.
+  //
+  // The user has the option of explicitly adding the parameter blocks
+  // using AddParameterBlock. This causes additional correctness
+  // checking; however, AddResidualBlock implicitly adds the parameter
+  // blocks if they are not present, so calling AddParameterBlock
+  // explicitly is not required.
+  //
+  // The Problem object by default takes ownership of the
+  // cost_function and loss_function pointers. These objects remain
+  // live for the life of the Problem object. If the user wishes to
+  // keep control over the destruction of these objects, then they can
+  // do this by setting the corresponding enums in the Options struct.
+  //
+  // Note: Even though the Problem takes ownership of cost_function
+  // and loss_function, it does not preclude the user from re-using
+  // them in another residual block. The destructor takes care to call
+  // delete on each cost_function or loss_function pointer only once,
+  // regardless of how many residual blocks refer to them.
+  //
+  // Example usage:
+  //
+  //   double x1[] = {1.0, 2.0, 3.0};
+  //   double x2[] = {1.0, 2.0, 5.0, 6.0};
+  //   double x3[] = {3.0, 6.0, 2.0, 5.0, 1.0};
+  //
+  //   Problem problem;
+  //
+  //   problem.AddResidualBlock(new MyUnaryCostFunction(...), NULL, x1);
+  //   problem.AddResidualBlock(new MyBinaryCostFunction(...), NULL, x2, x1);
+  //
+  ResidualBlockId AddResidualBlock(CostFunction* cost_function,
+                                   LossFunction* loss_function,
+                                   const vector<double*>& parameter_blocks);
+
+  // Convenience methods for adding residuals with a small number of
+  // parameters. This is the common case. Instead of specifying the
+  // parameter block arguments as a vector, list them as pointers.
+  ResidualBlockId AddResidualBlock(CostFunction* cost_function,
+                                   LossFunction* loss_function,
+                                   double* x0);
+  ResidualBlockId AddResidualBlock(CostFunction* cost_function,
+                                   LossFunction* loss_function,
+                                   double* x0, double* x1);
+  ResidualBlockId AddResidualBlock(CostFunction* cost_function,
+                                   LossFunction* loss_function,
+                                   double* x0, double* x1, double* x2);
+  ResidualBlockId AddResidualBlock(CostFunction* cost_function,
+                                   LossFunction* loss_function,
+                                   double* x0, double* x1, double* x2,
+                                   double* x3);
+  ResidualBlockId AddResidualBlock(CostFunction* cost_function,
+                                   LossFunction* loss_function,
+                                   double* x0, double* x1, double* x2,
+                                   double* x3, double* x4);
+  ResidualBlockId AddResidualBlock(CostFunction* cost_function,
+                                   LossFunction* loss_function,
+                                   double* x0, double* x1, double* x2,
+                                   double* x3, double* x4, double* x5);
+
+  // Add a parameter block with appropriate size to the problem.
+  // Repeated calls with the same arguments are ignored. Repeated
+  // calls with the same double pointer but a different size results
+  // in undefined behaviour.
+  void AddParameterBlock(double* values, int size);
+
+  // Add a parameter block with appropriate size and parameterization
+  // to the problem. Repeated calls with the same arguments are
+  // ignored. Repeated calls with the same double pointer but a
+  // different size results in undefined behaviour.
+  void AddParameterBlock(double* values,
+                         int size,
+                         LocalParameterization* local_parameterization);
+
+  // Hold the indicated parameter block constant during optimization.
+  void SetParameterBlockConstant(double* values);
+
+  // Allow the indicated parameter to vary during optimization.
+  void SetParameterBlockVariable(double* values);
+
+  // Set the local parameterization for one of the parameter blocks.
+  // The local_parameterization is owned by the Problem by default. It
+  // is acceptable to set the same parameterization for multiple
+  // parameters; the destructor is careful to delete local
+  // parameterizations only once. The local parameterization can only
+  // be set once per parameter, and cannot be changed once set.
+  void SetParameterization(double* values,
+                           LocalParameterization* local_parameterization);
+
+  // Number of parameter blocks in the problem. Always equals
+  // parameter_blocks().size() and parameter_block_sizes().size().
+  int NumParameterBlocks() const;
+
+  // The size of the parameter vector obtained by summing over the
+  // sizes of all the parameter blocks.
+  int NumParameters() const;
+
+  // Number of residual blocks in the problem. Always equals
+  // residual_blocks().size().
+  int NumResidualBlocks() const;
+
+  // The size of the residual vector obtained by summing over the
+  // sizes of all of the residual blocks.
+  int NumResiduals() const;
+
+ private:
+  friend class internal::SolverImpl;
+  internal::scoped_ptr<internal::ProblemImpl> problem_impl_;
+  DISALLOW_COPY_AND_ASSIGN(Problem);
+};
+
+}  // namespace ceres
+
+#endif  // CERES_PUBLIC_PROBLEM_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/rotation.h b/extern/libmv/third_party/ceres/include/ceres/rotation.h
new file mode 100644 (file)
index 0000000..e4227e7
--- /dev/null
@@ -0,0 +1,526 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: keir@google.com (Keir Mierle)
+//         sameeragarwal@google.com (Sameer Agarwal)
+//
+// Templated functions for manipulating rotations. The templated
+// functions are useful when implementing functors for automatic
+// differentiation.
+//
+// In the following, the Quaternions are laid out as 4-vectors, thus:
+//
+//   q[0]  scalar part.
+//   q[1]  coefficient of i.
+//   q[2]  coefficient of j.
+//   q[3]  coefficient of k.
+//
+// where: i*i = j*j = k*k = -1 and i*j = k, j*k = i, k*i = j.
+
+#ifndef CERES_PUBLIC_ROTATION_H_
+#define CERES_PUBLIC_ROTATION_H_
+
+#include <algorithm>
+#include <cmath>
+
+namespace ceres {
+
+// Convert a value in combined axis-angle representation to a quaternion.
+// The value angle_axis is a triple whose norm is an angle in radians,
+// and whose direction is aligned with the axis of rotation,
+// and quaternion is a 4-tuple that will contain the resulting quaternion.
+// The implementation may be used with auto-differentiation up to the first
+// derivative, higher derivatives may have unexpected results near the origin.
+template<typename T>
+void AngleAxisToQuaternion(T const* angle_axis, T* quaternion);
+
+// Convert a quaternion to the equivalent combined axis-angle representation.
+// The value quaternion must be a unit quaternion - it is not normalized first,
+// and angle_axis will be filled with a value whose norm is the angle of
+// rotation in radians, and whose direction is the axis of rotation.
+// The implemention may be used with auto-differentiation up to the first
+// derivative, higher derivatives may have unexpected results near the origin.
+template<typename T>
+void QuaternionToAngleAxis(T const* quaternion, T* angle_axis);
+
+// Conversions between 3x3 rotation matrix (in column major order) and
+// axis-angle rotation representations.  Templated for use with
+// autodifferentiation.
+template <typename T>
+void RotationMatrixToAngleAxis(T const * R, T * angle_axis);
+template <typename T>
+void AngleAxisToRotationMatrix(T const * angle_axis, T * R);
+
+// Conversions between 3x3 rotation matrix (in row major order) and
+// Euler angle (in degrees) rotation representations.
+//
+// The {pitch,roll,yaw} Euler angles are rotations around the {x,y,z}
+// axes, respectively.  They are applied in that same order, so the
+// total rotation R is Rz * Ry * Rx.
+template <typename T>
+void EulerAnglesToRotationMatrix(const T* euler, int row_stride, T* R);
+
+// Convert a 4-vector to a 3x3 scaled rotation matrix.
+//
+// The choice of rotation is such that the quaternion [1 0 0 0] goes to an
+// identity matrix and for small a, b, c the quaternion [1 a b c] goes to
+// the matrix
+//
+//         [  0 -c  b ]
+//   I + 2 [  c  0 -a ] + higher order terms
+//         [ -b  a  0 ]
+//
+// which corresponds to a Rodrigues approximation, the last matrix being
+// the cross-product matrix of [a b c]. Together with the property that
+// R(q1 * q2) = R(q1) * R(q2) this uniquely defines the mapping from q to R.
+//
+// The rotation matrix is row-major.
+//
+// No normalization of the quaternion is performed, i.e.
+// R = ||q||^2 * Q, where Q is an orthonormal matrix
+// such that det(Q) = 1 and Q*Q' = I
+template <typename T> inline
+void QuaternionToScaledRotation(const T q[4], T R[3 * 3]);
+
+// Same as above except that the rotation matrix is normalized by the
+// Frobenius norm, so that R * R' = I (and det(R) = 1).
+template <typename T> inline
+void QuaternionToRotation(const T q[4], T R[3 * 3]);
+
+// Rotates a point pt by a quaternion q:
+//
+//   result = R(q) * pt
+//
+// Assumes the quaternion is unit norm. This assumption allows us to
+// write the transform as (something)*pt + pt, as is clear from the
+// formula below. If you pass in a quaternion with |q|^2 = 2 then you
+// WILL NOT get back 2 times the result you get for a unit quaternion.
+template <typename T> inline
+void UnitQuaternionRotatePoint(const T q[4], const T pt[3], T result[3]);
+
+// With this function you do not need to assume that q has unit norm.
+// It does assume that the norm is non-zero.
+template <typename T> inline
+void QuaternionRotatePoint(const T q[4], const T pt[3], T result[3]);
+
+// zw = z * w, where * is the Quaternion product between 4 vectors.
+template<typename T> inline
+void QuaternionProduct(const T z[4], const T w[4], T zw[4]);
+
+// xy = x cross y;
+template<typename T> inline
+void CrossProduct(const T x[3], const T y[3], T x_cross_y[3]);
+
+template<typename T> inline
+T DotProduct(const T x[3], const T y[3]);
+
+// y = R(angle_axis) * x;
+template<typename T> inline
+void AngleAxisRotatePoint(const T angle_axis[3], const T pt[3], T result[3]);
+
+// --- IMPLEMENTATION
+
+// Duplicate rather than decorate every use of cmath with _USE_MATH_CONSTANTS.
+// Necessitated by Windows.
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#define CERES_NEED_M_PI_UNDEF
+#endif
+
+template<typename T>
+inline void AngleAxisToQuaternion(const T* angle_axis, T* quaternion) {
+  const T &a0 = angle_axis[0];
+  const T &a1 = angle_axis[1];
+  const T &a2 = angle_axis[2];
+  const T theta_squared = a0 * a0 + a1 * a1 + a2 * a2;
+
+  // For points not at the origin, the full conversion is numerically stable.
+  if (theta_squared > T(0.0)) {
+    const T theta = sqrt(theta_squared);
+    const T half_theta = theta * T(0.5);
+    const T k = sin(half_theta) / theta;
+    quaternion[0] = cos(half_theta);
+    quaternion[1] = a0 * k;
+    quaternion[2] = a1 * k;
+    quaternion[3] = a2 * k;
+  } else {
+    // At the origin, sqrt() will produce NaN in the derivative since
+    // the argument is zero.  By approximating with a Taylor series,
+    // and truncating at one term, the value and first derivatives will be
+    // computed correctly when Jets are used.
+    const T k(0.5);
+    quaternion[0] = T(1.0);
+    quaternion[1] = a0 * k;
+    quaternion[2] = a1 * k;
+    quaternion[3] = a2 * k;
+  }
+}
+
+template<typename T>
+inline void QuaternionToAngleAxis(const T* quaternion, T* angle_axis) {
+  const T &q1 = quaternion[1];
+  const T &q2 = quaternion[2];
+  const T &q3 = quaternion[3];
+  const T sin_squared = q1 * q1 + q2 * q2 + q3 * q3;
+
+  // For quaternions representing non-zero rotation, the conversion
+  // is numerically stable.
+  if (sin_squared > T(0.0)) {
+    const T sin_theta = sqrt(sin_squared);
+    const T k = T(2.0) * atan2(sin_theta, quaternion[0]) / sin_theta;
+    angle_axis[0] = q1 * k;
+    angle_axis[1] = q2 * k;
+    angle_axis[2] = q3 * k;
+  } else {
+    // For zero rotation, sqrt() will produce NaN in the derivative since
+    // the argument is zero.  By approximating with a Taylor series,
+    // and truncating at one term, the value and first derivatives will be
+    // computed correctly when Jets are used.
+    const T k(2.0);
+    angle_axis[0] = q1 * k;
+    angle_axis[1] = q2 * k;
+    angle_axis[2] = q3 * k;
+  }
+}
+
+// The conversion of a rotation matrix to the angle-axis form is
+// numerically problematic when then rotation angle is close to zero
+// or to Pi. The following implementation detects when these two cases
+// occurs and deals with them by taking code paths that are guaranteed
+// to not perform division by a small number.
+template <typename T>
+inline void RotationMatrixToAngleAxis(const T * R, T * angle_axis) {
+  // x = k * 2 * sin(theta), where k is the axis of rotation.
+  angle_axis[0] = R[5] - R[7];
+  angle_axis[1] = R[6] - R[2];
+  angle_axis[2] = R[1] - R[3];
+
+  static const T kOne = T(1.0);
+  static const T kTwo = T(2.0);
+
+  // Since the right hand side may give numbers just above 1.0 or
+  // below -1.0 leading to atan misbehaving, we threshold.
+  T costheta = std::min(std::max((R[0] + R[4] + R[8] - kOne) / kTwo,
+                                 T(-1.0)),
+                        kOne);
+
+  // sqrt is guaranteed to give non-negative results, so we only
+  // threshold above.
+  T sintheta = std::min(sqrt(angle_axis[0] * angle_axis[0] +
+                             angle_axis[1] * angle_axis[1] +
+                             angle_axis[2] * angle_axis[2]) / kTwo,
+                        kOne);
+
+  // Use the arctan2 to get the right sign on theta
+  const T theta = atan2(sintheta, costheta);
+
+  // Case 1: sin(theta) is large enough, so dividing by it is not a
+  // problem. We do not use abs here, because while jets.h imports
+  // std::abs into the namespace, here in this file, abs resolves to
+  // the int version of the function, which returns zero always.
+  //
+  // We use a threshold much larger then the machine epsilon, because
+  // if sin(theta) is small, not only do we risk overflow but even if
+  // that does not occur, just dividing by a small number will result
+  // in numerical garbage. So we play it safe.
+  static const double kThreshold = 1e-12;
+  if ((sintheta > kThreshold) || (sintheta < -kThreshold)) {
+    const T r = theta / (kTwo * sintheta);
+    for (int i = 0; i < 3; ++i) {
+      angle_axis[i] *= r;
+    }
+    return;
+  }
+
+  // Case 2: theta ~ 0, means sin(theta) ~ theta to a good
+  // approximation.
+  if (costheta > 0) {
+    const T kHalf = T(0.5);
+    for (int i = 0; i < 3; ++i) {
+      angle_axis[i] *= kHalf;
+    }
+    return;
+  }
+
+  // Case 3: theta ~ pi, this is the hard case. Since theta is large,
+  // and sin(theta) is small. Dividing by theta by sin(theta) will
+  // either give an overflow or worse still numerically meaningless
+  // results. Thus we use an alternate more complicated formula
+  // here.
+
+  // Since cos(theta) is negative, division by (1-cos(theta)) cannot
+  // overflow.
+  const T inv_one_minus_costheta = kOne / (kOne - costheta);
+
+  // We now compute the absolute value of coordinates of the axis
+  // vector using the diagonal entries of R. To resolve the sign of
+  // these entries, we compare the sign of angle_axis[i]*sin(theta)
+  // with the sign of sin(theta). If they are the same, then
+  // angle_axis[i] should be positive, otherwise negative.
+  for (int i = 0; i < 3; ++i) {
+    angle_axis[i] = theta * sqrt((R[i*4] - costheta) * inv_one_minus_costheta);
+    if (((sintheta < 0) && (angle_axis[i] > 0)) ||
+        ((sintheta > 0) && (angle_axis[i] < 0))) {
+      angle_axis[i] = -angle_axis[i];
+    }
+  }
+}
+
+template <typename T>
+inline void AngleAxisToRotationMatrix(const T * angle_axis, T * R) {
+  static const T kOne = T(1.0);
+  const T theta2 = DotProduct(angle_axis, angle_axis);
+  if (theta2 > 0.0) {
+    // We want to be careful to only evaluate the square root if the
+    // norm of the angle_axis vector is greater than zero. Otherwise
+    // we get a division by zero.
+    const T theta = sqrt(theta2);
+    const T wx = angle_axis[0] / theta;
+    const T wy = angle_axis[1] / theta;
+    const T wz = angle_axis[2] / theta;
+
+    const T costheta = cos(theta);
+    const T sintheta = sin(theta);
+
+    R[0] =     costheta   + wx*wx*(kOne -    costheta);
+    R[1] =  wz*sintheta   + wx*wy*(kOne -    costheta);
+    R[2] = -wy*sintheta   + wx*wz*(kOne -    costheta);
+    R[3] =  wx*wy*(kOne - costheta)     - wz*sintheta;
+    R[4] =     costheta   + wy*wy*(kOne -    costheta);
+    R[5] =  wx*sintheta   + wy*wz*(kOne -    costheta);
+    R[6] =  wy*sintheta   + wx*wz*(kOne -    costheta);
+    R[7] = -wx*sintheta   + wy*wz*(kOne -    costheta);
+    R[8] =     costheta   + wz*wz*(kOne -    costheta);
+  } else {
+    // At zero, we switch to using the first order Taylor expansion.
+    R[0] =  kOne;
+    R[1] = -angle_axis[2];
+    R[2] =  angle_axis[1];
+    R[3] =  angle_axis[2];
+    R[4] =  kOne;
+    R[5] = -angle_axis[0];
+    R[6] = -angle_axis[1];
+    R[7] =  angle_axis[0];
+    R[8] = kOne;
+  }
+}
+
+template <typename T>
+inline void EulerAnglesToRotationMatrix(const T* euler,
+                                        const int row_stride,
+                                        T* R) {
+  const T degrees_to_radians(M_PI / 180.0);
+
+  const T pitch(euler[0] * degrees_to_radians);
+  const T roll(euler[1] * degrees_to_radians);
+  const T yaw(euler[2] * degrees_to_radians);
+
+  const T c1 = cos(yaw);
+  const T s1 = sin(yaw);
+  const T c2 = cos(roll);
+  const T s2 = sin(roll);
+  const T c3 = cos(pitch);
+  const T s3 = sin(pitch);
+
+  // Rows of the rotation matrix.
+  T* R1 = R;
+  T* R2 = R1 + row_stride;
+  T* R3 = R2 + row_stride;
+
+  R1[0] = c1*c2;
+  R1[1] = -s1*c3 + c1*s2*s3;
+  R1[2] = s1*s3 + c1*s2*c3;
+
+  R2[0] = s1*c2;
+  R2[1] = c1*c3 + s1*s2*s3;
+  R2[2] = -c1*s3 + s1*s2*c3;
+
+  R3[0] = -s2;
+  R3[1] = c2*s3;
+  R3[2] = c2*c3;
+}
+
+template <typename T> inline
+void QuaternionToScaledRotation(const T q[4], T R[3 * 3]) {
+  // Make convenient names for elements of q.
+  T a = q[0];
+  T b = q[1];
+  T c = q[2];
+  T d = q[3];
+  // This is not to eliminate common sub-expression, but to
+  // make the lines shorter so that they fit in 80 columns!
+  T aa = a * a;
+  T ab = a * b;
+  T ac = a * c;
+  T ad = a * d;
+  T bb = b * b;
+  T bc = b * c;
+  T bd = b * d;
+  T cc = c * c;
+  T cd = c * d;
+  T dd = d * d;