diff --git a/.travis.sh b/.travis.sh index 522d82353..434187e4f 100755 --- a/.travis.sh +++ b/.travis.sh @@ -22,19 +22,8 @@ function build_and_test () sudo update-alternatives --set gcc /usr/bin/gcc-$GCC_VERSION fi - # gcc is too slow and we have a time limit in Travis CI: selective builds. - if [ "$BUILD_EXAMPLES" == "1" ]; then - GTSAM_BUILD_EXAMPLES_ALWAYS=ON - else - GTSAM_BUILD_EXAMPLES_ALWAYS=OFF - fi - if [ "$RUN_TESTS" == "1" ]; then - GTSAM_BUILD_TESTS=ON - else - GTSAM_BUILD_TESTS=OFF - fi - cmake $SOURCE_DIR \ + -DGTSAM_BUILD_UNSTABLE=$GTSAM_BUILD_UNSTABLE \ -DGTSAM_BUILD_EXAMPLES_ALWAYS=$GTSAM_BUILD_EXAMPLES_ALWAYS \ -DGTSAM_BUILD_TESTS=$GTSAM_BUILD_TESTS @@ -42,10 +31,13 @@ function build_and_test () make -j2 # Run tests: - if [ "$RUN_TESTS" == "1" ]; then + if [ "$GTSAM_BUILD_TESTS" == "ON" ]; then make check fi + # Print ccache stats + ccache -s + cd $SOURCE_DIR } diff --git a/.travis.yml b/.travis.yml index bce676721..4b4487103 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,8 +16,12 @@ addons: - libpython-dev python-numpy - libboost-all-dev -before_install: - - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew update ; fi +# before_install: +# - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew update ; fi + +install: + - if [ "$TRAVIS_OS_NAME" == "osx" ]; then HOMEBREW_NO_AUTO_UPDATE=1 brew install ccache ; fi + - if [ "$TRAVIS_OS_NAME" == "osx" ]; then export PATH="/usr/local/opt/ccache/libexec:$PATH" ; fi script: - bash .travis.sh @@ -27,23 +31,24 @@ env: - MAKEFLAGS="-j 2" - CCACHE_SLOPPINESS=pch_defines,time_macros +# gcc is too slow and we have a time limit in Travis CI: selective builds. matrix: include: - compiler: gcc os: linux - env: BUILD_EXAMPLES=1 + env: GTSAM_BUILD_UNSTABLE=ON GTSAM_BUILD_EXAMPLES_ALWAYS=ON GTSAM_BUILD_TESTS=OFF - compiler: gcc os: linux - env: RUN_TESTS=1 + env: GTSAM_BUILD_UNSTABLE=OFF GTSAM_BUILD_EXAMPLES_ALWAYS=OFF GTSAM_BUILD_TESTS=ON # gcc too slow for all tests - compiler: gcc os: linux - env: BUILD_EXAMPLES=1 GCC_VERSION="8" + env: GTSAM_BUILD_UNSTABLE=ON GTSAM_BUILD_EXAMPLES_ALWAYS=ON GTSAM_BUILD_TESTS=OFF GCC_VERSION="8" - compiler: clang os: linux - env: BUILD_EXAMPLES=1 - - compiler: gcc - os: osx - env: BUILD_EXAMPLES=1 + env: GTSAM_BUILD_UNSTABLE=ON GTSAM_BUILD_EXAMPLES_ALWAYS=ON GTSAM_BUILD_TESTS=OFF +# - compiler: gcc +# os: osx +# env: GTSAM_BUILD_UNSTABLE=ON GTSAM_BUILD_EXAMPLES_ALWAYS=ON GTSAM_BUILD_TESTS=OFF - compiler: clang os: osx - env: RUN_TESTS=1 + env: GTSAM_BUILD_UNSTABLE=ON GTSAM_BUILD_EXAMPLES_ALWAYS=OFF GTSAM_BUILD_TESTS=ON diff --git a/CMakeLists.txt b/CMakeLists.txt index e9498ac21..585213159 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -314,6 +314,29 @@ else() set(GTSAM_EIGEN_INCLUDE_FOR_BUILD "${CMAKE_SOURCE_DIR}/gtsam/3rdparty/Eigen/") endif() +# Detect Eigen version: +set(EIGEN_VER_H "${GTSAM_EIGEN_INCLUDE_FOR_BUILD}/Eigen/src/Core/util/Macros.h") +if (EXISTS ${EIGEN_VER_H}) + file(READ "${EIGEN_VER_H}" STR_EIGEN_VERSION) + + # Extract the Eigen version from the Macros.h file, lines "#define EIGEN_WORLD_VERSION XX", etc... + + string(REGEX MATCH "EIGEN_WORLD_VERSION[ ]+[0-9]+" GTSAM_EIGEN_VERSION_WORLD "${STR_EIGEN_VERSION}") + string(REGEX MATCH "[0-9]+" GTSAM_EIGEN_VERSION_WORLD "${GTSAM_EIGEN_VERSION_WORLD}") + + string(REGEX MATCH "EIGEN_MAJOR_VERSION[ ]+[0-9]+" GTSAM_EIGEN_VERSION_MAJOR "${STR_EIGEN_VERSION}") + string(REGEX MATCH "[0-9]+" GTSAM_EIGEN_VERSION_MAJOR "${GTSAM_EIGEN_VERSION_MAJOR}") + + string(REGEX MATCH "EIGEN_MINOR_VERSION[ ]+[0-9]+" GTSAM_EIGEN_VERSION_MINOR "${STR_EIGEN_VERSION}") + string(REGEX MATCH "[0-9]+" GTSAM_EIGEN_VERSION_MINOR "${GTSAM_EIGEN_VERSION_MINOR}") + + set(GTSAM_EIGEN_VERSION "${GTSAM_EIGEN_VERSION_WORLD}.${GTSAM_EIGEN_VERSION_MAJOR}.${GTSAM_EIGEN_VERSION_MINOR}") + + message(STATUS "Found Eigen version: ${GTSAM_EIGEN_VERSION}") +else() + message(WARNING "Cannot determine Eigen version, missing file: `${EIGEN_VER_H}`") +endif () + if (MSVC) if (BUILD_SHARED_LIBS) # mute eigen static assert to avoid errors in shared lib @@ -499,11 +522,7 @@ if(NOT MSVC AND NOT XCODE_VERSION) message(STATUS " C compilation flags : ${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${cmake_build_type_toupper}}") message(STATUS " C++ compilation flags : ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${cmake_build_type_toupper}}") endif() -if(GTSAM_USE_SYSTEM_EIGEN) - message(STATUS " Use System Eigen : Yes") -else() - message(STATUS " Use System Eigen : No") -endif() +message(STATUS " Use System Eigen : ${GTSAM_USE_SYSTEM_EIGEN} (Using version: ${GTSAM_EIGEN_VERSION})") if(GTSAM_USE_TBB) message(STATUS " Use Intel TBB : Yes") elseif(TBB_FOUND) diff --git a/doc/trustregion.bib b/doc/trustregion.bib index 7fcd509f4..7c87eef9b 100644 --- a/doc/trustregion.bib +++ b/doc/trustregion.bib @@ -8,7 +8,6 @@ %% Saved with string encoding Unicode (UTF-8) - @webpage{Hauser06lecture, Author = {Raphael Hauser}, Date-Added = {2011-10-10 15:21:22 +0000}, @@ -16,11 +15,5 @@ Title = {Lecture Notes on Unconstrained Optimization}, Url = {http://www.numerical.rl.ac.uk/nimg/oupartc/lectures/raphael/}, Year = {2006}, - Bdsk-Url-1 = {http://www.numerical.rl.ac.uk/nimg/oupartc/lectures/raphael/}, - Bdsk-File-1 = {YnBsaXN0MDDUAQIDBAUIJidUJHRvcFgkb2JqZWN0c1gkdmVyc2lvblkkYXJjaGl2ZXLRBgdUcm9vdIABqAkKFRYXGyIjVSRudWxs0wsMDQ4RFFpOUy5vYmplY3RzV05TLmtleXNWJGNsYXNzog8QgASABqISE4ACgAOAB1lhbGlhc0RhdGFccmVsYXRpdmVQYXRo0hgNGRpXTlMuZGF0YU8RAYwAAAAAAYwAAgAADE1hY2ludG9zaCBIRAAAAAAAAAAAAAAAAAAAAMpAsaxIKwAAAD/T8xBIYXVzZXIwNmxlY3R1cmUxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQn+Sv+qSlgAAAAAAAAAAAAMAAgAACSAAAAAAAAAAAAAAAAAAAAAKTGl0ZXJhdHVyZQAQAAgAAMpA6ewAAAARAAgAAL/q2OYAAAABAAwAP9PzAAUCJwAAvuwAAgA5TWFjaW50b3NoIEhEOlVzZXJzOgByaWNoYXJkOgBMaXRlcmF0dXJlOgBIYXVzZXIwNmxlY3R1cmUxAAAOACIAEABIAGEAdQBzAGUAcgAwADYAbABlAGMAdAB1AHIAZQAxAA8AGgAMAE0AYQBjAGkAbgB0AG8AcwBoACAASABEABIAKVVzZXJzL3JpY2hhcmQvTGl0ZXJhdHVyZS9IYXVzZXIwNmxlY3R1cmUxAAATAAEvAAAVAAIADv//AACABdIcHR4fWCRjbGFzc2VzWiRjbGFzc25hbWWjHyAhXU5TTXV0YWJsZURhdGFWTlNEYXRhWE5TT2JqZWN0XxAkLi4vLi4vLi4vTGl0ZXJhdHVyZS9IYXVzZXIwNmxlY3R1cmUx0hwdJCWiJSFcTlNEaWN0aW9uYXJ5EgABhqBfEA9OU0tleWVkQXJjaGl2ZXIACAARABYAHwAoADIANQA6ADwARQBLAFIAXQBlAGwAbwBxAHMAdgB4AHoAfACGAJMAmACgAjACMgI3AkACSwJPAl0CZAJtApQCmQKcAqkCrgAAAAAAAAIBAAAAAAAAACgAAAAAAAAAAAAAAAAAAALA}, - Bdsk-File-2 = {YnBsaXN0MDDUAQIDBAUIJidUJHRvcFgkb2JqZWN0c1gkdmVyc2lvblkkYXJjaGl2ZXLRBgdUcm9vdIABqAkKFRYXGyIjVSRudWxs0wsMDQ4RFFpOUy5vYmplY3RzV05TLmtleXNWJGNsYXNzog8QgASABqISE4ACgAOAB1lhbGlhc0RhdGFccmVsYXRpdmVQYXRo0hgNGRpXTlMuZGF0YU8RAYwAAAAAAYwAAgAADE1hY2ludG9zaCBIRAAAAAAAAAAAAAAAAAAAAMpAsaxIKwAAAD/T8xBIYXVzZXIwNmxlY3R1cmUyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQn+Xv+qSowAAAAAAAAAAAAMAAgAACSAAAAAAAAAAAAAAAAAAAAAKTGl0ZXJhdHVyZQAQAAgAAMpA6ewAAAARAAgAAL/q2PMAAAABAAwAP9PzAAUCJwAAvuwAAgA5TWFjaW50b3NoIEhEOlVzZXJzOgByaWNoYXJkOgBMaXRlcmF0dXJlOgBIYXVzZXIwNmxlY3R1cmUyAAAOACIAEABIAGEAdQBzAGUAcgAwADYAbABlAGMAdAB1AHIAZQAyAA8AGgAMAE0AYQBjAGkAbgB0AG8AcwBoACAASABEABIAKVVzZXJzL3JpY2hhcmQvTGl0ZXJhdHVyZS9IYXVzZXIwNmxlY3R1cmUyAAATAAEvAAAVAAIADv//AACABdIcHR4fWCRjbGFzc2VzWiRjbGFzc25hbWWjHyAhXU5TTXV0YWJsZURhdGFWTlNEYXRhWE5TT2JqZWN0XxAkLi4vLi4vLi4vTGl0ZXJhdHVyZS9IYXVzZXIwNmxlY3R1cmUy0hwdJCWiJSFcTlNEaWN0aW9uYXJ5EgABhqBfEA9OU0tleWVkQXJjaGl2ZXIACAARABYAHwAoADIANQA6ADwARQBLAFIAXQBlAGwAbwBxAHMAdgB4AHoAfACGAJMAmACgAjACMgI3AkACSwJPAl0CZAJtApQCmQKcAqkCrgAAAAAAAAIBAAAAAAAAACgAAAAAAAAAAAAAAAAAAALA}, - Bdsk-File-3 = {YnBsaXN0MDDUAQIDBAUIJidUJHRvcFgkb2JqZWN0c1gkdmVyc2lvblkkYXJjaGl2ZXLRBgdUcm9vdIABqAkKFRYXGyIjVSRudWxs0wsMDQ4RFFpOUy5vYmplY3RzV05TLmtleXNWJGNsYXNzog8QgASABqISE4ACgAOAB1lhbGlhc0RhdGFccmVsYXRpdmVQYXRo0hgNGRpXTlMuZGF0YU8RAYwAAAAAAYwAAgAADE1hY2ludG9zaCBIRAAAAAAAAAAAAAAAAAAAAMpAsaxIKwAAAD/T8xBIYXVzZXIwNmxlY3R1cmUzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQn+mv+qSpQAAAAAAAAAAAAMAAgAACSAAAAAAAAAAAAAAAAAAAAAKTGl0ZXJhdHVyZQAQAAgAAMpA6ewAAAARAAgAAL/q2PUAAAABAAwAP9PzAAUCJwAAvuwAAgA5TWFjaW50b3NoIEhEOlVzZXJzOgByaWNoYXJkOgBMaXRlcmF0dXJlOgBIYXVzZXIwNmxlY3R1cmUzAAAOACIAEABIAGEAdQBzAGUAcgAwADYAbABlAGMAdAB1AHIAZQAzAA8AGgAMAE0AYQBjAGkAbgB0AG8AcwBoACAASABEABIAKVVzZXJzL3JpY2hhcmQvTGl0ZXJhdHVyZS9IYXVzZXIwNmxlY3R1cmUzAAATAAEvAAAVAAIADv//AACABdIcHR4fWCRjbGFzc2VzWiRjbGFzc25hbWWjHyAhXU5TTXV0YWJsZURhdGFWTlNEYXRhWE5TT2JqZWN0XxAkLi4vLi4vLi4vTGl0ZXJhdHVyZS9IYXVzZXIwNmxlY3R1cmUz0hwdJCWiJSFcTlNEaWN0aW9uYXJ5EgABhqBfEA9OU0tleWVkQXJjaGl2ZXIACAARABYAHwAoADIANQA6ADwARQBLAFIAXQBlAGwAbwBxAHMAdgB4AHoAfACGAJMAmACgAjACMgI3AkACSwJPAl0CZAJtApQCmQKcAqkCrgAAAAAAAAIBAAAAAAAAACgAAAAAAAAAAAAAAAAAAALA}, - Bdsk-File-4 = {YnBsaXN0MDDUAQIDBAUIJidUJHRvcFgkb2JqZWN0c1gkdmVyc2lvblkkYXJjaGl2ZXLRBgdUcm9vdIABqAkKFRYXGyIjVSRudWxs0wsMDQ4RFFpOUy5vYmplY3RzV05TLmtleXNWJGNsYXNzog8QgASABqISE4ACgAOAB1lhbGlhc0RhdGFccmVsYXRpdmVQYXRo0hgNGRpXTlMuZGF0YU8RAYwAAAAAAYwAAgAADE1hY2ludG9zaCBIRAAAAAAAAAAAAAAAAAAAAMpAsaxIKwAAAD/T8xBIYXVzZXIwNmxlY3R1cmU0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQn+vv+qSpwAAAAAAAAAAAAMAAgAACSAAAAAAAAAAAAAAAAAAAAAKTGl0ZXJhdHVyZQAQAAgAAMpA6ewAAAARAAgAAL/q2PcAAAABAAwAP9PzAAUCJwAAvuwAAgA5TWFjaW50b3NoIEhEOlVzZXJzOgByaWNoYXJkOgBMaXRlcmF0dXJlOgBIYXVzZXIwNmxlY3R1cmU0AAAOACIAEABIAGEAdQBzAGUAcgAwADYAbABlAGMAdAB1AHIAZQA0AA8AGgAMAE0AYQBjAGkAbgB0AG8AcwBoACAASABEABIAKVVzZXJzL3JpY2hhcmQvTGl0ZXJhdHVyZS9IYXVzZXIwNmxlY3R1cmU0AAATAAEvAAAVAAIADv//AACABdIcHR4fWCRjbGFzc2VzWiRjbGFzc25hbWWjHyAhXU5TTXV0YWJsZURhdGFWTlNEYXRhWE5TT2JqZWN0XxAkLi4vLi4vLi4vTGl0ZXJhdHVyZS9IYXVzZXIwNmxlY3R1cmU00hwdJCWiJSFcTlNEaWN0aW9uYXJ5EgABhqBfEA9OU0tleWVkQXJjaGl2ZXIACAARABYAHwAoADIANQA6ADwARQBLAFIAXQBlAGwAbwBxAHMAdgB4AHoAfACGAJMAmACgAjACMgI3AkACSwJPAl0CZAJtApQCmQKcAqkCrgAAAAAAAAIBAAAAAAAAACgAAAAAAAAAAAAAAAAAAALA}, - Bdsk-File-5 = {YnBsaXN0MDDUAQIDBAUIJidUJHRvcFgkb2JqZWN0c1gkdmVyc2lvblkkYXJjaGl2ZXLRBgdUcm9vdIABqAkKFRYXGyIjVSRudWxs0wsMDQ4RFFpOUy5vYmplY3RzV05TLmtleXNWJGNsYXNzog8QgASABqISE4ACgAOAB1lhbGlhc0RhdGFccmVsYXRpdmVQYXRo0hgNGRpXTlMuZGF0YU8RAYwAAAAAAYwAAgAADE1hY2ludG9zaCBIRAAAAAAAAAAAAAAAAAAAAMpAsaxIKwAAAD/T8xBIYXVzZXIwNmxlY3R1cmU1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQn+5v+qSqAAAAAAAAAAAAAMAAgAACSAAAAAAAAAAAAAAAAAAAAAKTGl0ZXJhdHVyZQAQAAgAAMpA6ewAAAARAAgAAL/q2PgAAAABAAwAP9PzAAUCJwAAvuwAAgA5TWFjaW50b3NoIEhEOlVzZXJzOgByaWNoYXJkOgBMaXRlcmF0dXJlOgBIYXVzZXIwNmxlY3R1cmU1AAAOACIAEABIAGEAdQBzAGUAcgAwADYAbABlAGMAdAB1AHIAZQA1AA8AGgAMAE0AYQBjAGkAbgB0AG8AcwBoACAASABEABIAKVVzZXJzL3JpY2hhcmQvTGl0ZXJhdHVyZS9IYXVzZXIwNmxlY3R1cmU1AAATAAEvAAAVAAIADv//AACABdIcHR4fWCRjbGFzc2VzWiRjbGFzc25hbWWjHyAhXU5TTXV0YWJsZURhdGFWTlNEYXRhWE5TT2JqZWN0XxAkLi4vLi4vLi4vTGl0ZXJhdHVyZS9IYXVzZXIwNmxlY3R1cmU10hwdJCWiJSFcTlNEaWN0aW9uYXJ5EgABhqBfEA9OU0tleWVkQXJjaGl2ZXIACAARABYAHwAoADIANQA6ADwARQBLAFIAXQBlAGwAbwBxAHMAdgB4AHoAfACGAJMAmACgAjACMgI3AkACSwJPAl0CZAJtApQCmQKcAqkCrgAAAAAAAAIBAAAAAAAAACgAAAAAAAAAAAAAAAAAAALA}, - Bdsk-File-6 = {YnBsaXN0MDDUAQIDBAUIJidUJHRvcFgkb2JqZWN0c1gkdmVyc2lvblkkYXJjaGl2ZXLRBgdUcm9vdIABqAkKFRYXGyIjVSRudWxs0wsMDQ4RFFpOUy5vYmplY3RzV05TLmtleXNWJGNsYXNzog8QgASABqISE4ACgAOAB1lhbGlhc0RhdGFccmVsYXRpdmVQYXRo0hgNGRpXTlMuZGF0YU8RAYwAAAAAAYwAAgAADE1hY2ludG9zaCBIRAAAAAAAAAAAAAAAAAAAAMpAsaxIKwAAAD/T8xBIYXVzZXIwNmxlY3R1cmU2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQn/Fv+qSqgAAAAAAAAAAAAMAAgAACSAAAAAAAAAAAAAAAAAAAAAKTGl0ZXJhdHVyZQAQAAgAAMpA6ewAAAARAAgAAL/q2PoAAAABAAwAP9PzAAUCJwAAvuwAAgA5TWFjaW50b3NoIEhEOlVzZXJzOgByaWNoYXJkOgBMaXRlcmF0dXJlOgBIYXVzZXIwNmxlY3R1cmU2AAAOACIAEABIAGEAdQBzAGUAcgAwADYAbABlAGMAdAB1AHIAZQA2AA8AGgAMAE0AYQBjAGkAbgB0AG8AcwBoACAASABEABIAKVVzZXJzL3JpY2hhcmQvTGl0ZXJhdHVyZS9IYXVzZXIwNmxlY3R1cmU2AAATAAEvAAAVAAIADv//AACABdIcHR4fWCRjbGFzc2VzWiRjbGFzc25hbWWjHyAhXU5TTXV0YWJsZURhdGFWTlNEYXRhWE5TT2JqZWN0XxAkLi4vLi4vLi4vTGl0ZXJhdHVyZS9IYXVzZXIwNmxlY3R1cmU20hwdJCWiJSFcTlNEaWN0aW9uYXJ5EgABhqBfEA9OU0tleWVkQXJjaGl2ZXIACAARABYAHwAoADIANQA6ADwARQBLAFIAXQBlAGwAbwBxAHMAdgB4AHoAfACGAJMAmACgAjACMgI3AkACSwJPAl0CZAJtApQCmQKcAqkCrgAAAAAAAAIBAAAAAAAAACgAAAAAAAAAAAAAAAAAAALA}, - Bdsk-File-7 = {YnBsaXN0MDDUAQIDBAUIJidUJHRvcFgkb2JqZWN0c1gkdmVyc2lvblkkYXJjaGl2ZXLRBgdUcm9vdIABqAkKFRYXGyIjVSRudWxs0wsMDQ4RFFpOUy5vYmplY3RzV05TLmtleXNWJGNsYXNzog8QgASABqISE4ACgAOAB1lhbGlhc0RhdGFccmVsYXRpdmVQYXRo0hgNGRpXTlMuZGF0YU8RAYwAAAAAAYwAAgAADE1hY2ludG9zaCBIRAAAAAAAAAAAAAAAAAAAAMpAsaxIKwAAAD/T8xBIYXVzZXIwNmxlY3R1cmU3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQn/Pv+qSrAAAAAAAAAAAAAMAAgAACSAAAAAAAAAAAAAAAAAAAAAKTGl0ZXJhdHVyZQAQAAgAAMpA6ewAAAARAAgAAL/q2PwAAAABAAwAP9PzAAUCJwAAvuwAAgA5TWFjaW50b3NoIEhEOlVzZXJzOgByaWNoYXJkOgBMaXRlcmF0dXJlOgBIYXVzZXIwNmxlY3R1cmU3AAAOACIAEABIAGEAdQBzAGUAcgAwADYAbABlAGMAdAB1AHIAZQA3AA8AGgAMAE0AYQBjAGkAbgB0AG8AcwBoACAASABEABIAKVVzZXJzL3JpY2hhcmQvTGl0ZXJhdHVyZS9IYXVzZXIwNmxlY3R1cmU3AAATAAEvAAAVAAIADv//AACABdIcHR4fWCRjbGFzc2VzWiRjbGFzc25hbWWjHyAhXU5TTXV0YWJsZURhdGFWTlNEYXRhWE5TT2JqZWN0XxAkLi4vLi4vLi4vTGl0ZXJhdHVyZS9IYXVzZXIwNmxlY3R1cmU30hwdJCWiJSFcTlNEaWN0aW9uYXJ5EgABhqBfEA9OU0tleWVkQXJjaGl2ZXIACAARABYAHwAoADIANQA6ADwARQBLAFIAXQBlAGwAbwBxAHMAdgB4AHoAfACGAJMAmACgAjACMgI3AkACSwJPAl0CZAJtApQCmQKcAqkCrgAAAAAAAAIBAAAAAAAAACgAAAAAAAAAAAAAAAAAAALA}} + howpublished = {\href{http://www.numerical.rl.ac.uk/nimg/oupartc/lectures/raphael/}{link}}, +} diff --git a/doc/trustregion.lyx b/doc/trustregion.lyx index bc4393fdf..97bc6ec74 100644 --- a/doc/trustregion.lyx +++ b/doc/trustregion.lyx @@ -1,10 +1,11 @@ -#LyX 2.0 created this file. For more info see http://www.lyx.org/ -\lyxformat 413 +#LyX 2.1 created this file. For more info see http://www.lyx.org/ +\lyxformat 474 \begin_document \begin_header \textclass article \begin_preamble -\usepackage{amssymb} +\usepackage{url} +\usepackage{hyperref} \end_preamble \use_default_options true \maintain_unincluded_children false @@ -15,13 +16,13 @@ \font_roman default \font_sans default \font_typewriter default +\font_math auto \font_default_family default \use_non_tex_fonts false \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 - \graphics default \default_output_format default \output_sync 0 @@ -32,15 +33,24 @@ \use_hyperref false \papersize default \use_geometry false -\use_amsmath 1 -\use_esint 1 -\use_mhchem 1 -\use_mathdots 1 +\use_package amsmath 1 +\use_package amssymb 2 +\use_package cancel 1 +\use_package esint 1 +\use_package mathdots 1 +\use_package mathtools 1 +\use_package mhchem 1 +\use_package stackrel 0 +\use_package stmaryrd 1 +\use_package undertilde 1 \cite_engine basic +\cite_engine_type default +\biblio_style plain \use_bibtopic false \use_indices false \paperorientation portrait \suppress_date false +\justification true \use_refstyle 1 \index Index \shortcut idx @@ -231,7 +241,7 @@ key "Hauser06lecture" \end_inset - (in our /net/hp223/borg/Literature folder). +. \end_layout \begin_layout Standard @@ -465,22 +475,39 @@ where \end_inset . - A typical update rule [ -\color blue -see where this came from in paper -\color inherit -] is + A typical update rule, as per Lec. + 7-1.2 of +\begin_inset CommandInset citation +LatexCommand cite +key "Hauser06lecture" + +\end_inset + + is: \begin_inset Formula \[ -\Delta\leftarrow\begin{cases} -\max\left(\Delta,3\norm{\delta x_{d}}\right)\text{,} & \rho>0.75\\ -\Delta & 0.75>\rho>0.25\\ -\Delta/2 & 0.25>\rho +\Delta_{k+1}\leftarrow\begin{cases} +\Delta_{k}/4 & \rho<0.25\\ +\min\left(2\Delta_{k},\Delta_{max}\right)\text{,} & \rho>0.75\\ +\Delta_{k} & 0.75>\rho>0.25 \end{cases} \] \end_inset +where +\begin_inset Formula $\Delta_{k}\triangleq\norm{\delta x_{d}}$ +\end_inset + +. + Note that the rule is designed to ensure that +\begin_inset Formula $\Delta_{k}$ +\end_inset + +never exceeds the maximum trust region size +\begin_inset Formula $\Delta_{max}.$ +\end_inset + \end_layout @@ -593,9 +620,9 @@ To find the intersection of the line between \begin{align*} \Delta & =\norm{\left(1-\tau\right)\delta x_{u}+\tau\delta x_{n}}\\ \Delta^{2} & =\left(1-\tau\right)^{2}\delta x_{u}^{\t}\delta x_{u}+2\tau\left(1-\tau\right)\delta x_{u}^{\t}\delta x_{n}+\tau^{2}\delta x_{n}^{\t}\delta x_{n}\\ -0 & =uu-2\tau uu+\tau^{2}uu+2\tau un-2\tau^{2}un+\tau^{2}nn-\Delta^{2}\\ -0 & =\left(uu-2un+nn\right)\tau^{2}+\left(2un-2uu\right)\tau-\Delta^{2}+uu\\ -\tau & =\frac{-\left(2un-2uu\right)\pm\sqrt{\left(2un-2uu\right)^{2}-4\left(uu-2un+nn\right)\left(uu-\Delta^{2}\right)}}{2\left(uu-un+nn\right)} +0 & =\delta x_{u}^{\t}\delta x_{u}-2\tau\delta x_{u}^{\t}\delta x_{u}+\tau^{2}\delta x_{u}^{\t}\delta x_{u}+2\tau\delta x_{u}^{\t}\delta x_{n}-2\tau^{2}\delta x_{u}^{\t}\delta x_{n}+\tau^{2}\delta x_{n}^{\t}\delta x_{n}-\Delta^{2}\\ +0 & =\left(\delta x_{u}^{\t}\delta x_{u}-2\delta x_{u}^{\t}\delta x_{n}+\delta x_{n}^{\t}\delta x_{n}\right)\tau^{2}+\left(2\delta x_{u}^{\t}\delta x_{n}-2\delta x_{u}^{\t}\delta x_{u}\right)\tau-\Delta^{2}+\delta x_{u}^{\t}\delta x_{u}\\ +\tau & =\frac{-\left(2\delta x_{u}^{\t}\delta x_{n}-2\delta x_{u}^{\t}\delta x_{u}\right)\pm\sqrt{\left(2\delta x_{u}^{\t}\delta x_{n}-2\delta x_{u}^{\t}\delta x_{u}\right)^{2}-4\left(\delta x_{u}^{\t}\delta x_{u}-2\delta x_{u}^{\t}\delta x_{n}+\delta x_{n}^{\t}\delta x_{n}\right)\left(\delta x_{u}^{\t}\delta x_{u}-\Delta^{2}\right)}}{2\left(\delta x_{u}^{\t}\delta x_{u}-\delta x_{u}^{\t}\delta x_{n}+\delta x_{n}^{\t}\delta x_{n}\right)} \end{align*} \end_inset @@ -641,7 +668,7 @@ Thus, mathematically, we can write the dogleg update \begin_inset Formula \[ \delta x_{d}^{\left(k\right)}=\begin{cases} --\frac{\Delta}{\norm{g^{\left(k\right)}}}g^{\left(k\right)}\text{,} & \Delta<\norm{\delta x_{u}^{\left(k\right)}}\\ +-\frac{\Delta}{\norm{\delta x_{u}^{\left(k\right)}}}\delta x_{u}^{\left(k\right)}\text{,} & \Delta<\norm{\delta x_{u}^{\left(k\right)}}\\ \left(1-\tau^{\left(k\right)}\right)\delta x_{u}^{\left(k\right)}+\tau^{\left(k\right)}\delta x_{n}^{\left(k\right)}\text{,} & \norm{\delta x_{u}^{\left(k\right)}}<\Delta<\norm{\delta x_{n}^{\left(k\right)}}\\ \delta x_{n}^{\left(k\right)}\text{,} & \norm{\delta x_{n}^{\left(k\right)}}<\Delta \end{cases} diff --git a/doc/trustregion.pdf b/doc/trustregion.pdf index 31ca0c5b1..22dcac035 100644 Binary files a/doc/trustregion.pdf and b/doc/trustregion.pdf differ diff --git a/gtsam/base/Vector.h b/gtsam/base/Vector.h index 91aec85b8..74cb89918 100644 --- a/gtsam/base/Vector.h +++ b/gtsam/base/Vector.h @@ -63,6 +63,19 @@ GTSAM_MAKE_VECTOR_DEFS(12); typedef Eigen::VectorBlock SubVector; typedef Eigen::VectorBlock ConstSubVector; +/** + * Ensure we are not including a different version of Eigen in user code than + * while compiling gtsam, since it can lead to hard-to-understand runtime + * crashes. + */ +#if defined(GTSAM_EIGEN_VERSION_WORLD) +static_assert( + GTSAM_EIGEN_VERSION_WORLD==EIGEN_WORLD_VERSION && + GTSAM_EIGEN_VERSION_MAJOR==EIGEN_MAJOR_VERSION && + GTSAM_EIGEN_VERSION_MINOR==EIGEN_MINOR_VERSION, + "Error: GTSAM was built against a different version of Eigen"); +#endif + /** * print without optional string, must specify cout yourself */ diff --git a/gtsam/config.h.in b/gtsam/config.h.in index 8433f19b0..92380f8eb 100644 --- a/gtsam/config.h.in +++ b/gtsam/config.h.in @@ -52,6 +52,12 @@ // Whether Eigen with MKL will use OpenMP (if OpenMP was found, Eigen uses MKL, and GTSAM_WITH_EIGEN_MKL_OPENMP is enabled in CMake) #cmakedefine GTSAM_USE_EIGEN_MKL_OPENMP +// Eigen library version (needed to avoid mixing versions, which often leads +// to segfaults) +#cmakedefine GTSAM_EIGEN_VERSION_WORLD @GTSAM_EIGEN_VERSION_WORLD@ +#cmakedefine GTSAM_EIGEN_VERSION_MAJOR @GTSAM_EIGEN_VERSION_MAJOR@ +#cmakedefine GTSAM_EIGEN_VERSION_MINOR @GTSAM_EIGEN_VERSION_MINOR@ + // The default allocator to use #cmakedefine GTSAM_ALLOCATOR_BOOSTPOOL #cmakedefine GTSAM_ALLOCATOR_TBB diff --git a/gtsam/inference/BayesTree-inst.h b/gtsam/inference/BayesTree-inst.h index 16a11cc34..4df234004 100644 --- a/gtsam/inference/BayesTree-inst.h +++ b/gtsam/inference/BayesTree-inst.h @@ -36,19 +36,20 @@ namespace gtsam { /* ************************************************************************* */ template BayesTreeCliqueData BayesTree::getCliqueData() const { - BayesTreeCliqueData data; - for(const sharedClique& root: roots_) - getCliqueData(data, root); - return data; + BayesTreeCliqueData stats; + for (const sharedClique& root : roots_) getCliqueData(root, &stats); + return stats; } /* ************************************************************************* */ - template - void BayesTree::getCliqueData(BayesTreeCliqueData& data, sharedClique clique) const { - data.conditionalSizes.push_back(clique->conditional()->nrFrontals()); - data.separatorSizes.push_back(clique->conditional()->nrParents()); - for(sharedClique c: clique->children) { - getCliqueData(data, c); + template + void BayesTree::getCliqueData(sharedClique clique, + BayesTreeCliqueData* stats) const { + const auto conditional = clique->conditional(); + stats->conditionalSizes.push_back(conditional->nrFrontals()); + stats->separatorSizes.push_back(conditional->nrParents()); + for (sharedClique c : clique->children) { + getCliqueData(c, stats); } } @@ -133,34 +134,26 @@ namespace gtsam { } /* ************************************************************************* */ - // TODO: Clean up namespace { - template - int _pushClique(FactorGraph& fg, const boost::shared_ptr& clique) { - fg.push_back(clique->conditional_); + template + struct _pushCliqueFunctor { + _pushCliqueFunctor(FactorGraph* graph_) : graph(graph_) {} + FactorGraph* graph; + int operator()(const boost::shared_ptr& clique, int dummy) { + graph->push_back(clique->conditional_); return 0; } - - template - struct _pushCliqueFunctor { - _pushCliqueFunctor(FactorGraph& graph_) : graph(graph_) {} - FactorGraph& graph; - int operator()(const boost::shared_ptr& clique, int dummy) { - graph.push_back(clique->conditional_); - return 0; - } - }; - } + }; + } // namespace /* ************************************************************************* */ - template - void BayesTree::addFactorsToGraph(FactorGraph& graph) const - { + template + void BayesTree::addFactorsToGraph( + FactorGraph* graph) const { // Traverse the BayesTree and add all conditionals to this graph - int data = 0; // Unused - _pushCliqueFunctor functor(graph); - treeTraversal::DepthFirstForest(*this, data, functor); // FIXME: sort of works? -// treeTraversal::DepthFirstForest(*this, data, boost::bind(&_pushClique, boost::ref(graph), _1)); + int data = 0; // Unused + _pushCliqueFunctor functor(graph); + treeTraversal::DepthFirstForest(*this, data, functor); } /* ************************************************************************* */ @@ -434,51 +427,51 @@ namespace gtsam { } /* ************************************************************************* */ - template - void BayesTree::removePath(sharedClique clique, BayesNetType& bn, Cliques& orphans) - { + template + void BayesTree::removePath(sharedClique clique, BayesNetType* bn, + Cliques* orphans) { // base case is NULL, if so we do nothing and return empties above if (clique) { - // remove the clique from orphans in case it has been added earlier - orphans.remove(clique); + orphans->remove(clique); // remove me this->removeClique(clique); // remove path above me - this->removePath(typename Clique::shared_ptr(clique->parent_.lock()), bn, orphans); + this->removePath(typename Clique::shared_ptr(clique->parent_.lock()), bn, + orphans); - // add children to list of orphans (splice also removed them from clique->children_) - orphans.insert(orphans.begin(), clique->children.begin(), clique->children.end()); + // add children to list of orphans (splice also removed them from + // clique->children_) + orphans->insert(orphans->begin(), clique->children.begin(), + clique->children.end()); clique->children.clear(); - bn.push_back(clique->conditional_); - + bn->push_back(clique->conditional_); } } - /* ************************************************************************* */ - template - void BayesTree::removeTop(const KeyVector& keys, BayesNetType& bn, Cliques& orphans) - { + /* ************************************************************************* + */ + template + void BayesTree::removeTop(const KeyVector& keys, BayesNetType* bn, + Cliques* orphans) { gttic(removetop); // process each key of the new factor - for(const Key& j: keys) - { + for (const Key& j : keys) { // get the clique - // TODO: Nodes will be searched again in removeClique + // TODO(frank): Nodes will be searched again in removeClique typename Nodes::const_iterator node = nodes_.find(j); - if(node != nodes_.end()) { + if (node != nodes_.end()) { // remove path from clique to root this->removePath(node->second, bn, orphans); } } // Delete cachedShortcuts for each orphan subtree - //TODO: Consider Improving - for(sharedClique& orphan: orphans) - orphan->deleteCachedShortcuts(); + // TODO(frank): Consider Improving + for (sharedClique& orphan : *orphans) orphan->deleteCachedShortcuts(); } /* ************************************************************************* */ diff --git a/gtsam/inference/BayesTree.h b/gtsam/inference/BayesTree.h index c221a5ed6..9d632ff06 100644 --- a/gtsam/inference/BayesTree.h +++ b/gtsam/inference/BayesTree.h @@ -208,13 +208,13 @@ namespace gtsam { * Remove path from clique to root and return that path as factors * plus a list of orphaned subtree roots. Used in removeTop below. */ - void removePath(sharedClique clique, BayesNetType& bn, Cliques& orphans); + void removePath(sharedClique clique, BayesNetType* bn, Cliques* orphans); /** * Given a list of indices, turn "contaminated" part of the tree back into a factor graph. * Factors and orphans are added to the in/out arguments. */ - void removeTop(const KeyVector& keys, BayesNetType& bn, Cliques& orphans); + void removeTop(const KeyVector& keys, BayesNetType* bn, Cliques* orphans); /** * Remove the requested subtree. */ @@ -229,7 +229,7 @@ namespace gtsam { void addClique(const sharedClique& clique, const sharedClique& parent_clique = sharedClique()); /** Add all cliques in this BayesTree to the specified factor graph */ - void addFactorsToGraph(FactorGraph& graph) const; + void addFactorsToGraph(FactorGraph* graph) const; protected: @@ -238,7 +238,7 @@ namespace gtsam { int parentnum = 0) const; /** Gather data on a single clique */ - void getCliqueData(BayesTreeCliqueData& stats, sharedClique clique) const; + void getCliqueData(sharedClique clique, BayesTreeCliqueData* stats) const; /** remove a clique: warning, can result in a forest */ void removeClique(sharedClique clique); @@ -249,7 +249,26 @@ namespace gtsam { // Friend JunctionTree because it directly fills roots and nodes index. template friend class EliminatableClusterTree; - private: +#ifdef GTSAM_ALLOW_DEPRECATED_SINCE_V4 + public: + /// @name Deprecated + /// @{ + void removePath(sharedClique clique, BayesNetType& bn, Cliques& orphans) { + removePath(clique, &bn, &orphans); + } + void removeTop(const KeyVector& keys, BayesNetType& bn, Cliques& orphans) { + removeTop(keys, &bn, &orphans); + } + void getCliqueData(BayesTreeCliqueData& stats, sharedClique clique) const { + getCliqueData(clique, &stats); + } + void addFactorsToGraph(FactorGraph& graph) const{ + addFactorsToGraph(& graph); + } + /// @} +#endif + + private: /** Serialization function */ friend class boost::serialization::access; template diff --git a/gtsam/inference/FactorGraph.h b/gtsam/inference/FactorGraph.h index 0959989f9..600e3f9ed 100644 --- a/gtsam/inference/FactorGraph.h +++ b/gtsam/inference/FactorGraph.h @@ -270,7 +270,7 @@ class FactorGraph { typename std::enable_if< std::is_base_of::value>::type push_back(const BayesTree& bayesTree) { - bayesTree.addFactorsToGraph(*this); + bayesTree.addFactorsToGraph(this); } /** diff --git a/gtsam/inference/ISAM-inst.h b/gtsam/inference/ISAM-inst.h index 8ed41826e..1c183b70f 100644 --- a/gtsam/inference/ISAM-inst.h +++ b/gtsam/inference/ISAM-inst.h @@ -24,14 +24,14 @@ namespace gtsam { /* ************************************************************************* */ template -void ISAM::update_internal(const FactorGraphType& newFactors, - Cliques& orphans, const Eliminate& function) { +void ISAM::updateInternal(const FactorGraphType& newFactors, + Cliques* orphans, const Eliminate& function) { // Remove the contaminated part of the Bayes tree BayesNetType bn; const KeySet newFactorKeys = newFactors.keys(); if (!this->empty()) { KeyVector keyVector(newFactorKeys.begin(), newFactorKeys.end()); - this->removeTop(keyVector, bn, orphans); + this->removeTop(keyVector, &bn, orphans); } // Add the removed top and the new factors @@ -40,7 +40,7 @@ void ISAM::update_internal(const FactorGraphType& newFactors, factors += newFactors; // Add the orphaned subtrees - for (const sharedClique& orphan : orphans) + for (const sharedClique& orphan : *orphans) factors += boost::make_shared >(orphan); // Get an ordering where the new keys are eliminated last @@ -62,7 +62,7 @@ template void ISAM::update(const FactorGraphType& newFactors, const Eliminate& function) { Cliques orphans; - this->update_internal(newFactors, orphans, function); + this->updateInternal(newFactors, &orphans, function); } } diff --git a/gtsam/inference/ISAM.h b/gtsam/inference/ISAM.h index d6a40b539..fe6763a13 100644 --- a/gtsam/inference/ISAM.h +++ b/gtsam/inference/ISAM.h @@ -22,56 +22,67 @@ namespace gtsam { +/** + * A Bayes tree with an update methods that implements the iSAM algorithm. + * Given a set of new factors, it re-eliminates the invalidated part of the + * tree. \nosubgrouping + */ +template +class ISAM : public BAYESTREE { + public: + typedef BAYESTREE Base; + typedef typename Base::BayesNetType BayesNetType; + typedef typename Base::FactorGraphType FactorGraphType; + typedef typename Base::Clique Clique; + typedef typename Base::sharedClique sharedClique; + typedef typename Base::Cliques Cliques; + + private: + typedef typename Base::Eliminate Eliminate; + typedef typename Base::EliminationTraitsType EliminationTraitsType; + + public: + /// @name Standard Constructors + /// @{ + + /** Create an empty Bayes Tree */ + ISAM() {} + + /** Copy constructor */ + explicit ISAM(const Base& bayesTree) : Base(bayesTree) {} + + /// @} + /// @name Advanced Interface Interface + /// @{ + /** - * A Bayes tree with an update methods that implements the iSAM algorithm. - * Given a set of new factors, it re-eliminates the invalidated part of the tree. - * \nosubgrouping + * update the Bayes tree with a set of new factors, typically derived from + * measurements + * @param newFactors is a factor graph that contains the new factors + * @param function an elimination routine */ - template - class ISAM: public BAYESTREE - { - public: - - typedef BAYESTREE Base; - typedef typename Base::BayesNetType BayesNetType; - typedef typename Base::FactorGraphType FactorGraphType; - typedef typename Base::Clique Clique; - typedef typename Base::sharedClique sharedClique; - typedef typename Base::Cliques Cliques; - - private: - - typedef typename Base::Eliminate Eliminate; - typedef typename Base::EliminationTraitsType EliminationTraitsType; - - public: - - /// @name Standard Constructors - /// @{ - - /** Create an empty Bayes Tree */ - ISAM() {} - - /** Copy constructor */ - ISAM(const Base& bayesTree) : Base(bayesTree) {} - - /// @} - /// @name Advanced Interface Interface - /// @{ - - /** - * update the Bayes tree with a set of new factors, typically derived from measurements - * @param newFactors is a factor graph that contains the new factors - * @param function an elimination routine - */ - void update(const FactorGraphType& newFactors, const Eliminate& function = EliminationTraitsType::DefaultEliminate); - - /** update_internal provides access to list of orphans for drawing purposes */ - void update_internal(const FactorGraphType& newFactors, Cliques& orphans, + void update( + const FactorGraphType& newFactors, const Eliminate& function = EliminationTraitsType::DefaultEliminate); - /// @} + /** updateInternal provides access to list of orphans for drawing purposes + */ + void updateInternal( + const FactorGraphType& newFactors, Cliques* orphans, + const Eliminate& function = EliminationTraitsType::DefaultEliminate); - }; + /// @} -}/// namespace gtsam +#ifdef GTSAM_ALLOW_DEPRECATED_SINCE_V4 + /// @name Deprecated + /// @{ + void update_internal( + const FactorGraphType& newFactors, Cliques& orphans, + const Eliminate& function = EliminationTraitsType::DefaultEliminate) { + updateInternal(newFactors, &orphans, function); + } + /// @} +#endif +}; + +} // namespace gtsam