Update Ceres to latest upstream version

Brings new bounds limiting and also prepares build system
for the changes in the upstream.

Namely shared_ptr header and namespace is now being detected
by a build system rather than by hacks in the code.

This commit includes some changes to auto-detection flags
in SCons, presumably adding more consistency there. This
is main changes which are suppoed to be reviewed here.

Reviewers: campbellbarton

Differential Revision: https://developer.blender.org/D581
This commit is contained in:
Sergey Sharybin 2014-05-02 05:52:56 +06:00
parent 0a0e4e0e69
commit 72ac596e19
134 changed files with 3118 additions and 1499 deletions

@ -40,11 +40,13 @@ import string
import shutil
import re
# store path to tools
# store path to tools and modules
toolpath=os.path.join(".", "build_files", "scons", "tools")
modulespath=os.path.join(".", "build_files", "scons", "Modules")
# needed for importing tools
# needed for importing tools and modules
sys.path.append(toolpath)
sys.path.append(modulespath)
import Blender
import btools
@ -176,6 +178,16 @@ if crossbuild and platform not in ('win32-vc', 'win64-vc'):
env['OURPLATFORM'] = platform
# Put all auto configuration run-time tests here
from FindSharedPtr import FindSharedPtr
from FindUnorderedMap import FindUnorderedMap
conf = Configure(env)
FindSharedPtr(conf)
FindUnorderedMap(conf)
env = conf.Finish()
configfile = os.path.join("build_files", "scons", "config", platform + "-config.py")
if os.path.exists(configfile):

@ -791,6 +791,78 @@ macro(TEST_UNORDERED_MAP_SUPPORT)
endif()
endmacro()
macro(TEST_SHARED_PTR_SUPPORT)
# This check are coming from Ceres library.
#
# Find shared pointer header and namespace.
#
# This module defines the following variables:
#
# SHARED_PTR_FOUND: TRUE if shared_ptr found.
# SHARED_PTR_TR1_MEMORY_HEADER: True if <tr1/memory> header is to be used
# for the shared_ptr object, otherwise use <memory>.
# SHARED_PTR_TR1_NAMESPACE: TRUE if shared_ptr is defined in std::tr1 namespace,
# otherwise it's assumed to be defined in std namespace.
include(CheckIncludeFileCXX)
set(SHARED_PTR_FOUND FALSE)
CHECK_INCLUDE_FILE_CXX(memory HAVE_STD_MEMORY_HEADER)
if(HAVE_STD_MEMORY_HEADER)
# Finding the memory header doesn't mean that shared_ptr is in std
# namespace.
#
# In particular, MSVC 2008 has shared_ptr declared in std::tr1. In
# order to support this, we do an extra check to see which namespace
# should be used.
include(CheckCXXSourceCompiles)
CHECK_CXX_SOURCE_COMPILES("#include <memory>
int main() {
std::shared_ptr<int> int_ptr;
return 0;
}"
HAVE_SHARED_PTR_IN_STD_NAMESPACE)
if(HAVE_SHARED_PTR_IN_STD_NAMESPACE)
message("-- Found shared_ptr in std namespace using <memory> header.")
set(SHARED_PTR_FOUND TRUE)
else()
CHECK_CXX_SOURCE_COMPILES("#include <memory>
int main() {
std::tr1::shared_ptr<int> int_ptr;
return 0;
}"
HAVE_SHARED_PTR_IN_TR1_NAMESPACE)
if(HAVE_SHARED_PTR_IN_TR1_NAMESPACE)
message("-- Found shared_ptr in std::tr1 namespace using <memory> header.")
set(SHARED_PTR_TR1_NAMESPACE TRUE)
set(SHARED_PTR_FOUND TRUE)
endif()
endif()
endif()
if(NOT SHARED_PTR_FOUND)
# Further, gcc defines shared_ptr in std::tr1 namespace and
# <tr1/memory> is to be included for this. And what makes things
# even more tricky is that gcc does have <memory> header, so
# all the checks above wouldn't find shared_ptr.
CHECK_INCLUDE_FILE_CXX("tr1/memory" HAVE_TR1_MEMORY_HEADER)
if(HAVE_TR1_MEMORY_HEADER)
CHECK_CXX_SOURCE_COMPILES("#include <tr1/memory>
int main() {
std::tr1::shared_ptr<int> int_ptr;
return 0;
}"
HAVE_SHARED_PTR_IN_TR1_NAMESPACE_FROM_TR1_MEMORY_HEADER)
if(HAVE_SHARED_PTR_IN_TR1_NAMESPACE_FROM_TR1_MEMORY_HEADER)
message("-- Found shared_ptr in std::tr1 namespace using <tr1/memory> header.")
set(SHARED_PTR_TR1_MEMORY_HEADER TRUE)
set(SHARED_PTR_TR1_NAMESPACE TRUE)
set(SHARED_PTR_FOUND TRUE)
endif()
endif()
endif()
endmacro()
# when we have warnings as errors applied globally this
# needs to be removed for some external libs which we dont maintain.

@ -0,0 +1,42 @@
def FindSharedPtr(conf):
"""
Detect shared_ptr availability
"""
found = False
namespace = None
header = None
if conf.CheckCXXHeader("memory"):
# Finding the memory header doesn't mean that shared_ptr is in std
# namespace.
#
# In particular, MSVC 2008 has shared_ptr declared in std::tr1. In
# order to support this, we do an extra check to see which namespace
# should be used.
if conf.CheckType('std::shared_ptr<int>', language = 'CXX', includes="#include <memory>"):
print("-- Found shared_ptr in std namespace using <memory> header.")
namespace = 'std'
header = 'memory'
elif conf.CheckType('std::tr1::shared_ptr<int>', language = 'CXX', includes="#include <memory>"):
print("-- Found shared_ptr in std::tr1 namespace using <memory> header..")
namespace = 'std::tr1'
header = 'memory'
if not namespace and conf.CheckCXXHeader("tr1/memory"):
# Further, gcc defines shared_ptr in std::tr1 namespace and
# <tr1/memory> is to be included for this. And what makes things
# even more tricky is that gcc does have <memory> header, so
# all the checks above wouldn't find shared_ptr.
if conf.CheckType('std::tr1::shared_ptr<int>', language = 'CXX', includes="#include <tr1/memory>"):
print("-- Found shared_ptr in std::tr1 namespace using <tr1/memory> header..")
namespace = 'std::tr1'
header = 'tr1/memory'
if not namespace:
print("-- Unable to find shared_ptrred_map>.")
conf.env['WITH_SHARED_PTR_SUPPORT'] = namespace and header
conf.env['SHARED_PTR_NAMESPACE'] = namespace
conf.env['SHARED_PTR_HEADER'] = header

@ -1,10 +1,11 @@
def test_unordered_map(conf):
def FindUnorderedMap(conf):
"""
Detect unordered_map availability
Returns (True/False, namespace, include prefix)
"""
namespace = None
header = None
if conf.CheckCXXHeader("unordered_map"):
# Even so we've found unordered_map header file it doesn't
# mean unordered_map and unordered_set will be declared in
@ -17,16 +18,21 @@ def test_unordered_map(conf):
if conf.CheckType('std::unordered_map<int, int>', language = 'CXX', includes="#include <unordered_map>"):
print("-- Found unordered_map/set in std namespace.")
return True, 'std', ''
namespace = 'std'
header = 'unordered_map'
elif conf.CheckType('std::tr1::unordered_map<int, int>', language = 'CXX', includes="#include <unordered_map>"):
print("-- Found unordered_map/set in std::tr1 namespace.")
return True, 'std::tr1', ''
namespace = 'std::tr1'
header = 'unordered_map'
else:
print("-- Found <unordered_map> but can not find neither std::unordered_map nor std::tr1::unordered_map.")
return False, '', ''
elif conf.CheckCXXHeader("tr1/unordered_map"):
print("-- Found unordered_map/set in std::tr1 namespace.")
return True, 'std::tr1', 'tr1/'
namespace = 'std::tr1'
header = 'tr1/unordered_map'
else:
print("-- Unable to find <unordered_map> or <tr1/unordered_map>. ")
return False, '', ''
conf.env['WITH_UNORDERED_MAP_SUPPORT'] = namespace and header
conf.env['UNORDERED_MAP_NAMESPACE'] = namespace
conf.env['UNORDERED_MAP_HEADER'] = header

@ -1,4 +1,4 @@
from Modules.FindPython import FindPython
from FindPython import FindPython
py = FindPython()

@ -46,10 +46,23 @@ if(WITH_LIBMV)
-DLIBMV_NO_FAST_DETECTOR=
)
TEST_SHARED_PTR_SUPPORT()
if(SHARED_PTR_FOUND)
if(SHARED_PTR_TR1_MEMORY_HEADER)
add_definitions(-DCERES_TR1_MEMORY_HEADER)
endif()
if(SHARED_PTR_TR1_NAMESPACE)
add_definitions(-DCERES_TR1_SHARED_PTR)
endif()
else()
message(FATAL_ERROR "Unable to find shared_ptr.")
endif()
list(APPEND INC
third_party/gflags
third_party/glog/src
third_party/ceres/include
third_party/ceres/config
../../intern/guardedalloc
)

@ -6,6 +6,7 @@
import sys
import os
from FindSharedPtr import FindSharedPtr
Import('env')
@ -13,6 +14,15 @@ defs = []
incs = '.'
if env['WITH_BF_LIBMV']:
if not env['WITH_SHARED_PTR_SUPPORT']:
print("-- Unable to find shared_ptr which is required for compilation.")
exit(1)
if env['SHARED_PTR_HEADER'] == 'tr1/memory':
defs.append('CERES_TR1_MEMORY_HEADER')
if env['SHARED_PTR_NAMESPACE'] == 'std::tr1':
defs.append('CERES_TR1_SHARED_PTR')
defs.append('GOOGLE_GLOG_DLL_DECL=')
defs.append('WITH_LIBMV')
defs.append('WITH_LIBMV_GUARDED_ALLOC')
@ -27,7 +37,7 @@ if env['WITH_BF_LIBMV']:
src += env.Glob('libmv/tracking/*.cc')
src += env.Glob('third_party/gflags/*.cc')
incs += ' ../Eigen3 third_party/gflags third_party/glog/src third_party/ceres/include ../../intern/guardedalloc'
incs += ' ../Eigen3 third_party/gflags third_party/glog/src third_party/ceres/include third_party/ceres/config ../../intern/guardedalloc'
incs += ' ' + env['BF_PNG_INC']
incs += ' ' + env['BF_ZLIB_INC']

@ -139,10 +139,23 @@ if(WITH_LIBMV)
-DLIBMV_NO_FAST_DETECTOR=
)
TEST_SHARED_PTR_SUPPORT()
if(SHARED_PTR_FOUND)
if(SHARED_PTR_TR1_MEMORY_HEADER)
add_definitions(-DCERES_TR1_MEMORY_HEADER)
endif()
if(SHARED_PTR_TR1_NAMESPACE)
add_definitions(-DCERES_TR1_SHARED_PTR)
endif()
else()
message(FATAL_ERROR "Unable to find shared_ptr.")
endif()
list(APPEND INC
third_party/gflags
third_party/glog/src
third_party/ceres/include
third_party/ceres/config
../../intern/guardedalloc
)
@ -264,6 +277,15 @@ defs = []
incs = '.'
if env['WITH_BF_LIBMV']:
if not env['WITH_SHARED_PTR_SUPPORT']:
print("-- Unable to find shared_ptr which is required for compilation.")
exit(1)
if env['SHARED_PTR_HEADER'] == 'tr1/memory':
defs.append('CERES_TR1_MEMORY_HEADER')
if env['SHARED_PTR_NAMESPACE'] == 'std::tr1':
defs.append('CERES_TR1_SHARED_PTR')
defs.append('GOOGLE_GLOG_DLL_DECL=')
defs.append('WITH_LIBMV')
defs.append('WITH_LIBMV_GUARDED_ALLOC')
@ -272,7 +294,7 @@ if env['WITH_BF_LIBMV']:
src = env.Glob('*.cc')
$src
incs += ' ../Eigen3 third_party/gflags third_party/glog/src third_party/ceres/include ../../intern/guardedalloc'
incs += ' ../Eigen3 third_party/gflags third_party/glog/src third_party/ceres/include third_party/ceres/config ../../intern/guardedalloc'
incs += ' ' + env['BF_PNG_INC']
incs += ' ' + env['BF_ZLIB_INC']

@ -30,6 +30,7 @@ set(INC
.
include
internal
config
../gflags
../../
)
@ -44,7 +45,6 @@ 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_crs_matrix.cc
internal/ceres/block_random_access_dense_matrix.cc
internal/ceres/block_random_access_diagonal_matrix.cc
internal/ceres/block_random_access_matrix.cc
@ -69,6 +69,8 @@ set(SRC
internal/ceres/dense_sparse_matrix.cc
internal/ceres/detect_structure.cc
internal/ceres/dogleg_strategy.cc
internal/ceres/dynamic_compressed_row_jacobian_writer.cc
internal/ceres/dynamic_compressed_row_sparse_matrix.cc
internal/ceres/evaluator.cc
internal/ceres/file.cc
internal/ceres/generated/partitioned_matrix_view_d_d_d.cc
@ -159,7 +161,6 @@ set(SRC
internal/ceres/block_evaluate_preparer.h
internal/ceres/block_jacobian_writer.h
internal/ceres/block_jacobi_preconditioner.h
internal/ceres/block_random_access_crs_matrix.h
internal/ceres/block_random_access_dense_matrix.h
internal/ceres/block_random_access_diagonal_matrix.h
internal/ceres/block_random_access_matrix.h
@ -185,6 +186,9 @@ set(SRC
internal/ceres/dense_sparse_matrix.h
internal/ceres/detect_structure.h
internal/ceres/dogleg_strategy.h
internal/ceres/dynamic_compressed_row_finalizer.h
internal/ceres/dynamic_compressed_row_jacobian_writer.h
internal/ceres/dynamic_compressed_row_sparse_matrix.h
internal/ceres/evaluator.h
internal/ceres/execution_summary.h
internal/ceres/file.h
@ -253,6 +257,8 @@ set(SRC
# internal/ceres/generated/partitioned_matrix_view_2_3_d.cc
# internal/ceres/generated/partitioned_matrix_view_2_4_3.cc
# internal/ceres/generated/partitioned_matrix_view_2_4_4.cc
# internal/ceres/generated/partitioned_matrix_view_2_4_8.cc
# internal/ceres/generated/partitioned_matrix_view_2_4_9.cc
# internal/ceres/generated/partitioned_matrix_view_2_4_d.cc
# internal/ceres/generated/partitioned_matrix_view_2_d_d.cc
# internal/ceres/generated/partitioned_matrix_view_4_4_2.cc
@ -269,6 +275,8 @@ set(SRC
# 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_8.cc
# internal/ceres/generated/schur_eliminator_2_4_9.cc
# internal/ceres/generated/schur_eliminator_2_4_d.cc
# internal/ceres/generated/schur_eliminator_2_d_d.cc
# internal/ceres/generated/schur_eliminator_4_4_2.cc

File diff suppressed because it is too large Load Diff

@ -29,29 +29,28 @@ defs.append('CERES_HAVE_RWLOCK')
if env['WITH_BF_OPENMP']:
defs.append('CERES_USE_OPENMP')
def define_unordered_map(conf):
found, namespace, include_prefix = test_unordered_map(conf)
if found:
if not include_prefix:
if namespace == 'std':
defs.append('CERES_STD_UNORDERED_MAP')
return True
elif namespace == 'std::tr1':
defs.append('CERES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE')
return True
else:
if namespace == 'std::tr1':
defs.append('CERES_TR1_UNORDERED_MAP')
return True
return False
conf = Configure(env)
if not define_unordered_map(conf):
if env['WITH_UNORDERED_MAP_SUPPORT']:
if env['UNORDERED_MAP_HEADER'] == 'unordered_map':
if env['UNORDERED_MAP_NAMESPACE'] == 'std':
defs.append('CERES_STD_UNORDERED_MAP')
elif env['UNORDERED_MAP_NAMESPACE'] == 'std::tr1':
defs.append('CERES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE')
elif env['UNORDERED_MAP_NAMESPACE'] == 'std::tr1':
defs.append('CERES_TR1_UNORDERED_MAP')
else:
print("-- Replacing unordered_map/set with map/set (warning: slower!)")
defs.append('CERES_NO_UNORDERED_MAP')
env = conf.Finish()
incs = '. ../../ ../../../Eigen3 ./include ./internal ../gflags'
if not env['WITH_SHARED_PTR_SUPPORT']:
print("-- Unable to find shared_ptr which is required for compilation.")
exit(1)
if env['SHARED_PTR_HEADER'] == 'tr1/memory':
defs.append('CERES_TR1_MEMORY_HEADER')
if env['SHARED_PTR_NAMESPACE'] == 'std::tr1':
defs.append('CERES_TR1_SHARED_PTR')
incs = '. ../../ ../../../Eigen3 ./include ./internal ../gflags ./config'
# work around broken hashtable in 10.5 SDK
if env['OURPLATFORM'] == 'darwin' and env['WITH_BF_BOOST']:

@ -123,6 +123,7 @@ set(INC
.
include
internal
config
../gflags
../../
)
@ -230,29 +231,28 @@ defs.append('CERES_HAVE_RWLOCK')
if env['WITH_BF_OPENMP']:
defs.append('CERES_USE_OPENMP')
def define_unordered_map(conf):
found, namespace, include_prefix = test_unordered_map(conf)
if found:
if not include_prefix:
if namespace == 'std':
defs.append('CERES_STD_UNORDERED_MAP')
return True
elif namespace == 'std::tr1':
defs.append('CERES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE')
return True
else:
if namespace == 'std::tr1':
defs.append('CERES_TR1_UNORDERED_MAP')
return True
return False
conf = Configure(env)
if not define_unordered_map(conf):
if env['WITH_UNORDERED_MAP_SUPPORT']:
if env['UNORDERED_MAP_HEADER'] == 'unordered_map':
if env['UNORDERED_MAP_NAMESPACE'] == 'std':
defs.append('CERES_STD_UNORDERED_MAP')
elif env['UNORDERED_MAP_NAMESPACE'] == 'std::tr1':
defs.append('CERES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE')
elif env['UNORDERED_MAP_NAMESPACE'] == 'std::tr1':
defs.append('CERES_TR1_UNORDERED_MAP')
else:
print("-- Replacing unordered_map/set with map/set (warning: slower!)")
defs.append('CERES_NO_UNORDERED_MAP')
env = conf.Finish()
incs = '. ../../ ../../../Eigen3 ./include ./internal ../gflags'
if not env['WITH_SHARED_PTR_SUPPORT']:
print("-- Unable to find shared_ptr which is required for compilation.")
exit(1)
if env['SHARED_PTR_HEADER'] == 'tr1/memory':
defs.append('CERES_TR1_MEMORY_HEADER')
if env['SHARED_PTR_NAMESPACE'] == 'std::tr1':
defs.append('CERES_TR1_SHARED_PTR')
incs = '. ../../ ../../../Eigen3 ./include ./internal ../gflags ./config'
# work around broken hashtable in 10.5 SDK
if env['OURPLATFORM'] == 'darwin' and env['WITH_BF_BOOST']:

@ -0,0 +1,45 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2014 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: alexs.mac@gmail.com (Alex Stewart)
// Default (empty) configuration options for Ceres.
//
// IMPORTANT: Most users of Ceres will not use this file, when compiling Ceres
// with CMake, CMake will configure a new config.h with the currently
// selected Ceres compile options and copy it into the source
// directory before compilation. However, for some users of Ceres
// who compile without CMake, this file ensures that Ceres will
// compile, with the user either specifying manually the Ceres
// compile options, or passing them directly through the compiler.
#ifndef CERES_PUBLIC_INTERNAL_CONFIG_H_
#define CERES_PUBLIC_INTERNAL_CONFIG_H_
#endif // CERES_PUBLIC_INTERNAL_CONFIG_H_

@ -43,8 +43,6 @@ 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_crs_matrix.cc
internal/ceres/block_random_access_crs_matrix.h
internal/ceres/block_random_access_dense_matrix.cc
internal/ceres/block_random_access_dense_matrix.h
internal/ceres/block_random_access_diagonal_matrix.cc
@ -64,6 +62,7 @@ internal/ceres/casts.h
internal/ceres/cgnr_linear_operator.h
internal/ceres/cgnr_solver.cc
internal/ceres/cgnr_solver.h
internal/ceres/CMakeLists.txt
internal/ceres/collections_port.h
internal/ceres/compressed_col_sparse_matrix_utils.cc
internal/ceres/compressed_col_sparse_matrix_utils.h
@ -94,6 +93,11 @@ internal/ceres/detect_structure.cc
internal/ceres/detect_structure.h
internal/ceres/dogleg_strategy.cc
internal/ceres/dogleg_strategy.h
internal/ceres/dynamic_compressed_row_finalizer.h
internal/ceres/dynamic_compressed_row_jacobian_writer.cc
internal/ceres/dynamic_compressed_row_jacobian_writer.h
internal/ceres/dynamic_compressed_row_sparse_matrix.cc
internal/ceres/dynamic_compressed_row_sparse_matrix.h
internal/ceres/evaluator.cc
internal/ceres/evaluator.h
internal/ceres/execution_summary.h
@ -109,6 +113,8 @@ internal/ceres/generated/partitioned_matrix_view_2_3_9.cc
internal/ceres/generated/partitioned_matrix_view_2_3_d.cc
internal/ceres/generated/partitioned_matrix_view_2_4_3.cc
internal/ceres/generated/partitioned_matrix_view_2_4_4.cc
internal/ceres/generated/partitioned_matrix_view_2_4_8.cc
internal/ceres/generated/partitioned_matrix_view_2_4_9.cc
internal/ceres/generated/partitioned_matrix_view_2_4_d.cc
internal/ceres/generated/partitioned_matrix_view_2_d_d.cc
internal/ceres/generated/partitioned_matrix_view_4_4_2.cc
@ -126,6 +132,8 @@ 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_8.cc
internal/ceres/generated/schur_eliminator_2_4_9.cc
internal/ceres/generated/schur_eliminator_2_4_d.cc
internal/ceres/generated/schur_eliminator_2_d_d.cc
internal/ceres/generated/schur_eliminator_4_4_2.cc
@ -231,3 +239,4 @@ internal/ceres/visibility.cc
internal/ceres/visibility.h
internal/ceres/wall_time.cc
internal/ceres/wall_time.h
config/ceres/internal/config.h

@ -107,11 +107,18 @@ namespace ceres {
template <typename Functor, int kGlobalSize, int kLocalSize>
class AutoDiffLocalParameterization : public LocalParameterization {
public:
AutoDiffLocalParameterization() :
functor_(new Functor()) {}
// Takes ownership of functor.
explicit AutoDiffLocalParameterization(Functor* functor) :
functor_(functor) {}
virtual ~AutoDiffLocalParameterization() {}
virtual bool Plus(const double* x,
const double* delta,
double* x_plus_delta) const {
return Functor()(x, delta, x_plus_delta);
return (*functor_)(x, delta, x_plus_delta);
}
virtual bool ComputeJacobian(const double* x, double* jacobian) const {
@ -128,7 +135,7 @@ class AutoDiffLocalParameterization : public LocalParameterization {
const double* parameter_ptrs[2] = {x, zero_delta};
double* jacobian_ptrs[2] = { NULL, jacobian };
return internal::AutoDiff<Functor, double, kGlobalSize, kLocalSize>
::Differentiate(Functor(),
::Differentiate(*functor_,
parameter_ptrs,
kGlobalSize,
x_plus_delta,
@ -137,6 +144,9 @@ class AutoDiffLocalParameterization : public LocalParameterization {
virtual int GlobalSize() const { return kGlobalSize; }
virtual int LocalSize() const { return kLocalSize; }
private:
internal::scoped_ptr<Functor> functor_;
};
} // namespace ceres

@ -38,12 +38,14 @@
#ifndef CERES_PUBLIC_C_API_H_
#define CERES_PUBLIC_C_API_H_
#include "ceres/internal/port.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Init the Ceres private data. Must be called before anything else. */
void ceres_init();
CERES_EXPORT void ceres_init();
/* Equivalent to CostFunction::Evaluate() in the C++ API.
*
@ -88,23 +90,23 @@ typedef void (*ceres_loss_function_t)(void* user_data,
*
* See loss_function.h for the details of each loss function.
*/
void* ceres_create_huber_loss_function_data(double a);
void* ceres_create_softl1_loss_function_data(double a);
void* ceres_create_cauchy_loss_function_data(double a);
void* ceres_create_arctan_loss_function_data(double a);
void* ceres_create_tolerant_loss_function_data(double a, double b);
CERES_EXPORT void* ceres_create_huber_loss_function_data(double a);
CERES_EXPORT void* ceres_create_softl1_loss_function_data(double a);
CERES_EXPORT void* ceres_create_cauchy_loss_function_data(double a);
CERES_EXPORT void* ceres_create_arctan_loss_function_data(double a);
CERES_EXPORT void* ceres_create_tolerant_loss_function_data(double a, double b);
/* Free the given stock loss function data. */
void ceres_free_stock_loss_function_data(void* loss_function_data);
CERES_EXPORT void ceres_free_stock_loss_function_data(void* loss_function_data);
/* This is an implementation of ceres_loss_function_t contained within Ceres
* itself, intended as a way to access the various stock Ceres loss functions
* from the C API. This should be passed to ceres_add_residual() below, in
* combination with a user_data pointer generated by
* ceres_create_stock_loss_function() above. */
void ceres_stock_loss_function(void* user_data,
double squared_norm,
double out[3]);
CERES_EXPORT void ceres_stock_loss_function(void* user_data,
double squared_norm,
double out[3]);
/* Equivalent to Problem from the C++ API. */
struct ceres_problem_s;
@ -115,11 +117,11 @@ typedef struct ceres_residual_block_id_s ceres_residual_block_id_t;
/* Create and destroy a problem */
/* TODO(keir): Add options for the problem. */
ceres_problem_t* ceres_create_problem();
void ceres_free_problem(ceres_problem_t* problem);
CERES_EXPORT ceres_problem_t* ceres_create_problem();
CERES_EXPORT void ceres_free_problem(ceres_problem_t* problem);
/* Add a residual block. */
ceres_residual_block_id_t* ceres_problem_add_residual_block(
CERES_EXPORT ceres_residual_block_id_t* ceres_problem_add_residual_block(
ceres_problem_t* problem,
ceres_cost_function_t cost_function,
void* cost_function_data,
@ -130,7 +132,7 @@ ceres_residual_block_id_t* ceres_problem_add_residual_block(
int* parameter_block_sizes,
double** parameters);
void ceres_solve(ceres_problem_t* problem);
CERES_EXPORT void ceres_solve(ceres_problem_t* problem);
/* TODO(keir): Figure out a way to pass a config in. */

@ -34,8 +34,8 @@
#ifndef CERES_PUBLIC_CERES_H_
#define CERES_PUBLIC_CERES_H_
#define CERES_VERSION 1.8.0
#define CERES_ABI_VERSION 1.8.0
#define CERES_VERSION 1.9.0
#define CERES_ABI_VERSION 1.9.0
#include "ceres/autodiff_cost_function.h"
#include "ceres/autodiff_local_parameterization.h"

@ -70,7 +70,7 @@ namespace ceres {
// ccf_residual[i] = f_i(my_cost_function_residual[i])
//
// and the Jacobian will be affected appropriately.
class ConditionedCostFunction : public CostFunction {
class CERES_EXPORT 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

@ -60,7 +60,7 @@ namespace ceres {
// 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 {
class CERES_EXPORT CostFunction {
public:
CostFunction() : num_residuals_(0) {}

@ -196,9 +196,9 @@ class CovarianceImpl;
// covariance.GetCovarianceBlock(y, y, covariance_yy)
// covariance.GetCovarianceBlock(x, y, covariance_xy)
//
class Covariance {
class CERES_EXPORT Covariance {
public:
struct Options {
struct CERES_EXPORT Options {
Options()
#ifndef CERES_NO_SUITESPARSE
: algorithm_type(SPARSE_QR),

@ -38,7 +38,7 @@ namespace ceres {
// A compressed row sparse matrix used primarily for communicating the
// Jacobian matrix to the user.
struct CRSMatrix {
struct CERES_EXPORT CRSMatrix {
CRSMatrix() : num_rows(0), num_cols(0) {}
int num_rows;

@ -46,25 +46,24 @@
namespace ceres {
#if defined(_MSC_VER)
inline bool IsFinite (double x) { return _finite(x); }
inline bool IsInfinite(double x) { return !_finite(x) && !_isnan(x); }
inline bool IsNaN (double x) { return _isnan(x); }
inline bool IsFinite (double x) { return _finite(x) != 0; }
inline bool IsInfinite(double x) { return _finite(x) == 0 && _isnan(x) == 0; }
inline bool IsNaN (double x) { return _isnan(x) != 0; }
inline bool IsNormal (double x) {
int classification = _fpclass(x);
return classification == _FPCLASS_NN ||
classification == _FPCLASS_PN;
}
#elif defined(ANDROID)
// On Android when using the GNU STL, the C++ fpclassify functions are not
// available. Strictly speaking, the std functions are are not standard until
// C++11. Instead use the C99 macros on Android.
#elif defined(ANDROID) && defined(_STLPORT_VERSION)
// On Android, when using the STLPort, the C++ isnan and isnormal functions
// are defined as macros.
inline bool IsNaN (double x) { return isnan(x); }
inline bool IsNormal (double x) { return isnormal(x); }
// On Android NDK r6, when using STLPort, the isinf and isfinite functions are
// not available, so reimplement them.
# if defined(_STLPORT_VERSION)
inline bool IsInfinite(double x) {
return x == std::numeric_limits<double>::infinity() ||
x == -std::numeric_limits<double>::infinity();
@ -72,17 +71,15 @@ inline bool IsInfinite(double x) {
inline bool IsFinite(double x) {
return !isnan(x) && !IsInfinite(x);
}
# else
inline bool IsFinite (double x) { return isfinite(x); }
inline bool IsInfinite(double x) { return isinf(x); }
# endif // defined(_STLPORT_VERSION)
#else
# else
// These definitions are for the normal Unix suspects.
// TODO(keir): Test the "else" with more platforms.
inline bool IsFinite (double x) { return std::isfinite(x); }
inline bool IsInfinite(double x) { return std::isinf(x); }
inline bool IsNaN (double x) { return std::isnan(x); }
inline bool IsNormal (double x) { return std::isnormal(x); }
#endif
} // namespace ceres

@ -31,8 +31,19 @@
#ifndef CERES_PUBLIC_INTERNAL_PORT_H_
#define CERES_PUBLIC_INTERNAL_PORT_H_
// This file needs to compile as c code.
#ifdef __cplusplus
#include <string>
#include "ceres/internal/config.h"
#if defined(CERES_TR1_MEMORY_HEADER)
#include <tr1/memory>
#else
#include <memory>
#endif
namespace ceres {
// It is unfortunate that this import of the entire standard namespace is
@ -45,6 +56,33 @@ using namespace std;
// "string" implementation in the global namespace.
using std::string;
#if defined(CERES_TR1_SHARED_PTR)
using std::tr1::shared_ptr;
#else
using std::shared_ptr;
#endif
} // namespace ceres
#endif // __cplusplus
// A macro to signal which functions and classes are exported when
// building a DLL with MSVC.
//
// Note that the ordering here is important, CERES_BUILDING_SHARED_LIBRARY
// is only defined locally when Ceres is compiled, it is never exported to
// users. However, in order that we do not have to configure config.h
// separately for building vs installing, if we are using MSVC and building
// a shared library, then both CERES_BUILDING_SHARED_LIBRARY and
// CERES_USING_SHARED_LIBRARY will be defined when Ceres is compiled.
// Hence it is important that the check for CERES_BUILDING_SHARED_LIBRARY
// happens first.
#if defined(_MSC_VER) && defined(CERES_BUILDING_SHARED_LIBRARY)
# define CERES_EXPORT __declspec(dllexport)
#elif defined(_MSC_VER) && defined(CERES_USING_SHARED_LIBRARY)
# define CERES_EXPORT __declspec(dllimport)
#else
# define CERES_EXPORT
#endif
#endif // CERES_PUBLIC_INTERNAL_PORT_H_

@ -41,7 +41,7 @@ namespace ceres {
// This struct describes the state of the optimizer after each
// iteration of the minimization.
struct IterationSummary {
struct CERES_EXPORT IterationSummary {
IterationSummary()
: iteration(0),
step_is_valid(false),
@ -211,7 +211,7 @@ struct IterationSummary {
// const bool log_to_stdout_;
// };
//
class IterationCallback {
class CERES_EXPORT IterationCallback {
public:
virtual ~IterationCallback() {}
virtual CallbackReturnType operator()(const IterationSummary& summary) = 0;

@ -649,6 +649,8 @@ struct NumTraits<ceres::Jet<T, N> > {
return ceres::Jet<T, N>(1e-12);
}
static inline Real epsilon() { return Real(std::numeric_limits<T>::epsilon()); }
enum {
IsComplex = 0,
IsInteger = 0,

@ -107,7 +107,7 @@ namespace ceres {
//
// 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 {
class CERES_EXPORT LocalParameterization {
public:
virtual ~LocalParameterization() {}
@ -133,7 +133,7 @@ class LocalParameterization {
// Some basic parameterizations
// Identity Parameterization: Plus(x, delta) = x + delta
class IdentityParameterization : public LocalParameterization {
class CERES_EXPORT IdentityParameterization : public LocalParameterization {
public:
explicit IdentityParameterization(int size);
virtual ~IdentityParameterization() {}
@ -150,7 +150,7 @@ class IdentityParameterization : public LocalParameterization {
};
// Hold a subset of the parameters inside a parameter block constant.
class SubsetParameterization : public LocalParameterization {
class CERES_EXPORT SubsetParameterization : public LocalParameterization {
public:
explicit SubsetParameterization(int size,
const vector<int>& constant_parameters);
@ -160,7 +160,9 @@ class SubsetParameterization : public LocalParameterization {
double* x_plus_delta) const;
virtual bool ComputeJacobian(const double* x,
double* jacobian) const;
virtual int GlobalSize() const { return constancy_mask_.size(); }
virtual int GlobalSize() const {
return static_cast<int>(constancy_mask_.size());
}
virtual int LocalSize() const { return local_size_; }
private:
@ -172,7 +174,7 @@ class SubsetParameterization : public LocalParameterization {
// 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 {
class CERES_EXPORT QuaternionParameterization : public LocalParameterization {
public:
virtual ~QuaternionParameterization() {}
virtual bool Plus(const double* x,

@ -82,7 +82,7 @@
namespace ceres {
class LossFunction {
class CERES_EXPORT LossFunction {
public:
virtual ~LossFunction() {}
@ -128,7 +128,7 @@ class LossFunction {
// 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 {
class CERES_EXPORT TrivialLoss : public LossFunction {
public:
virtual void Evaluate(double, double*) const;
};
@ -171,7 +171,7 @@ class TrivialLoss : public LossFunction {
//
// The scaling parameter 'a' corresponds to 'delta' on this page:
// http://en.wikipedia.org/wiki/Huber_Loss_Function
class HuberLoss : public LossFunction {
class CERES_EXPORT HuberLoss : public LossFunction {
public:
explicit HuberLoss(double a) : a_(a), b_(a * a) { }
virtual void Evaluate(double, double*) const;
@ -187,7 +187,7 @@ class HuberLoss : public LossFunction {
// rho(s) = 2 (sqrt(1 + s) - 1).
//
// At s = 0: rho = [0, 1, -1/2].
class SoftLOneLoss : public LossFunction {
class CERES_EXPORT SoftLOneLoss : public LossFunction {
public:
explicit SoftLOneLoss(double a) : b_(a * a), c_(1 / b_) { }
virtual void Evaluate(double, double*) const;
@ -204,7 +204,7 @@ class SoftLOneLoss : public LossFunction {
// rho(s) = log(1 + s).
//
// At s = 0: rho = [0, 1, -1].
class CauchyLoss : public LossFunction {
class CERES_EXPORT CauchyLoss : public LossFunction {
public:
explicit CauchyLoss(double a) : b_(a * a), c_(1 / b_) { }
virtual void Evaluate(double, double*) const;
@ -225,7 +225,7 @@ class CauchyLoss : public LossFunction {
// rho(s) = a atan(s / a).
//
// At s = 0: rho = [0, 1, 0].
class ArctanLoss : public LossFunction {
class CERES_EXPORT ArctanLoss : public LossFunction {
public:
explicit ArctanLoss(double a) : a_(a), b_(1 / (a * a)) { }
virtual void Evaluate(double, double*) const;
@ -264,7 +264,7 @@ class ArctanLoss : public LossFunction {
// concentrated in the range a - b to a + b.
//
// At s = 0: rho = [0, ~0, ~0].
class TolerantLoss : public LossFunction {
class CERES_EXPORT TolerantLoss : public LossFunction {
public:
explicit TolerantLoss(double a, double b);
virtual void Evaluate(double, double*) const;
@ -305,7 +305,7 @@ class ComposedLoss : public LossFunction {
// 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 {
class CERES_EXPORT ScaledLoss : public LossFunction {
public:
// Constructs a ScaledLoss wrapping another loss function. Takes
// ownership of the wrapped loss function or not depending on the
@ -362,7 +362,7 @@ class ScaledLoss : public LossFunction {
//
// Solve(options, &problem, &summary)
//
class LossFunctionWrapper : public LossFunction {
class CERES_EXPORT LossFunctionWrapper : public LossFunction {
public:
LossFunctionWrapper(LossFunction* rho, Ownership ownership)
: rho_(rho), ownership_(ownership) {

@ -56,7 +56,7 @@ namespace ceres {
// which would be the case if the covariance matrix S is rank
// deficient.
class NormalPrior: public CostFunction {
class CERES_EXPORT 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.

@ -117,14 +117,14 @@ typedef internal::ResidualBlock* ResidualBlockId;
// problem.AddResidualBlock(new MyBinaryCostFunction(...), x2, x3);
//
// Please see cost_function.h for details of the CostFunction object.
class Problem {
class CERES_EXPORT Problem {
public:
struct Options {
struct CERES_EXPORT Options {
Options()
: cost_function_ownership(TAKE_OWNERSHIP),
loss_function_ownership(TAKE_OWNERSHIP),
local_parameterization_ownership(TAKE_OWNERSHIP),
enable_fast_parameter_block_removal(false),
enable_fast_removal(false),
disable_all_safety_checks(false) {}
// These flags control whether the Problem object owns the cost
@ -138,17 +138,21 @@ class Problem {
Ownership loss_function_ownership;
Ownership local_parameterization_ownership;
// If true, trades memory for a faster RemoveParameterBlock() operation.
// If true, trades memory for faster RemoveResidualBlock() and
// RemoveParameterBlock() operations.
//
// RemoveParameterBlock() takes time proportional to the size of the entire
// Problem. If you only remove parameter blocks from the Problem
// occassionaly, this may be acceptable. However, if you are modifying the
// Problem frequently, and have memory to spare, then flip this switch to
// By default, RemoveParameterBlock() and RemoveResidualBlock() take time
// proportional to the size of the entire problem. If you only ever remove
// parameters or residuals from the problem occassionally, this might be
// acceptable. However, if you have memory to spare, enable this option to
// make RemoveParameterBlock() take time proportional to the number of
// residual blocks that depend on it. The increase in memory usage is an
// additonal hash set per parameter block containing all the residuals that
// depend on the parameter block.
bool enable_fast_parameter_block_removal;
// residual blocks that depend on it, and RemoveResidualBlock() take (on
// average) constant time.
//
// The increase in memory usage is twofold: an additonal hash set per
// parameter block containing all the residuals that depend on the parameter
// block; and a hash set in the problem containing all residuals.
bool enable_fast_removal;
// By default, Ceres performs a variety of safety checks when constructing
// the problem. There is a small but measurable performance penalty to
@ -276,7 +280,7 @@ class Problem {
// residual blocks that depend on the parameter are also removed, as
// described above in RemoveResidualBlock().
//
// If Problem::Options::enable_fast_parameter_block_removal is true, then the
// If Problem::Options::enable_fast_removal is true, then the
// removal is fast (almost constant time). Otherwise, removing a parameter
// block will incur a scan of the entire Problem object.
//
@ -300,7 +304,7 @@ class Problem {
// Hold the indicated parameter block constant during optimization.
void SetParameterBlockConstant(double* values);
// Allow the indicated parameter to vary during optimization.
// Allow the indicated parameter block to vary during optimization.
void SetParameterBlockVariable(double* values);
// Set the local parameterization for one of the parameter blocks.
@ -312,6 +316,15 @@ class Problem {
void SetParameterization(double* values,
LocalParameterization* local_parameterization);
// Get the local parameterization object associated with this
// parameter block. If there is no parameterization object
// associated then NULL is returned.
const LocalParameterization* GetParameterization(double* values) const;
// Set the lower/upper bound for the parameter with position "index".
void SetParameterLowerBound(double* values, int index, double lower_bound);
void SetParameterUpperBound(double* values, int index, double upper_bound);
// Number of parameter blocks in the problem. Always equals
// parameter_blocks().size() and parameter_block_sizes().size().
int NumParameterBlocks() const;
@ -336,6 +349,9 @@ class Problem {
// block, then ParameterBlockLocalSize = ParameterBlockSize.
int ParameterBlockLocalSize(const double* values) const;
// Is the given parameter block present in this problem or not?
bool HasParameterBlock(const double* values) const;
// Fills the passed parameter_blocks vector with pointers to the
// parameter blocks currently in the problem. After this call,
// parameter_block.size() == NumParameterBlocks.
@ -353,7 +369,7 @@ class Problem {
// Get all the residual blocks that depend on the given parameter block.
//
// If Problem::Options::enable_fast_parameter_block_removal is true, then
// If Problem::Options::enable_fast_removal is true, then
// getting the residual blocks is fast and depends only on the number of
// residual blocks. Otherwise, getting the residual blocks for a parameter
// block will incur a scan of the entire Problem object.

@ -46,7 +46,7 @@ namespace ceres {
class Problem;
// Interface for non-linear least squares solvers.
class Solver {
class CERES_EXPORT Solver {
public:
virtual ~Solver();
@ -55,7 +55,7 @@ class Solver {
// problems; however, better performance is often obtainable with tweaking.
//
// The constants are defined inside types.h
struct Options {
struct CERES_EXPORT Options {
// Default constructor that sets up a generic sparse problem.
Options() {
minimizer_type = TRUST_REGION;
@ -107,15 +107,14 @@ class Solver {
num_linear_solver_threads = 1;
linear_solver_ordering = NULL;
use_postordering = false;
dynamic_sparsity = false;
min_linear_solver_iterations = 1;
max_linear_solver_iterations = 500;
eta = 1e-1;
jacobi_scaling = true;
use_inner_iterations = false;
inner_iteration_tolerance = 1e-3;
inner_iteration_ordering = NULL;
logging_type = PER_MINIMIZER_ITERATION;
minimizer_progress_to_stdout = false;
trust_region_problem_dump_directory = "/tmp";
@ -126,7 +125,6 @@ class Solver {
update_state_every_iteration = false;
}
~Options();
// Minimizer options ----------------------------------------
// Ceres supports the two major families of optimization strategies -
@ -367,7 +365,7 @@ class Solver {
// Minimizer terminates when
//
// max_i |gradient_i| < gradient_tolerance * max_i|initial_gradient_i|
// max_i |x - Project(Plus(x, -g(x))| < gradient_tolerance
//
// This value should typically be 1e-4 * function_tolerance.
double gradient_tolerance;
@ -480,10 +478,7 @@ class Solver {
// the parameter blocks into two groups, one for the points and one
// for the cameras, where the group containing the points has an id
// smaller than the group containing cameras.
//
// Once assigned, Solver::Options owns this pointer and will
// deallocate the memory when destroyed.
ParameterBlockOrdering* linear_solver_ordering;
shared_ptr<ParameterBlockOrdering> linear_solver_ordering;
// Sparse Cholesky factorization algorithms use a fill-reducing
// ordering to permute the columns of the Jacobian matrix. There
@ -506,6 +501,21 @@ class Solver {
// matrix. Setting use_postordering to true enables this tradeoff.
bool use_postordering;
// Some non-linear least squares problems are symbolically dense but
// numerically sparse. i.e. at any given state only a small number
// of jacobian entries are non-zero, but the position and number of
// non-zeros is different depending on the state. For these problems
// it can be useful to factorize the sparse jacobian at each solver
// iteration instead of including all of the zero entries in a single
// general factorization.
//
// If your problem does not have this property (or you do not know),
// then it is probably best to keep this false, otherwise it will
// likely lead to worse performance.
// This settings affects the SPARSE_NORMAL_CHOLESKY solver.
bool dynamic_sparsity;
// Some non-linear least squares problems have additional
// structure in the way the parameter blocks interact that it is
// beneficial to modify the way the trust region step is computed.
@ -576,7 +586,7 @@ class Solver {
// the lower numbered groups are optimized before the higher
// number groups. Each group must be an independent set. Not
// all parameter blocks need to be present in the ordering.
ParameterBlockOrdering* inner_iteration_ordering;
shared_ptr<ParameterBlockOrdering> inner_iteration_ordering;
// Generally speaking, inner iterations make significant progress
// in the early stages of the solve and then their contribution
@ -703,7 +713,7 @@ class Solver {
string solver_log;
};
struct Summary {
struct CERES_EXPORT Summary {
Summary();
// A brief one line description of the state of the solver after
@ -941,7 +951,7 @@ class Solver {
};
// Helper function which avoids going through the interface.
void Solve(const Solver::Options& options,
CERES_EXPORT void Solve(const Solver::Options& options,
Problem* problem,
Solver::Summary* summary);

@ -45,7 +45,6 @@ namespace ceres {
// Basic integer types. These typedefs are in the Ceres namespace to avoid
// conflicts with other packages having similar typedefs.
typedef short int16;
typedef int int32;
// Argument type used in interfaces that can optionally take ownership
@ -306,7 +305,7 @@ enum TerminationType {
// by the user was satisfied.
//
// 1. (new_cost - old_cost) < function_tolerance * old_cost;
// 2. max_i |gradient_i| < gradient_tolerance * max_i|initial_gradient_i|
// 2. max_i |gradient_i| < gradient_tolerance
// 3. |step|_2 <= parameter_tolerance * ( |x|_2 + parameter_tolerance)
//
// The user's parameter blocks will be updated with the solution.
@ -379,9 +378,9 @@ enum DumpFormatType {
TEXTFILE
};
// For SizedCostFunction and AutoDiffCostFunction, DYNAMIC can be specified for
// the number of residuals. If specified, then the number of residuas for that
// cost function can vary at runtime.
// For SizedCostFunction and AutoDiffCostFunction, DYNAMIC can be
// specified for the number of residuals. If specified, then the
// number of residuas for that cost function can vary at runtime.
enum DimensionType {
DYNAMIC = -1
};
@ -403,69 +402,75 @@ enum CovarianceAlgorithmType {
SPARSE_QR
};
const char* LinearSolverTypeToString(LinearSolverType type);
bool StringToLinearSolverType(string value, LinearSolverType* type);
CERES_EXPORT const char* LinearSolverTypeToString(
LinearSolverType type);
CERES_EXPORT bool StringToLinearSolverType(string value,
LinearSolverType* type);
const char* PreconditionerTypeToString(PreconditionerType type);
bool StringToPreconditionerType(string value, PreconditionerType* type);
CERES_EXPORT const char* PreconditionerTypeToString(PreconditionerType type);
CERES_EXPORT bool StringToPreconditionerType(string value,
PreconditionerType* type);
const char* VisibilityClusteringTypeToString(VisibilityClusteringType type);
bool StringToVisibilityClusteringType(string value,
CERES_EXPORT const char* VisibilityClusteringTypeToString(
VisibilityClusteringType type);
CERES_EXPORT bool StringToVisibilityClusteringType(string value,
VisibilityClusteringType* type);
const char* SparseLinearAlgebraLibraryTypeToString(
CERES_EXPORT const char* SparseLinearAlgebraLibraryTypeToString(
SparseLinearAlgebraLibraryType type);
bool StringToSparseLinearAlgebraLibraryType(
CERES_EXPORT bool StringToSparseLinearAlgebraLibraryType(
string value,
SparseLinearAlgebraLibraryType* type);
const char* DenseLinearAlgebraLibraryTypeToString(
CERES_EXPORT const char* DenseLinearAlgebraLibraryTypeToString(
DenseLinearAlgebraLibraryType type);
bool StringToDenseLinearAlgebraLibraryType(
CERES_EXPORT bool StringToDenseLinearAlgebraLibraryType(
string value,
DenseLinearAlgebraLibraryType* type);
const char* TrustRegionStrategyTypeToString(TrustRegionStrategyType type);
bool StringToTrustRegionStrategyType(string value,
CERES_EXPORT const char* TrustRegionStrategyTypeToString(
TrustRegionStrategyType type);
CERES_EXPORT bool StringToTrustRegionStrategyType(string value,
TrustRegionStrategyType* type);
const char* DoglegTypeToString(DoglegType type);
bool StringToDoglegType(string value, DoglegType* type);
CERES_EXPORT const char* DoglegTypeToString(DoglegType type);
CERES_EXPORT bool StringToDoglegType(string value, DoglegType* type);
const char* MinimizerTypeToString(MinimizerType type);
bool StringToMinimizerType(string value, MinimizerType* type);
CERES_EXPORT const char* MinimizerTypeToString(MinimizerType type);
CERES_EXPORT bool StringToMinimizerType(string value, MinimizerType* type);
const char* LineSearchDirectionTypeToString(LineSearchDirectionType type);
bool StringToLineSearchDirectionType(string value,
CERES_EXPORT const char* LineSearchDirectionTypeToString(
LineSearchDirectionType type);
CERES_EXPORT bool StringToLineSearchDirectionType(string value,
LineSearchDirectionType* type);
const char* LineSearchTypeToString(LineSearchType type);
bool StringToLineSearchType(string value, LineSearchType* type);
CERES_EXPORT const char* LineSearchTypeToString(LineSearchType type);
CERES_EXPORT bool StringToLineSearchType(string value, LineSearchType* type);
const char* NonlinearConjugateGradientTypeToString(
CERES_EXPORT const char* NonlinearConjugateGradientTypeToString(
NonlinearConjugateGradientType type);
bool StringToNonlinearConjugateGradientType(
CERES_EXPORT bool StringToNonlinearConjugateGradientType(
string value,
NonlinearConjugateGradientType* type);
const char* LineSearchInterpolationTypeToString(
CERES_EXPORT const char* LineSearchInterpolationTypeToString(
LineSearchInterpolationType type);
bool StringToLineSearchInterpolationType(
CERES_EXPORT bool StringToLineSearchInterpolationType(
string value,
LineSearchInterpolationType* type);
const char* CovarianceAlgorithmTypeToString(
CERES_EXPORT const char* CovarianceAlgorithmTypeToString(
CovarianceAlgorithmType type);
bool StringToCovarianceAlgorithmType(
CERES_EXPORT bool StringToCovarianceAlgorithmType(
string value,
CovarianceAlgorithmType* type);
const char* TerminationTypeToString(TerminationType type);
CERES_EXPORT const char* TerminationTypeToString(TerminationType type);
bool IsSchurType(LinearSolverType type);
bool IsSparseLinearAlgebraLibraryTypeAvailable(
CERES_EXPORT bool IsSchurType(LinearSolverType type);
CERES_EXPORT bool IsSparseLinearAlgebraLibraryTypeAvailable(
SparseLinearAlgebraLibraryType type);
bool IsDenseLinearAlgebraLibraryTypeAvailable(
CERES_EXPORT bool IsDenseLinearAlgebraLibraryTypeAvailable(
DenseLinearAlgebraLibraryType type);
} // namespace ceres

@ -0,0 +1,287 @@
# 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)
SET(CERES_INTERNAL_SRC
array_utils.cc
blas.cc
block_evaluate_preparer.cc
block_jacobi_preconditioner.cc
block_jacobian_writer.cc
block_random_access_dense_matrix.cc
block_random_access_diagonal_matrix.cc
block_random_access_matrix.cc
block_random_access_sparse_matrix.cc
block_sparse_matrix.cc
block_structure.cc
c_api.cc
canonical_views_clustering.cc
cgnr_solver.cc
compressed_col_sparse_matrix_utils.cc
compressed_row_jacobian_writer.cc
compressed_row_sparse_matrix.cc
conditioned_cost_function.cc
conjugate_gradients_solver.cc
coordinate_descent_minimizer.cc
corrector.cc
covariance.cc
covariance_impl.cc
cxsparse.cc
dense_normal_cholesky_solver.cc
dense_qr_solver.cc
dense_sparse_matrix.cc
detect_structure.cc
dogleg_strategy.cc
dynamic_compressed_row_jacobian_writer.cc
dynamic_compressed_row_sparse_matrix.cc
evaluator.cc
file.cc
gradient_checking_cost_function.cc
implicit_schur_complement.cc
incomplete_lq_factorization.cc
iterative_schur_complement_solver.cc
levenberg_marquardt_strategy.cc
lapack.cc
line_search.cc
line_search_direction.cc
line_search_minimizer.cc
linear_least_squares_problems.cc
linear_operator.cc
linear_solver.cc
local_parameterization.cc
loss_function.cc
low_rank_inverse_hessian.cc
minimizer.cc
normal_prior.cc
parameter_block_ordering.cc
partitioned_matrix_view.cc
polynomial.cc
preconditioner.cc
problem.cc
problem_impl.cc
program.cc
residual_block.cc
residual_block_utils.cc
schur_complement_solver.cc
schur_eliminator.cc
schur_jacobi_preconditioner.cc
scratch_evaluate_preparer.cc
single_linkage_clustering.cc
solver.cc
solver_impl.cc
sparse_matrix.cc
sparse_normal_cholesky_solver.cc
split.cc
stringprintf.cc
suitesparse.cc
triplet_sparse_matrix.cc
trust_region_minimizer.cc
trust_region_strategy.cc
types.cc
visibility.cc
visibility_based_preconditioner.cc
wall_time.cc
)
# Heuristic for determining LIB_SUFFIX. FHS recommends that 64-bit systems
# install native libraries to lib64 rather than lib. Most distros seem to
# follow this convention with a couple notable exceptions (Debian-based and
# Arch-based distros) which we try to detect here.
IF (CMAKE_SYSTEM_NAME MATCHES "Linux" AND
NOT DEFINED LIB_SUFFIX AND
NOT CMAKE_CROSSCOMPILING AND
CMAKE_SIZEOF_VOID_P EQUAL "8" AND
NOT EXISTS "/etc/debian_version" AND
NOT EXISTS "/etc/arch-release")
SET(LIB_SUFFIX "64")
ENDIF ()
# Also depend on the header files so that they appear in IDEs.
FILE(GLOB CERES_INTERNAL_HDRS *.h)
# Include the specialized schur solvers.
IF (SCHUR_SPECIALIZATIONS)
FILE(GLOB CERES_INTERNAL_SCHUR_FILES generated/*.cc)
ELSE (SCHUR_SPECIALIZATIONS)
# Only the fully dynamic solver. The build is much faster this way.
FILE(GLOB CERES_INTERNAL_SCHUR_FILES generated/*_d_d_d.cc)
ENDIF (SCHUR_SPECIALIZATIONS)
# Primarily for Android, but optionally for others, use the minimal internal
# Glog implementation.
IF (MINIGLOG)
ADD_LIBRARY(miniglog STATIC miniglog/glog/logging.cc)
INSTALL(TARGETS miniglog
EXPORT CeresExport
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib${LIB_SUFFIX}
ARCHIVE DESTINATION lib${LIB_SUFFIX})
ENDIF (MINIGLOG)
SET(CERES_LIBRARY_PUBLIC_DEPENDENCIES ${GLOG_LIBRARIES})
IF (SUITESPARSE AND SUITESPARSE_FOUND)
LIST(APPEND CERES_LIBRARY_PRIVATE_DEPENDENCIES ${SUITESPARSE_LIBRARIES})
ENDIF (SUITESPARSE AND SUITESPARSE_FOUND)
IF (CXSPARSE AND CXSPARSE_FOUND)
LIST(APPEND CERES_LIBRARY_PRIVATE_DEPENDENCIES ${CXSPARSE_LIBRARIES})
ENDIF (CXSPARSE AND CXSPARSE_FOUND)
IF (BLAS_FOUND AND LAPACK_FOUND)
LIST(APPEND CERES_LIBRARY_PRIVATE_DEPENDENCIES ${LAPACK_LIBRARIES})
LIST(APPEND CERES_LIBRARY_PRIVATE_DEPENDENCIES ${BLAS_LIBRARIES})
ENDIF (BLAS_FOUND AND LAPACK_FOUND)
IF (OPENMP_FOUND)
IF (NOT MSVC)
LIST(APPEND CERES_LIBRARY_PRIVATE_DEPENDENCIES gomp)
LIST(APPEND CERES_LIBRARY_PRIVATE_DEPENDENCIES ${CMAKE_THREAD_LIBS_INIT})
ENDIF (NOT MSVC)
ENDIF (OPENMP_FOUND)
SET(CERES_LIBRARY_SOURCE
${CERES_INTERNAL_SRC}
${CERES_INTERNAL_HDRS}
${CERES_INTERNAL_SCHUR_FILES})
ADD_LIBRARY(ceres ${CERES_LIBRARY_SOURCE})
SET_TARGET_PROPERTIES(ceres PROPERTIES
VERSION ${CERES_VERSION}
SOVERSION ${CERES_VERSION_MAJOR}
)
IF (BUILD_SHARED_LIBS)
# When building a shared library, mark all external libraries as
# PRIVATE so they don't show up as a dependency.
TARGET_LINK_LIBRARIES(ceres
LINK_PUBLIC ${CERES_LIBRARY_PUBLIC_DEPENDENCIES}
LINK_PRIVATE ${CERES_LIBRARY_PRIVATE_DEPENDENCIES})
ELSE (BUILD_SHARED_LIBS)
# When building a static library, all external libraries are
# PUBLIC(default) since the user needs to link to them.
# They will be listed in CeresTargets.cmake.
SET(CERES_LIBRARY_DEPENDENCIES
${CERES_LIBRARY_PUBLIC_DEPENDENCIES}
${CERES_LIBRARY_PRIVATE_DEPENDENCIES})
TARGET_LINK_LIBRARIES(ceres ${CERES_LIBRARY_DEPENDENCIES})
ENDIF (BUILD_SHARED_LIBS)
INSTALL(TARGETS ceres
EXPORT CeresExport
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib${LIB_SUFFIX}
ARCHIVE DESTINATION lib${LIB_SUFFIX})
IF (BUILD_TESTING AND GFLAGS)
ADD_LIBRARY(gtest gmock_gtest_all.cc gmock_main.cc)
ADD_LIBRARY(test_util
evaluator_test_utils.cc
numeric_diff_test_utils.cc
test_util.cc)
TARGET_LINK_LIBRARIES(gtest ${GFLAGS_LIBRARIES} ${GLOG_LIBRARIES})
TARGET_LINK_LIBRARIES(test_util ceres gtest ${GLOG_LIBRARIES})
MACRO (CERES_TEST NAME)
ADD_EXECUTABLE(${NAME}_test ${NAME}_test.cc)
TARGET_LINK_LIBRARIES(${NAME}_test test_util ceres gtest)
ADD_TEST(NAME ${NAME}_test
COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${NAME}_test
--test_srcdir
${CMAKE_SOURCE_DIR}/data)
ENDMACRO (CERES_TEST)
CERES_TEST(array_utils)
CERES_TEST(autodiff)
CERES_TEST(autodiff_cost_function)
CERES_TEST(autodiff_local_parameterization)
CERES_TEST(block_random_access_dense_matrix)
CERES_TEST(block_random_access_diagonal_matrix)
CERES_TEST(block_random_access_sparse_matrix)
CERES_TEST(block_sparse_matrix)
CERES_TEST(c_api)
CERES_TEST(canonical_views_clustering)
CERES_TEST(compressed_row_sparse_matrix)
CERES_TEST(conditioned_cost_function)
CERES_TEST(corrector)
CERES_TEST(cost_function_to_functor)
CERES_TEST(covariance)
CERES_TEST(dense_sparse_matrix)
CERES_TEST(dynamic_autodiff_cost_function)
CERES_TEST(dynamic_compressed_row_sparse_matrix)
CERES_TEST(dynamic_numeric_diff_cost_function)
CERES_TEST(evaluator)
CERES_TEST(gradient_checker)
CERES_TEST(gradient_checking_cost_function)
CERES_TEST(graph)
CERES_TEST(graph_algorithms)
CERES_TEST(implicit_schur_complement)
CERES_TEST(incomplete_lq_factorization)
CERES_TEST(iterative_schur_complement_solver)
CERES_TEST(jet)
CERES_TEST(levenberg_marquardt_strategy)
CERES_TEST(dogleg_strategy)
CERES_TEST(local_parameterization)
CERES_TEST(loss_function)
CERES_TEST(minimizer)
CERES_TEST(normal_prior)
CERES_TEST(numeric_diff_cost_function)
CERES_TEST(numeric_diff_functor)
CERES_TEST(ordered_groups)
CERES_TEST(parameter_block)
CERES_TEST(parameter_block_ordering)
CERES_TEST(partitioned_matrix_view)
CERES_TEST(polynomial)
CERES_TEST(problem)
CERES_TEST(residual_block)
CERES_TEST(residual_block_utils)
CERES_TEST(rotation)
CERES_TEST(schur_complement_solver)
CERES_TEST(schur_eliminator)
CERES_TEST(single_linkage_clustering)
CERES_TEST(small_blas)
CERES_TEST(solver_impl)
# TODO(sameeragarwal): This test should ultimately be made
# independent of SuiteSparse.
IF (SUITESPARSE AND SUITESPARSE_FOUND)
CERES_TEST(compressed_col_sparse_matrix_utils)
ENDIF (SUITESPARSE AND SUITESPARSE_FOUND)
CERES_TEST(symmetric_linear_solver)
CERES_TEST(triplet_sparse_matrix)
CERES_TEST(trust_region_minimizer)
CERES_TEST(unsymmetric_linear_solver)
CERES_TEST(visibility)
CERES_TEST(visibility_based_preconditioner)
# Put the large end to end test last.
CERES_TEST(system)
ENDIF (BUILD_TESTING AND GFLAGS)

@ -32,7 +32,10 @@
#include <cmath>
#include <cstddef>
#include <string>
#include "ceres/fpclassify.h"
#include "ceres/stringprintf.h"
namespace ceres {
namespace internal {
@ -55,6 +58,20 @@ bool IsArrayValid(const int size, const double* x) {
return true;
}
int FindInvalidValue(const int size, const double* x) {
if (x == NULL) {
return size;
}
for (int i = 0; i < size; ++i) {
if (!IsFinite(x[i]) || (x[i] == kImpossibleValue)) {
return i;
}
}
return size;
};
void InvalidateArray(const int size, double* x) {
if (x != NULL) {
for (int i = 0; i < size; ++i) {
@ -63,5 +80,19 @@ void InvalidateArray(const int size, double* x) {
}
}
void AppendArrayToString(const int size, const double* x, string* result) {
for (int i = 0; i < size; ++i) {
if (x == NULL) {
StringAppendF(result, "Not Computed ");
} else {
if (x[i] == kImpossibleValue) {
StringAppendF(result, "Uninitialized ");
} else {
StringAppendF(result, "%12g ", x[i]);
}
}
}
}
} // namespace internal
} // namespace ceres

@ -57,6 +57,14 @@ void InvalidateArray(int size, double* x);
// equal to the "impossible" value used by InvalidateArray.
bool IsArrayValid(int size, const double* x);
// If the array contains an invalid value, return the index for it,
// otherwise return size.
int FindInvalidValue(const int size, const double* x);
// Utility routine to print an array of doubles to a string. If the
// array pointer is NULL, it is treated as an array of zeros.
void AppendArrayToString(const int size, const double* x, string* result);
extern const double kImpossibleValue;
} // namespace internal

@ -29,6 +29,7 @@
// Author: sameeragarwal@google.com (Sameer Agarwal)
#include "ceres/blas.h"
#include "ceres/internal/port.h"
#include "glog/logging.h"
extern "C" void dsyrk_(char* uplo,

@ -1,170 +0,0 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2013 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)
#include "ceres/block_random_access_crs_matrix.h"
#include <algorithm>
#include <set>
#include <utility>
#include <vector>
#include "ceres/compressed_row_sparse_matrix.h"
#include "ceres/internal/port.h"
#include "ceres/internal/scoped_ptr.h"
#include "ceres/mutex.h"
#include "ceres/triplet_sparse_matrix.h"
#include "ceres/types.h"
#include "glog/logging.h"
namespace ceres {
namespace internal {
BlockRandomAccessCRSMatrix::BlockRandomAccessCRSMatrix(
const vector<int>& blocks,
const set<pair<int, int> >& block_pairs)
: kMaxRowBlocks(10 * 1000 * 1000),
blocks_(blocks) {
CHECK_LT(blocks.size(), kMaxRowBlocks);
col_layout_.resize(blocks_.size(), 0);
row_strides_.resize(blocks_.size(), 0);
// Build the row/column layout vector and count the number of scalar
// rows/columns.
int num_cols = 0;
for (int i = 0; i < blocks_.size(); ++i) {
col_layout_[i] = num_cols;
num_cols += blocks_[i];
}
// Walk the sparsity pattern and count the number of non-zeros.
int num_nonzeros = 0;
for (set<pair<int, int> >::const_iterator it = block_pairs.begin();
it != block_pairs.end();
++it) {
const int row_block_size = blocks_[it->first];
const int col_block_size = blocks_[it->second];
num_nonzeros += row_block_size * col_block_size;
}
VLOG(2) << "Matrix Size [" << num_cols
<< "," << num_cols
<< "] " << num_nonzeros;
crsm_.reset(new CompressedRowSparseMatrix(num_cols, num_cols, num_nonzeros));
int* rows = crsm_->mutable_rows();
int* cols = crsm_->mutable_cols();
double* values = crsm_->mutable_values();
// Iterate over the sparsity pattern and fill the scalar sparsity
// pattern of the underlying compressed sparse row matrix. Along the
// way also fill out the Layout object which will allow random
// access into the CRS Matrix.
set<pair<int, int> >::const_iterator it = block_pairs.begin();
vector<int> col_blocks;
int row_pos = 0;
rows[0] = 0;
while (it != block_pairs.end()) {
// Add entries to layout_ for all the blocks for this row.
col_blocks.clear();
const int row_block_id = it->first;
const int row_block_size = blocks_[row_block_id];
int num_cols = 0;
while ((it != block_pairs.end()) && (it->first == row_block_id)) {
layout_[IntPairToLong(it->first, it->second)] =
new CellInfo(values + num_cols);
col_blocks.push_back(it->second);
num_cols += blocks_[it->second];
++it;
};
// Count the number of non-zeros in the row block.
for (int j = 0; j < row_block_size; ++j) {
rows[row_pos + j + 1] = rows[row_pos + j] + num_cols;
}
// Fill out the sparsity pattern for each row.
int col_pos = 0;
for (int j = 0; j < col_blocks.size(); ++j) {
const int col_block_id = col_blocks[j];
const int col_block_size = blocks_[col_block_id];
for (int r = 0; r < row_block_size; ++r) {
const int column_block_begin = rows[row_pos + r] + col_pos;
for (int c = 0; c < col_block_size; ++c) {
cols[column_block_begin + c] = col_layout_[col_block_id] + c;
}
}
col_pos += col_block_size;
}
row_pos += row_block_size;
values += row_block_size * num_cols;
row_strides_[row_block_id] = num_cols;
}
}
// Assume that the user does not hold any locks on any cell blocks
// when they are calling SetZero.
BlockRandomAccessCRSMatrix::~BlockRandomAccessCRSMatrix() {
// TODO(sameeragarwal) this should be rationalized going forward and
// perhaps moved into BlockRandomAccessMatrix.
for (LayoutType::iterator it = layout_.begin();
it != layout_.end();
++it) {
delete it->second;
}
}
CellInfo* BlockRandomAccessCRSMatrix::GetCell(int row_block_id,
int col_block_id,
int* row,
int* col,
int* row_stride,
int* col_stride) {
const LayoutType::iterator it =
layout_.find(IntPairToLong(row_block_id, col_block_id));
if (it == layout_.end()) {
return NULL;
}
*row = 0;
*col = 0;
*row_stride = blocks_[row_block_id];
*col_stride = row_strides_[row_block_id];
return it->second;
}
// Assume that the user does not hold any locks on any cell blocks
// when they are calling SetZero.
void BlockRandomAccessCRSMatrix::SetZero() {
crsm_->SetZero();
}
} // namespace internal
} // namespace ceres

@ -1,108 +0,0 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2013 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_BLOCK_RANDOM_ACCESS_CRS_MATRIX_H_
#define CERES_INTERNAL_BLOCK_RANDOM_ACCESS_CRS_MATRIX_H_
#include <set>
#include <vector>
#include <utility>
#include "ceres/mutex.h"
#include "ceres/block_random_access_matrix.h"
#include "ceres/compressed_row_sparse_matrix.h"
#include "ceres/collections_port.h"
#include "ceres/integral_types.h"
#include "ceres/internal/macros.h"
#include "ceres/internal/port.h"
#include "ceres/internal/scoped_ptr.h"
#include "ceres/types.h"
namespace ceres {
namespace internal {
// A square BlockRandomAccessMatrix where the underlying storage is a
// compressed row sparse matrix. The matrix need not be symmetric.
class BlockRandomAccessCRSMatrix : public BlockRandomAccessMatrix {
public:
// blocks is an array of block sizes. block_pairs is a set of
// <row_block_id, col_block_id> pairs to identify the non-zero cells
// of this matrix.
BlockRandomAccessCRSMatrix(const vector<int>& blocks,
const set<pair<int, int> >& block_pairs);
// The destructor is not thread safe. It assumes that no one is
// modifying any cells when the matrix is being destroyed.
virtual ~BlockRandomAccessCRSMatrix();
// BlockRandomAccessMatrix Interface.
virtual CellInfo* GetCell(int row_block_id,
int col_block_id,
int* row,
int* col,
int* row_stride,
int* col_stride);
// This is not a thread safe method, it assumes that no cell is
// locked.
virtual void SetZero();
// Since the matrix is square, num_rows() == num_cols().
virtual int num_rows() const { return crsm_->num_rows(); }
virtual int num_cols() const { return crsm_->num_cols(); }
// Access to the underlying matrix object.
const CompressedRowSparseMatrix* matrix() const { return crsm_.get(); }
CompressedRowSparseMatrix* mutable_matrix() { return crsm_.get(); }
private:
int64 IntPairToLong(int a, int b) {
return a * kMaxRowBlocks + b;
}
const int64 kMaxRowBlocks;
// row/column block sizes.
const vector<int> blocks_;
vector<int> col_layout_;
vector<int> row_strides_;
// A mapping from <row_block_id, col_block_id> to the position in
// the values array of tsm_ where the block is stored.
typedef HashMap<long int, CellInfo* > LayoutType;
LayoutType layout_;
scoped_ptr<CompressedRowSparseMatrix> crsm_;
friend class BlockRandomAccessCRSMatrixTest;
CERES_DISALLOW_COPY_AND_ASSIGN(BlockRandomAccessCRSMatrix);
};
} // namespace internal
} // namespace ceres
#endif // CERES_INTERNAL_BLOCK_RANDOM_ACCESS_CRS_MATRIX_H_

@ -34,6 +34,9 @@ namespace ceres {
namespace internal {
bool CellLessThan(const Cell& lhs, const Cell& rhs) {
if (lhs.block_id == rhs.block_id) {
return (lhs.position < rhs.position);
}
return (lhs.block_id < rhs.block_id);
}

@ -45,8 +45,6 @@
namespace ceres {
namespace internal {
class BlockStructureProto;
typedef int32 BlockSize;
struct Block {
@ -89,16 +87,6 @@ struct CompressedColumnBlockStructure {
vector<CompressedColumn> cols;
};
// Deserialize the given block structure proto to the given block structure.
// Destroys previous contents of block_structure.
void ProtoToBlockStructure(const BlockStructureProto &proto,
CompressedRowBlockStructure *block_structure);
// Serialize the given block structure to the given proto. Destroys previous
// contents of proto.
void BlockStructureToProto(const CompressedRowBlockStructure &block_structure,
BlockStructureProto *proto);
} // namespace internal
} // namespace ceres

@ -29,6 +29,9 @@
// Author: David Gallup (dgallup@google.com)
// Sameer Agarwal (sameeragarwal@google.com)
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_NO_SUITESPARSE
#include "ceres/canonical_views_clustering.h"

@ -41,6 +41,9 @@
#ifndef CERES_INTERNAL_CANONICAL_VIEWS_CLUSTERING_H_
#define CERES_INTERNAL_CANONICAL_VIEWS_CLUSTERING_H_
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_NO_SUITESPARSE
#include <vector>

@ -33,6 +33,8 @@
#ifndef CERES_INTERNAL_COLLECTIONS_PORT_H_
#define CERES_INTERNAL_COLLECTIONS_PORT_H_
#include "ceres/internal/port.h"
#if defined(CERES_NO_UNORDERED_MAP)
# include <map>
# include <set>

@ -40,6 +40,44 @@
namespace ceres {
namespace internal {
void CompressedRowJacobianWriter::PopulateJacobianRowAndColumnBlockVectors(
const Program* program, CompressedRowSparseMatrix* jacobian) {
const vector<ParameterBlock*>& parameter_blocks =
program->parameter_blocks();
vector<int>& col_blocks = *(jacobian->mutable_col_blocks());
col_blocks.resize(parameter_blocks.size());
for (int i = 0; i < parameter_blocks.size(); ++i) {
col_blocks[i] = parameter_blocks[i]->LocalSize();
}
const vector<ResidualBlock*>& residual_blocks =
program->residual_blocks();
vector<int>& row_blocks = *(jacobian->mutable_row_blocks());
row_blocks.resize(residual_blocks.size());
for (int i = 0; i < residual_blocks.size(); ++i) {
row_blocks[i] = residual_blocks[i]->NumResiduals();
}
}
void CompressedRowJacobianWriter::GetOrderedParameterBlocks(
const Program* program,
int residual_id,
vector<pair<int, int> >* evaluated_jacobian_blocks) {
const ResidualBlock* residual_block =
program->residual_blocks()[residual_id];
const int num_parameter_blocks = residual_block->NumParameterBlocks();
for (int j = 0; j < num_parameter_blocks; ++j) {
const ParameterBlock* parameter_block =
residual_block->parameter_blocks()[j];
if (!parameter_block->IsConstant()) {
evaluated_jacobian_blocks->push_back(
make_pair(parameter_block->index(), j));
}
}
sort(evaluated_jacobian_blocks->begin(), evaluated_jacobian_blocks->end());
}
SparseMatrix* CompressedRowJacobianWriter::CreateJacobian() const {
const vector<ResidualBlock*>& residual_blocks =
program_->residual_blocks();
@ -71,7 +109,7 @@ SparseMatrix* CompressedRowJacobianWriter::CreateJacobian() const {
total_num_effective_parameters,
num_jacobian_nonzeros + total_num_effective_parameters);
// At this stage, the CompressedSparseMatrix is an invalid state. But this
// At this stage, the CompressedRowSparseMatrix is an invalid state. But this
// seems to be the only way to construct it without doing a memory copy.
int* rows = jacobian->mutable_rows();
int* cols = jacobian->mutable_cols();
@ -132,22 +170,7 @@ SparseMatrix* CompressedRowJacobianWriter::CreateJacobian() const {
}
CHECK_EQ(num_jacobian_nonzeros, rows[total_num_residuals]);
// Populate the row and column block vectors for use by block
// oriented ordering algorithms. This is useful when
// Solver::Options::use_block_amd = true.
const vector<ParameterBlock*>& parameter_blocks =
program_->parameter_blocks();
vector<int>& col_blocks = *(jacobian->mutable_col_blocks());
col_blocks.resize(parameter_blocks.size());
for (int i = 0; i < parameter_blocks.size(); ++i) {
col_blocks[i] = parameter_blocks[i]->LocalSize();
}
vector<int>& row_blocks = *(jacobian->mutable_row_blocks());
row_blocks.resize(residual_blocks.size());
for (int i = 0; i < residual_blocks.size(); ++i) {
row_blocks[i] = residual_blocks[i]->NumResiduals();
}
PopulateJacobianRowAndColumnBlockVectors(program_, jacobian);
return jacobian;
}
@ -164,25 +187,10 @@ void CompressedRowJacobianWriter::Write(int residual_id,
const ResidualBlock* residual_block =
program_->residual_blocks()[residual_id];
const int num_parameter_blocks = residual_block->NumParameterBlocks();
const int num_residuals = residual_block->NumResiduals();
// It is necessary to determine the order of the jacobian blocks before
// copying them into the CompressedRowSparseMatrix. Just because a cost
// function uses parameter blocks 1 after 2 in its arguments does not mean
// that the block 1 occurs before block 2 in the column layout of the
// jacobian. Thus, determine the order by sorting the jacobian blocks by their
// position in the state vector.
vector<pair<int, int> > evaluated_jacobian_blocks;
for (int j = 0; j < num_parameter_blocks; ++j) {
const ParameterBlock* parameter_block =
residual_block->parameter_blocks()[j];
if (!parameter_block->IsConstant()) {
evaluated_jacobian_blocks.push_back(
make_pair(parameter_block->index(), j));
}
}
sort(evaluated_jacobian_blocks.begin(), evaluated_jacobian_blocks.end());
GetOrderedParameterBlocks(program_, residual_id, &evaluated_jacobian_blocks);
// Where in the current row does the jacobian for a parameter block begin.
int col_pos = 0;

@ -39,6 +39,7 @@
namespace ceres {
namespace internal {
class CompressedRowSparseMatrix;
class Program;
class SparseMatrix;
@ -49,11 +50,44 @@ class CompressedRowJacobianWriter {
: program_(program) {
}
// PopulateJacobianRowAndColumnBlockVectors sets col_blocks and
// row_blocks for a CompressedRowSparseMatrix, based on the
// parameter block sizes and residual sizes respectively from the
// program. This is useful when Solver::Options::use_block_amd =
// true;
//
// This function is static so that it is available to other jacobian
// writers which use CompressedRowSparseMatrix (or derived types).
// (Jacobian writers do not fall under any type hierarchy; they only
// have to provide an interface as specified in program_evaluator.h).
static void PopulateJacobianRowAndColumnBlockVectors(
const Program* program,
CompressedRowSparseMatrix* jacobian);
// It is necessary to determine the order of the jacobian blocks
// before copying them into a CompressedRowSparseMatrix (or derived
// type). Just because a cost function uses parameter blocks 1
// after 2 in its arguments does not mean that the block 1 occurs
// before block 2 in the column layout of the jacobian. Thus,
// GetOrderedParameterBlocks determines the order by sorting the
// jacobian blocks by their position in the state vector.
//
// This function is static so that it is available to other jacobian
// writers which use CompressedRowSparseMatrix (or derived types).
// (Jacobian writers do not fall under any type hierarchy; they only
// have to provide an interface as specified in
// program_evaluator.h).
static void GetOrderedParameterBlocks(
const Program* program,
int residual_id,
vector<pair<int, int> >* evaluated_jacobian_blocks);
// JacobianWriter interface.
// Since the compressed row matrix has different layout than that assumed by
// the cost functions, use scratch space to store the jacobians temporarily
// then copy them over to the larger jacobian in the Write() function.
// Since the compressed row matrix has different layout than that
// assumed by the cost functions, use scratch space to store the
// jacobians temporarily then copy them over to the larger jacobian
// in the Write() function.
ScratchEvaluatePreparer* CreateEvaluatePreparers(int num_threads) {
return ScratchEvaluatePreparer::Create(*program_, num_threads);
}

@ -286,6 +286,13 @@ void CompressedRowSparseMatrix::ToCRSMatrix(CRSMatrix* matrix) const {
matrix->values.resize(matrix->rows[matrix->num_rows]);
}
void CompressedRowSparseMatrix::SetMaxNumNonZeros(int num_nonzeros) {
CHECK_GE(num_nonzeros, 0);
cols_.resize(num_nonzeros);
values_.resize(num_nonzeros);
}
void CompressedRowSparseMatrix::SolveLowerTriangularInPlace(
double* solution) const {
for (int r = 0; r < num_rows_; ++r) {
@ -377,6 +384,9 @@ CompressedRowSparseMatrix* CompressedRowSparseMatrix::Transpose() const {
}
transpose_rows[0] = 0;
*(transpose->mutable_row_blocks()) = col_blocks_;
*(transpose->mutable_col_blocks()) = row_blocks_;
return transpose;
}

@ -115,6 +115,9 @@ class CompressedRowSparseMatrix : public SparseMatrix {
const vector<int>& col_blocks() const { return col_blocks_; }
vector<int>* mutable_col_blocks() { return &col_blocks_; }
// Destructive array resizing method.
void SetMaxNumNonZeros(int num_nonzeros);
// Non-destructive array resizing method.
void set_num_rows(const int num_rows) { num_rows_ = num_rows; }
void set_num_cols(const int num_cols) { num_cols_ = num_cols; }

@ -28,6 +28,9 @@
//
// Author: strandmark@google.com (Petter Strandmark)
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_NO_CXSPARSE
#include "ceres/cxsparse.h"

@ -31,6 +31,9 @@
#ifndef CERES_INTERNAL_CXSPARSE_H_
#define CERES_INTERNAL_CXSPARSE_H_
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_NO_CXSPARSE
#include <vector>

@ -0,0 +1,51 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2014 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: richie.stebbing@gmail.com (Richard Stebbing)
#ifndef CERES_INTERNAL_DYNAMIC_COMPRESED_ROW_FINALIZER_H_
#define CERES_INTERNAL_DYNAMIC_COMPRESED_ROW_FINALIZER_H_
#include "ceres/casts.h"
#include "ceres/dynamic_compressed_row_sparse_matrix.h"
namespace ceres {
namespace internal {
struct DynamicCompressedRowJacobianFinalizer {
void operator()(SparseMatrix* base_jacobian, int num_parameters) {
DynamicCompressedRowSparseMatrix* jacobian =
down_cast<DynamicCompressedRowSparseMatrix*>(base_jacobian);
jacobian->Finalize(num_parameters);
}
};
} // namespace internal
} // namespace ceres
#endif // CERES_INTERNAL_DYNAMIC_COMPRESED_ROW_FINALISER_H_

@ -0,0 +1,107 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2014 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: richie.stebbing@gmail.com (Richard Stebbing)
#include "ceres/compressed_row_jacobian_writer.h"
#include "ceres/dynamic_compressed_row_jacobian_writer.h"
#include "ceres/casts.h"
#include "ceres/dynamic_compressed_row_sparse_matrix.h"
#include "ceres/parameter_block.h"
#include "ceres/program.h"
#include "ceres/residual_block.h"
namespace ceres {
namespace internal {
ScratchEvaluatePreparer*
DynamicCompressedRowJacobianWriter::CreateEvaluatePreparers(int num_threads) {
return ScratchEvaluatePreparer::Create(*program_, num_threads);
}
SparseMatrix* DynamicCompressedRowJacobianWriter::CreateJacobian() const {
// Initialize `jacobian` with zero number of `max_num_nonzeros`.
const int num_residuals = program_->NumResiduals();
const int num_effective_parameters = program_->NumEffectiveParameters();
DynamicCompressedRowSparseMatrix* jacobian =
new DynamicCompressedRowSparseMatrix(num_residuals,
num_effective_parameters,
0);
CompressedRowJacobianWriter::PopulateJacobianRowAndColumnBlockVectors(
program_, jacobian);
return jacobian;
}
void DynamicCompressedRowJacobianWriter::Write(int residual_id,
int residual_offset,
double **jacobians,
SparseMatrix* base_jacobian) {
DynamicCompressedRowSparseMatrix* jacobian =
down_cast<DynamicCompressedRowSparseMatrix*>(base_jacobian);
// Get the `residual_block` of interest.
const ResidualBlock* residual_block =
program_->residual_blocks()[residual_id];
const int num_residuals = residual_block->NumResiduals();
vector<pair<int, int> > evaluated_jacobian_blocks;
CompressedRowJacobianWriter::GetOrderedParameterBlocks(
program_, residual_id, &evaluated_jacobian_blocks);
// `residual_offset` is the residual row in the global jacobian.
// Empty the jacobian rows.
jacobian->ClearRows(residual_offset, num_residuals);
// Iterate over each parameter block.
for (int i = 0; i < evaluated_jacobian_blocks.size(); ++i) {
const ParameterBlock* parameter_block =
program_->parameter_blocks()[evaluated_jacobian_blocks[i].first];
const int parameter_block_jacobian_index =
evaluated_jacobian_blocks[i].second;
const int parameter_block_size = parameter_block->LocalSize();
// For each parameter block only insert its non-zero entries.
for (int r = 0; r < num_residuals; ++r) {
for (int c = 0; c < parameter_block_size; ++c) {
const double& v = jacobians[parameter_block_jacobian_index][
r * parameter_block_size + c];
// Only insert non-zero entries.
if (v != 0.0) {
jacobian->InsertEntry(
residual_offset + r, parameter_block->delta_offset() + c, v);
}
}
}
}
}
} // namespace internal
} // namespace ceres

@ -0,0 +1,83 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2014 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: richie.stebbing@gmail.com (Richard Stebbing)
//
// A jacobian writer that directly writes to dynamic compressed row sparse
// matrices.
#ifndef CERES_INTERNAL_DYNAMIC_COMPRESSED_ROW_JACOBIAN_WRITER_H_
#define CERES_INTERNAL_DYNAMIC_COMPRESSED_ROW_JACOBIAN_WRITER_H_
#include "ceres/evaluator.h"
#include "ceres/scratch_evaluate_preparer.h"
namespace ceres {
namespace internal {
class Program;
class SparseMatrix;
class DynamicCompressedRowJacobianWriter {
public:
DynamicCompressedRowJacobianWriter(Evaluator::Options /* ignored */,
Program* program)
: program_(program) {
}
// JacobianWriter interface.
// The compressed row matrix has different layout than that assumed by
// the cost functions. The scratch space is therefore used to store
// the jacobians (including zeros) temporarily before only the non-zero
// entries are copied over to the larger jacobian in `Write`.
ScratchEvaluatePreparer* CreateEvaluatePreparers(int num_threads);
// Return a `DynamicCompressedRowSparseMatrix` which is filled by
// `Write`. Note that `Finalize` must be called to make the
// `CompressedRowSparseMatrix` interface valid.
SparseMatrix* CreateJacobian() const;
// Write only the non-zero jacobian entries for a residual block
// (specified by `residual_id`) into `base_jacobian`, starting at the row
// specifed by `residual_offset`.
//
// This method is thread-safe over residual blocks (each `residual_id`).
void Write(int residual_id,
int residual_offset,
double **jacobians,
SparseMatrix* base_jacobian);
private:
Program* program_;
};
} // namespace internal
} // namespace ceres
#endif // CERES_INTERNAL_DYNAMIC_COMPRESSED_ROW_JACOBIAN_WRITER_H_

@ -0,0 +1,107 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2014 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: richie.stebbing@gmail.com (Richard Stebbing)
#include <cstring>
#include "ceres/dynamic_compressed_row_sparse_matrix.h"
namespace ceres {
namespace internal {
DynamicCompressedRowSparseMatrix::DynamicCompressedRowSparseMatrix(
int num_rows,
int num_cols,
int initial_max_num_nonzeros)
: CompressedRowSparseMatrix(num_rows,
num_cols,
initial_max_num_nonzeros) {
dynamic_cols_.resize(num_rows);
dynamic_values_.resize(num_rows);
}
void DynamicCompressedRowSparseMatrix::InsertEntry(int row,
int col,
const double& value) {
CHECK_GE(row, 0);
CHECK_LT(row, num_rows());
CHECK_GE(col, 0);
CHECK_LT(col, num_cols());
dynamic_cols_[row].push_back(col);
dynamic_values_[row].push_back(value);
}
void DynamicCompressedRowSparseMatrix::ClearRows(int row_start,
int num_rows) {
for (int r = 0; r < num_rows; ++r) {
const int i = row_start + r;
CHECK_GE(i, 0);
CHECK_LT(i, this->num_rows());
dynamic_cols_[i].resize(0);
dynamic_values_[i].resize(0);
}
}
void DynamicCompressedRowSparseMatrix::Finalize(int num_additional_elements) {
// `num_additional_elements` is provided as an argument so that additional
// storage can be reserved when it is known by the finalizer.
CHECK_GE(num_additional_elements, 0);
// Count the number of non-zeros and resize `cols_` and `values_`.
int num_jacobian_nonzeros = 0;
for (int i = 0; i < dynamic_cols_.size(); ++i) {
num_jacobian_nonzeros += dynamic_cols_[i].size();
}
SetMaxNumNonZeros(num_jacobian_nonzeros + num_additional_elements);
// Flatten `dynamic_cols_` into `cols_` and `dynamic_values_`
// into `values_`.
int index_into_values_and_cols = 0;
for (int i = 0; i < num_rows(); ++i) {
mutable_rows()[i] = index_into_values_and_cols;
const int num_nonzero_columns = dynamic_cols_[i].size();
if (num_nonzero_columns > 0) {
memcpy(mutable_cols() + index_into_values_and_cols,
&dynamic_cols_[i][0],
dynamic_cols_[i].size() * sizeof(dynamic_cols_[0][0]));
memcpy(mutable_values() + index_into_values_and_cols,
&dynamic_values_[i][0],
dynamic_values_[i].size() * sizeof(dynamic_values_[0][0]));
index_into_values_and_cols += dynamic_cols_[i].size();
}
}
mutable_rows()[num_rows()] = index_into_values_and_cols;
CHECK_EQ(index_into_values_and_cols, num_jacobian_nonzeros)
<< "Ceres bug: final index into values_ and cols_ should be equal to "
<< "the number of jacobian nonzeros. Please contact the developers!";
}
} // namespace internal
} // namespace ceres

@ -0,0 +1,99 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2014 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: richie.stebbing@gmail.com (Richard Stebbing)
//
// A compressed row sparse matrix that provides an extended interface to
// allow dynamic insertion of entries. This is provided for the use case
// where the sparsity structure and number of non-zero entries is dynamic.
// This flexibility is achieved by using an (internal) scratch space that
// allows independent insertion of entries into each row (thread-safe).
// Once insertion is complete, the `Finalize` method must be called to ensure
// that the underlying `CompressedRowSparseMatrix` is consistent.
//
// This should only be used if you really do need a dynamic sparsity pattern.
#ifndef CERES_INTERNAL_DYNAMIC_COMPRESSED_ROW_SPARSE_MATRIX_H_
#define CERES_INTERNAL_DYNAMIC_COMPRESSED_ROW_SPARSE_MATRIX_H_
#include "ceres/compressed_row_sparse_matrix.h"
namespace ceres {
namespace internal {
class DynamicCompressedRowSparseMatrix : public CompressedRowSparseMatrix {
public:
// Set the number of rows and columns for the underlyig
// `CompressedRowSparseMatrix` and set the initial number of maximum non-zero
// entries. Note that following the insertion of entries, when `Finalize`
// is called the number of non-zeros is determined and all internal
// structures are adjusted as required. If you know the upper limit on the
// number of non-zeros, then passing this value here can prevent future
// memory reallocations which may improve performance. Otherwise, if no
// upper limit is available a value of 0 is sufficient.
//
// Typical usage of this class is to define a new instance with a given
// number of rows, columns and maximum number of non-zero elements
// (if available). Next, entries are inserted at row and column positions
// using `InsertEntry`. Finally, once all elements have been inserted,
// `Finalize` must be called to make the underlying
// `CompressedRowSparseMatrix` consistent.
DynamicCompressedRowSparseMatrix(int num_rows,
int num_cols,
int initial_max_num_nonzeros);
// Insert an entry at a given row and column position. This method is
// thread-safe across rows i.e. different threads can insert values
// simultaneously into different rows. It should be emphasised that this
// method always inserts a new entry and does not check for existing
// entries at the specified row and column position. Duplicate entries
// for a given row and column position will result in undefined
// behavior.
void InsertEntry(int row, int col, const double& value);
// Clear all entries for rows, starting from row index `row_start`
// and proceeding for `num_rows`.
void ClearRows(int row_start, int num_rows);
// Make the underlying internal `CompressedRowSparseMatrix` data structures
// consistent. Additional space for non-zero entries in the
// `CompressedRowSparseMatrix` can be reserved by specifying
// `num_additional_elements`. This is useful when it is known that rows will
// be appended to the `CompressedRowSparseMatrix` (e.g. appending a diagonal
// matrix to the jacobian) as it prevents need for future reallocation.
void Finalize(int num_additional_elements);
private:
vector<vector<int> > dynamic_cols_;
vector<vector<double> > dynamic_values_;
};
} // namespace internal
} // namespace ceres
#endif // CERES_INTERNAL_DYNAMIC_COMPRESSED_ROW_SPARSE_MATRIX_H_

@ -35,6 +35,8 @@
#include "ceres/compressed_row_sparse_matrix.h"
#include "ceres/crs_matrix.h"
#include "ceres/dense_jacobian_writer.h"
#include "ceres/dynamic_compressed_row_finalizer.h"
#include "ceres/dynamic_compressed_row_jacobian_writer.h"
#include "ceres/evaluator.h"
#include "ceres/internal/port.h"
#include "ceres/program_evaluator.h"
@ -63,9 +65,17 @@ Evaluator* Evaluator::Create(const Evaluator::Options& options,
BlockJacobianWriter>(options,
program);
case SPARSE_NORMAL_CHOLESKY:
return new ProgramEvaluator<ScratchEvaluatePreparer,
CompressedRowJacobianWriter>(options,
program);
if (options.dynamic_sparsity) {
return new ProgramEvaluator<ScratchEvaluatePreparer,
DynamicCompressedRowJacobianWriter,
DynamicCompressedRowJacobianFinalizer>(
options, program);
} else {
return new ProgramEvaluator<ScratchEvaluatePreparer,
CompressedRowJacobianWriter>(options,
program);
}
default:
*error = "Invalid Linear Solver Type. Unable to create evaluator.";
return NULL;

@ -61,11 +61,13 @@ class Evaluator {
Options()
: num_threads(1),
num_eliminate_blocks(-1),
linear_solver_type(DENSE_QR) {}
linear_solver_type(DENSE_QR),
dynamic_sparsity(false) {}
int num_threads;
int num_eliminate_blocks;
LinearSolverType linear_solver_type;
bool dynamic_sparsity;
};
static Evaluator* Create(const Options& options,

@ -59,6 +59,8 @@ SPECIALIZATIONS = [(2, 2, 2),
(2, 3, "Eigen::Dynamic"),
(2, 4, 3),
(2, 4, 4),
(2, 4, 8),
(2, 4, 9),
(2, 4, "Eigen::Dynamic"),
(2, "Eigen::Dynamic", "Eigen::Dynamic"),
(4, 4, 2),
@ -124,6 +126,9 @@ template class SchurEliminator<%s, %s, %s>;
"""
SPECIALIZATION_FILE = """
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/schur_eliminator_impl.h"

@ -57,6 +57,8 @@ SPECIALIZATIONS = [(2, 2, 2),
(2, 3, "Eigen::Dynamic"),
(2, 4, 3),
(2, 4, 4),
(2, 4, 8),
(2, 4, 9),
(2, 4, "Eigen::Dynamic"),
(2, "Eigen::Dynamic", "Eigen::Dynamic"),
(4, 4, 2),
@ -103,7 +105,7 @@ HEADER = """// Ceres Solver - A fast non-linear least squares minimizer
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specialization.py.
// This file is generated using generate_partitioned_matrix_view_specializations.py.
// Editing it manually is not recommended.
"""
@ -122,6 +124,9 @@ template class PartitionedMatrixView<%s, %s, %s>;
"""
SPECIALIZATION_FILE = """
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/partitioned_matrix_view_impl.h"

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specialization.py.
// This file is generated using generate_partitioned_matrix_view_specializations.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/partitioned_matrix_view_impl.h"

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specialization.py.
// This file is generated using generate_partitioned_matrix_view_specializations.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/partitioned_matrix_view_impl.h"

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specialization.py.
// This file is generated using generate_partitioned_matrix_view_specializations.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/partitioned_matrix_view_impl.h"

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specialization.py.
// This file is generated using generate_partitioned_matrix_view_specializations.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/partitioned_matrix_view_impl.h"

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specialization.py.
// This file is generated using generate_partitioned_matrix_view_specializations.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/partitioned_matrix_view_impl.h"

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specialization.py.
// This file is generated using generate_partitioned_matrix_view_specializations.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/partitioned_matrix_view_impl.h"

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specialization.py.
// This file is generated using generate_partitioned_matrix_view_specializations.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/partitioned_matrix_view_impl.h"

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specialization.py.
// This file is generated using generate_partitioned_matrix_view_specializations.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/partitioned_matrix_view_impl.h"

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specialization.py.
// This file is generated using generate_partitioned_matrix_view_specializations.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/partitioned_matrix_view_impl.h"

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specialization.py.
// This file is generated using generate_partitioned_matrix_view_specializations.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/partitioned_matrix_view_impl.h"

@ -0,0 +1,59 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2013 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)
//
// Template specialization of PartitionedMatrixView.
//
// ========================================
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_partitioned_matrix_view_specializations.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/partitioned_matrix_view_impl.h"
#include "ceres/internal/eigen.h"
namespace ceres {
namespace internal {
template class PartitionedMatrixView<2, 4, 8>;
} // namespace internal
} // namespace ceres
#endif // CERES_RESTRICT_SCHUR_SPECIALIZATION

@ -0,0 +1,59 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2013 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)
//
// Template specialization of PartitionedMatrixView.
//
// ========================================
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_partitioned_matrix_view_specializations.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/partitioned_matrix_view_impl.h"
#include "ceres/internal/eigen.h"
namespace ceres {
namespace internal {
template class PartitionedMatrixView<2, 4, 9>;
} // namespace internal
} // namespace ceres
#endif // CERES_RESTRICT_SCHUR_SPECIALIZATION

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specialization.py.
// This file is generated using generate_partitioned_matrix_view_specializations.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/partitioned_matrix_view_impl.h"

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specialization.py.
// This file is generated using generate_partitioned_matrix_view_specializations.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/partitioned_matrix_view_impl.h"

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specialization.py.
// This file is generated using generate_partitioned_matrix_view_specializations.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/partitioned_matrix_view_impl.h"

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specialization.py.
// This file is generated using generate_partitioned_matrix_view_specializations.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/partitioned_matrix_view_impl.h"

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specialization.py.
// This file is generated using generate_partitioned_matrix_view_specializations.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/partitioned_matrix_view_impl.h"

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specialization.py.
// This file is generated using generate_partitioned_matrix_view_specializations.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/partitioned_matrix_view_impl.h"

@ -37,7 +37,7 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specialization.py.
// This file is generated using generate_partitioned_matrix_view_specializations.py.
// Editing it manually is not recommended.

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specializations.py.
// This file is generated using generate_eliminator_specialization.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/schur_eliminator_impl.h"

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specializations.py.
// This file is generated using generate_eliminator_specialization.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/schur_eliminator_impl.h"

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specializations.py.
// This file is generated using generate_eliminator_specialization.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/schur_eliminator_impl.h"

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specializations.py.
// This file is generated using generate_eliminator_specialization.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/schur_eliminator_impl.h"

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specializations.py.
// This file is generated using generate_eliminator_specialization.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/schur_eliminator_impl.h"

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specializations.py.
// This file is generated using generate_eliminator_specialization.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/schur_eliminator_impl.h"

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specializations.py.
// This file is generated using generate_eliminator_specialization.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/schur_eliminator_impl.h"

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specializations.py.
// This file is generated using generate_eliminator_specialization.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/schur_eliminator_impl.h"

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specializations.py.
// This file is generated using generate_eliminator_specialization.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/schur_eliminator_impl.h"

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specializations.py.
// This file is generated using generate_eliminator_specialization.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/schur_eliminator_impl.h"

@ -0,0 +1,59 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2010, 2011, 2012, 2013 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)
//
// Template specialization of SchurEliminator.
//
// ========================================
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specialization.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/schur_eliminator_impl.h"
#include "ceres/internal/eigen.h"
namespace ceres {
namespace internal {
template class SchurEliminator<2, 4, 8>;
} // namespace internal
} // namespace ceres
#endif // CERES_RESTRICT_SCHUR_SPECIALIZATION

@ -0,0 +1,59 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2010, 2011, 2012, 2013 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)
//
// Template specialization of SchurEliminator.
//
// ========================================
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specialization.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/schur_eliminator_impl.h"
#include "ceres/internal/eigen.h"
namespace ceres {
namespace internal {
template class SchurEliminator<2, 4, 9>;
} // namespace internal
} // namespace ceres
#endif // CERES_RESTRICT_SCHUR_SPECIALIZATION

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specializations.py.
// This file is generated using generate_eliminator_specialization.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/schur_eliminator_impl.h"

@ -40,6 +40,9 @@
// This file is generated using generate_eliminator_specialization.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/schur_eliminator_impl.h"

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specializations.py.
// This file is generated using generate_eliminator_specialization.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/schur_eliminator_impl.h"

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specializations.py.
// This file is generated using generate_eliminator_specialization.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/schur_eliminator_impl.h"

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specializations.py.
// This file is generated using generate_eliminator_specialization.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/schur_eliminator_impl.h"

@ -37,9 +37,12 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specializations.py.
// This file is generated using generate_eliminator_specialization.py.
// Editing it manually is not recommended.
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
#include "ceres/schur_eliminator_impl.h"

@ -37,7 +37,7 @@
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
//=========================================
//
// This file is generated using generate_eliminator_specializations.py.
// This file is generated using generate_eliminator_specialization.py.
// Editing it manually is not recommended.

@ -77,7 +77,6 @@ struct UnsignedInteger {
#undef CERES_INTSIZE
typedef Integer< 8>::type int8;
typedef Integer<16>::type int16;
typedef Integer<32>::type int32;
typedef Integer<64>::type int64;

@ -28,7 +28,6 @@
//
// Author: sameeragarwal@google.com (Sameer Agarwal)
#ifndef CERES_NO_LINE_SEARCH_MINIMIZER
#include <iomanip>
#include <iostream> // NOLINT
@ -67,15 +66,17 @@ FunctionSample ValueAndGradientSample(const double x,
return sample;
};
} // namespace
std::ostream& operator<<(std::ostream &os, const FunctionSample& sample);
// Convenience stream operator for pushing FunctionSamples into log messages.
std::ostream& operator<<(std::ostream &os,
const FunctionSample& sample) {
std::ostream& operator<<(std::ostream &os, const FunctionSample& sample) {
os << sample.ToDebugString();
return os;
}
} // namespace
LineSearch::LineSearch(const LineSearch::Options& options)
: options_(options) {}
@ -274,7 +275,7 @@ void ArmijoLineSearch::Search(const double step_size_estimate,
"satisfying the sufficient decrease condition within "
"specified max_num_iterations: %d.",
options().max_num_iterations);
LOG(WARNING) << summary->error;
LOG_IF(WARNING, !options().is_silent) << summary->error;
return;
}
@ -292,7 +293,7 @@ void ArmijoLineSearch::Search(const double step_size_estimate,
StringPrintf("Line search failed: step_size too small: %.5e "
"with descent_direction_max_norm: %.5e.", step_size,
descent_direction_max_norm);
LOG(WARNING) << summary->error;
LOG_IF(WARNING, !options().is_silent) << summary->error;
return;
}
@ -545,15 +546,16 @@ bool WolfeLineSearch::BracketingPhase(
// conditions, or a valid bracket containing such a point. Stop searching
// and set bracket_low to the size size amongst all those tested which
// minimizes f() and satisfies the Armijo condition.
LOG(WARNING) << "Line search failed: Wolfe bracketing phase shrank "
<< "bracket width: " << fabs(current.x - previous.x)
<< ", to < tolerance: " << options().min_step_size
<< ", with descent_direction_max_norm: "
<< descent_direction_max_norm << ", and failed to find "
<< "a point satisfying the strong Wolfe conditions or a "
<< "bracketing containing such a point. Accepting "
<< "point found satisfying Armijo condition only, to "
<< "allow continuation.";
LOG_IF(WARNING, !options().is_silent)
<< "Line search failed: Wolfe bracketing phase shrank "
<< "bracket width: " << fabs(current.x - previous.x)
<< ", to < tolerance: " << options().min_step_size
<< ", with descent_direction_max_norm: "
<< descent_direction_max_norm << ", and failed to find "
<< "a point satisfying the strong Wolfe conditions or a "
<< "bracketing containing such a point. Accepting "
<< "point found satisfying Armijo condition only, to "
<< "allow continuation.";
*bracket_low = current;
break;
@ -566,7 +568,7 @@ bool WolfeLineSearch::BracketingPhase(
"find a point satisfying strong Wolfe conditions, or a "
"bracket containing such a point within specified "
"max_num_iterations: %d", options().max_num_iterations);
LOG(WARNING) << summary->error;
LOG_IF(WARNING, !options().is_silent) << summary->error;
// Ensure that bracket_low is always set to the step size amongst all
// those tested which minimizes f() and satisfies the Armijo condition
// when we terminate due to the 'artificial' max_num_iterations condition.
@ -605,7 +607,7 @@ bool WolfeLineSearch::BracketingPhase(
StringPrintf("Line search failed: step_size too small: %.5e "
"with descent_direction_max_norm: %.5e", step_size,
descent_direction_max_norm);
LOG(WARNING) << summary->error;
LOG_IF(WARNING, !options().is_silent) << summary->error;
return false;
}
@ -689,7 +691,7 @@ bool WolfeLineSearch::ZoomPhase(const FunctionSample& initial_position,
initial_position.ToDebugString().c_str(),
bracket_low.ToDebugString().c_str(),
bracket_high.ToDebugString().c_str());
LOG(WARNING) << summary->error;
LOG_IF(WARNING, !options().is_silent) << summary->error;
solution->value_is_valid = false;
return false;
}
@ -710,7 +712,7 @@ bool WolfeLineSearch::ZoomPhase(const FunctionSample& initial_position,
"within specified max_num_iterations: %d, "
"(num iterations taken for bracketing: %d).",
options().max_num_iterations, num_bracketing_iterations);
LOG(WARNING) << summary->error;
LOG_IF(WARNING, !options().is_silent) << summary->error;
return false;
}
if (fabs(bracket_high.x - bracket_low.x) * descent_direction_max_norm
@ -722,7 +724,7 @@ bool WolfeLineSearch::ZoomPhase(const FunctionSample& initial_position,
"too small with descent_direction_max_norm: %.5e.",
fabs(bracket_high.x - bracket_low.x),
descent_direction_max_norm);
LOG(WARNING) << summary->error;
LOG_IF(WARNING, !options().is_silent) << summary->error;
return false;
}
@ -773,7 +775,7 @@ bool WolfeLineSearch::ZoomPhase(const FunctionSample& initial_position,
"between low_step: %.5e and high_step: %.5e "
"at which function is valid.",
solution->x, bracket_low.x, bracket_high.x);
LOG(WARNING) << summary->error;
LOG_IF(WARNING, !options().is_silent) << summary->error;
return false;
}
@ -817,5 +819,3 @@ bool WolfeLineSearch::ZoomPhase(const FunctionSample& initial_position,
} // namespace internal
} // namespace ceres
#endif // CERES_NO_LINE_SEARCH_MINIMIZER

@ -33,8 +33,6 @@
#ifndef CERES_INTERNAL_LINE_SEARCH_H_
#define CERES_INTERNAL_LINE_SEARCH_H_
#ifndef CERES_NO_LINE_SEARCH_MINIMIZER
#include <string>
#include <vector>
#include "ceres/internal/eigen.h"
@ -71,6 +69,7 @@ class LineSearch {
max_num_iterations(20),
sufficient_curvature_decrease(0.9),
max_step_expansion(10.0),
is_silent(false),
function(NULL) {}
// Degree of the polynomial used to approximate the objective
@ -144,6 +143,8 @@ class LineSearch {
// By definition for expansion, max_step_expansion > 1.0.
double max_step_expansion;
bool is_silent;
// The one dimensional function that the line search algorithm
// minimizes.
Function* function;
@ -295,5 +296,4 @@ class WolfeLineSearch : public LineSearch {
} // namespace internal
} // namespace ceres
#endif // CERES_NO_LINE_SEARCH_MINIMIZER
#endif // CERES_INTERNAL_LINE_SEARCH_H_

Some files were not shown because too many files have changed in this diff Show More